Verilog语法 - 阻塞赋值 & 非阻塞赋值


1. 非阻塞赋值

  • 代码如下
always @( posedge clk )
begin
    b<=a;
    c<=b;
end
  • RTL会综合出两个寄存器串行,如下波形图所示,第一个时钟上升沿来临时,会把a的旧值赋值给b;同时,c获得的是b的旧值,而不是从a那里拿到的新值。
  • 非阻塞赋值可以理解成 a对b的赋值 并不阻塞 b对c的赋值,两行代码可以看成并行执行,在时钟沿到来时,b和c同时获得值;
  • 波形图如下

2. 阻塞赋值

  • 代码如下
always @(posedge clk)
begin
    b=a;
    c=b;
end
  • RTL只会综合出一个寄存器,在上升沿来临时,会把a的旧值赋值给b,之后,b再将从a获得的新值赋值给c。
  • 阻塞赋值可以理解成a赋值给b的这个过程阻塞b赋值给c,所以当b拿到了a的旧值之后,才会赋值给c。

3. 阻塞赋值和非阻塞赋值的原则

  • 错误的使用阻塞赋值可能会导致出现竞争冒险:如果在一个过程块中阻塞赋值的RHS 变量正好是另一个过程块中阻塞赋值的LHS 变量,这两个过程块又用同一个时钟沿触发,如果阻塞赋值的次序安排不好,就会出现竞争。
  • 使用下面的原则编码会更安全
    • 时序电路建模时,用非阻塞赋值。
    • 锁存器建模时,使用非阻塞赋值。
    • 用always 块写组合逻辑时,采用阻塞赋值。
    • 在同一个always 块中同时建立时序和组合逻辑电路时,用非阻塞赋值。
    • 在同一个always 块中不要同时使用非阻塞赋值和阻塞赋值。
  • 注意,阻塞赋值和非阻塞赋值都是可用在always块中的时序逻辑和组合逻辑。只是遵守上面的原则编码会更安全。
posted @ 2023-06-16 10:29  可达达鸭  阅读(167)  评论(0编辑  收藏  举报