2014-07-05 50 views
4

初學者在這裏。我試圖在Verilog中編寫一個簡單的16位微處理器,並在Spartan 6上實現它。ALU實現所有已簽名的操作(根本沒有未簽名的操作)。所有的輸入都是連線並被簽名。結果存儲在一個有符號的寄存器中。Verilog中的簽名乘法溢出檢測

我的問題是找到一個明智的方法來檢測溢出。目前,檢測到溢出的速度並不重要,因爲它所做的只是觸發故障並暫停系統。

我相信我已經想通了如何檢測加法和減法的溢出,但我仍然想要保證。

這裏此外,其中O,溢出標誌寄存器:

if((a_in >= 0) && (b_in >= 0) && (res_out < 0)) o <= 1'b1; 
else if((a_in < 0) && (b_in < 0) && (res_out >= 0)) o <= 1'b1; 
else o <= 1'b0; 

這裏的減法:

if((a_in >= 0) && (b_in < 0) && (res_out < 0)) o <= 1'b1; 
else if((a_in < 0) && (b_in > 0) && (res_out >= 0)) o <= 1'b1; 
else o <= 1'b0; 

控制矩陣需要的保持時間A_IN和B_IN的護理,以使溢出檢測可以完成,因爲只有在計算結果後纔會完成(在下一個時鐘週期中)。

我在這裏找了一些東西,我發現的所有東西都是在其他語言(如C或C++)中檢測到溢出。我正在尋找一個在有符號乘法中檢測溢出的示例實現。

輸入a_in和b_in都是有符號線,並且是16位寬。結果寄存器res_out是有符號的,也是16位寬。理想情況下,我會有一個33位寬的結果寄存器,其中溢出不會發生,但這不是一個選項。

幫助表示讚賞。任何更好的方法來檢測加法和減法溢出也是受歡迎的。

回答

7

看看檢測溢出和下溢另外,分析一個簡單的4位示例,將符號擴展爲5位。

此外,所有+已經

3 : [0]0011 
+ 3 : [0]0011 
= 6 : [0]0110 

負數

-3 : [1]1101 
+ -3 : [1]1101 
= -6 : [1]1010 

現在造成溢出:結果應該是+8,但不能代表在4位。

+7 : [0]0111 
    +1 : [0]0001 
    +8 : [0]1000 

現在導致下溢:結果應該是-9,但不能用4位表示。

-8 : [1]1000 
+ -1 : [1]1111 
    -9 : [1]0111 

因此溢和下溢是容易的,如果我們簽了1位

localparam WIDTH = 4; 
localparam MSB = WIDTH-1; 
logic [WIDTH-1:0] a; 
logic [WIDTH-1:0] b; 
logic [WIDTH-1:0] result; 
logic extra; 
logic overflow; 
logic underflow; 


always @* begin 
    {extra, result} = {a[MSB], a} + {b[MSB], b} ; 
    overflow = ({extra, result[MSB]} == 2’b01); 
    underflow = ({extra, result[MSB]} == 2’b10); 
end 

關於乘法擴大投入,我不明白你爲什麼不能有一個32位的寄存器來檢測。即使將最終輸出減少到16個也是如此。

執行位縮減時,您需要檢查該值是否低於最小負數,您可以使用寬度減小來支持該最小負數。

注:除了結果長得比最大輸入大1位。截斷回原始寬度時發生上溢/下溢。

隨着乘法的結果是既加在一起的寬度,16位16位*結果以32位的答案。很確定你不需要33位。如果不保留全寬,那麼很難判斷截斷時結果是否會溢出。設計這些具有廣泛組合結果的東西是很常見的,並且只通過觸發器爲ALU的最終輸出輸出如此多的位。

我認爲保持32比特的輸出和相對於一個符號的16比特數的最大值/最小值,將合成比僅使用16位乘法器和額外的邏輯來檢測溢出條件小。

+0

這是一個令人難以置信的優雅的解決方案。謝謝。我知道我可以使用一個33位的結果寄存器來進行乘法運算,但是如果不這樣做,效率會更高。但是我可能會使用更大的結果寄存器,它不會改變當前的實現。 –

+0

@ShreyasVinod我已經添加了另一段來嘗試和擴大這一點。沒有使用全寬結果檢測乘法器溢出沒有很好的見解。 – Morgan

+0

我對此並不確定,但我認爲您需要額外的一點來保持標誌。看起來很適合我。 16位×16位將是32d'4294967296。需要多一點的標誌。 –

0

例如,如果您添加7和-3,則將失敗。

7 : [0]0111 
- 3 : [1]1101 
= 4 : [1]0100 

結果會顯示這是下溢但是這不是下溢,而是+4。

+0

+7(00111)+( - 3)(11101)是+4(00100)。你似乎已經嘗試過減法而已。如果你想減去,請理解你會做(+7) - (+3)而不是(+7) - (-3)。即00111 - 00011 = 00100。 –