SVA 中$rose的理解


上图中第一个时序图中的属性'checkiack'将会通过,因为 'inter'和'iack'信号都符合$ rose的要求(两个连续的时钟值不同,'0'后跟'1')。 但是,第二个时序图失败,因为虽然$rose(intr)符合$rose的要求,'iack'没有。 'iack'在两个时钟沿之间不会从'0'变为'1'。

$rose并不意味着posedge,$fell并不意味着negedge。 换句话说,一旦检测到'intr'上的posedge,断言就不会认为$ rose(intr)是真的。 $ rose()/ $ fell()行为是通过在两个连续的时钟边缘对表达式进行“采样”得出的,并且看看这些值是否相反来判断是符合$ rose()还是$ fell()。也就是说,并发断言的基本规定了一切。必须在采样边缘采样,行为基于采样值。


这是一个非常重要的例子。 它解释了使用电平敏感的采样与边缘敏感采样的区别。 两者都是正确的使用,除了 你需要知道在什么时候使用。 如上图所示,电平敏感评价是边缘敏感性评价的超集。 如果实际上你的意思是用边缘敏感评估,但是当你使用电平敏感的采样时,会显著降低仿真性能。

在上面的property中,如果你想要做的是检查iack从非活动状态('0')到活动状态'1',一旦边缘敏感的intr被asserted,以下将会更合适。 之后,intr的状态并不重要。

