Verilog 阻塞和非阻塞赋值的区别

电器工程 验证日志
2022-01-20 22:56:03

当我遇到以下内容时,我正在阅读此页面http://www.asic-world.com/verilog/verilog_one_day3.html :

我们通常必须复位触发器,因此每次时钟从 0 转换到 1(posedge)时,我们检查是否复位(同步复位),然后我们继续正常逻辑。如果我们仔细观察,我们会发现在组合逻辑的情况下,我们有“=”用于赋值,而对于顺序块,我们有“<=”运算符。好吧,“=”是阻塞赋值,“<=”是非阻塞赋值。“=”在开始/结束内顺序执行代码,而非阻塞“<=”并行执行。

我相当确定非阻塞分配是顺序的,而阻塞分配是并行的。毕竟,您可以在 always 块之外使用 assign 语句进行阻塞分配,并且这些语句都是并行运行的。这是一个错误,还是总是块内的行为不同?而且,如果在 always 块内的行为不同,是否可以在 always 块外进行非阻塞分配?

3个回答

相当确定非阻塞分配是顺序的,而阻塞分配是并行的。

阻塞赋值是“串行”执行的,因为阻塞赋值会阻塞下一条语句的执行,直到它完成。因此,下一个语句的结果可能取决于第一个语句的完成。

非阻塞赋值并行执行,因为它描述了所有同时发生的赋值。第 2 行语句的结果将不依赖于第 1 行语句的结果。相反,第二行将执行,就好像第一行还没有发生一样。

赋值语句既不是“阻塞”也不是“非阻塞”,它们是“连续的”。赋值语句的输出总是等于其输入的指定函数。“阻塞”和“非阻塞”分配只存在于 always 块中。

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

always 块可用于对组合逻辑或顺序逻辑进行建模(systemverilog 具有 always_comb 和 always_ff 来明确这一点)。在对组合逻辑进行建模时,使用 = 通常更有效,但它通常并不重要。

在对时序逻辑进行建模时(例如,总是 @(posedge clk) ),您通常使用非阻塞分配。这使您可以根据“时钟沿之前的状态”来确定“时钟沿之后的状态”。

有时在连续的 always 块中使用阻塞赋值作为“变量”很有用。如果您这样做,则需要牢记两个关键规则。

  1. 不要从分配它的 always 块外部访问在顺序 always 块内设置了阻塞分配的 reg。
  2. 不要将阻塞和非阻塞分配混合到同一个 reg。

违反这些规则可能会导致综合失败和/或模拟与综合之间的行为差​​异。

术语阻塞赋值使人们感到困惑,因为阻塞这个词似乎暗示了时间顺序逻辑。但在综合逻辑中并不意味着这个,因为一切都是并行运行的

一个不太容易混淆的术语可能是立即分配,它仍然可以区分组合逻辑的中间结果与输入到非透明存储元件(例如时钟寄存器),这可能具有延迟分配

从法律的角度来看,一切都很顺利。事实上,即使在序列中,您也可以=将视为阻塞(时序)操作。always_comb但是,在这种情况下,时序和并行之间的区别绝对没有区别,因为该always_comb块被定义为重复,直到指令序列收敛到稳定状态——这正是硬件电路将要做的(如果它满足时序要求)。

Verilog 的可综合子集(尤其是 SystemVerilog)非常简单易用——只要您了解了必要的习惯用法。你只需要巧妙地使用与语言中所谓的行为元素相关的术语。