10-阻塞赋值和非阻塞赋值

1.阻塞赋值和非阻塞赋值

阻塞赋值的赋值号用"="表示,对应的电路结构往往与触发边沿没有关系,只与输入电平的变化有关系,它的操作可以认为是只有一个步骤的操作,即计算赋值号右边的语句并更新赋值号左边的语句,此时不允许有来自任何其他verilog语句的干扰,直到现行的赋值完成,才允许下一条的赋值语句执行
串行块(begin end)中,各条赋值语将以它们在顺序块中的排列次序依次执行

a = 1;
b = 2;
c = 3;
begin 
  a = b + 1; // a = 3
  b = a + 2; // b = 5
  c = a - 1; // c = 4
end

非阻塞赋值的赋值号用"<="表示,对应的电路结构往往与触发沿有关系,只有在触发沿的时刻才能进行非阻塞赋值;
非阻塞赋值操作可以看作是两个步骤的过程:在赋值开始时刻,计算赋值号右边的语句(所有赋值号右边的结果),在赋值结束时刻(end),更新赋值号左边的语句
在计算非阻塞赋值号右边的语句和更新赋值号左边语句期间,允许其他的verilog语句同时进行操作
非阻塞赋值只能用于寄存器类型变量进行赋值,因此只能用于initial语句和always语句,不允许用于连续赋值语句assign

a = 1;
b = 2;
c = 3;
begin                         // 开始   结束
  a <= b + 1;  // 三条语句并行执行  3     3
  b <= a + 2;  //                 3     3
  c <= a - 1;  //                 0     0
end   

2.实践

2.1 阻塞赋值

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 == 1'b0)
      begin
        in_reg = 2'b0;
        out = 1'b0;
      end
    else 
      begin
        in_reg = in;
        out = in_reg;
      end
  end
endmodule
  • 创建quartus工程,进行编译
`timescale 1ns/1ns
module tb_blocking();
  reg sys_clk;
  reg sys_rst_n;
  reg [1:0] in;
  wire [1:0] out;

  // 初始化时钟和复位信号,输入信号
  intial begin
    sys_clk = 1'b1;
    sys_rst_n <= 1'b0;
    in <=2'b0;
    #20;
    sys_rst_in = 1'b1;
  end
  
  // 模拟时钟
  initial begin
    #10;
    sys_clk = ~sys_clk;
  end  
  
  always #10 in <= {$random} % 4; // 生成非负数0,1,2,3

  blocking block_inst(
     .sys_clk (sys_clk),
     .sys_rst_n (sys_rst_n),
     .in      (in),
     .out     (out)
  );
    
endmodule

2.2 非阻塞赋值

module nonblocking(
  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 <= 1'b0;
      end
    else 
      begin
        in_reg <= in;
        out <= in_reg;
      end
  end
endmodule


  • 当想要对想要的信号打两拍的时候,使用非阻塞赋值
  • 时序逻辑电路使用非阻塞赋值,组合逻辑电路使用阻塞赋值
  • always语句块实现组合逻辑,使用阻塞赋值,不能即使用阻塞赋值又使用非阻塞赋值
  • 避免锁存器latch,使用锁存器的时候使用非阻塞赋值的方式
  • 一个always语句块只对一个变量进行赋值
posted @ 2023-05-24 23:14  Icer_Newer  阅读(108)  评论(0编辑  收藏  举报