1 分钟阅读 次阅读

概要:本文介绍了 Verilog 中阻塞赋值(=)与非阻塞赋值(<=)的区别,并通过实例代码演示它们在仿真中的行为差异,包括赋值顺序对逻辑和时间的影响,帮助读者理解过程赋值与连续赋值的不同,并掌握其在实际编码中的使用方式。

1. 过程赋值与连续赋值简介

首先明确,阻塞赋值和非阻塞赋值都属于过程赋值。

  • 过程赋值:在 initial 和 always 中的赋值。赋值后值将保持不变,直到下一次赋值。
  • 连续赋值:表达式一直处于激活状态,一旦操作数改变,结果随之改变(如组合逻辑的描述方式)。

2. 阻塞赋值与非阻塞赋值的语法

  • 阻塞赋值(Blocking Assignment):使用 =
    → 当前语句执行完毕后,才会执行下一条语句(顺序执行)

  • 非阻塞赋值(Non-blocking Assignment):使用 <=
    → 当前语句不会阻塞,所有非阻塞赋值几乎同时调度执行(并行执行)


3. 示例代码分析

以下是一个 Verilog 示例,展示两种赋值的使用及其在仿真中行为的差异。

`timescale 1ns/1ns
 
module test ;
    reg [3:0]   ai, bi ;
    reg [3:0]   ai2, bi2 ;
    reg [3:0]   value_blk ;
    reg [3:0]   value_non ;
    reg [3:0]   value_non2 ;
 
    initial begin
        ai            = 4'd1 ;   //(1)
        bi            = 4'd2 ;   //(2)
        ai2           = 4'd7 ;   //(3)
        bi2           = 4'd8 ;   //(4)
        #20 ;                    //(5)
 
        //non-block-assigment with block-assignment
        ai            = 4'd3 ;     //(6)
        bi            = 4'd4 ;     //(7)
        value_blk     = ai + bi ;  //(8)
        value_non     <= ai + bi ; //(9)
 
        //non-block-assigment itself
        ai2           <= 4'd5 ;           //(10)
        bi2           <= 4'd6 ;           //(11)
        value_non2    <= ai2 + bi2 ;      //(12)
    end
 
    //stop the simulation
    always begin
        #10 ;
        if ($time >= 1000) $finish ;
    end
 
endmodule

4. 仿真时间段分析

alt text

4.1 时间段一:0 ~ 20ns(语句 (1)-(4))

  • 所有赋值为阻塞赋值(=),顺序执行
  • 没有时间控制语句(如 #),故所有赋值发生在同一个时间点(0ns)
信号
ai 1
bi 2
ai2 7
bi2 8
value_blk 未赋值
value_non 未赋值
value_non2 未赋值

4.2 时间段二:20ns 以后(语句 (6)-(12))

执行顺序说明:

  • (6)、(7)、(8):阻塞赋值,依次执行
    • ai = 3
    • bi = 4
    • value_blk = ai + bi = 3 + 4 = 7
  • (9)、(10)、(11)、(12):非阻塞赋值,几乎同时调度

    • 执行 (9):value_non <= ai + bi,此时 ai=3, bi=4 → value_non = 7
    • 执行 (10)、(11):ai2 和 bi2 更新为 5 和 6,但不会立刻影响 (12)
    • 执行 (12):value_non2 <= ai2 + bi2,使用旧值 ai2=7, bi2=8 → value_non2 = 15
信号
ai 3
bi 4
ai2 5
bi2 6
value_blk 7
value_non 7
value_non2 15

5. 总结

  • 阻塞赋值用于描述顺序逻辑,常用于组合逻辑模拟。
  • 非阻塞赋值用于描述并行逻辑,适合建模时序逻辑。
  • 非阻塞赋值不会立即改变变量的值,直到当前时间步结束后统一更新。
  • 在写 always 块描述触发器(如 D 触发器)时,应使用非阻塞赋值,以避免竞态与不确定性。

6. 表格总结(执行后变量值)

时间点 信号
0ns ai 1
  bi 2
  ai2 7
  bi2 8
  value_blk 未赋值
  value_non 未赋值
  value_non2 未赋值
20ns+ ai 3
  bi 4
  ai2 5
  bi2 6
  value_blk 7
  value_non 7
  value_non2 15

标签:

分类:

更新时间:

留下评论