0 前言
这段时间在整合一个小ip,因为要验证每个feature是否可行,需要用testbench + C语言的方式进行仿真验证,由于每种feature不仅要在C语言中修改寄存器配置,还要再testbench修改寄存器的配置,这导致每验证一种feature既需要修改C语言,也需要修改testbench,非常繁琐
并且也不想把所有的feature写在一个testbench中(仿真时间会变长很多,尤其是需要dump波形的时候),如果验证完一个feature后,把调教好的testbench注释掉,一番注释下来,看着也恶心,并且等所有feature都搞好后,仿真的时间还是很长
于是就希望能有一种方式,在验证不同的feature时可以吃不同的 testbench,一番搜索下来,找到了$test$plusargs
的方法
1 语法介绍
先捋清两个词:plusargs
、plusargs_string
- plusargs:仿真时添加的参数
- plusargs_string:编译时提供的字符串
上面提到两个词,编译和仿真,以vcs为例,整个执行过程主要分为两步,编译和仿真(irun/xrun有三步,编译、细化elaborate、仿真)
编译的过程是检查语法、展开所有的参数、宏以及include的文件等等;仿真的过程我的理解就是打入设定的激励,验证功能是否符合预期
vcs成功编译后会生成一个可执行文件simv,如下图
在执行simv即可进行仿真
开始介绍主角,直接抄文档中的例子了
initial begin
if ($test$plusargs("HELLO")) $display("Hello argument found.");
if ($test$plusargs("HE")) $display("The HE subset string is detected.");
if ($test$plusargs("H")) $display("Argument starting with H found.");
if ($test$plusargs("HELLO_HERE"))$display("Long argument.");
if ($test$plusargs("HI")) $display("Simple greeting.");
if ($test$plusargs("LO")) $display("Does not match.");
end
在上面这段代码中,$test$plusargs("HELLO")
中的HELLO是plusargs_string,也就是编译时提供的字符串,编译完成后,在进行仿真时(执行simv),+
不同的plusargs会打印不同的内容
只有当plusargs_string的内容完全匹配plusargs的部分或全部内容时,$test$plusargs()
会返回一个非0的整数
原文如下:
原文的plusargs是HELLO,并给出了执行结果
2 示例
做个实验测试一下,代码如下:
module tb;
initial begin
$display("*********************\n");
if($test$plusargs("test"))
$display("\t test found \n");
if($test$plusargs("test_pattern"))
$display("\t test_pattern found \n");
if($test$plusargs("te"))
$display("\t te found \n");
if($test$plusargs("taa"))
$display("\t taa found \n");
$display("*********************\n");
#10;
$finish;
end
endmodule
编译之后生成可执行文件 simv
,然后执行simv +test
仿真结果如下
在上面的例子中,只有test
和te
部分或全部匹配test
,因此只打印了这两个语句的内容
3 多种情况的testbench怎么写
就像开头说的情况,我需要多种testbench如何借助这种方法实现呢,思路如下:
- 针对不同的情况,写多份配置过程,并保存在不同的文本中,比如需要三种配置,可以写三份文本,并保存为test_1.sv, test_2.sv, test_3.sv
- 在testbench中,利用$test$plusargs include这三个文本
给出一个简单的模板
module tb;
/* 此处省略tb中clk、dump等等内容 */
initial begin
if($test$plusargs("test_1"))
`include "./test_1.sv";
if($test$plusargs("test_2"))
`include "./test_2.sv";
if($test$plusargs("test_3"))
`include "./test_3.sv";
end
endmodule
在仿真时,通过+
不同的plusargs就可以执行不同testbench了