2
\$\begingroup\$

First I'm very new to verilog.. and test benches are driving me crazy. I have a pipelined multiplier and I'm trying to write a test bench to auto-check it. My problem is that I apply stimulus to the input, but the correct answer doesn't come out until 5 cycles later. So in the test bench I'm calculating the answer when the stimulus hits, which will never match the output. I figure there must be an easy solution to this but have yet to figure it out.

Code of my test bench is below. The module is a 32bit multiplier with pipelines.

Result is calculated after i_Aj & i_Ak are set, however the module does not produce an answer in o_Ai for five cycles. That's the gist of the problem.

module scalar_multiply_tb;

 reg [31:0] i_Aj, i_Ak;
 reg clk;
 wire [31:0] o_Ai;
 reg [32:0] count1, count2;

 initial
 begin
  clk <= 1'b0;
  i_Aj <= 32'b0;
  i_Ak <= 32'b0;

  repeat (50) @(posedge clk);
  //check all possible input
   for(count1 = 1; count1 <= 32'hffffffff; count1 = count1 + 1)  //Aj max 2^32
   begin
     for(count2 = 1; count2 <= 32'hffffffff; count2 = count2 + 1) //Ak max 2^32
      begin
       i_Aj = count1;
       i_Ak = count2;
       @(posedge clk);
      end
    end
  end

  always #10 clk <= ~clk;

  scalar_multiply u_scalar_multiply (i_Ak, i_Aj, clk, o_Ai);
   reg [63:0] Aj_d, Ak_d;
   reg [63:0] result;

   always@(posedge clk) 
    begin
     Aj_d <= i_Aj;
     Ak_d <= i_Ak;
    end

    always@(Aj_d or Ak_d) 
    begin
      result <= Aj_d*Ak_d;
    end  

   always@(result) 
    begin
     $display("CLK=%t,Aj=%d,Ak=%d,result=%d,actual=%d", $time,Aj_d,Ak_d,result,o_Ai);
     if(result != o_Ai)
      $display("ERROR: %t,sj=%d,sk=%d,result=%d,actual=%d", $time,Aj_d,Ak_d,result,o_Ai);
     end
    initial begin
     $dumpfile("dump.vcd");
     $dumpvars;
     #32000 $finish;
    end
endmodule
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Create a pipeline for the results in your testbench:

   parameter PIPE = 5;
   reg [63:0] result [1:PIPE];

   always@(posedge clk) 
    begin
     Aj_d <= i_Aj;
     Ak_d <= i_Ak;
    end

    always@(Aj_d or Ak_d) 
    begin
      result[1] <= Aj_d*Ak_d;
      for (int i=2; i<=PIPE; i++) result[i] <= result[i-1];
    end  

   always@(result[PIPE]) 
    begin
     $display("CLK=%t,Aj=%d,Ak=%d,result=%d,actual=%d", $time,Aj_d,Ak_d,result[PIPE],o_Ai);
     if(result[PIPE] !== o_Ai)
      $display("ERROR: %t,sj=%d,sk=%d,result=%d,actual=%d", $time,Aj_d,Ak_d,result[PIPE],o_Ai);
     end
\$\endgroup\$
1
  • \$\begingroup\$ Or you can just pipeline all 3 of them. It's not like it will consume any more logic resources, it's just the testbench. \$\endgroup\$ Oct 27, 2015 at 21:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.