1、什么是D触发器
D 触发器的功能为:在一个脉冲信号(一般为晶振产生的时钟脉冲)上升沿或下降沿的作用下,将信号从输入端 D 送到输出端 Q,如果时钟脉冲的边沿信号未出现,即使输入信号改变,输出信号仍然保持原值,且寄存器拥有复位清零功能
区分一个设计是组合逻辑电路还是时序逻辑电路主要是看数据工作是不是在时钟沿下进行的,在 FPGA 的设计中,复杂的电路设计都要用到时序逻辑电路,往往都是以时序逻辑电路为主,组合逻辑为辅的混合逻辑电路。
2、同步复位的 D 触发器
同步复位的 D 触发器中的“同步”是和工作时钟同步的意思,也就是说,当时钟的上升沿(也可以是下降沿,一般习惯上为上升沿触发)来到时检测到按键的复位操作才有效,否则无效。下面这个图所示最右边的三根红色的竖线表达的就是这种效果,sys_rst_n 被拉低后 led_out 没有立刻变为 0,而是当 syc_clk 的上升沿到来的时候 led_out 才复位成功,在复位释放的时候也是相同原因。
3、异步复位的 D 触发器
异步复位的 D 触发器中的“异步”是和工作时钟不同步的意思,也就是说,寄存器的复位不关心时钟的上升沿来不来,只要有检测到按键被按下,就立刻执行复位操作。如图
所示最右边的两根红色的竖线表达了这种效果,sys_rst_n 被拉低后 led_out 立刻变为0,而不是等待 syc_clk 的上升沿到来的时候 led_out 才复位,而在复位释放的时候 led_out不会立刻变为 key_in 的值,因为还要等待时钟上升沿到来到时才能检测到 key_in 的值,此时才将 key_in 的值赋值给 led_out。
4、同步复位的D触发器RTL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| module flip_flop ( input wire sys_clk , input wire sys_rst_n, input wire key_in , output reg led_out ); always@(posedge sys_clk) if(sys_rst_n == 1'b0) led_out <= 1'b0; else led_out <= key_in; endmodule
|
5、异步复位的D触发器RTL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 异步复位的 D 触发器 module flip_flop ( input wire sys_clk , input wire sys_rst_n , input wire key_in , output reg led_out ); always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) led_out <= 1'b0; else led_out <= key_in; endmodule
|
6、D触发器的测试文件TetBench编写
#20 是一个 延迟控制(Delay Control) 语法,表示 延迟 20 个时间单位 后再执行后续语句。
我们再来对下面的testbench代码做出相关的理解:
1 2 3 4
| initial begin $timeformat(-9, 0, "ns", 6); $monitor("@time %t: key_in=%b led_out=%b", $time, key_in, led_out); end
|
这个时间展示代码我们可以让其展示出下面这个波形:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| `timescale 1ns/1ns
module tb_flip_flop();
wire led_out ;
reg sys_clk ; reg sys_rst_n ; reg key_in ;
initial begin sys_clk = 1'b1; sys_rst_n <= 1'b0; key_in <= 1'b0; #20 sys_rst_n <= 1'b1; #210 sys_rst_n <= 1'b0; #40 sys_rst_n <= 1'b1; end
always #10 sys_clk = ~sys_clk;
always #20 key_in <= {$random} % 2;
initial begin $timeformat(-9, 0, "ns", 6); $monitor("@time %t: key_in=%b led_out=%b", $time, key_in, led_out); end
flip_flop flip_flop_inst ( .sys_clk (sys_clk ), .sys_rst_n (sys_rst_n ), .key_in (key_in ),
.led_out (led_out ) );
endmodule
|