8 位无符号 Booth 乘数中的值 -128

问题描述 投票:0回答:0

我刚开始写 verilog,我尝试实现一个包含 8 位无符号 Booth 乘法器的 MAC,但是当我输入 -128 时遇到了一些错误。我该如何解决这个问题?

下面是我的代码

module MAC(
    input [7:0] ifmap,   // Input feature map
    input [7:0] filter,  // Filter
    input [23:0] psum,   // Partial sum
    output reg [23:0] updated_psum  // Updated partial sum
);

    reg  [15:0] p, ans;
    reg  [7:0] neg_ifmap;
    reg [23:0] prod;
    integer i, lookup_tbl, operate;
    
    initial begin
        p = 16'b0;
        ans = 16'b0;
        // Two's complement of a negative number
        assign neg_ifmap = (~ifmap) + 1;
    end

    always @(*) begin
        p = 16'b0;
        
        for (i = 1; i <= 7; i = i + 2) begin
            if (i == 1)
                lookup_tbl = 0;
            else
                lookup_tbl = filter[i-2];

            lookup_tbl = lookup_tbl + 4*filter[i] + 2*filter[i-1];

            if (lookup_tbl == 0 || lookup_tbl == 7)
                operate = 0;
            else if (lookup_tbl == 3 || lookup_tbl == 4)
                operate = 2;
            else
                operate = 1;

            if (filter[i] == 1) 
               operate = -1*operate;
                
            case (operate)
            1: begin
                ans = {{8{ifmap[7]}}, ifmap};
                ans = ans << (i-1);
                p = p + ans;
            end
            2: begin
                ans = {{8{ifmap[7]}}, ifmap} << 1;
                ans = ans << (i-1);
                p = p + ans;
            end
            -1: begin
                ans = {{8{neg_ifmap[7]}}, neg_ifmap};
                ans = ans << (i-1);
                p = p + ans;
            end
            -2: begin
                ans = {{8{neg_ifmap[7]}}, neg_ifmap} << 1; // negative a
                ans = ans << (i - 1);
                p = p + ans;
            end
            endcase

        end
        prod = {{8{p[15]}}, p};
        updated_psum <= prod + psum;
    end
endmodule

下面是我的测试平台

`include "MAC.v"

module MAC_tb;
    reg signed [7:0]   a;
    reg signed [7:0]   b;
    reg signed [23:0]  c;
    wire [23:0] result;
    
    
    MAC MAC0(
        .ifmap(a),
        .filter(b),
        .psum(c),
        .updated_psum(result)
    );
  
    reg signed [23:0] answer;
    reg signed [23:0]  test_c[4:0];
    
    integer i, j, k;
    integer err;
    
    initial begin
        `ifdef FSDB
            $fsdbDumpfile("MAC.fsdb");
            $fsdbDumpvars("+struct", "+mda", MAC0);
        `endif

        test_c[0] = {24{1'b1}};
        test_c[1] = 24'b0;
        test_c[2] = 24'b0101_0101_0101_0101_0101_0101;
        test_c[3] = 24'b1010_1010_1010_1010_1010_1010;
        test_c[4] = 24'b0011_0011_0011_0011_0011_0011;
        err = 0;
        for (i = 8'b0; i <= 8'b1111_1111; i = i+1) begin
            for (j = 8'b0; j <= 8'b1111_1111; j = j+1) begin
                for (k = 8'd0; k <= 8'd4; k = k+1) begin
                    a = i;
                    b = j;
                    c = test_c[k]; 
                    answer = a * b + c;
                    #100
                    if(answer != result) begin
                        $display("Error      :%d*%d+%d=%d", a, b, c, answer);
                        $display("Your result:%d*%d+%d=%d", a, b, c, $signed(result));
                        err = err + 1;
                    end else begin
                        err = err;
                    end
                end
            end
        end
        $display("Error times:%d", err);
    end

endmodule

个人认为可能是-128导致二进制补码运算出错。 我也有尝试直接计算的问题。

verilog unsigned
© www.soinside.com 2019 - 2024. All rights reserved.