property checkiack;
   @ (posedge clk) $rose(intr) |=[$rose(iack);
endproperty
但是如果你要做如下图所示的事情? 那么你就遇到了真正的麻烦。 如下图所示,由于intr是对电平敏感的采样,当它被采样到为高电平时,它会查找边沿敏感的iack? 但因为intr是电平敏感,下一个时钟也是高,它将每个时钟启动一个新线程并进行$rose(iack)检查。 由于iack没有在第二个线程从0变成1,property失败。 很有可能你不希望看到这种失败。


<think>好的,用户现在问的是关于SVA(SystemVerilog Assertions)的sequence里延迟前后记录时间的问题。我需要先回顾之前的对话历史,看看用户之前问了什么,然后确保这次的回答符合他们的需求。 用户之前的问题是关于异步复位同步释放的SVA验证,特别是在时钟抖动的情况下如何处理。我给出了详细的步骤,包括问题分析、验证方案设计、关键技术点说明、注意事项以及改进建议。现在用户的新问题是关于在SVA sequence如何记录延迟前后的时间,这可能涉及到如何在断言精确测量时间差,用于验证时序要求。 首先,我需要理解用户的具体需求。他们可能在设计验证时遇到了需要测量两个事件之间时间间隔的情况,例如信号跳变后,经过一定延迟后另一个信号的变化是否符合预期。特别是在存在时钟抖动的情况下,精确的时间记录变得重要,因为传统的基于固定周期的检查可能不适用。 接下来,我需要回忆SystemVerilog处理时间记录的相关系统函数,比如$realtime和$time。这些函数可以用来获取当前仿真时间,从而计算时间差。在SVA,sequence通常用于描述一系列按时间顺序发生的事件,因此在sequence内部或前后记录时间戳是关键。 然后,我需要考虑用户可能的实际应用场景。比如,在验证异步复位同步释放时,需要确保复位释放后经过三个时钟周期的同步,但由于时钟抖动,这三个周期的时间可能不是固定的。用户可能需要在每个同步阶段记录时间,并检查它们之间的间隔是否符合动态调整的时间窗口,而不是固定的周期倍数。 另外,用户提到的“延迟前后记录时间”可能涉及到在sequence的不同阶段(如##1、##2等延迟操作符前后)记录时间,以验证每个阶段的延迟是否符合预期。例如,在复位释放后,第一个触发器同步,第二个触发器在下一个时钟边沿同步,但由于时钟抖动,这两个边沿之间的时间可能不是严格的周期长度,需要动态计算允许的时间范围。 我需要确保回答涵盖以下内容: 1. SVA记录时间的方法,如使用$realtime和局部变量。 2. 如何在sequence使用这些方法来捕获事件前后的时间戳。 3. 示例代码,展示具体的实现方式,特别是处理时钟抖动的动态时间窗口。 4. 注意事项,比如时间精度的设置、变量的作用域、以及如何处理多个并发的事件。 可能还需要解释为什么使用$realtime而不是$time,因为$realtime可以提供更高精度的时间值,适合需要精确时间测量的场景。此外,要提醒用户在测试平台设置适当的时间单位和精度,以避免因精度不足导致的测量错误。 还需要考虑用户可能遇到的常见问题,比如时间记录的变量作用域问题。在SVA,局部变量可以在sequence声明,并在整个sequence使用,这有助于在不同的延迟步骤传递时间戳。示例代码应该展示如何声明和使用这些局部变量,以及如何在不同步骤间传递时间值。 此外,结合之前的回答,用户可能需要将这种时间记录方法应用到异步复位同步释放的验证,因此需要展示如何将时间记录与同步阶段检查结合起来,特别是在时钟抖动的情况下如何动态调整允许的时间窗口。例如,每个同步阶段的时间间隔可能需要根据时钟抖动的范围进行调整,而不是固定为周期长度。 最后,总结关键点,强调动态时间窗口的重要性,以及如何通过SVA的sequence和系统函数来实现精确的时间验证,确保设计在存在时钟抖动时仍能正确工作。</think>在SVA(SystemVerilog Assertions),对`sequence`内延迟前后时间的记录是验证时序行为的关键技术,尤其在存在时钟抖动或动态时序要求的场景。以下是详细的技术解析和实现方法: --- ### **一、核心概念** 在SVA,`sequence`的延迟操作符(如`##1`、`##[min:max]`)用于描述事件的时间关系。**记录延迟前后的时间**主要用于: 1. 验证实际时间间隔是否符合预期(例如:信号跳变后,经过特定时间窗口是否满足条件) 2. 处理非理想时钟场景(如时钟抖动、频率变化) 3. 调试时序违规时定位具体延迟阶段 --- ### **二、实现方法** 需结合`$realtime`系统函数和局部变量(`local variable`)记录时间戳。以下为典型场景的实现: #### **示例代码:记录延迟前后的时间差** ```systemverilog sequence delay_time_check; real t_start, t_end; // 声明局部变量记录时间 (trigger_event, t_start = $realtime) // 触发事件时记录起始时间 ##[1:3] // 允许1到3个时钟周期的延迟 (target_event, t_end = $realtime) // 目标事件时记录结束时间 // 验证时间差是否符合要求(考虑时钟抖动) , (t_end - t_start) inside {[1.8*`CLK_PERIOD : 2.2*`CLK_PERIOD]}; endsequence ``` #### **关键点说明** 1. **时间记录函数** - `$realtime`:返回**仿真实际时间**(含小数精度,单位由`timescale`决定) - `$time`:返回整数时间(精度较低) 2. **动态时间窗口计算** - 若时钟周期为`10ns`且抖动范围为±10%,则时间窗口应设为: $$ \text{允许时间差} \in [0.9T, 1.1T] \cup [1.8T, 2.2T] \cup ... $$ - 使用`inside`操作符动态匹配范围 3. **变量作用域** - 局部变量(如`t_start`、`t_end`)仅在`sequence`内有效 - 跨`sequence`传递时间需通过参数或全局变量 --- ### **三、典型应用场景** #### **场景1:异步复位同步释放验证** ```systemverilog property async_reset_check; real t_release; @(posedge clk) ($rose(async_rst_n), t_release = $realtime) // 复位释放时刻 |=> // 下一个时钟周期 (1, $display("Sync stage1 at t=%0t", $realtime)) ##1 // 第二个同步阶段 (1, $display("Sync stage2 at t=%0t", $realtime)) ##1 // 第三个同步阶段 (1, $display("Sync stage3 at t=%0t", $realtime)) // 总时间偏差检查 , ($realtime - t_release) <= 3.3*`CLK_PERIOD; // 允许10%抖动累积 endproperty ``` #### **场景2:信号建立/保持时间检查** ```systemverilog sequence setup_hold_check; real t_data_change; ($changed(data), t_data_change = $realtime) // 数据变化时刻 ##0 // 立即检查时钟边沿 (@(posedge clk)[->1], ($realtime - t_data_change) >= `T_SETUP); endsequence ``` --- ### **四、调试技巧** 1. **时间戳打印** ```systemverilog // 在sequence插入调试信息 (trigger_event, $display("Trigger at t=%0t", $realtime)) ##2 (target_event, $display("Target at t=%0t", $realtime)) ``` 2. **波形标记** ```systemverilog // 使用系统任务标记关键时间点 ($rose(signal), t_mark = $realtime, $wave_debug("Reset released")) ``` --- ### **五、注意事项** 1. **时间精度一致性** 确保`timescale`设置与设计文件一致(如`timescale 1ns/1ps`),否则`$realtime`返回值可能不符合预期。 2. **非阻塞事件处理** 若需要精确对齐时钟边沿,建议使用`@(posedge clk)`同步采样,避免异步事件导致的测量误差。 3. **多线程冲突** 当多个`sequence`同时修改全局时间变量时,需使用`protected`或`semaphore`避免竞争。 --- ### **六、扩展应用** 结合覆盖率收集,可分析时间分布的统计特征: ```systemverilog covergroup delay_time_cg @(posedge clk); coverpoint ($realtime - t_start) / `CLK_PERIOD { bins normal = {[0.9:1.1]}; bins fast = {[0:0.9)}; bins slow = {(1.1:2.0]}; } endgroup ``` --- 通过精确记录和动态时间窗口验证,可有效应对时钟抖动等非理想时序场景。实际应用,建议配合EDA工具的时序调试功能(如Synopsys VC Formal、Cadence JasperGold)进行可视化分析。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值