在这篇文章中你真的会用`timescale吗?曾讨论了Verilog中的时间格式设置系统任务`timescale。本文再来介绍两种与时间格式相关的系统任务,分别是:
顾名思义,就是打印时间格式`timescale,它的语法格式如下:
printtimescale_task ::=$printtimescale [ ( hierarchical_identifier ) ] ;
其中的hierarchical_identifier代表模块层次,这意味着其不仅可以打印当前module的时间格式,同样可以打印指定module的时间格式。
其输出内容如下:
Time scale of (module_name) is unit / precision
举个例子:
- //module test_a定义
- `timescale 1 ms / 1 us //单位1ms,精度1us
- module test_a;
-
- initial begin
- $printtimescale(test_a); //打印module test_a的时间格式
- $printtimescale(test_b_inst); //打印module test_b_inst(被例化的test_b module)的时间格式
- end
-
- test_b test_b_inst(); //例化module test_b
-
- endmodule
-
- //module test_b定义
- `timescale 1 ns / 1 ps //单位1ns,精度1ps
- module test_b;
- endmodule
在上述testbench中,将模块test_a的时间单位/时间精度分别设置成了1ms/1us;同时在模块test_a中例化了模块模块test_b,其时间单位/时间精度分别设置成了1ns/1ps;然后分别打印了两个模块的时间格式,仿真结果(打印内容)如下:

与预期设计一致。
timeformat用于配置其他打印系统任务中($write, $display,$strobe, $monitor, $fwrite, $fdisplay, $fstrobe, and $fmonitor)%t类型的打印格式,它的语法格式如下:
timeformat_task ::= $timeformat [ ( units_number , precision_number , suffix_string , minimum_field_width ) ] ;
其中的units_number使用下表中的数字来表示对应的时间单位:

0对应1s,-1则对应100ms,````以此类推,-15则对应1fs,可以看到这个对应关系基本上就是时间单位换算关系,非常好记。一般多使用-9即ns的打印方法。
其中的precision_number 表示时间精度,即需要打印到小数点后几位。
其中的suffix_string 用来在时间后打印一个用户自定义的字符串。
其中的minimum_field_width 表示时间值字符串与后缀字符串合起来的这部分字符串的最小长度,若这部分字符串不足这个长度,则在这部分字符串之前补空格。
如果没有调用该系统函数对时间格式进行设置,则其默认设置如下:

即时间单位为`timescale设置的时间精度,不精确到小数点后,打印的字符串为空,最小长度为20个长度。
举个例子:分别打印在默认格式下和设置时间格式为单位1ns,精度小数点后3位,打印字符串 ns,最小打印长度10的情况下的仿真时间。如下:
-
- `timescale 1 ns / 1 ps //单位1ns,精度1ps
-
- module test_a;
-
- initial begin
- #10
- $display("%t",$realtime); //打印默认格式的仿真时间
- #10
- $timeformat(-9,3," ns",10);
- $display("%t",$realtime); //打印用户设定的格式的仿真时间
- end
-
- endmodule
其仿真结果如下:

参考资料1:IEEE Standard for Verilog® Hardware Description Language(IEEE Std 1364™-2005)