在 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 行。除了一个明显的问题,为什么它不起作用,我也不明白以下内容:

  1. x - 电线或寄存器应该使用什么?
  2. 我可以不用'generate'\'for'循环吗?可能有一种方法可以简化代码。
  3. 是否可以在 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