Bootstrap

阻塞赋值和非阻塞赋值

理论学习

                阻塞赋值 用                 =        表示 ,这种对应的电路结构常常与触发器没有关系,只与输入电平的变化有关系。可以将阻塞赋值的操作看作只有一个步骤的操作,即将计算赋值符号的右边赋值给左边,在未执行完之前,不允许其他verilog语句执行。

                非阻塞赋值 用           <=        表示,这种对应的电路结构常常与触发沿有关系,只有在触发沿才能执行。非阻塞逻辑开始时 先计算式子右边的语句,赋值操作结束时才更行式子左边的语句,可以认为需要两个步骤来完成赋值。非阻塞赋值执行的时候,其他verilog语句都能同时计算。

阻塞赋值

module    blocking    
(
    input    wire    sys_clk    ,
    input    wire    sus_rst_n    ,

    input    wire    [1:0]    in    ,
    output   reg     [1:0]    out
);

    reg    [1:0]    in_reg    ;//给out延迟 1 clk
    
    always(posedge sys_clk or negedge sys_rst_n )
    begin
        if(sys_rst_n == 1'b0)
        begin
            in_reg    =    2'b0    ;
            out       =    2'b0    ;
        end
        else
        begin
            in_reg    =    in        ;
            out       =    in_reg    ;
        end
    end




endmodule

阻塞赋值对应的tb

`timescale    1ns/1ns



module    tb_blocking();


    reg    sys_clk        ;
    reg    sys_rst_n      ;
    reg    [1:0]    in    ;
    wire   [1:0]    out   ;


    initial
    begin
        sys_clk     =         1'b0    ;
        sys_rst_n   <=        1'b0    ;
        int         <=        2'b0    ;
        #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

非阻塞赋值,可以看到这样子有两组寄存器。

module    non_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 == 1'b0)
        begin
            in_reg    <=    2'b0    ;
            out       <=    2'b0    ;
        end
        else
        begin
            in_reg    <=    in        ;
            out       <=    in_reg    ;
        end
    end


endmodule

非阻塞赋值对应的tb,结果发现,in和in_reg有一个clk延时,in_reg和out有一个延时,也就是in和out有两个延时。

module   tb_non_blocking();


    reg    sys_clk      ;
    reg    sys_rst_n    ;
    reg    [1:0]    in           ;
    wire   [1:0]    out          ;


    initial
    begin
        sys_clk     =    1'b1    ;
        sys_rst_n  <=    1'b1    ;
        in         <=    2'b0    ;
        #20    ;
        sys_rst_n  <=    1'b1    ;
    end


    always #10    sys_clk    =    ~sys_clk    ;

    always #20    in    <=    {$random}%4    ;

    non_block    non_block_inst
    (
        .sys_clk        (sys_clk)      ,
        .sys_rst_n      (sys_rst_n)    ,
        .in             (in)           ,
        .out            (out)
    );


endmodule 

;