问题描述
我对在绘制硬件图时如何解释阻塞和非阻塞分配感到有些困惑.我们是否必须推断非阻塞赋值给了我们一个寄存器?那么根据这个语句c ,c 将是一个寄存器对,但不是 a 和 b?
I am a little confused about how blocking and non blocking assignments are interpreted when it comes to drawing a hardware diagram. Do we have to infer that a non blocking assignment gives us a register? Then according to this statement c <= a+b
, c would be a register right, but not a and b?
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
推荐答案
一开始要弄清楚阻塞和非阻塞赋值之间的差异绝对有点棘手.但不用担心 - 有一个方便的经验法则:
It's definitely a bit tricky to get your head around the differences between blocking and nonblocking assignments initially. But no fear - there's a handy rule of thumb:
如果您想使用 always
块来推断组合逻辑,请使用阻塞赋值 (=
).如果您需要时序逻辑,请使用带有非阻塞分配 () 的计时
always
块.并且尽量不要将两者混为一谈.
你上面的代码可能不是最好的例子.在不知道您要构建的加法器/触发器结构的情况下,存在组合反馈路径(不好)的危险.由于您没有输入总线,您实际上是在尝试构造 a
、b
&c
凭空而来!
Your code above is probably not the best example. Without knowing what adder/flipflop structure you were trying to build, there's the danger of having combo feedback paths (which are bad). And since you've no input buses, you're essentially trying to construct a
, b
& c
out of thin air!
但是为了回答您的问题,分配给时钟 always
块内的任何变量都将推断触发器,除非它使用阻塞运算符 (=
) 分配并用作一种局部变量.
But to answer your question, any variable assigned to within a clocked always
block will infer a flipflop, unless its assigned using the blocking operator (=
) and used as a kind of a local variable.
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/real 之间严重的模拟不匹配硬件操作.verilog 模拟器对 =
和 的处理完全不同.阻塞赋值意味着立即将值赋值给变量".非阻塞赋值意味着弄清楚要分配给这个变量的内容,并将其存储起来以备将来分配".阅读以更好地理解这一点的好论文是:另请参阅:http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
A big reason for following the rule of thumb and not mixing blocking and nonblocking assignments within an always
block, is that mixing your assignments can cause serious simulation mismatches between RTL sims and gate-sims/real hardware operation. The verilog simulator treats =
and <=
quite differently. Blocking assignments mean 'assign the value to the variable right away this instant'. Nonblocking assignments mean 'figure out what to assign to this variable, and store it away to assign at some future time'. A good paper to read to understand this better is: Also see: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
这篇关于如何解释 Verilog 中的阻塞与非阻塞赋值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!