首页 > 解决方案 > 触发器测试台显示不正确的值

问题描述

我需要为 design.sv 接口中的 4 个触发器模块实现测试平台。除了 bar1 之外,模块 foo1、foo2 和 bar2 工作正常(运行时可以看到,预期值与输出值相同)。我不知道为什么会这样。 https://www.edaplayground.com/x/XaWu

//testbench for the bar1 flip flop.
module general_tb3 (
);
  logic a, b, c, clk;
  logic x, y, w;
  bar1 uut(a, b, c, clk, x, y, w);
  
        
  initial 
    begin
      $dumpfile("dump.vcd"); 
      $dumpvars(1);
    end
    
  function logic output_x3;
    input a, b;
      begin
        output_x3 <= a | b;
      end
  endfunction
  
  function logic output_y3;
    input a, b, c;
      begin
        output_y3 <= ~((a | b) & c);
      end
  endfunction
  
  function logic output_w3;
    input a, b, c;
      begin
        output_w3 <= a | ~((a | b) & c);
      end
  endfunction
  
// Seção de testes com atribuição de valores para f e f_expected
    initial 
    begin
      
      #10000 $display("\nBar1 tests");
      #10000 $display ("| a | b | c | clk | x | y | w | x_expected | y_expected| w_expected|");
      
            a = 0; b = 0; c = 0; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 0), output_y3(0, 0, 0), output_w3(0, 0, 0) );
      
      a = 0; b = 0; c = 0; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 0), output_y3(0, 0, 0), output_w3(0, 0, 0) );
      
      a = 0; b = 0; c = 1; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 0), output_y3(0, 0, 1), output_w3(0, 0, 1) );
      
      a = 0; b = 0; c = 1; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 0), output_y3(0, 0, 1), output_w3(0, 0, 1) );
      
      a = 0; b = 1; c = 0; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 0), output_y3(0, 1, 0), output_w3(0, 1, 0) );
      
      a = 0; b = 1; c = 0; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 1), output_y3(0, 1, 0), output_w3(0, 1, 0) );
      
      a = 0; b = 1; c = 1; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 1), output_y3(0, 1, 1), output_w3(0, 1, 1) );
      
      a = 0; b = 1; c = 1; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(0, 1), output_y3(0, 1, 1), output_w3(0, 1, 1) );
      
      a = 1; b = 0; c = 0; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 0), output_y3(1, 0, 0), output_w3(1, 0, 0) );
      
      a = 1; b = 0; c = 0; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 0), output_y3(1, 0, 0), output_w3(1, 0, 0) );
      
      a = 1; b = 0; c = 1; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 0), output_y3(1, 0, 1), output_w3(1, 0, 1) );
      
      a = 1; b = 0; c = 1; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 0), output_y3(1, 0, 1), output_w3(1, 0, 1) );
      
      a = 1; b = 1; c = 0; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 1), output_y3(1, 1, 0), output_w3(1, 1, 0) );
      
      a = 1; b = 1; c = 0; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 1), output_y3(1, 1, 0), output_w3(1, 1, 0) );
      
      a = 1; b = 1; c = 1; clk = 0; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 1), output_y3(1, 1, 1), output_w3(1, 1, 1) );
      
      a = 1; b = 1; c = 1; clk = 1; 
      #10000 $display("| %0h | %0h | %0h |  %0h  | %0h | %0h | %0h |    %0h       |  %0h        | %0h         |", a, b, c, clk, x, y, w, output_x3(1, 1), output_y3(1, 1, 1), output_w3(1, 1, 1) );

end
endmodule

这款人字拖的设计:

module bar1 (a, b, c, clk, x, y, w);
  input a, b, c, clk;
  output reg x, y, w;
  always @(negedge clk)
    begin
      x <= a | b;
      y <= ~(x & c);
      w <= a | y;
    end
endmodule

输出:


# KERNEL: Bar1 tests
# KERNEL: | a | b | c | clk | x | y | w | x_expected | y_expected| w_expected|
# KERNEL: | 0 | 0 | 0 |  0  | 0 | 1 | x |    x       |  x        | x         |
# KERNEL: | 0 | 0 | 0 |  1  | 0 | 1 | x |    0       |  1        | 1         |
# KERNEL: | 0 | 0 | 1 |  0  | 0 | 1 | 1 |    0       |  1        | 1         |
# KERNEL: | 0 | 0 | 1 |  1  | 0 | 1 | 1 |    0       |  1        | 1         |
# KERNEL: | 0 | 1 | 0 |  0  | 1 | 1 | 1 |    0       |  1        | 1         |
# KERNEL: | 0 | 1 | 0 |  1  | 1 | 1 | 1 |    0       |  1        | 1         |
# KERNEL: | 0 | 1 | 1 |  0  | 1 | 0 | 1 |    1       |  1        | 1         |
# KERNEL: | 0 | 1 | 1 |  1  | 1 | 0 | 1 |    1       |  0        | 0         |
# KERNEL: | 1 | 0 | 0 |  0  | 1 | 1 | 1 |    1       |  0        | 0         |
# KERNEL: | 1 | 0 | 0 |  1  | 1 | 1 | 1 |    1       |  1        | 1         |
# KERNEL: | 1 | 0 | 1 |  0  | 1 | 0 | 1 |    1       |  1        | 1         |
# KERNEL: | 1 | 0 | 1 |  1  | 1 | 0 | 1 |    1       |  0        | 1         |
# KERNEL: | 1 | 1 | 0 |  0  | 1 | 1 | 1 |    1       |  0        | 1         |
# KERNEL: | 1 | 1 | 0 |  1  | 1 | 1 | 1 |    1       |  1        | 1         |
# KERNEL: | 1 | 1 | 1 |  0  | 1 | 0 | 1 |    1       |  1        | 1         |
# KERNEL: | 1 | 1 | 1 |  1  | 1 | 0 | 1 |    1       |  0        | 1         |

标签: system-verilogtest-benchflip-flop

解决方案


考虑这个测试台设计。

创建与其他输入信号分开的时钟。然后,在时钟边缘驱动一切。

使用for循环来驱动其他输入。

使用信号对您的设计进行建模x_expx这是使用与设计信号相同的时序生成的。

使用时钟的相反边沿显示所有值;这避免了竞争条件。

module general_tb3;
  bit a, b, c, clk;
  logic x, y, w;
  logic x_exp;

  bar1 uut(a, b, c, clk, x, y, w);

initial begin
    $dumpfile("dump.vcd");
    $dumpvars(1);
end

always #10_000 clk = ~clk;

initial begin
    for (int i=0; i<8; i++) begin
        @(negedge clk) {a, b, c} <= i;
    end
    @(negedge clk);
    #5 $finish;
end

always @(negedge clk) x_exp <= (a | b);

initial begin
    @(posedge clk); // Avoid unknowns at the start
    forever @(posedge clk) begin
        $display($time, " abc=%03b x=%b x_exp=%b", {a, b, c}, x, x_exp);
    end
end
endmodule

y您可以为和添加预期值w

这是输出:

           30000 abc=000 x=0 x_exp=0
           50000 abc=001 x=0 x_exp=0
           70000 abc=010 x=0 x_exp=0
           90000 abc=011 x=1 x_exp=1
          110000 abc=100 x=1 x_exp=1
          130000 abc=101 x=1 x_exp=1
          150000 abc=110 x=1 x_exp=1
          170000 abc=111 x=1 x_exp=1

要在仿真开始时消除未知值,您可以在设计中使用复位信号


推荐阅读