课程代码 :04830100 EDA 和 Verilog HDL 专题 佟冬 Microprocessor R&D Center tongdong@mprc.pku.edu.cn http://mprc.pku.edu.cn/courses/digital/2011fall 1
电子设计自动化软件 CAD, Computer-aid Design EDA, Electronic Design Automatic ESL, Electronic System Level 系统设计 (C/C++,SystemC) 设计输入 (Verilog, VHDL, Schematic) 设计验证 设计综合 (ASIC, FPGA, Analog) 后端 (Back-end) 设计 2
1 设计输入 Design Entry 原理图输入 激励和输出逻辑方程 状态表 状态图或者 ASM 图 硬件描述语言 Verilog VHDL 3
2 综合 Synthesis 状态优化 选择状态分配方案 选择触发器类型 对组合逻辑进行优化 4
3 设计验证 Verification 功能分析与验证 模拟 Simulation 形式化验证 Formal Verification 时序分析 Timing Analysis Timing Methodology 5
4 后端 (Back-end) 设计 时钟树生成 Place & Route 参数提取, 后仿真 物理验证 ( 信号完整性分析等 ) 形成加工工艺文件 FPGA ASIC, GDSII 6
MaxPlusII 的界面 7
产生一个原理图文件 8
原理图编辑界面 9
放置元器件和画连线 10
异或门电路的实现 11
放置输入 / 输出端口并命名 Input/Output/Bidir 12
建立项目 project 保存文件, 定义文件名 建立项目名称, 与文件名一致 File->Project->Set Project to Current File 综合 :Maxp+Plus II->Compiler 修改设计错误 13
时序分析 Timing Analysis Max+Plus II->Timing Analyzer 14
模拟验证 建立波形文件 保存相同的目录文件名 15
输入激励向量和观察输出 Node->Enter Nodes From SNF File->End Time 定义模拟时间 Option->Grid 定义时钟周期单位 输入所有输入端口的波形 ( 时钟 /Reset) Max+Plus II->Simulator 16
查看输出波形文件验证设计功能 17
硬件描述语言 HDL Hardware description languages 在多种抽象级别上描述硬件 结构级描述 (Structural description) 原理图的文本替代 功能模块 (module) 的模块层次化组合 行为级 / 功能级描述 (Behavioral/functional description) 描写模块做什么? 而不描述如何做 可综合产生模块电路 模拟语义 18
硬件描述语言 HDLs Abel (~1983) - Data-I/O 开发 面向可编程逻辑器件 对状态机的支持不足够得好 ISP (~1977) CMU 研究项目 面向模拟, 不能综合 Verilog (~1985) - Gateway 开发 ( 被 Cadence 合并 ) 类 Pascal 和 C 语言 延迟 delays 只在模拟器中有效 很容易有效地编程 IEEE 标准 VHDL (~1987) 美国国防部 DoD 发起的标准 类 Ada 语言 ( 着重于可复用性和可维护性 ) 显式的模拟语义 很通用但也很繁琐 IEEE 标准 19
Verilog HDL 语言 支持结构级和行为级描述 结构级 电路的外在结构 如, 每个门的例化和门间的连接关系 行为级 程序描述电路的输入输出行为 许多结构级的实现可以有相同的行为 如, 一个布尔函数的不同实现 当前大多数采用行为级 Verilog 描述 用结构级描述来描述原理图 20
结构模型 Structural model module xor_gate (out, a, b); input a, b; output out; wire abar, bbar, t1, t2; inverter inva (abar, a); inverter invb (bbar, b); and_gate and1 (t1, a, bbar); and_gate and2 (t2, b, abar); or_gate or1 (out, t1, t2); endmodule 21
简单的行为模型 behavioral model 连续赋值 Continuous assignment Reg 和 Wire 的区别 module xor_gate (out, a, b); input a, b; output out; assign #6 out = a ^ b; endmodule 从输入变化到输出变化的延迟 模拟寄存器, 保持信号值的踪迹 22
简单的行为级模型 always 块 module xor_gate (out, a, b); input a, b; output out; reg out; always @(a or b) begin #6 out = a ^ b; end endmodule 敏感向量表, 表明块被执行的条件入, 信号跳变 23
通过 testbench 测试台 驱动模拟 module testbench (x, y); output x, y; reg [1:0] cnt; 2-bit 向量 initial begin cnt = 0; repeat (4) begin #10 cnt = cnt + 1; $display ("@ time=%d, x=%b, y=%b, cnt=%b", $time, x, y, cnt); end #10 $finish; end initial 块只在模拟开始时执行一次, 初始化不可综合, 只在模拟时有效 控制台打印 assign x = cnt[1]; assign y = cnt[0]; endmodule 停止模拟 24
完整的模拟 采用原理图例化激励模块和被测模块进行测试和验证 test-bench x y a b z 25
例子 : 比较器 Comparator module Compare1 (Equal, Alarger, Blarger, A, B); input A, B; output Equal, Alarger, Blarger; assign #5 Equal = (A & B) (~A & ~B); assign #3 Alarger = (A & ~B); assign #3 Blarger = (~A & B); endmodule 26
更复杂的行为级模型 module life (n0, n1, n2, n3, n4, n5, n6, n7, self, out); input n0, n1, n2, n3, n4, n5, n6, n7, self; output out; reg out; reg [3:0] count; reg [3:0] i; wire [7:0] neighbors; assign neighbors = {n7, n6, n5, n4, n3, n2, n1, n0}; always @(neighbors or self) begin count = 0; for (i = 0; i < 8; i = i+1) count = count + neighbors[i]; out = (count == 3); out = out ((self == 1) & (count == 2)); end endmodule 27
HDL 和编程语言的关系 程序结构 Program Structure 多次例化相同类型的模块 通过原理图表明模块之间的连接关系 模块的层次化结构 赋值 Assignment 连续赋值 continuous assignment ( 逻辑始终计算 ) 传播延迟 propagation delay ( 计算耗费时间 ) 信号时序非常重要 ( 计算的结果何时产生效果 ) 数据结构 Data structures 位宽显式的拼写出来, 不支持动态结构 不支持指针 并行性 Parallelism 硬件是自然地并行运行 ( 必须支持多线程 ) 赋值并行的发生 ( 不仅仅是串行执行的 ) 28
HDL 和组合逻辑 Modules: 说明输入, 输出, 双向和内部信号 连续赋值 : 一个门的输出任何时刻都是输入的函数结果 ( 不需要调用 ) 传播延迟 : 输入影响输出的时间和延迟的概念 构成 Composition: 通过线将模块连接在一起 层次化 : 模块分解成一些功能模块 29
电子手表的日历子系统 确定一个月的天数 ( 控制钟表的显示 ) 用来控制手表的 LCD 显示屏 integer number_of_days ( month, leap_year_flag); inputs: month, leap year flag outputs: number of days 采用软件实现可帮助理解问题 } switch (month) { case 1: return (31); case 2: if (leap_year_flag == 1) then return (29) else return (28); case 3: return (31); case 4: return (30); case 5: return (31); case 6: return (30); case 7: return (31); case 8: return (31); case 9: return (30); case 10: return (31); case 11: return (30); case 12: return (31); default: return (0); } 30
HDL 和时序逻辑 触发器 表示时钟, 状态变化的定时 同步和异步 移位寄存器 :Shift registers 简单的计数器 :Simple counters 31
Verilog 中的触发器 采用 always 块的敏感向量表 sensitivity list 等待时钟的边沿事件 module dff (clk, d, q); input clk, d; output q; reg q; always @(posedge clk) q = d; endmodule 上升沿 posedge, 下降沿 negedge 32
触发器 同步 / 异步的 reset/set 一个线等待时钟事件成 三个并行线程, 只有一个等待时钟事件 module dff (clk, s, r, d, q); input clk, s, r, d; output q; reg q; always @(posedge clk) if (r) q = 1'b0; else if (s) q = 1'b1; else q = d; endmodule 同步 异步 module dff (clk, s, r, d, q); input clk, s, r, d; output q; reg q; always @(posedge r) q = 1'b0; always @(posedge s) q = 1'b1; always @(posedge clk) q = d; endmodule 33
Verilog 中不正确的寄存器 采用 always 块的敏感向量表 sensitivity list 等待时钟的改变事件 module dff (clk, d, q); input clk, d; output q; reg q; always @(clk) q = d; endmodule 不正确! q 会在时钟的上升沿和下降沿都变化没有硬件的对应 34
阻塞 Blocking 和 非阻塞 Non-Blocking 赋值 阻塞赋值 Blocking assignments (X=A) 再执行下一条语句前完成赋值 非阻塞赋值 Non-blocking assignments (X<=A) 不改变变量值直到发生程序块的执行点 ( 延迟或等待 ) 例子 : swap always @(posedge CLK) begin temp = B; B = A; A = temp; end always @(posedge CLK) begin A <= B; B <= A; end 35
寄存器传输级 Register-transfer-level (RTL) 赋值 非阻塞赋值也成为 RTL 赋值 如果寄存器在一个等待时钟沿 always 块中 所有寄存器同时改变状态 // B,C,D all get the value of A always @(posedge clk) begin B = A; C = B; D = C; end // implements a shift register too always @(posedge clk) begin B <= A; C <= B; D <= C; end 36
Mobius 计数器 initial begin A 1 b0; B 1 b0; C 1 b0; D = 1 b0; end always @(posedge clk) begin A <= ~D; B <= A; C <= B; D <= C; end 37
二进制计数器 module binary_counter (clk, c8, c4, c2, c1); input clk; output c8, c4, c2, c1; reg [3:0] count; initial begin count = 0; end always @(posedge clk) begin count = count + 1; end assign c8 = count[3]; assign c4 = count[2]; assign c2 = count[1]; assign c1 = count[0]; endmodule module binary_counter (clk, c8, c4, c2, c1, rco); input clk; output c8, c4, c2, c1, rco; reg [3:0] count; reg rco; initial begin... end always @(posedge clk) begin... end assign c8 = count[3]; assign c4 = count[2]; assign c2 = count[1]; assign c1 = count[0]; assign rco = (count == 4b 1111); endmodule 38
连接操作 {expr1,, exprn} module binary_counter (clk, c8, c4, c2, c1, rco); input clk; output c8, c4, c2, c1, rco; reg [3:0] count; reg rco; initial begin end count = 0; always @(posedge clk) begin end {rco, count} = {1 b0, count} + 1; assign c8 = count[3]; assign c4 = count[2]; assign c2 = count[1]; assign c1 = count[0]; endmodule 39
硬件描述语言和时序逻辑 有穷状态自动机 FSM 结构级特点 : 触发器和组合逻辑分离 行为级特点 : 状态转换和输出逻辑 数据通路 = 数据计算 + 寄存器 算术或逻辑操作 存储控制单元 40
FSM 例子 从连续的 1 中去掉一个 1 Moore Mealy zero [0] 1 0 zero [0] 0/0 0 0 one1 [0] 1 two1s [1] 1 0/0 one1 [0] 1/0 1/1 41
Verilog 状态机 Moore 机 module reduce (clk, reset, in, out); input clk, reset, in; output out; 状态分配, ( 在一个地方容易改 ) parameter zero = 2 b00; parameter one1 = 2 b01; parameter two1s = 2 b10; reg out; reg [2:1] state; // state variables reg [2:1] next_state; always @(posedge clk) if (reset) state = zero; else state = next_state; 0 0 zero [0] 1 one1 [0] 1 two1s [1] 0 1 42
Moore 机 ( 续 ) always @(in or state) case (state) zero: // last input was a zero begin if (in) next_state = one1; else next_state = zero; end one1: // we've seen one 1 begin if (in) next_state = two1s; else next_state = zero; end two1s: // we've seen at least 2 ones begin if (in) next_state = two1s; else next_state = zero; end endcase 一定要包括所有的输入 状态一定要完备最好有 default 条件否则产生 Latch, 非常危险 注意输出有状态决定 always @(state) case (state) zero: out = 0; one1: out = 0; two1s: out = 1; endcase endmodule 43
Mealy 机 module reduce (clk, reset, in, out); input clk, reset, in; output out; reg out; reg state; // state variables reg next_state; always @(posedge clk) if (reset) state = zero; else state = next_state; always @(in or state) case (state) zero: // last input was a zero begin out = 0; if (in) next_state = one; else next_state = zero; end one: // we've seen one 1 if (in) begin next_state = one; out = 1; end else begin next_state = zero; out = 0; end endcase endmodule 0/0 zero [0] one1 [0] 1/0 0/0 1/1 44
Maxplus II 实例演示 四位加法器 模 9 异步清零加法器 注意冒险! 45