在搭建验证环境时,经常需要在环境中插入很多info用于输出一定的log信息用于进行debug,在插入这些info方法的时候,经常需要同时输出该方法执行的具体时间,用于方便定位问题,为此在Verilog和SystemVerilog中提供了一堆关于time的方法,如果对于这些方法使用的不是很恰当,可能显示出来的结果与期望有些许差异,本文将通过示例,说明这一对time的方法是如何做的妖。
1 $time
当$time被调用时,将会返回一个64位的整型变量,用于表示该系统函数调用时的仿真时刻,返回的这个值是按照以下步骤得到:
(1)当前延迟值依据模块设置的timescale时间单位和精度得到实际仿真时间;
(2)调用该函数返回的值为上一步得到的时间按照timescale设置的时间单位缩小表示后四舍五入得到的整型值;
【示例】
【仿真结果】
示例中,时间变化主要包括仿真器波形显示时间和$time调用返回显示的时间,这两个时间的变化过程如下:
sig从“00”变成“11”发生在12ns,该时间由当前模块的时间单位和时间精度决定,即(1.234267*10≈12),$time返回的时间是12ns按照设置的时间单位缩小至1.2后四舍五入取整得到的,所以此时log显示时间为1;
sig从“11”变成“01”发生在24ns,该时间由当前模块的时间单位和时间精度决定,即(第一次延迟值1.234267*10≈12,当前延迟值1.225232*10≈12,12+12=24),$time返回的时间是24ns按照设置的时间单位缩小至2.4后四舍五入取整得到的,所以此时log显示时间为2;
sig从“01”变成“10”发生在36ns,该时间由当前模块的时间单位和时间精度决定,即(第一次延迟值1.234267*10≈12,第二次延迟值1.225232*10≈12,当前延迟值1.245678*10≈12,12+12+12=36),$time返回的时间是36ns按照设置的时间单位缩小至3.6后四舍五入取整得到的,所以此时log显示时间为4;
为了进一步理解时间的变化,我们将示例中使用的时间单位和时间精度“10ns/1ns”修改为“10ns/1ps”来看下仿真时间和$time显示的时间之间的关系。
【示例】
【仿真结果】
通过仿真结果可以看到,因为时间精度的修改,此时的仿真时间分别变为了:12.343ns、24.595ns和37.052ns,但是$time调用显示的时间还是1、2和4。可见仿真时间是受当前module的时间单位和时间精度的影响,sig第一次变化时$time返回值为1.234267*10≈12.343ns按照设置的时间单位级缩小至1.2343后四舍五入取整得到,所以此时log显示1,sig第二次变化时$time返回值为当前延迟值(1.225232*10≈12.252ns)与第一次延迟值(12.343ns)之和24.595ns按照设置的时间单位级缩小至2.4595后四舍五入取整得到,所以此时log显示时间为2,sig第三次变化时返回值为当前延迟值(1.245678*10≈12.457ns)与前两次延迟值(12.343+12.252)之和37.052ns按照设置的时间单位级缩小至3.7052后四舍五入取整得到,所以log显示为4。仿真结果汇总如下表。
2 $stime
当$stime被调用时,将会返回一个32位的无符号整型变量,用于表示该系统函数调用时的仿真时刻,返回的这个值会按照当前模块设置的时间单位,对调用时刻值进行四舍五入后显示具体时间,其用法与$time类似,只是$stime返回32位整型变量,所以其调用时表示的时间范围相较$time小,示例与$time相同,此处不再赘述。
3 $realtime
当$realtime被调用时,将会返回一个real型变量,所以其表示出来的形式一般为小数形式,用于表示该系统函数调用时的仿真时刻,时间单位为当前模块设置的时间单位。
【示例】
【仿真结果】
示例中,时间变化主要包括仿真器波形显示时间和$realtime调用显示的时间,这两个时间在之间的关系以及变化过程如下:
sig从“00”变成“11”发生在12ns,该时间由当前模块的时间单位和时间精度决定,即(1.234267*10≈12),$realtime返回的时间是12ns按照设置的时间单位缩小至1.2后得到,所以此时log显示时间为1.2;
sig从“11”变成“01”发生在24ns,该时间由当前模块的时间单位和时间精度决定,即(第一次延迟值1.234267*10≈12,当前延迟值1.225232*10≈12,12+12=24),$realtime返回的时间是24ns按照设置的时间单位缩小至2.4后得到,所以此时log显示时间为2.4;
sig从“01”变成“10”发生在36ns,该时间由当前模块的时间单位和时间精度决定,即(第一次延迟值1.234267*10≈12,第二次延迟值1.225232*10≈12,当前延迟值1.245678*10≈12,12+12+12=36),$realtime返回的时间是36ns按照设置的时间单位缩小至3.6后得到,所以此时log显示时间为3.6;
为了进一步理解时间的变化,我们将示例中使用的时间单位和时间精度“10ns/1ns”修改为“10ns/本文示例1ps”来看下仿真时间和$realtime显示的时间之间的关系。
【示例】
【仿真结果】
通过仿真结果可以看到,因为时间精度的修改,此时的仿真时间分别变为了:12.343ns、24.595ns和37.052ns,但是$realtime调用显示的时间还是1.2343、2.4595和3.7052。可见仿真时间是受当前module的时间单位和时间精度的影响,sig第一次变化时$realtime返回值为(1.234267*10≈12.343ns)12.343ns按照设置的时间单位级缩小至1.2343后得到,所以log显示为1.2343。sig第二次变化时$realtime返回值为当前延迟值(1.225232*10≈12.252ns)与第一次延迟值(12.343ns)之和24.595ns按照设置的时间单位级缩小至2.4595后得到,所以log显示为2.4595,sig第三次变化时返回值为当前延迟值(1.245678*10≈12.457ns)与前两次延迟值(12.343+12.252)之和37.052ns按照设置的时间单位级缩小至3.7052后得到,所以log显示为3.7052。仿真结果汇总如下表。
通过仿真结果可以看到,仿真时间是按照当前module设置的时间单位和时间精度进行显示,而$realtime函数显示的时间为仿真时间按照时间单位数量级缩小后得到的。
通过上述示例可以看到,在进行仿真时,当出现log显示时间与波形不一致时,要注意产生log信息使用的关于time的函数是什么,同时也要注意当前模块设置的时间单位和精度,如果为了得到与仿真波形时间吻合的时间,可以使用$realtime。
END
文章来源:处芯积律
推荐阅读
更多IC设计干货请关注IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。