Verilog 其他系统任务
仿真控制:$finish, $stop
系统任务 | 调用格式 | 任务描述 |
---|---|---|
退出仿真 | $finish( type ) ; | 结束仿真,参数 type 可选择退出仿真时是否打印信息
type=0: 直接退出不打印 type=1: 打印仿真时间和该语句所在的位置行信息 type=2: 打印仿真时间、位置、存储器和 CPU 时间的使用情况 |
暂停仿真 | $stop( type ) ; | 暂停仿真,用法格式与 $finish 相同 |
$finish
与 $stop
都有让仿真停止的功能,但他们还是有区别的。
$finish
是结束本次仿真。$stop
是暂停当前的仿真。仿真暂停后通过 Verilog 仿真工具或命令行还可以使仿真继续进行,而结束仿真后仿真无论如何也不能再进行。$stop
类似于 C 语言的断点调试功能。
下面用仿真说明 type 类型对应的打印信息。
initial begin
forever begin
#100;
if ($time >= 10000) $finish(0) ;
//if ($time >= 10000) $finish(1) ;
//if ($time >= 10000) $finish(2) ;
end
end
$finish(0)
,仿真退出时不打印任何信息。
$finish(1)
,仿真退出时打印仿真时间和 $finish
所在的行信息,如下所示。
模块 test 时间精度为 ns,但是仿真器时间精度为 ps,所以打印的时间信息相差 1000 倍。
$finish(2)
,仿真退出时不仅打印仿真时间和行信息,还打印 PC 机使用的时间以及及存储器的使用情况,如下所示。
时间格式:$printtimescale, $timeformat
系统任务 | 调用格式及说明 |
---|---|
打印时间
单位和精度 |
$printtimescale( hierarchy ) ; |
该系统任务会按照如下格式打印 timescale 信息
TimeScale of ( hierarchy ) is 1 ( unit ) / 1 ( precision ) hierarchy 为模块访问层次,可省略,此时打印当前模块的 timescale 信息 |
|
设置时间
单位和精度 |
$timeformat(unit_num, precision_num, suffix_string, min_field_width) |
unit_num,设置时间单位,默认以 `timescale 为准
precision_num, 设置时间单位中小数的有效位数,默认为 0 suffix_string, 设置时间后缀信息,例如 "ns" 等,默认为空 min_field_width, 设置时间信息所占的字符节数,默认为 20 |
当显示任务(如 $display
、$monitor
等)和文件写任务(如 $display
等)使用格式 "%t
" 进行数据输出时,$timeformat
可以指定时间单位信息的输出格式。
$timeformat
中 unit_num
是使用有符号数来指定时间单位的,其对应关系如下表所示:
unit_num | 时间单位 | unit_num | 时间单位 |
---|---|---|---|
0 | 1 s | -8 | 10 ns |
-1 | 100 ms | -9 | 1 ns |
-2 | 10 ms | -10 | 100 ps |
-3 | 1 ms | -11 | 10 ps |
-4 | 100 us | -12 | 1 ps |
-5 | 10 us | -13 | 100 fs |
-6 | 1 us | -14 | 10 fs |
-7 | 100 ns | -15 | 1 fs |
利用如下代码对时间刻度的 2 个系统任务进行简单的仿真。
//change timescale
initial begin
# 10 ;
//ps精度,小数为5位有效数字,单位后缀显示"my-ps", 占15个字符大小的长度
$timeformat(-12, 5, " my-ps", 15) ;
end
initial begin
# 5 ;
$printtimescale() ;
$display("Time before resetup: %t", $time);
# 10 ;
$printtimescale() ;
$display("Time after resetup: %t", $time);
end
仿真 log 如下所示。
由图可以对比 $timeformat
设置前后时间的显示格式。
此外,此过程中 timescale 始终是没有变的,$timeformat
只是改变了时间的显示格式。
仿真时间:$time, $stime, $realtime
系统任务调用 | 说明 |
---|---|
$time | 返回一个 64bit 整数型时间值 |
$stime | 返回一个 32bit 整数型时间值 |
$realtime | 返回一个实数型时间值,可以是浮点数 |
仿真代码如下:
initial begin
#10;
$display("$time output1: %t", $time);
$display("$stime output1: %t", $stime);
$display("$realtime output1: %t", $realtime);
#3.2;
$display("$time output2: %t", $time);
$display("$stime output2: %t", $stime);
$display("$realtime output2: %t", $realtime);
#5.6;
$display("$time output2: %t", $time);
$display("$stime output2: %t", $stime);
$display("$realtime output2: %t", $realtime);
end
仿真 log 如下所示。
由于仿真时间短,$time
与 $stime
是没有区别的。
但是 $realtime
会按照当前的时间精度对仿真时间进行准确读取,而 $time
和 $stime
会根据时间精度对当前时间进行四舍五入的读取。
命令行传参:$test$plusargs, $value$plusargs
Verilog 还提供了交互任务 $test$plusargs
和 $value$plusargs
,仿真时可通过命令行传参的方式进行参数的传递,为仿真调试提供了极大的便利。
系统任务 | 调用格式 | 任务描述 |
---|---|---|
字符串传参 | $test$plusargs( str ) ; | 仿真时通过命令行传递的字符串数据如果和 str 一致,则返回值为 1, 否则为 0。 |
数值传参 | $value$plusargs( str, var ) ; | 仿真时通过命令行传递的字符串数据如果和 str 一致,则返回值为 1, 否则为 0。
需要在 str 内部指定传递给 module 内 var 变量的类型,格式可参考显示任务 $display |
使用 $test$plusargs( str )
时,只需在仿真命令行中加入"+str "即可。
使用 $value$plusargs( str,var )
时,需要在 str 内部指定传递参数时数值的类型。而在命令行传递参数时,数值不需要添加任何有关进制的说明,只保留相关进制的数值即可。命令行传递参数的格式需要参照 $value$plusargs
时 str 声明的格式。
下面用仿真说明:
initial begin
if ($test$plusargs("DISPLAY_CTRL")) begin
$display("Display simulation information!!!");
end
end
reg [1:0] display_sel ;
initial begin
if ($value$plusargs("INFO_SEL=%b", display_sel)) begin
$display("Parameter transfer succeeds!!!");
end
else begin
display_sel = 2'b0 ;
end
end
initial begin
#1 ;
if (display_sel == 2'b01)
$display("You have selected W3cschool!!!");
else if (display_sel == 2'b10)
$display("You have selected Verilog!!!");
else if (display_sel == 2'b11)
$display("You have selected Me!!!");
else
$display("What do you really what???");
end
在仿真命令行中增加: +DISPLAY_CTRL +INFO_SEL=01
则仿真 log 如下,由此可知,字符串参数和二进制参数均传递正确。
点击这里下载源码