在预先携带进位加法器的数据流描述中(下面附有一部分代码),C [1]依赖于C [0],依此类推,这需要顺序执行。我们知道“ assign”语句是并行执行的,但是此代码也可以提供正确的结果。这怎么可能?请详细说明这些语句的执行方式。
assign C[0] = cin;
assign C[1] = G[0] | (P[0] & C[0]);
assign C[2] = G[1] | (P[1] & C[1]);
assign C[3] = G[2] | (P[2] & C[2]);
assign C[4] = G[3] | (P[3] & C[3]);
答案 0 :(得分:4)
正如您所说,它们是并行执行的。我认为更好的单词是 concurrent ,这使得 parallel 一词可以描述拓扑。
Verilog仿真是事件驱动的。 事件是对变量或网络(或Verilog event
)的值的更改。发生事件时,这将导致执行线程。这将创建更多事件,这将导致更多线程执行,依此类推。这种情况一直持续到模拟停止时再没有其他事件为止。 (这称为 event starvation 。)如果事件一直持续生成,则模拟将永远不会停止(除非执行$stop
或$finish
语句。)
那么,什么是线程? initial
块,always
块或assign
语句-这些都是彼此同时执行的。
那么,模拟器如何知道事件后要执行哪些线程?每个线程都有一个敏感列表,可以是显式的也可以是隐式的。这是网,变量或Verilog event
的列表。这些事件中的任何事件都会导致线程执行。一些总是块具有明确的敏感度列表,例如always @(posedge clock or posedge reset)
;其他具有隐式敏感性列表,例如assign
语句。 assign
语句对分配右侧的所有网络或变量都敏感。
所以,声明
assign C[0] = cin;
仅对cin
敏感。因此,它将在cin
发生更改时执行。执行时,它可能在C[0]
上生成一个事件。这句话
assign C[1] = G[0] | (P[0] & C[0]);
对C[0]
(以及G[0]
和P[0]
)敏感,因此,如果C[0]
上有一个事件,它将执行,可能会导致{{ 1}}等。
这就是您的代码提供“正确结果”的方式。