我正在学习verilog,我已经阅读了一些教程,但我对此有点困惑:
何时以及为何使用“assign”关键字以及何时以及为何使用“< =”运算符。在什么情况下?我很清楚“< =”和“=”之间的区别,即非阻塞和阻塞,但除此之外,一些文献首先使用“assign”,其他文档甚至不使用此关键字。
示例:
指定var_z = x | ~y
var_z< = a + b
谢谢。
答案 0 :(得分:8)
assign
用于驾驶有线/网络类型声明。由于导线根据驱动它们的值更改值,每当 RHS 上的操作数发生变化时,该值评估并分配给LHS(从而模拟电线)。
当右侧值发生变化时,连续分配会将值驱动到网络中,因此连续分配始终处于活动状态,并且只要右侧操作数发生更改,就会发生分配。
连续分配在更高抽象级别提供模型组合逻辑,而不是 Gate-Level 逻辑。
always
是一个程序块,用于建模寄存器和组合逻辑。 always
块包含敏感列表,即事件列表,必须在其上评估块内的逻辑。
always(@ posedge clk)
在每个上升沿时触发块内的逻辑。从而模拟翻转类型的行为。
always @ (*)
对所有RHS 语句都很敏感。如果始终块的RHS中的任何更改,则会评估并分配该特定表达式。这与assign
语句类似,但此类型的块用于驱动reg
数据类型。
// var_z needs to be driven continuously
// Evaluated when any of x or y changes
assign var_z = x|~y
有关详细信息,请参阅assign statement和Continuous assignments。
来到阻止和非阻止语句:
阻止声明必须先执行 执行顺序块后面的语句。
N 阻止声明允许您计划分配,而不会阻止程序流程。
通过以下示例可以更好地理解阻止和非阻塞分配:
x = #10 5; // x = 5 at time 10ns
y = #5 6; // y = 6 at time 15ns
x <= #10 5; // y = 6 at time 10ns
y <= #5 6; // y = 6 at time 5ns
此处,在阻止分配中,y
在x
分配值后进行评估。使用非阻止分配时,x
和y
会被评估并推送到模拟器内部队列,并在10ns
和{5ns
分配分别为{1}}。
阻止分配会立即影响 。非阻塞分配发生在处理当前&#34;时间差值&#34;的末尾。
因此,直观地说,我们可以说,由于组合块需要持续驱动,因此必须使用阻止语句。然而,为了模拟顺序硬件,保留或保留值,必须使用非阻塞分配。
// model a flop var_z
var_z <= a+b;
通过非阻塞分配有效地完成流水线建模。考虑移位寄存器示例:
// Improper hardware, q3 is directly assigned the value of d
always @(posedge clk) begin
q1 = d;
q2 = q1;
q3 = q2; end
// Proper hardware, q3=q2, q2=q1 and q1=d
always @(posedge clk) begin
q1 <= d;
q2 <= q1;
q3 <= q2; end
上面的示例在使用非阻塞分配时对适当的硬件进行建模。有关详细信息,请参阅CummingsSNUG2000SJ_NBA论文this link。