2015-12-05 254 views
0

我正在設計一個Verilog處理器。我正在研究ALU,特別是ALU的乘數。在用小的正數進行乘法運算時,我可以得到正確的結果,但如果我嘗試乘以有符號數,我會遇到問題。當一個正數乘以一個負數時,結果將不會一直擴展到64位,如果兩個負數相乘,那麼這個數字是完全不正確的(符號和數值)。任何人都可以看到問題在哪裏?我認爲我沒有進行算術轉換,但我調整了這一點,但仍然得到了錯誤的結果。有符號乘數Verilog

module multiplier(
     input[31:0] operand1, 
     input[31:0] operand2, 
     output reg [63:0] product 
    ); 

reg [64:0] prod; 
reg [31:0] mcand; 
reg [31:0] sum; 
integer i = 0; 


always @* begin 


    prod = {32'b0,operand1}; 
    mcand = operand2; 

    for(i=0;i<32;i=i+1) begin 

     //test 0 bit of product 
     case(prod[0]) 
      1'b0:begin  //if prod[0] == 0, arithmetic shift right 
        prod = prod>>>1; 
      end 

      1'b1:begin //if prod[0] == 1, add multiplicand to upper 32 
          //bits and arithmetic shift right 
        prod = {(prod[63:32]+mcand[31:0]),prod[31:0]}; 
        prod = prod>>>1; 
       end 
     endcase 
    end 

product = prod[63:0]; 

end 


endmodule 
+0

任何不在RTL中使用'*'的理由? – Morgan

回答

0

對於>>>執行帶符號移位的變量必須聲明爲signed。

reg signed [64:0] prod; 

簡短示例on eda playground

另請注意,prod = {32'b0,operand1};不是符號擴展名。你應該使用:

prod = { {32{operand[31]}}, operand1 }; 
+0

謝謝,經過簽名的聲明會使代碼返回正確的值,但該符號仍然不正確。該算法要求我填充變量'prod'的高32位,因此對於這個實現 'prod = {32'b0,operand1}'是正確的 – tcas271