[文档].艾米电子 - 触发器与锁存器,Verilog
对读者的假设
已经掌握:
内容
1 D触发器
这里从D触发器来开始时序逻辑的学习。数字电路的课上会设计很多的触发器,此处仅以简单的D触发器和T触发器为例。关于其真值表,请自行查找数字电路参考书学习。
1.1 同步复位D触发器
首先需要明白的概念上同步复位和异步复位的区别。所谓同步复位,指的是同步复位信号就是指复位信号只在所需时钟边沿到来时才有效,其他时刻则无效。一般情况下,只要复位信号持续时间大于一个时钟周期,就可以保证正确复位。
图1.1.1 同步复位的D触发器
代码1.1 同步复位的D-ff
module d_ff( input CLK, input RST_n, input D, output reg Q, output Q_n ); always @ (posedge CLK) if (!RST_n) Q <= 1'b0; else Q <= D; assign Q_n = ~Q; endmodule
在Quartus II中,选择Tools>Nestlist Viewers查看RTL Viewer和Technology Map Viewer( Post-Mapping)。
图1.1.2 同步复位的D-ff的RTL视图
图1.1.3 同步复位的D-ff的Technology Map Viewer( Post-Mapping)
在图1.1.3中,直接打开的视图如上图所示,双击Q~0后变为下图,即此处的LOGIC_CELL_COMB(8888)映射成了与门。观察图1.1.2和图1.2.3,我们发现,单纯的RTL视图已经不能准确反应HDL所描述的电路,此时我们通过Technology Map Viewer( Post-Mapping)可以更准确的查看到底HDL映射成怎样的底层电路。该图显示的结果与预期结果一致。
代码1.1.2 同步复位的D-ff的testbench
`timescale 1ns/1ns module d_ff_tb; reg clk, rst_n; reg d; wire q, q_n; initial begin clk = 0; forever #20 clk = ~clk; end initial begin rst_n = 0; #10 rst_n = 1; #50 rst_n = 0; #60 rst_n = 1; end initial d = 1; initial #200 $stop; d_ff d_ff_inst( .CLK(clk), .RST_n(rst_n), .D(d), .Q(q), .Q_n(q_n) ); endmodule
图1.1.4 同步复位的功能仿真波形
观察图1.1.4,在t=70ns处,复位信号拉低,但是不在时钟的上升沿,输出q未能复位;在t=100ns处,复位信号拉低,此时时钟真好处于上升沿,因此输出q得以复位。同时需要注意,复位信号无效后,输出q只能在下一个时钟上升沿到来后,才能停止复位。这就是所谓的同步复位D触发器。
图1.1.5 同步复位的门级仿真波形
观察1.1.5,我们发现,与功能仿真不同的是,输出q上电自动复位;直到检测到下一个时钟上升沿复位信号为高,输出q才停止复位;其他时刻的波形与功能仿真一致。
1.2 异步复位D触发器
异步复位,即无论时钟边沿到来与否,只要复位信号有效输出就会被复位。
图1.2.1 异步复位的D-ff
代码1.2.1 异步复位的D-ff
module d_ff( input CLK, input RST_n, input D, output reg Q, output Q_n ); always @ (posedge CLK, negedge RST_n) if (!RST_n) Q <= 1'b0; else Q <= D; assign Q_n = ~Q; endmodule
与同步复位的D-ff的Verilog代码不同之处是,在敏感信号列表中,加入了下降沿的复位信号。
图1.2.2 异步复位的D-ff的RTL视图
使用代码1.1.2的testbench,编译查看其前后仿真波形。观察后,我们发现,异步复位信号只要有效,输出q立即复位。
图1.2.3 异步复位的D-ff的前后仿真波形
2 T触发器
图2.1 T-FF的符号
T触发器可由D触发器和JK触发器变换而来。当时钟的上升沿到来时,若T=0,则次态和现态保持一致;若T=1,则次态为现态的翻转。
代码2.1 T-FF
module t_ff( input CLK, input RST_n, input T, output reg Q, output Q_n ); always @ (posedge CLK, negedge RST_n) if (!RST_n) Q <= 1'b0; else if (T) Q <= !Q; assign Q_n = ~Q; endmodule
注意第9~11行的always块内进程语句,缺少了else。
always @ (posedge CLK, negedge RST_n) if (!RST_n) Q <= 1'b0; else if (T) Q <= !Q;
实际上等同于与下面的写法,即else所隐含的保持现态的语句可以省略。
always @ (posedge CLK, negedge RST_n) if (!RST_n) Q <= 1'b0; else if (T) Q <= !Q; else Q <= Q;
通过Tools>Netlist Viewers>Technology Map Viewer(Post-Mapping)查看,上述HDl被翻译成的具体电路。
图2.2 T-FF的Technology Map Viewer
代码2.2 T-FF的testbench
`timescale 1ns/1ns module t_ff_tb; reg clk, rst_n; reg t; wire q, q_n; //++++++++++++++++++++++++++++++++++++++ // 时钟与复位激励 可重复调用 parameter CLK_PERIOD = 20, RESET_TIME = 10; initial clk = 0; initial forever #(CLK_PERIOD/2) clk = ~clk; initial rst_n = 0; initial #RESET_TIME rst_n = 1; //-------------------------------------- initial t = 0; initial forever #25 t = {$random}%2; initial #200 $stop; t_ff t_ff_inst( .CLK(clk), .RST_n(rst_n), .T(t), .Q(q), .Q_n(q_n) ); endmodule
第18行,调用$random产生随机数。$random%n随机生成{-n+1, n+1}之间的有符号整数;{$random}%N随机生成{0, n-1}之间的正整数。此处将随机产生0~1的正整数。
initial forever #25 t = {$random}%2;
图2.3 T-FF的RTL级仿真波形
有上图我们可以看到,当时钟的上升沿到来时,若T=0,则次态和现态保持一致;若T=1,则次态为现态的翻转。而翻转的英文单词为toggle,即T-FF的名字来源。
3 门控D锁存器
图3.1 D-latch的符号
门控D锁存器只有在clk为高电平时,输出Q才随着输入D变化;当clk为低电平的时,锁存器的状态将被冻结,输出Q保持不变,直到clk恢复为高电平为止。
代码3.1 门控D锁存器
module d_latch( input CLK, input RST_n, input D, output reg Q ); always@* if (!RST_n) Q <= 1'b0; else if (CLK == 1'b) Q <= D; endmodule
图3.2 门控D锁存器的Technology Mapping Viewer
代码3.2 门控D锁存器的testbench
`timescale 1ns/1ns module d_latch_tb; reg clk, rst_n; reg d; wire q; //++++++++++++++++++++++++++++++++++++++ // 时钟与复位激励 可重复调用 parameter CLK_PERIOD = 20, RESET_TIME = 10; initial clk = 0; initial forever #(CLK_PERIOD/2) clk = ~clk; initial rst_n = 0; initial #RESET_TIME rst_n = 1; //-------------------------------------- initial begin d = 0; repeat(10) #11 d = ~d; #10 $stop; end d_latch d_latch_inst( .CLK(clk), .RST_n(rst_n), .D(d), .Q(q) ); endmodule
注意第19行,repeat(n)表示连续执行下面的一块(begin-end内)语句n次。此处为10次。
repeat(10) #11 d = ~d;
图3.3 门控D锁存器的RTL级仿真波形
如图所示,当时钟为高电平是,Q随D变化而变化;而当时钟为高电平时,Q值保持不变。
图3.4所示为门控D触发器基本时序参数模型。在clk下降沿到来之前,D必须保持稳定的最短时间叫做锁存器的建立时间t_su,在clk的下降沿之后,D必须保持稳定的最短时间叫做锁存器的保持时间t_h。
图3.4 门控D触发器基本时序参数
4 亚稳态
图4.1 异步复位的D-ff
图4.2 触发器的时序参数
如图4.2所示,在clk的上升沿到来之前,D必须保持稳定的最短时间为触发器的建立时间t_su;在clk的上升沿到来之后,D必须保持稳定的最短时间为触发器的保持时间t_h。如果t_su或t_h不能严格达到电路的要求,那么触发器就会进入不稳定状态,即亚稳态。从clk的上升沿起,Q随D变化而变化所需要的时间为clk到Q的传播延迟t_cQ。
结语
本文暂时到此结束,一些相关概念,后面会继续有所讨论。
参考
1. http://www.asic-world.com/examples/verilog/flip_flop.html
2. Stephen Brown, Zvonko Vranesic .Fundamentals of Digital Logic with Verilog Design 2nd Edition.Mc Graw Hill