Specman e同步事件问题:同一周期事件触发expect规则误报求解决
这个问题我之前做验证时也碰到过,核心原因是你当前的expect规则把second_e触发的周期也纳入了“不能变化”的检查范围,而实际上你希望这个周期的变化是合法的。
先拆解下你原来的规则为什么会失败:
expect @first_e => {[0..]*(not {change(my_signal)}); @second_e} @clock;
这里的;在Specman/e里代表下一个周期的顺序执行,整个序列的逻辑是:从first_e触发后,连续N个周期(N≥0)都没有my_signal变化,然后在下一个周期触发second_e。但如果second_e和change(my_signal)在同一个周期发生,这个周期的not {change(my_signal)}是假的,规则会默认要求序列的每一段都满足条件,所以就判定失败了。
给你两个直接解决的方案,都是针对“允许second_e周期的变化”来调整规则:
方案1:使用until操作符(推荐)
until是Specman里专门用来处理“直到某个事件发生,事件发生的周期不约束”的场景,语法正好匹配你的需求:
expect @first_e => { (not {change(my_signal)}) until @second_e } @clock;
这个规则的语义是:从first_e触发后,每个周期都保证my_signal没有变化,直到second_e触发——注意,second_e触发的那个周期,即使my_signal发生变化,也不会被判定为违规,完美符合你的要求。
方案2:使用before操作符
如果你更想明确“只检查second_e之前的周期”,可以用before操作符:
expect @first_e => { (not {change(my_signal)})[*] before @second_e } @clock;
这里的[*]表示重复任意次,before @second_e意味着这个“无变化”的序列必须在second_e触发前结束,完全不会涉及second_e所在的周期,自然也就不会因为该周期的变化报错。
这两种方案都能解决你的问题,其中until的语义更贴合“两个时间点之间不变化,第二个时间点允许变化”的业务需求,推荐优先使用。
内容的提问来源于stack exchange,提问作者Halona

