相关阅读
Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482
`timescale编译指令用于指定该指令后编译单元内的模块的时间单位和时间精度,直到在编译单元中遇到了另一个`timescale编译指令(关于编译单元,可以参考Verilog基础:八种命名空间)。时间单位是时间的度量单位,例如延迟值;而仿真精度决定了仿真器最小可分辨的时间值。
如果在一个编译单元内没有使用`timescale编译指令或者使用了`resetall编译指令进行复位,则模块的时间单位和时间精度默认是由仿真器决定的。如果在一个层次设计中,一些模块使用`timescale编译指令指定了时间单位和时间精度,而一些使用由仿真器决定的默认值,则会报错,如例1所示。这导致了如果使用多文件单编译单元,可能出现是否报错取决于编译顺序的情况,如例2所示。
// 例1 // 文件: timescale.v `timescale 1ns/1ns module aaa(); bbb bbb_inst(a); endmodule `resetall module bbb(input a); // 错误,因为bbb模块使用默认值,而aaa模块指定了`timescale initial #5 $display("bbb"); endmodule// 例2 // 文件1: timescale1.v `timescale 1ns/1ns module aaa(); bbb bbb_inst(a); endmodule // 文件2: timescale2.v module bbb(input a); initial #5 $display("bbb"); endmodule // ***如果选择多文件单编译单元*** // 当先编译timescale2.v时,会报错,因为此时timescale2.v使用默认值;当先编译timescale1.v时不会报错,因为此时timescale2.v也会被`timescale 1ns/1ns影响 // 对于Modelsim,可以通过改变命令行中这两个源文件的前后顺序,改变其编译顺序 // ***如果使用单文件单编译单元*** // 一定会报错,因为timescale2.v使用默认值`timescale编译指令的语法如图1所示。
图1 `timescale编译指令的BNF范式
time_unit参数指定了时间单位;而time_precision参数指定了时间精度。time_precision参数不能比time_unit参数还大,也就是说时间精度最大与时间单位相同,这很好理解,如果一个时间精度都大于时间单位了,那它将成为实际意义上的时间单位。
time_unit参数和time_precision参数由两部分组成,一个整数值和一个时间字符串,其中整数值可以是1,10,100,而字符串可以是s,ms,us,ns, ps和fs。时间字符串具体含义如表1所示。
表1 时间精度和时间单位的含义
| 时间字符串 | 含义 |
| s | 秒 |
| ms | 毫秒 |
| us | 微秒 |
| ns | 纳秒 |
| ps | 皮秒 |
| fs | 飞秒 |
一个延迟值在被使用前会因为时间精度而四舍五入,如例3和例4所示。
// 例3 // 文件: timescale.v `timescale 100ns/10ns module aaa(); initial #1.55 a=1; endmodule在例3中,由于时间单位是100ns,所以1.55实际上表示155ns;而时间精度是10ns,代表需要以10ns作为单位四舍五入,155ns以10ns作为单位四舍五入是160ns,因此真正的延迟时间值为160ns。
// 例4 // 文件: timescale.v `timescale 1ns/1ps module aaa(); initial #1.6666 a=1; endmodule在例4中,由于时间单位是1ns,所以1.6666实际上表示1.6666ns;而时间精度是1ps,代表需要以1ps作为单位四舍五入,1.6666ns以1ps作为单位四舍五入是1.667ns,因此真正的延迟时间值为1.667ns。
一个层次设计的所有模块中最小的时间精度决定了仿真的时间精度,它也是仿真可以推进的最小单位和使用转换说明%t打印时的默认输出单位,需要注意的是,仿真的时间精度并不一定和各模块的时间精度相同,如例5所示。
// 例5 // 文件: timescale.v `timescale 1ps/10fs module aaa(); reg a; bbb bbb_inst(a); initial #5 a=1; endmodule `timescale 1ns/1ns module bbb(input a); initial @(a) $display("%t", $realtime); endmodule 输出: 500在例5中,仿真的时间精度为层次设计中最小的10fs,而模块bbb的时间精度为1ns。当使用转换说明%t显示$realtime系统函数返回值时,会将其单位转换为仿真的时间精度10fs(以仿真的时间精度为单位是系统任务$timeformat的默认行为)。由于$display()系统任务在5ps时被调用,用10fs作为单位显示是500,即500*10fs。
仿真的时间精度也是仿真器能维护和推进的最小时间,换句话说如果用仿真的时间精度作为仿真时间的单位则不会有小数。对于上例来说,如果仿真器推进时间小于10fs,则会忽略而不能累计。