调度图用于描述元素的行为以及它们之间的相互作用。此相互作用描述了事件执行及其调度。需要注意的是,就块或进程执行而言,Verilog 和 SystemVerilog 类似于并行编程语言。
在讨论区域之前,我们必须了解 仿真时间 simulation time 和 时间槽time slot。
术语 仿真时间 用于指代仿真器维护的时间值,以模拟系统描述所需的实际时间。
一个 时间槽 包含了在每个仿真时间的事件区域中处理的所有仿真活动。针对特定仿真时间的所有仿真活动都会被执行,直到该时间槽内不再有进一步的仿真活动,即,不会推进仿真时间。 “请注意,时间槽内仿真事件的执行可能需要通过多次迭代来处理该相同时间槽内的仿真事件区域。”
事件#
事件(event)用于两个或多个并发活动进程之间的同步。首先,我们需要声明事件,然后使用 -> 或 -» 运算符触发它。
进程可以通过使用 @ 运算符或 wait(event_name.triggered) 来等待事件。 当 @ 和 wait 同时出现在同一点时,会发生竞态条件。
创建一个事件:
event e;
触发事件:
-> e;
等待事件被触发:
@e;
或者
wait(e.triggered);
Verilog 中的事件区域:#
SystemVerilog 中的事件区域:#
解释#
用于实现正确的 RTL 功能的区域:
• 活动区域(Active、Inactive 和 NBA 区域)。
用于实现正确的验证执行的区域:
• 预定、反应式区域(反应式、重新激活、重新 NBA)和延迟区域。
用于实现并发断言检查的区域:
• 预定、观察和反应式区域。
应该避免的区域:
• 非活动区域。
让我们讨论一下 SystemVerilog 的所有区域
1. 预定区域#
该区域的功能是对并发断言使用的值进行采样。预定区域在每个时间槽中只执行一次,在推进仿真时间后立即执行(没有反馈路径重新执行预定区域)。
关于实现是否实际上必须在预定区域执行采样,或者采样是否可以在前一个时间槽的延迟区域中完成,还存在一些疑问。因为延迟和预定区域都是只读区域。
“断言中使用的变量的值是在一个时间槽的预定区域中进行采样的,并且在观察区域中评估断言。”
采样值始终是相对于时钟表达式定义的。因此,只有在触发时钟表达式的时间槽的预定区域中采样值是必要的,而不是在每个时间槽中都进行。
2. 活动区域集合#
这个活动区域集合包括 i. 活动区域 ii. 非活动区域 和 iii. NBA 区域。
活动区域集合用于安排模块中包含的阻塞和非阻塞赋值。 从模块调用的所有任务和函数也安排在活动区域集合中。 活动区域集合用于安排 RTL 和行为代码。
i. 活动区域#
活动区域保存当前正在评估的活动区域集合事件,并且可以以任何顺序进行处理。
该区域的功能是以任何顺序评估和执行当前模块的所有活动:
- 执行所有模块的阻塞赋值。
- 执行所有模块的连续赋值。
- 评估所有非阻塞赋值的右手边(RHS),并安排更新到 NBA 区域。
- 评估 Verilog 原语的输入并更新输出。
- 执行 $display 和 $finish 命令。
ii. 非活动区域#
非活动区域保存在处理完所有活动事件后要评估的事件。
如果在活动区域集合中执行事件,则显式的 #0 延迟控制需要将进程挂起,并将事件安排到当前时间槽的非活动区域,以便进程可以在下一个非活动到活动迭代中恢复。
大多数用户继续使用 #0 赋值来防止由于从多个 always 块对同一变量进行赋值而存在的竞争条件。遵循良好编码规范的用户不需要 #0 RTL 赋值,因此,非活动区域未使用。
iii. NBA 区域#
该区域的功能是执行已安排在活动区域中的所有当前执行非阻塞赋值的左手边(LHS)变量的更新。 NBA(非阻塞赋值更新)区域保存要在处理完所有非活动事件后评估的事件。 如果在活动区域集合中执行事件,则非阻塞赋值会在当前或稍后的仿真时间中创建一个 NBA 区域中的事件。
3. 观察区域#
该区域的功能是使用在预定区域中采样的值评估并发断言。执行通过或失败操作阻塞的断言实际上会将与 pass 和 fail 代码相关联的进程安排到反应式区域,而不是观察区域。
这是因为并发断言被设计为严格作为监视器,它们不允许修改设计的状态。但是,断言无法安排任何活动区域事件。
4. 重新活动区域集合#
这个重新活动区域集合包括 i. 重新活动区域 ii. 重新非活动区域 和 iii. 重新 NBA 区域。
重新活动区域集合用于安排包含在程序代码中的阻塞赋值、#0 阻塞赋值和非阻塞赋值。从程序调用的任何任务或函数也安排到重新活动集合事件区域中。 重新活动区域集合的预期目的是在 RTL 代码稳定到半稳态之后,在相同的时间槽中调度测试台刺激驱动程序和测试台验证检查。
i. 重新活动区域#
重新活动区域保存当前正在评估的重新活动区域集合事件,并且可以以任何顺序进行处理。 在检查器、程序块中指定的代码和并发断言的操作块中安排的阻塞赋值的代码 安排在重新活动区域中。
该区域的主要功能是评估和执行所有当前程序活动。
- 执行所有程序的阻塞赋值。
- 执行所有程序的连续赋值。
- 执行并发断言的通过/失败代码。
- 评估所有程序非阻塞赋值的右手边(RHS),并安排更新到重新 NBA 区域。
- 执行 $exit 和隐式 $exit 命令。
此区域用于执行由程序块生成的验证过程。由于反应式区域位于时间槽的末尾,因此在仿真的这一点处执行的进程具有对