阻塞赋值与非阻塞赋值

阻塞赋值与非阻塞赋值

1. 理论学习

阻塞赋值的赋值号用“ = ”表示。

阻塞赋值的操作可以认为是只有一个步骤的操作,即计算赋值号右边的语句并更新赋值号左边的语句,此时不允许有来自任何其他 Verilog 语句的干扰,直到现行的赋值完成时刻,即把当前赋值号右边的值 赋值给左边的时刻完成后,它才允许下一条的赋值语句的执行。

阻塞的概念是指在同一个 always 块中,其后面的赋值语句是在前一句赋值语句结束后再开始下面的赋值

非阻塞赋值的赋值号用“ <= ”表示。

非阻塞操作开始时计算非阻塞赋值符的赋值号右边的语句,赋值操作结束时刻才更新赋值号左边的语句,可以认为是两个步骤(赋值开始时刻和结束时刻)来完成非阻塞赋值。
在计算非阻塞语句赋值号右边的语句和更新赋值号左边的语句期间,其他的 Verilog 语句包括其他 的 Verilog 非阻塞赋值语句都能同时计算赋值号右边的语句和更新赋值号左边的语句,允许其他的 Verilog 语句同时进行操作。

  • 注意:非阻塞操作只能用于对寄存器类型变量进行赋值,因此只能用于“initial”和“always”块 中,不允许用于连续赋值“assign”。

2. 代码部分

阻塞赋值

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)
    if(sys_rst_n == 1'b0)
        begin
            in_reg = 2'b0;
            out    = 2'b0;
        end
    else
        begin
            in_reg = in;            //in_reg被赋值,但是占用20ns“阻塞”
            out    = in_reg;        //而后out被in_reg赋值,所以波形显示“延迟了”20ns
        end
        
endmodule
阻塞赋值仿真代码
`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'b1;
    sys_rst_n  <= 1'b0;
    in         <= 2'b0;
    #20;
    sys_rst_n  <= 1'b1;
    end

always #10 sys_clk = ~sys_clk;

always #20 in <= {$random}%4;       //取0123,因为单位是2bits

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)
    if(sys_rst_n == 1'b0)
        begin
            in_reg <= 2'b0;
            out    <= 2'b0;
        end
    else
        begin
            in_reg <= in;            
            out    <= in_reg;        
        end
        
endmodule
非阻塞赋值仿真代码
`timescale 1ns/1ns
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'b0;
    in         <= 2'b0;
    #20;
    sys_rst_n  <= 1'b1;
    end

always #10 sys_clk = ~sys_clk;

always #20 in <= {$random}%4;       //取0123,因为单位是2bits

non_blocking non_blocking_inst
(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    .in             (in),
    
    .out            (out)
);
endmodule

3. 仿真图以及解析

阻塞赋值:

在这里插入图片描述

与sys_clk无关,只要in_reg改变,out跟着直接变,没有sys_clk的20 ns的等待,但是这样子赋值的话电路就不确定,所以尽量要使用非阻塞赋值

非阻塞赋值:

在这里插入图片描述

与sys_clk有关,每一次in -> in_reg, in_reg -> out的过程,都要经过sys_clk的等待,但是这样子赋值是并行进行,电路确定,所以设计FPGA应多使用非阻塞赋值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值