在 Verilog 测试台中循环测试模式
Loop over test patterns in Verilog testbench
第一天与 verilog 作斗争,这是一个简单的模块:
module example4_23 (x, f);
input [0:6] x;
output f;
assign f = x[0] & x[1] & x[2] & x[3] & x[4] & x[5] & x[6];
endmodule
那我想给它写一个testbench。首先,我为 x 使用了 7 位寄存器(无数组)——一切正常,但现在我想 运行 它有几个测试模式,所以我宣布一个数组并想遍历它和 运行每次都有新输入的模块。
module test;
reg [0:6] arr [0:1] = {7'b0011111,7'b1100000}; // all patterns
reg [0:1] arr_size; // number of patterns
wire [0:6] x; // current pattern
wire f; // output
initial begin
$write("| TIME | x0 | x1 | x2 | x3 | x4 | x5 | x6 | f |"); // header
$display;
arr_size = $size(arr); // 2
end
// go through all test patterns, assign it to x and run the module
genvar i;
generate
for (i=0; i<2; i=i+1) // if use 'i<arr_size' gives an error
begin
assign x = arr[i]; // change to '..= arr[1]' or '..= arr[0]' successfully makes one test
example4_23 dut (x,f);
end
endgenerate
// anytime there is a change - output on the screen
always @(x,f)
begin
$strobe("%6d %4d %4d %4d %4d %4d %4d %4d %5d", $time, x[0],x[1],x[2],x[3],x[4],x[5],x[6], f);
end
endmodule
目前编译后我只看到 header 行。除了一个明显的问题,为什么它不起作用,我也不明白以下内容:
- x - 电线或寄存器应该使用什么?
- 我可以不用'generate'\'for'循环吗?可能有一种方法可以简化代码。
- 是否可以在 FOR 循环中使用变量 arr_size 而不是数字?
提前致谢。
我很惊讶你没有收到有关为 f
分配多个值的错误。
请记住,verilog(或任何其他 HDL)创建物理电路,生成块创建给定电路的多个版本。在这种情况下,您正在创建 example4_23
模块的两个实例,并且都驱动相同的输出。 Generate
循环以空间方式运行,而 always
块中的 for 循环在添加延迟时是时间性的。
回答你的问题:1)使用reg
,并在always
块中延迟赋值; 2)是的! (见下面的例子); 3)是的!使用一个参数!
因此,您可以进行以下更改:
- 将
wire arr_size
替换为 localparam ARR_SIZE = 2
(或视情况而定)
- 将
reg [0:6] arr [0:1]
更改为 reg [0:6] arr [0:ARR_SIZE1-]
- 用
initial
块中的基本 for 循环替换 generate
循环
- 测试向量数组可以是参数,而不是电线或 reg
- 添加延迟。现在,您的测试台不随时间变化,仅在 space 内变化。使用
#
(见下文) 记录延迟
- 使用
always @(*)
代替always @(x,f)
以下是我要实施的内容:
module test;
localparam ARR_SIZE = 2; // number of patterns
localparam [0:6] arr [0:ARR_SIZE-1] = {7'b0011111,7'b1100000}; // all patterns
reg[0:6] x; // current pattern
wire f; // output
integer i;
example4_23 dut (x,f);
initial begin
$write("| TIME | x0 | x1 | x2 | x3 | x4 | x5 | x6 | f |"); // header
$display;
for (i=0; i< ARR_SIZE; i=i+1) begin
x = arr[i];
#5; // delay 5 timesteps
end
end
// anytime there is a change - output on the screen
always @(*)
begin
$strobe("%6d %4d %4d %4d %4d %4d %4d %4d %5d", $time, x[0],x[1],x[2],x[3],x[4],x[5],x[6], f);
end
endmodule
第一天与 verilog 作斗争,这是一个简单的模块:
module example4_23 (x, f);
input [0:6] x;
output f;
assign f = x[0] & x[1] & x[2] & x[3] & x[4] & x[5] & x[6];
endmodule
那我想给它写一个testbench。首先,我为 x 使用了 7 位寄存器(无数组)——一切正常,但现在我想 运行 它有几个测试模式,所以我宣布一个数组并想遍历它和 运行每次都有新输入的模块。
module test;
reg [0:6] arr [0:1] = {7'b0011111,7'b1100000}; // all patterns
reg [0:1] arr_size; // number of patterns
wire [0:6] x; // current pattern
wire f; // output
initial begin
$write("| TIME | x0 | x1 | x2 | x3 | x4 | x5 | x6 | f |"); // header
$display;
arr_size = $size(arr); // 2
end
// go through all test patterns, assign it to x and run the module
genvar i;
generate
for (i=0; i<2; i=i+1) // if use 'i<arr_size' gives an error
begin
assign x = arr[i]; // change to '..= arr[1]' or '..= arr[0]' successfully makes one test
example4_23 dut (x,f);
end
endgenerate
// anytime there is a change - output on the screen
always @(x,f)
begin
$strobe("%6d %4d %4d %4d %4d %4d %4d %4d %5d", $time, x[0],x[1],x[2],x[3],x[4],x[5],x[6], f);
end
endmodule
目前编译后我只看到 header 行。除了一个明显的问题,为什么它不起作用,我也不明白以下内容:
- x - 电线或寄存器应该使用什么?
- 我可以不用'generate'\'for'循环吗?可能有一种方法可以简化代码。
- 是否可以在 FOR 循环中使用变量 arr_size 而不是数字?
提前致谢。
我很惊讶你没有收到有关为 f
分配多个值的错误。
请记住,verilog(或任何其他 HDL)创建物理电路,生成块创建给定电路的多个版本。在这种情况下,您正在创建 example4_23
模块的两个实例,并且都驱动相同的输出。 Generate
循环以空间方式运行,而 always
块中的 for 循环在添加延迟时是时间性的。
回答你的问题:1)使用reg
,并在always
块中延迟赋值; 2)是的! (见下面的例子); 3)是的!使用一个参数!
因此,您可以进行以下更改:
- 将
wire arr_size
替换为localparam ARR_SIZE = 2
(或视情况而定) - 将
reg [0:6] arr [0:1]
更改为reg [0:6] arr [0:ARR_SIZE1-]
- 用
initial
块中的基本 for 循环替换generate
循环 - 测试向量数组可以是参数,而不是电线或 reg
- 添加延迟。现在,您的测试台不随时间变化,仅在 space 内变化。使用
#
(见下文) 记录延迟
- 使用
always @(*)
代替always @(x,f)
以下是我要实施的内容:
module test;
localparam ARR_SIZE = 2; // number of patterns
localparam [0:6] arr [0:ARR_SIZE-1] = {7'b0011111,7'b1100000}; // all patterns
reg[0:6] x; // current pattern
wire f; // output
integer i;
example4_23 dut (x,f);
initial begin
$write("| TIME | x0 | x1 | x2 | x3 | x4 | x5 | x6 | f |"); // header
$display;
for (i=0; i< ARR_SIZE; i=i+1) begin
x = arr[i];
#5; // delay 5 timesteps
end
end
// anytime there is a change - output on the screen
always @(*)
begin
$strobe("%6d %4d %4d %4d %4d %4d %4d %4d %5d", $time, x[0],x[1],x[2],x[3],x[4],x[5],x[6], f);
end
endmodule