#systemverilog# 之 event region 和 timeslot 仿真调度(七)Active/NBA 咋跳转的?

本文深入探讨SystemVerilog的仿真调度,分析了Active域和NBA域(非阻塞赋值域)的执行顺序,通过实例展示了"先Active域,后NBA域"以及"先Active域,后NBA域,后NBA域"的情况。通过VCS仿真和glitch模式,观察到在NBA域中完成的数据变化,并讨论了Active(2)域的缺失原因和如何构造包含Active(2)的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一 目的

二 案例分析

2.1 先Active域,后 NBA 域

2.2 先Active域,后 NBA 域,后NBA域

【变形一】为什么没有出现Active(2)

【变形二】可以构造出这样一个Active(2)吗

三 总结

一 目的

作为仿真调度专栏文章,前面所有文章,多数都是围绕文字在做文章,重在理论分析。今天抽空整理和实操一下,仿真调度的执行,具体是怎么和代码结合起来的。这才是我们的终极目的。理论千万次,不如实操一次。本文章,会介绍常见的调度域的执行情形,后期如果遇到更加复杂的,会增补改文章。

参考语法书如下:

 

二 案例分析

2.1 

<think>好的,用户现在的问题是询问在仿真中#0通常用在什么情况,以及它能解决什么问题。首先,我需要回顾一下之前用户的对话历史,确保回答的一致性连贯性。之前的对话中,用户询问了关于在非阻塞赋值中使用#0时,后面的非阻塞赋值是否能采样到变化后的值,我详细解释了非阻塞赋值的执行机制,并通过示例流程图说明了#0的影响。 现在用户的问题更广泛,询问#0的一般使用场景解决的问题。我需要先明确SystemVerilog中的事件区域划分,尤其是Active、InactiveNBA区域。然后思考#0在这些区域中的作用,即把进程挂起到当前时间步的Inactive区域末尾。 接下来,我需要列举常见的#0使用场景。例如,竞争条件避免、控制执行顺序、与阻塞赋值混合时的同步问题等。需要具体说明每个场景下如何使用#0,以及为什么能解决问题。同时要指出潜在的风险,比如滥用可能导致设计不可靠或仿真结果不一致。 然后,用户可能想知道为什么需要这样的延迟,而不直接使用非阻塞赋值或者调整代码顺序。需要解释仿真器的执行机制,不同区域的执行顺序,以及#0如何影响这些顺序。同时,可能需要提到,虽然#0可以解决某些问题,但在实际硬件设计中应谨慎使用,因为它可能引入仿真与综合不一致的情况。 还要考虑用户可能的背景。用户可能正在学习SystemVerilog仿真,或者在调试竞争条件的问题,想要理解如何正确使用#0。因此,回答需要结构清晰,分点说明,既有理论解释又有实例,帮助用户理解应用场景注意事项。 最后,需要总结使用#0的推荐做法,强调其作为临时调试手段的定位,以及在正式代码中应优先考虑其他设计方法。同时,通过代码示例对比使用#0前后的行为差异,增强理解。 总结思考路径:解释事件区域→列举使用场景→每个场景的问题解决方案→注意事项替代方案→示例说明→总结建议。确保回答覆盖用户需求,同时避免技术错误。</think>--- ### **关键结论** **`#0`主要用于控制仿真器事件区域的执行顺序**,其核心价值是: 1. **解决代码顺序与仿真执行顺序不一致导致的竞争问题** 2. **临时同步多个进程的执行时序** 3. **调试时强制调整信号采样/更新顺序** --- ### **1. 本质原理:事件区域与`#0`的作用** #### **SystemVerilog事件区域(按执行顺序)**: 1. **Active区域**:执行阻塞赋值、连续赋值、模块输入更新等 2. **Inactive区域**:处理`#0`挂起的进程 3. **NBA区域(Non-blocking Assignment)**:更新非阻塞赋值的左端 4. **Postponed区域**:执行`$strobe`等语句 #### **`#0`的作用**: 将当前进程**挂起到当前时间步的Inactive区域末尾**,从而: - **延迟本进程的后续操作** - **允许其他进程在相同时间步内优先执行** --- ### **2. 典型应用场景与解决方案** #### **场景1:混合阻塞与非阻塞赋值时的竞争问题** ```systemverilog always @(posedge clk) begin a = 1; // 阻塞赋值(立即生效) b <= a; // 非阻塞赋值(右端锁定当前a值) end always @(posedge clk) begin c <= b; // 另一进程的非阻塞赋值 end ``` **问题**:若两个`always`块执行顺序不确定,可能导致`c`采样到`b`的旧值 **解决方案**: ```systemverilog always @(posedge clk) begin a = 1; #0; // 挂起到Inactive末尾,确保其他进程先执行 b <= a; end ``` #### **场景2:控制同一进程中多个赋值的执行顺序** ```systemverilog always @(posedge clk) begin x = y; // 阻塞赋值 z = x; // 依赖x的更新值 end ``` **问题**:若其他进程在`x = y`后立即读取`x`,可能得到旧值 **解决方案**: ```systemverilog always @(posedge clk) begin x = y; #0; // 允许其他进程感知x的更新 z = x; end ``` #### **场景3:同步多个进程的触发时序** ```systemverilog always @(data) begin // 进程A:处理data变化 end always @(data) begin // 进程B:依赖进程A的结果 end ``` **问题**:进程B可能在进程A完成前执行 **解决方案**: ```systemverilog always @(data) begin // 进程A逻辑... #0; // 让进程B先执行 // 后续操作 end ``` --- ### **3. 使用`#0`的典型问题解决** | 问题类型 | `#0`的作用机制 | 示例场景 | |-------------------------|----------------------------------------|-----------------------------------| | 信号采样与更新竞争 | 强制其他进程先执行 | 确保非阻塞赋值右端采样稳定值 | | 跨进程执行顺序不确定性 | 调整进程在事件区域中的优先级 | 同步多个`always`块的触发顺序 | | 组合逻辑反馈环路 | 打破零延时循环 | 避免组合逻辑振荡 | --- ### **4. 代码示例对比** #### **未使用`#0`时的竞争问题**: ```systemverilog always @(posedge clk) begin a = 1; b = a; // b可能得到旧值(若其他进程修改了a) end always @(posedge clk) begin a = 2; // 仿真器执行顺序不确定 end ``` #### **使用`#0`后的确定行为**: ```systemverilog always @(posedge clk) begin a = 1; #0; // 等待其他进程执行 b = a; // 确保a已完成所有更新 end always @(posedge clk) begin a = 2; end ``` --- ### **5. 注意事项与风险** 1. **不可综合**:`#0`仅用于仿真,综合工具会忽略 2. **过度使用风险**: - 掩盖设计缺陷(应优先优化代码结构) - 导致仿真与真实硬件行为不一致 3. **替代方案优先**: - 合理使用非阻塞赋值(`<=`) - 通过时钟域划分明确时序 - 采用分层验证策略(如SV/UVM) --- ### **6. 推荐使用原则** 1. **调试工具定位**:仅作为临时调试手段 2. **局部精确控制**:在明确竞争发生的代码段使用 3. **配合注释说明**:标注使用原因预期效果 4. **最终代码清理**:在正式版本中尽量移除`#0` --- ### **附:`#0`执行流程示意图** ``` Time Step开始 │ ├─ Active区域 │ ├─ 执行阻塞赋值 │ └─ 遇到#0,挂起进程到Inactive末尾 │ ├─ Inactive区域 │ └─ 恢复被挂起的进程 │ ├─ NBA区域 │ └─ 更新非阻塞赋值左端 │ └─ Postponed区域 └─ 执行$strobe等语句 ``` 通过合理使用`#0`,可在仿真层面精细控制时序,但需始终谨记:**其本质是绕过设计问题的临时方案,非根本解决之道**。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那么菜

你的鼓励和批评是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值