如何在 verilog 中 运行 多个测试用例?
How to run multiple testcases in verilog?
我已经在 "tc1.v" 和 "tc2.v" 中编写了我的测试用例。测试用例以任务的形式出现。例如:
//tc1.v
task tc1(input reg [31:0] j,input reg Reset,output reg dataValidIn);
//logic
endtask
//tc2.v
task tc2(input reg [31:0] counter,input reg Reset,output reg dataValidIn);
//logic
endtask
module top_test;
//inputs and outputs
//logic
`ifdef testcase1
`include "tc1.v";
`else
`include "tc2.v"
`endif
endmodule
问题是我想 运行 每个 posedge 时钟的测试用例。如果我在 always 块中包含 'ifdef 部分,modelsim 会抛出错误。无论如何我可以做到这一点吗?
从您上面的代码来看,`include 所包含的只是任务声明,而不是实际的任务调用。在代码的其他地方,您必须在 initial
或 always
块中调用类似 tc1(x, y, z);
的内容。此外,为了使其更具可扩展性,我建议不要有条件地包含任务声明并将其留给调用来确定要执行哪个任务 运行。因此,您可以简单地在任务调用处添加所需的代码而不是任务包含:
// Have a macro for your test case, you can also declare this in the commandline
`define TESTCASE 1
module top_test;
...
`include "tc1.v"
`include "tc2.v"
...
always @(posedge clk) begin
// Switch on the test case to determine which to use
// NOTE THAT IF THE TASK TAKES LONGER THAN 1 CLOCK CYCLE TO COMPLETE, THIS WILL NOT WORK FOR A TASK PER CLOCK
case (`TESTCASE)
1: tc1(...);
2: tc2(...);
default: begin
$display("ERROR: Bad Testcase supplied %d", `TESTCASE);
$finish;
end
endcase
end
...
endmodule
我使用的另一种解决方案是使用运行时间开关将测试用例指定给模拟器。这使您不必为每个测试重新编译 test/design,并且您可以批处理 运行 所有测试而无需重新编译。
Verilog 有一个系统调用 $value$plusargs (string, variable)
,可以从模拟器参数中提取任何变量。您可以使用它来提取测试名称,并使用 if
或 case
语句在不同来源之间 select 就像上面的答案一样。
您可以像这样启动模拟器<simulator> +TESTNAME=tc1
在您的测试台代码中,您将提取 TESTNAME 参数
if ($value$plusargs("TESTNAME=%s", testname)) begin
$display("Running test %0s.", testname);
if (testname == "tc1")
`include "tc1.v"
else if (testname == "tc2)
`include "tc2.v"
end
我已经在 "tc1.v" 和 "tc2.v" 中编写了我的测试用例。测试用例以任务的形式出现。例如:
//tc1.v
task tc1(input reg [31:0] j,input reg Reset,output reg dataValidIn);
//logic
endtask
//tc2.v
task tc2(input reg [31:0] counter,input reg Reset,output reg dataValidIn);
//logic
endtask
module top_test;
//inputs and outputs
//logic
`ifdef testcase1
`include "tc1.v";
`else
`include "tc2.v"
`endif
endmodule
问题是我想 运行 每个 posedge 时钟的测试用例。如果我在 always 块中包含 'ifdef 部分,modelsim 会抛出错误。无论如何我可以做到这一点吗?
从您上面的代码来看,`include 所包含的只是任务声明,而不是实际的任务调用。在代码的其他地方,您必须在 initial
或 always
块中调用类似 tc1(x, y, z);
的内容。此外,为了使其更具可扩展性,我建议不要有条件地包含任务声明并将其留给调用来确定要执行哪个任务 运行。因此,您可以简单地在任务调用处添加所需的代码而不是任务包含:
// Have a macro for your test case, you can also declare this in the commandline
`define TESTCASE 1
module top_test;
...
`include "tc1.v"
`include "tc2.v"
...
always @(posedge clk) begin
// Switch on the test case to determine which to use
// NOTE THAT IF THE TASK TAKES LONGER THAN 1 CLOCK CYCLE TO COMPLETE, THIS WILL NOT WORK FOR A TASK PER CLOCK
case (`TESTCASE)
1: tc1(...);
2: tc2(...);
default: begin
$display("ERROR: Bad Testcase supplied %d", `TESTCASE);
$finish;
end
endcase
end
...
endmodule
我使用的另一种解决方案是使用运行时间开关将测试用例指定给模拟器。这使您不必为每个测试重新编译 test/design,并且您可以批处理 运行 所有测试而无需重新编译。
Verilog 有一个系统调用 $value$plusargs (string, variable)
,可以从模拟器参数中提取任何变量。您可以使用它来提取测试名称,并使用 if
或 case
语句在不同来源之间 select 就像上面的答案一样。
您可以像这样启动模拟器<simulator> +TESTNAME=tc1
在您的测试台代码中,您将提取 TESTNAME 参数
if ($value$plusargs("TESTNAME=%s", testname)) begin
$display("Running test %0s.", testname);
if (testname == "tc1")
`include "tc1.v"
else if (testname == "tc2)
`include "tc2.v"
end