verilogsystem-verilogtest-benchiverilog

Matrix Multiplication Testbench Yields Inconsistent Results


I'm using iverilog with -g2012 flag to compile the following matrix multiplication code and testbench:

`timescale 1ns / 1ps

module testbench();

// Testbench parameters
parameter m1 = 2;
parameter n1 = 2;
parameter m2 = 2;
parameter n2 = 2;

// Testbench variables
logic clk;
real matrix_a[m1*n1-1:0];
real matrix_b[m2*n2-1:0];
real result_matrix[m1*n2-1:0];

// Instantiate the module under test
matrix_dot_product #(.m1(m1), .n1(n1), .m2(m2), .n2(n2)) uut (
    .clk(clk),
    .matrix_a(matrix_a),
    .matrix_b(matrix_b),
    .result_matrix(result_matrix)
);


initial clk = 0;
always #5 clk = ~clk;

initial begin
    $dumpfile("testbench.vcd");
    $dumpvars(0, testbench);

    #10;

    matrix_a[0] = 1.0;
    matrix_a[1] = 2.0;
    matrix_a[2] = 3.0;
    matrix_a[3] = 4.0;

    matrix_b[0] = 1.0;
    matrix_b[1] = 2.0;
    matrix_b[2] = 3.0;
    matrix_b[3] = 4.0;

    #10;

    // $display("Result matrix:");
    for (int i = 0; i < m1*n2; i++) begin
        $display("result_matrix[%0d] = %f", i, result_matrix[i]);
    end

    // Finish the simulation
    $finish;
end
endmodule


module matrix_dot_product #(
    parameter m1 = 2,
    parameter n1 = 2,
    parameter m2 = 2,
    parameter n2 = 2
)(
    input logic clk,
    input real matrix_a[m1*n1-1:0],
    input real matrix_b[m2*n2-1:0],
    output real result_matrix[m1*n2-1:0]
);

    integer i, j, k;
    real sum;
    real product;

    always @(posedge clk) begin
        for (i = 0; i < m1; i++) begin
            for (j = 0; j < n2; j++) begin
                sum = 0;
                for (k = 0; k < n1; k++) begin
                    product = matrix_a[i*n1+k] * matrix_b[k*n2+j];
                    sum = sum + product;
                end
                result_matrix[i*n2+j] = sum;
            end
        end
        for (int i = 0; i < m1*n2; i++) begin
            $display("result_matrix[%0d] = %f", i, result_matrix[i]);
        end
    end
endmodule

I get the following output when running this matrix multiply test bench:

MODULE OUTPUT
result_matrix[0] = 0.000000
result_matrix[1] = 0.000000
result_matrix[2] = 0.000000
result_matrix[3] = 0.000000

MODULE OUTPUT
result_matrix[0] = 7.000000
result_matrix[1] = 10.000000
result_matrix[2] = 15.000000
result_matrix[3] = 22.000000

TEST BENCH OUTPUT
result_matrix[0] = 0.000000
result_matrix[1] = 0.000000
result_matrix[2] = 0.000000
result_matrix[3] = 0.000000

Based on my output, the code multiplies correctly when running inside the module; however, it doesn't seem to effect the output of the matrix in the testbench. I'd appreciate any help with this issue.


Solution

  • Your code has compile errors when I try to run with the version of iverilog that I have installed (10.3).

    However, the code produces the expected output when I run with the Cadence and Synopsys simulators:

    result_matrix[0] = 0.000000
    result_matrix[1] = 0.000000
    result_matrix[2] = 0.000000
    result_matrix[3] = 0.000000
    result_matrix[0] = 7.000000
    result_matrix[1] = 10.000000
    result_matrix[2] = 15.000000
    result_matrix[3] = 22.000000
    result_matrix[0] = 7.000000
    result_matrix[1] = 10.000000
    result_matrix[2] = 15.000000
    result_matrix[3] = 22.000000
    

    It is a bug in the version of iverilog you are using. Try your code on EDA Playground.


    It would be helpful to show the $time and hierarchy %m in your $display statements.