我正在学习verilog,我已经阅读了一些教程,但我对此有点困惑:
何时以及为何使用"assign"关键字以及何时以及为何使用"<="运算符.在什么情况下?我很清楚"<="和"="之间的区别,即非阻塞和阻塞,但除此之外,一些文献首先使用"assign",其他文档甚至不使用此关键字.
例:
分配var_z = x | ~y
var_z <= a + b
谢谢.
sha*_*111 10
assign
用于驱动电线/网络类型声明.由于导线根据驱动它们的值改变值,每当RHS上的操作数改变时,该值被评估并分配给LHS(从而模拟导线).
只要右侧值发生变化,连续分配就会将值驱动到网络中,因此连续分配始终处于活动状态,并且只要右侧操作数发生变化,就会发生分配.
连续分配在比门级逻辑更高的抽象级别上提供模型组合逻辑.
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
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅assign语句和Continuous assignment.
来到阻止和非阻塞语句:
一个阻塞语句必须被执行之前,它后面的顺序块中的语句的执行.
阻塞语句中的 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
Run Code Online (Sandbox Code Playgroud)
这里,在阻挡分配,y
被后评价x
被赋予一个值.当使用非阻塞分配,x
并y
进行评估,并被推入模拟器内部队列,并分配在10ns
与5ns
分别.
阻止分配会立即生效.非阻塞分配在处理当前 "时间增量" 结束时发生.
因此,直观地说,我们可以说由于组合块需要持续驱动,因此必须使用阻塞语句.而对于保持或保留值的顺序硬件建模,必须使用非阻塞分配.
// model a flop var_z
var_z <= a+b;
Run Code Online (Sandbox Code Playgroud)
通过非阻塞分配有效地完成流水线建模.考虑移位寄存器示例:
// 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
Run Code Online (Sandbox Code Playgroud)
上面的示例在使用非阻塞分配时对适当的硬件进行建模.有关更多信息,请参阅CummingsSNUG2000SJ_NBA文章,此链接.