Verilog和Systemverilog仿真运行时会调用系统函数,本文主要对$test$plusargs和$value$plusargs做详细介绍和对比,系统函数的介绍参考的是VCS User Guide和IEEE Verilog-2005标准,不同IDE可能不太一样。
首先得介绍下宏定义的使用方法,即`ifdef, `elsif, `endif等代码在代码中,
test.v
------------------------
initial begin
`ifdef dumpon
$dumpfile("results.vcd");
$dumpvars;
`endif
end
如果要能够成功调用$dump等函数,需要在编译(compile)时指定`define的宏定义,其使用方法如下:
<compile-option> -define dumpon test.v
那么,在仿真过程中不需要该部分定义时该如何处理呢?
当需要改变编译条件时,经常需要重新编译。并且一旦编译通过,在编译阶段指定的宏定义在整个仿真运行过程中一直有效,因此,如果需要修改宏定义,则需要重新进行编译,从而降低了仿真的效率。
为此,可以使用$test$plusargs和$value$plusargs进行解决,该函数的调用发生在仿真运行(run)阶段。这样仅需要对设计进行一次编译即可,如果需要改变相应的条件,可以在run的时候动态指定,这样有利于脚本处理进行回归的验证,同时也有利于object的动态construct。
1.$test$plusargs
在运行(run)仿真时指定要选择的条件,即只需要在仿真运行命令(run-options)中指定参数需要选择的条件即可,例如下例中,如果要将test01.dat、test02.dat、test03.dat分别load到各自的men中,仅需要如下命令在运行命令中加入“<+test01+test02 +test03>”即可.
<run-options>+test01+test02+test03...
当仿真运行时,$test$plusargs会在命令行中搜索指定的字符,若找到相应字符,在函数返回“1”,否则返回“0”。如果下次仿真时不需要test01时,仅需要将test01从运行命令中删除即可。
test.v
------------------------
initial begin
if($test$plusargs("test01"))
$readmemh("test01.dat", mem01);
if($test$plusargs("test02"))
$readmemh("test02.dat", mem02);
if($test$plusargs("test03"))
$readmemh("test03.dat", mem03);
end
2.$value$plusargs
$value$plusargs可以讲运行命令(run-options)中的参数值传递给指定的信号或者字符,其语法格式如下:
Integer=$value$plusargs(“string”,signalname);
其中string=”plusarg_format”+”format_string”,”plusarg_format”指定了用户定义的要进行传递的值,”format_string”指定了要传递的值的格式(类似$display中定义的%s、%h、etc.),并且string中”plusarg_format”和”format_string”格式应该为”plusarg_format4va”(=/+)”format_string”。如果转换后的位宽和传递的值不一致,则按照如下规则转换:
plusarg位宽与sigalname的关系 | Signalname值 |
< | plusarg左补零 |
> | plusarg截位 |
plusarg为负数 | 按照正数处理 |
不匹配 | 若为指定默认值,则reg类型为x |
$value$plusargs使用示例如下:
test.v
------------------------
if($value$plusargs("FINISH=%d", stop_clk))begin
repeat(stop_clk)@(posedge clk);
$finish
end
if(value$plusargs("TESTNAME=%s", testname))begin
$display("Running test %0s", testname);
end
if($value$plusargs("FREQ=%0f", frequency))begin
frequency = 8.333333;
end
若使用的运行命令如下:
<run-options>+FINISH=10000+TESTNAME=this_test+FREQ=5.6666
则上例的运行结果为:
stop_clk : 10000
testname:this_test
frequency:5.6666(如果run-options中没有增加“FREQ=5.6666”,那么frequency为8.333333)。
3.Conclusion
$test$plusargs和$value$plusargs的使用最终的目的就是再不修改代码的情况下只在运行命令的时候就可以根据实际需求调整测试用例同时提高运行效率。但是在实际使用$test$plusargs和$value$plusargs时,需要在编写代码初期考虑好使用的范围,否则,则实际仿真时未必可以对仿真带来便捷。