\$test\$plusargs vs. \$value\$plusargs

$test$plusargs()$value$plusargs()做为进行Verilog和SystemVerilog仿真运行时调用的系统函数,可以在仿真命令直接进行赋值,并且不局限于不同仿真器对于参数在仿真命令中定义格式不同的限制,也避免了更改参数带来的需要频繁编译的问题。使用这两条命令对于搭建测试平台有一定的便利。

1. 介绍

在进行宏定义时,我们经常使用 `ifdef等命令在代码中,如:

// test.v
initial begin
  `ifdef dumpop
    $dumpfile("results.vcd");
    $dumpvars;
  `endif
end

如果希望成功调用$dump等函数,需要在编译时指定`define的宏定义:

<compile-option> -define dumpon test.v

但是如果后面的仿真过程中不需要该部分的定义时该如何处理呢? 当需要改变编译条件时,经常需要重新编译。并且一旦编译通过,在编译阶段指定的宏定义在整个仿真运行过程中一直有效,因此,如果需要修改宏定义,需要进行重新编译,这就降低了仿真的效率。

为此,可以使用$test$plusargs()$value$plusargs()进行解决,该函数的调用发生在仿真运行(run)阶段。这样只需要对设计进行一次编译即可,如果需要改变相应的条件,可以在run的时候动态指定,这样有利于脚本处理,也有利于object的动态construct。

2. $test$plusargs()

在运行(run)仿真时指定要选择的条件,即只需要在仿真运行命令(run-options)中指定需要的条件即可,如下例中,如果要将test01.dat, test02.dat, test03.dat分别载入到各自的mem中,仅需要在运行命令中加入+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
<run-option>+test01+test02+test03...

3. $value$plusargs()

$value$plusargs()可以将运行命令(run-options)中的参数传递给指定的信号或者字符,其语法格式如下:

Integer = $value$plusargs("string",signalname);

其中string = "plusarg_format"+"format_string"plusarg_format指定了用户定义要进行传递的值,format_string指定了要传递值的格式(类似$display中定义的%s,%h等)。

示例:

//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
  $display("frequency: %0f",frequency);
  ......
end

若使用如下运行命令:

  <run-option>+FINISH=1000+TESTNAME=this_test+FREQ=5.6666

则上例的运行结果为:

stop_clk: 1000
testname: this_test
frequency: 5.666
posted @ 2024-12-10 13:44  Vinson88  阅读(61)  评论(0)    收藏  举报