FPGA学习笔记(5)——阻塞赋值与非阻塞赋值


一、阻塞赋值

1.顶层模块代码

module  blocking
(
    input   wire        sys_clk     ,
    input   wire        sys_ret_n   ,
    input   wire[1:0]   in          ,
    
    output  reg [1:0]   out         
);

reg[1:0]   in_reg;

always@(posedge sys_clk or negedge  sys_ret_n)
    if(sys_ret_n == 1'b0)
        begin
            in_reg  = 2'b0;     
            out     = 2'b0;
        end
    else
        begin
            in_reg  =   in;             
            out     =   in_reg;        
        end

endmodule

描述了异步上升沿触发器,传递两位宽数据,定义了一个中间变量in_reg,没有在构成的电路显示:
在这里插入图片描述

2.testbench代码

`timescale  1ns/1ns
module  tb_blocking();
    reg         sys_clk     ;
    reg         sys_ret_n   ;
    reg [1:0]   in          ;
                            
    wire[1:0]   out         ;

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

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

blocking    tb_blocking_inst
(
    .sys_clk     (sys_clk     ),
    .sys_ret_n   (sys_ret_n   ),
    .in          (in          ),
                              
    .out         (out         )
);

endmodule

3.仿真结果

在这里插入图片描述
in_reg与in延迟一个周期是由于这一次的赋值由触发器完成,上一节笔记验证过,这是触发器的特性。
然而,作为中间变量的in_reg和out没有延迟,因为使用了阻塞赋值,等式右边的值(out)一旦变化会立即赋值给左边的变量(in_reg)

非阻塞赋值

1.顶层模块代码

仅仅将always模块中的赋值全部改为非阻塞赋值。

module  blocking
(
    input   wire        sys_clk     ,
    input   wire        sys_ret_n   ,
    input   wire[1:0]   in          ,
    
    output  reg [1:0]   out         
);

reg[1:0]   in_reg;

always@(posedge sys_clk or negedge  sys_ret_n)
    if(sys_ret_n == 1'b0)
        begin
            in_reg  <= 2'b0;     
            out     <= 2'b0;
        end
    else
        begin
            in_reg  <=   in;             
            out     <=   in_reg;        
        end

endmodule

对应的电路图:
在这里插入图片描述
定义了两个触发器,前一个的Q接下一个的D,类似于移位寄存器,接了相同的异步置零和时钟。

2.仿真结果

testbench不变即可,得到下面的仿真结果:
在这里插入图片描述
发现in_reg滞后in一个周期,而out滞后in_reg一个周期。

总结以及注意

(1)在编写时序逻辑的代码时采用非阻塞赋值的方式
(2)使用 always 块来编写组合逻辑的代码时要用阻塞赋值的方式
(3)在同一个 always 块中不要既要用非阻塞赋值又用阻塞方式赋值
(4)虽然锁存器电路建模是不推荐的,但是如果使用到要采用非阻塞赋值的方式。
(5)一个 always 块只一个变量进行赋值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值