首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Verilog中解释阻塞赋值与非阻塞赋值?

如何在Verilog中解释阻塞赋值与非阻塞赋值?
EN

Stack Overflow用户
提问于 2011-01-11 09:19:22
回答 6查看 34.8K关注 0票数 26

当涉及到绘制硬件图时,我对如何解释阻塞和非阻塞赋值感到有点困惑。我们必须推断非阻塞赋值会给我们一个寄存器吗?那么根据这条语句c <= a+b,c将是一个寄存器,对吧,但不是a和b?

代码语言:javascript
复制
module add (input logic clock,  
output logic[7:0] f);   

logic[7:0] a, b, c;  

always_ff @(posedge clock)  
begin   
  a = b + c;   
  b = c + a;   
  c <= a + b;  
end   

assign f = c;  

endmodule
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-01-11 20:27:40

一开始要弄清楚阻塞和非阻塞赋值之间的区别肯定有点棘手。但不要害怕--有一条方便的经验法则:

如果要使用always块推断组合逻辑,请使用阻塞赋值(=)。如果您希望使用时序逻辑,请使用带非阻塞分配的时钟always块(<=)。尽量不要把两者混为一谈。

你上面的代码可能不是最好的例子。如果不知道您试图构建的加法器/触发器结构,就会有组合反馈路径的危险(这是不好的)。由于您没有输入总线,因此您实际上是在试图凭空构建abc

但是为了回答你的问题,任何在时钟always块中赋值的变量都会推断出触发器,除非它是使用阻塞运算符(=)赋值的,并被用作一种局部变量。

代码语言:javascript
复制
module add
  (
   input clock,
   input [7:0] in1,
   input [7:0] in2,
   output logic [7:0] f1, f2, f3, f4, f5
   );   


   // f1 will be a flipflop
   always_ff @(posedge clock) begin
      f1 = in1 + in2;
   end


   // f2 will be a flipflop
   always_ff @(posedge clock) begin
      f2 <= in1 + in2;
   end


   // f3 will be a flipflop
   // c1 will be a flipflop
   logic [7:0] c1;
   always_ff @(posedge clock) begin
      c1 <= in1 + in2;
      f3 <= c1 + in1;
   end


   // f4 will be a flipflop
   // c2 is used only within the always block and so is treated
   // as a tmp variable and won't be inferred as a flipflop
   logic [7:0] c2;
   always_ff @(posedge clock) begin
      c2 = in1 + in2;
      f4 = c2 + in1;
   end


   // c3 will be a flipflop, as it's used outside the always block
   logic [7:0] c3;
   always_ff @(posedge clock) begin
      c3 = in1 + in2;
   end

   assign f5 = c3 + in1;

endmodule

遵循经验法则,不在always块中混合阻塞和非阻塞赋值的一个重要原因是,混合你的赋值可能导致RTL sims和gate-sims/真实硬件操作之间严重的模拟不匹配。verilog模拟器以完全不同的方式对待=<=。阻塞赋值意味着“立即将值赋给变量”。非阻塞赋值意味着“找出要分配给这个变量的值,并将其存储起来,以便在将来某个时候赋值”。更好地理解这一点的一篇好文章是:另请参阅:http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf

票数 33
EN

Stack Overflow用户

发布于 2011-01-23 22:56:43

传统的Verilog智慧完全错了。对局部变量使用阻塞赋值是没有问题的。但是,您永远不应该对同步通信使用阻塞赋值,因为这是不确定的。

按照语义的规定,时钟始终块内的非阻塞赋值将始终推断触发器。

时钟始终块内的阻塞赋值是否推断触发器完全取决于如何使用它。如果变量可能在赋值之前被读取,则将推断触发器。否则,这就像一个临时变量,它将导致一些组合逻辑。

票数 45
EN

Stack Overflow用户

发布于 2014-01-15 13:35:26

只是想补充一下Jan Decaluwe的答案。似乎几乎没有代码真正使用Jan Decaluwe所描述的内容,即使它是绝对正确的。多亏了Mr.Cummings,现在混合阻塞和非阻塞语句是一种禁忌。

问题是,大多数地方都避免对局部变量使用阻塞语句,而且Google的即时搜索空间中几乎没有代码给出了一个如何做到这一点的例子。我唯一找到Jan提到的编码风格的地方是the winning code in this article。还有这个,我偶然发现的

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4653284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档