system verilog $fell

博主在仿真中遇到$fell异常触发,怀疑是由于时钟作用下复位信号延迟导致的非0值到0的变化。讨论了可能的规避策略,不希望频繁检查,只关注信号跳转。寻求避免这种早期触发的解决方案。

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

在这里插入图片描述
这个$ fell是说从一个非0的值到0,今天仿真遇到一个奇怪的问题,$ fell 被异常触发了,期望的是ce_nvm下降沿触发检测,但是提前就触发了呢,波形明明一直显示为0,没有变化,怎么就触发了呢,如果有知道的请下面留言,谢谢
猜测是没有时钟之前所有信号被认为是非0值,一旦时钟有了,然后才按照RTL的逻辑变成对应的值。因为刚有时钟的时候复位还没有抬起来,复位值为0,这样就出现了非零值->0的一个变化导致$fell被触发,那有什么方式能够规避呢?
不想用ce_nvm ##1 !ce_nvm,因为为了节省仿真消耗,我只想在信号跳转的时候检查一下,而不是一直检查。

<think>我们正在讨论SystemVerilog中的throughout关键字。这是一个时序操作符,用于在断言中指定某个条件必须在整个序列过程中持续成立。 根据SVA(SystemVerilog Assertions)规范,throughout用于表示在给定序列的整个过程中,某个条件必须一直为真。 格式为:expression throughout sequence_expr 示例: 假设我们想要检查,在信号start为高开始,直到信号end为高的整个过程中,信号enable必须一直为高。 我们可以这样写: assert property (@(posedge clk) (start ##1 (end [->1])) throughout enable); 但是注意,上面的写法可能并不直观。更常见的写法可能是: assert property (@(posedge clk) $rose(start) |-> enable throughout (##[1:$] $rose(end))); 然而,实际上throughout操作符的左侧是一个表达式,右侧是一个序列。它表示左侧表达式在右侧序列的整个过程中必须持续为真。 另一个例子:检查在从a为高开始,直到b为高的整个过程中,c必须一直为高。 a throughout (##[1:$] b) // 这个序列表示:a为高,并且在接下来的某个周期(至少一个周期后)b为高,而在这整个过程中(从a开始到b发生)c必须一直为高?注意,这里我们通常需要将c与a分开。 实际上,我们通常这样写: assert property (@(posedge clk) $rose(a) |-> (c) throughout (##[1:$] b)); 或者更准确地说,我们可以这样: assert property (@(posedge clk) a |-> (c throughout (##[1:$] b))); 但要注意,这个断言的起始点是a为高的时刻,然后要求从那个时刻开始直到b出现(可能在多个周期后)的整个过程中,c必须一直为高。 然而,上面的写法有一个问题:throughout操作符的右侧序列(##[1:$] b)是从当前时刻开始的,也就是说,在a为高的那个时刻,序列(##[1:$] b)开始,要求从下一个周期开始直到b出现。那么,在a为高的那个周期,c是否必须为高?是的,因为整个序列包括当前周期(即a为高的周期)直到b出现的周期,所以c必须在整个区间内为高。 下面是一个更清晰的例子: sequence s; b ##1 c; endsequence property p; a throughout s; endproperty assert property (@(posedge clk) p); 这个断言的意思是:当序列s发生时(即b发生然后下一个周期c发生),在整个序列s发生的过程中(即从b发生到c发生的两个周期),a必须一直为真。 注意:throughout操作符要求左侧表达式在右侧序列的整个时间区间内(从序列开始到序列结束)都成立。 我们还可以用throughout来检查一个信号在某个事件持续期间一直保持某个值。例如,在总线请求req发出后,直到总线应答ack返回的整个过程中,总线请求req必须一直保持为高。 assert property (@(posedge clk) $rose(req) |-> req throughout (##[1:$] ack)); 这里,从req上升沿开始,直到ack上升沿(注意,这里我们用了##[1:$] ack,表示ack在req上升沿后的任意周期发生),req必须一直保持为高。 但是,注意:如果ack在req上升沿的同一个周期发生,那么throughout的序列区间就是0个周期?因为##[1:$]要求至少一个周期后,所以ack不会在同一个周期发生。所以这个断言要求ack至少在一个周期后发生,并且从req上升沿开始(包括该周期)直到ack发生,req必须一直为高。 下面我们给出一个简单的例子,在仿真中演示: 假设: 周期1:req=0, ack=0 周期2:req=1(上升沿),ack=0 -> 断言开始 周期3:req=1, ack=0 周期4:req=1, ack=1 -> 断言结束(成功) 如果在周期3,req变为0,而ack还没有来,那么在周期3的上升沿,由于req在序列过程中变低,断言失败。 因此,throughout是一个强大的操作符,用于确保在某个事件序列的整个过程中,某个条件始终满足。 现在,我们总结一下: 语法:expression throughout sequence_expr 含义:在序列sequence_expr开始到结束的每一个时钟周期,表达式expression都必须为真。 注意事项: - 序列sequence_expr的起始点就是throughout开始检查的点,即当前时刻(如果序列是从当前时刻开始)。 - 序列sequence_expr可以跨多个周期,expression必须在这些周期中都为真。 常见错误: 将throughout与and操作混淆。and操作是序列与序列之间的操作,而throughout是表达式与序列之间的操作。 另外,throughout也可以用于更复杂的序列中,作为构建更复杂断言的基础。 参考引用:IEEE Standard for SystemVerilog-Unified Hardware Design, Specification, and Verification Language (IEEE Std 1800-2017) [^1] 现在,根据要求,我们需要生成相关问题。 §§相关问题§§ 1. throughout操作符和and操作符在SVA中有什么区别? 2. 能否给出一个throughout操作符在覆盖率中使用例子? 3. 在SVA中,throughout操作符能否用于异步断言? 4. 如何调试一个包含throughout操作符的断言失败? 5. 在throughout操作符中,如果序列是空序列(即立即结束),那么表达式需要保持多久?</think>### SystemVerilog `throughout` 关键字详解 `throughout` 是 SystemVerilog 断言(SVA)中的时序操作符,用于指定**某个条件必须在整个序列执行期间持续成立**。其基本语法为: ``` (expression) throughout sequence_expr ``` #### 核心功能 1. **持续性验证**:确保表达式 `expression` 在序列 `sequence_expr` 的**整个持续时间内**保持为真 2. **时序关联**:将瞬态条件与时间相关的序列绑定 3. **断言监控**:常用于验证协议或状态机的稳定条件 #### 典型应用场景 ##### 1. 总线协议检查 ```systemverilog property bus_busy_check; @(posedge clk) $rose(bus_request) |-> (bus_grant throughout (##[1:10] $fell(bus_request))); endproperty ``` **含义**:一旦总线请求(`bus_request`)置起,总线授权(`bus_grant`)必须在请求释放前的整个周期内保持有效[^1]。 ##### 2. 状态机稳定性验证 ```systemverilog sequence data_valid_seq; ##2 start_transfer ##[1:5] end_transfer; endsequence assert property ( @(posedge clk) (state == ACTIVE) throughout data_valid_seq ); ``` **含义**:在数据传输序列(`start_transfer` 到 `end_transfer`)期间,状态机必须始终保持在 `ACTIVE` 状态[^1]。 ##### 3. 时钟门控检查 ```systemverilog property clock_gating; @(posedge clk) enable_gating |-> (clock_enable throughout $fell(enable_gating)[->1]); endproperty ``` **含义**:使能门控信号后,时钟使能信号必须持续有效直到门控关闭。 #### 关键特性 | 特性 | 说明 | |------|------| | **起始点** | 从序列的第一个匹配点开始验证 | | **结束点** | 持续到序列的最后一个匹配点 | | **强度** | 表达式失效会立即导致断言失败 | | **嵌套能力** | 可与其他操作符(如 `and`/`or`)组合使用 | #### 与类似操作符对比 - **`and`**:要求两个序列**同时开始**,不强制全程重叠 ```systemverilog (a_seq and b_seq) // a和b同时开始但可能不同时结束 ``` - **`throughout`**:强制表达式**完全覆盖**序列周期 ```systemverilog (expr throughout seq) // expr必须覆盖整个seq周期 ``` #### 使用注意事项 1. **序列长度敏感**:空序列(零长度)会导致 `throughout` 立即成功 2. **采样时机**:基于断言时钟的**预采样值**(Preponed region) 3. **复位处理**:建议结合 `disable iff` 处理异步复位 ```systemverilog assert property ( @(posedge clk) disable iff (reset) (signal > threshold) throughout data_phase ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值