当前位置:   article > 正文

时序逻辑滞后一拍问题_采用时序逻辑滞后一个时钟周期

采用时序逻辑滞后一个时钟周期

一、滞后一拍的现象

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

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
  • 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

产生的效果:
在这里插入图片描述

我们可以看到,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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

同上的Testbench,产生的仿真效果
在这里插入图片描述

我们可以看到,in_reg滞后in一个时钟周期,out居然不滞后in_reg了,这是为什么呢?



只能意会,不能言传,因为赋值语句,在赋值时候,相当于右边的信号有一个寄存器,需要寄存一拍。



总结:

1、时序逻辑:非阻塞赋值,组合逻辑:阻塞赋值(官方推荐)
2、always语句块中不要即使用阻塞赋值,又使用非阻塞赋值
3、锁存器不推荐使用,使用时要用非阻塞赋值
4、一个always语句块只对一个变量赋值

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/532294
推荐阅读
相关标签
  

闽ICP备14008679号