timescale应用:
timescale是Verilog HDL中的一种时间尺度预编译指令,它用来定义模块的仿真时的时间单位和时间精度,格式如下:
`timescale 仿真时间单位/时间精度
仿真时间单位:这是仿真中时间的基础单位。例如时间单位是1ns(纳秒),那么1的时间单位就是1纳秒,3就是3纳秒
时间精度:就是模块仿真时间和延时的精确程度,比如:定义时间精度为10ns,那么仿真就可以精确地模拟到10ns级别的时间与信号变化关系,而8ns或者18ns是不可能做到的, 时序中所有的延时至多也只能精确到10ns
注意:用于说明仿真时间单位和时间精度的数字只能是1、10、100,不能为其它的数字。而且,时间精度不能比时间单位还要大,最多一样大,比如下面定义都是对的:
`timescale 1ns/1ps
`timescale 100ns/100ns
下面的定义是错的:
`timescale 1ps/1ns
在编译过程中,timescale指令影响编译器指令后面所有模块中的时延值,直至遇到另一个timescale指令resetall指令。
timescale错误场景:
在verilog中一个没有指定timescale的verilog模块就有可能错误的继承了前面编译模块的无效timescale参数,在多个模块嵌套使用的时候,可能就会出现时间刻度不统一的情况,从而出现仿真结束时间与"设置值不符的现象"。
比如通过 uvm_root::set_timeout(1us);结果uvm在仿真进行到1ms的时候,才会自动timeout结束。这是因为对于sv而言,timeout其运行本质并不是"特定的时间"而只是对64位的数字进行计数,而仿真器在运行仿真时,对于不同的module,interface,pkg和program“单元”,仿真时间精度可能是不同的。
举例说明,例如仿真的testbench设置的timescale值为1ps/1ps, 则uvm_pkg的timescale 值为1ns/1ps,在testcase中设置超时时间为1us:
time timeout_value=1us;
uvm_root::get().set_timeout(timeout_value);
那么在testcaes中,timeout_value变量的值是1us/1ps =1000000,只是单纯的数字值; uvm_root拿到该参数后,会根据自身的仿真步长1ns,持续1000000个仿真步长后停止仿真,所以在uvm_pkg,停止仿真的时间就变成了1000000*1ns = 1ms;
对于仿真器而言,timescale声明的作用范围和宏很像,如果单元文件前面有`timescale 的声明,则仿真器在编译(xmvlog)的时候会为其添加timescale的编译信息。如果一个文件此前都没有声明过`timescale,则该文件单元的timescale会被仿真器设为UN_SET。如果当前文件未声明,但是之前的文件声明了,则编译器沿用之前的timesacle.
解决方法:
1. 不用仿真器提前编译好的uvm_pkg lib ,手动编译uvm_pkg文件,在编译文件前设置好对应的timescale。
2. 使用-timescale选项为未声明timescale的单元添加默认timescale;或者使用-override_timescale 选项override某个单元的timescale。
在仿真时可以用$printtimescale函数查看当前仿真域的timescale, 或者xrun支持-print_timescale选项,会在编译的时候打印出各个单元的timescale
其他
- 关于本文,您有什么想法均可在评论区留言交流。
- 自身能力不足,如有错误还请多多指出!