内容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/1nsmodule d_ff_tb;reg clk, rst_n;reg d;wire q, q_n;initial begin clk = 0; forever #20 clk = ~clk;endinitial begin rst_n = 0; #10 rst_n = 1; #50 rst_n = 0; #60 rst_n = 1;endinitial 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/1nsmodule 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的名字来源。 |