时序逻辑滞后一拍问题
时序逻辑电路输出比输入滞后一拍的原因
文章共1,257字 · 阅读需要大约5分钟
一键AI生成摘要,助你高效阅读
问答
·
一、滞后一拍的现象
1、Verilog代码
module flip_flop(
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_in ,
output reg led_out
);
// asynchronous reset D flip-flop
always @(posedge sys_clk) begin
if (sys_rst_n == 1'b0)
led_out <= 1'b0;
else
led_out <= key_in;
end
2、仿真现象
如图所示,led_out输出总比key_in输出延迟一个时钟周期
二、产生此现象的原因
主要是非阻塞赋值与阻塞语句赋值的原因
解释如下:
①首先我们来看这一个代码段产生的效果
代码段:(主要是注意always块中的非阻塞赋值)
module blocking(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [1:0] in ,
output reg [1:0] out
);
reg [1:0] in_reg;
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
in_reg <= 2'b00;
out <= 2'b00;
end
else begin
in_reg <= in; // 注意这一行
out <= in_reg; // 也要注意这一行,都是非阻塞赋值
end
end
endmodule
Testbench代码段:
module tb_blocking();
reg sys_clk;
reg sys_rst_n;
reg [1:0] in;
// blocking Outputs
wire [1:0] out;
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
in <= 2'b00;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
always #20 in <= {$random} % 4;
blocking blocking_inst(
.sys_clk ( sys_clk ),
.sys_rst_n ( sys_rst_n ),
.in ( in ),
.out ( out )
);
endmodule
产生的效果:
我们可以看到,in_reg总是滞后in一个时钟周期,out滞后in_reg一个时钟周期
②当我们把代码中always块的非阻塞赋值改为阻塞赋值时
代码段:
module blocking(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [1:0] in ,
output reg [1:0] out
);
reg [1:0] in_reg;
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
in_reg <= 2'b00;
out <= 2'b00;
end
else begin
in_reg = in; // 注意这一行
out = in_reg; // 也注意这一行,阻塞赋值
end
end
endmodule
同上的Testbench,产生的仿真效果
我们可以看到,in_reg滞后in一个时钟周期,out居然不滞后in_reg了,这是为什么呢?
只能意会,不能言传,因为赋值语句,在赋值时候,相当于右边的信号有一个寄存器,需要寄存一拍。
总结:
1、时序逻辑:非阻塞赋值,组合逻辑:阻塞赋值(官方推荐)
2、always语句块中不要即使用阻塞赋值,又使用非阻塞赋值
3、锁存器不推荐使用,使用时要用非阻塞赋值
4、一个always语句块只对一个变量赋值
更多推荐
已为社区贡献1条内容
所有评论(0)