sv验证环境中bus.mon.sig与@bus.mon同时使用的反面案例

前言

上周定位某童鞋的环境代码,定位出一个感觉非常经典的验证环境时间问题,特此记录以兹鼓励~。~~

现象

代码示意如下,验证环境构建于module中,本意是希望对其rtl时序,在wait到mon.vld后@一拍时钟,之后从队列中取数进行处理,下面的代码直接变成打印:

initial begin
    forever begin
        wait (bus.mon.vld == 1'b1);
        @bus.mon;
        $display("%t, pop_front this cyc", $realtime);
    end
end

当时出现的错误是,发现只有一拍的valid信号,但是却发生了两次取值行为,且发生在两拍:

打印结果为:

2010.000ns, pop_front this cyc
2020.000ns, pop_front this cyc

为了进一步确定行为,在wait和@之后分别加入打印:

initial begin
    forever begin
        wait (bus.mon.vld == 1'b1);
        $display("%t, wait dao le!", $realtime);
        @bus.mon;
        $display("%t, pop_front this cyc", $realtime);
    end
end

打印结果为:

2010.000ns, wait dao le!
2010.000ns, pop_front this cyc
2010.000ns, wait dao le!
2020.000ns, pop_front this cyc

可以确定在2010ns时刻wait生效了2次。 

分析

首先明确下,这个现象是不符合代码本意的,本意应该是一拍有效取一个数据出来,那么接下来具体分析下为什么是这种现象;

由灵魂画手把波形画一下!

顺便在把time slot的图搬出来对着看,因为环境搭建并启动于于module中,只需要module regions的就够了:

那么在2010ns时间点,进程上在做哪些事呢?

1. 2010ns ts之前的1ps(interface中设置的skew)采样rtl vld信号为1,在active-observed之间bus.mon.vld值跳变为1;

2. 时钟bus.mon在observed域跳变为1;

对应的时序结构如下图,那么也就不难发现为什么wait会判定成功2次了:

因此时间线就理清楚了:

2010ns, bus.mon.vld跳变为1 -->

wait(bus.mon.vld)在observed之前生效 -->

@bus.mon成功(observed域)-->

执行环境语句,不消耗时间,forever回wait语句 -->

wait(bus.mon.vld)再次成功,此时仍为2010ns -->

@bus.mon不成功(关于@和wait的区别请查询绿皮书吧),该进程等待在这里,等下一次bus.mon上升沿-->

时间推进到2020ns,@bus.mon成功,再一次执行下面的语句。

结论

该波形是符合system verilog的规则的,但是不符合设计者意图,因此,就别这么搞了吧。

乖乖的@bus.mon (if bus,mon.vld) ......是最安全的。

ps.

在modelsim上未复现该波形,以后不用了。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

尼德兰的喵

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值