Verilog Signed Multiplication “loses” the Signed Bit

verilog

I am writing a code which uses a multiplier module which returns weird answers when one of the inputs is a negative number. I am guessing this has to do with how Verilog treats signed numbers and the module is not storing the result properly in the 'reg signed out' decleration. All my input/output/wire/reg declarations are signed, so I am not sure what I am missing and what else I need to do to tell Verilog to take care of this. Sorry for the beginner question!

For example,

When X[0] is 1610 and Theta1[1] is -123, the result I am getting from the multiplier module is:
6914897148530

Here are the relevant parts of my code:

module mult(in1, in2, out, mult_start); // multiplication module

input signed    [32-1:0]    in1, in2;
input               mult_start;

output      signed [64-1:0] out;
reg         signed [64-1:0] out;

always @(in1 or in2 or mult_start)
begin
    if (mult_start)
    begin
        out <= (in1 * in2) & {64{1'b1}};
    end
    else
        out <= out;
end
endmodule



module child_one (clk, rst_b, sig_start, Input_X, Input_Theta1)

// Internal Variables Memory
reg signed [`REG_LENGTH-1:0] Theta1 [0:217-1];
reg signed [`REG_LENGTH-1:0] X [0:216-1];
wire signed [`OUT_LENGTH-1:0] prod_1 [0:217-1];
reg signed [`OUT_LENGTH-1:0] prod_sum;
wire signed [`OUT_LENGTH-1:0] sig_result;

mult mult_001 (X[0], Theta1[1], prod_1[1], mult_start); 
mult mult_002 (X[1], Theta1[2], prod_1[2], mult_start); 
mult mult_003 (X[2], Theta1[3], prod_1[3], mult_start); 
mult mult_004 (X[3], Theta1[4], prod_1[4], mult_start); 

always @(posedge clk or negedge rst_b)
begin
    if (sig_start == 1) 
    begin
        if (state == 4'b0000)
        begin
            state <= 4'b0001; // initialize state variable to zero
            k <= 0;
            result_done <= 0;
            index <= 0;
        end
        else if (state == 4'b0001) // Start Multiplication Operation
        begin
            k               <= result_done ?      0     : k + 1;
            result_done     <= result_done ?      1     : (k == 10);
            state       <= result_done ?      4'b0010   : 4'b0001;
            mult_start  <= result_done ?      1'b1  : 1'b0; 
        //mult_start <= 1'b1;
        //state <= 4'b0010;
        end
        else if (state == 4'b0010) // Stop Multiplication Operation
        begin
            k <= 0;
            result_done <= 0;
            mult_start <= 0;
            state <= 4'b0011;
        end
    end
end

endmodule

Thanks,

Faisal.

Best Answer

Thanks for all the help and suggestions. Writing a separate testbench for the mult module helped arrive at a solution.

My issue was in the mult module. Since my inputs are 32 bits long, the mult output would be 32*2+1 = 65 bits long. My output port 'out' was only assigned to be 64 bits long which resulted in a sign issue when the answer was a negative number. Assigning it to be 65 bits long took care of my problem.

Related Topic