什么时候使用 "assign" 关键字以及什么时候使用“<=”运算符?

When exactly to use "assign" keyword and when to use "<=" operators?

我正在学习 verilog,我已经阅读了一些教程,但对此我有点困惑:

何时以及为何使用 "assign" 关键字以及何时以及为何使用“<=”运算符。在什么情况下?我很清楚“<=”和“=”之间的区别,非阻塞和阻塞,但除此之外,一些文献开始使用 "assign" 而其他文献甚至不使用此关键字。

示例:

分配 var_z = x|~y

var_z <= a + b

谢谢。

assign 用于 driving wire/net 类型声明。由于电线根据驱动它们的值更改值 ,每当 RHS 上的操作数发生变化时,该值就会被 评估 并分配给 LHS(从而模拟电线)。

只要right-hand侧值发生变化,连续赋值就会将值驱动到网络中,因此连续赋值始终处于活动状态并且只要 right-hand 侧操作数发生变化,就会发生赋值。

连续赋值提供了一个组合逻辑模型更高的抽象层次 =58=]Gate-Level 逻辑.

always 是一个程序块,用于建模 寄存器 和组合逻辑。 always 块包含 敏感度列表 ,即 事件列表 ,必须评估块内的逻辑。

always(@ posedge clk) 在每个 上升沿 触发块内的逻辑。从而对一种 flop 行为进行建模。

always @ (*) 所有 RHS 语句敏感。如果 always 块的 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 and Continuous assignments

开始 阻塞和 non-blocking 语句:

A blocking statement must be executed before the execution of the statements that follow it in a sequential block.

Non blocking statements allow you to schedule assignments without blocking the procedural flow.

阻塞和 non-blocking 分配可以通过以下示例更好地理解:

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

这里,在阻塞赋值中,yx赋值后求值。在使用 non-blocking 赋值时,xy 被评估并推入 模拟器 内部队列并分配分别在 10ns5ns

阻塞赋值立即生效。非阻塞分配发生在处理当前“时间增量”的结束时。

所以,直觉上,我们可以说,由于组合块需要连续驱动,使用块语句 必须完成。同时,为了对 顺序硬件 进行建模, 持有或保留 一个值,non-blocking 赋值 必须使用。

// model a flop var_z
var_z <= a+b;

管道建模可以通过 non-blocking 分配有效地完成。考虑一个移位寄存器示例:

// 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 paper, this link