verilog設計32位ALU
阿新 • • 發佈:2021-01-29
一 設計思路
(一) 輸入、輸出
- 三個輸入:兩個32位輸入數X、Y及計算型別OP。
- 兩個輸出:計算結果result及有無溢位overflow。
- 計算型別程式碼
(1)OP = 0有符號數相加,
(2)OP = 1有符號數相減,
(3)OP = 2無符號數相加,
(4)OP = 3無符號數相減,
(5)OP = 4邏輯左移(X左移Y位),
(6)OP = 5邏輯右移(X右移Y位)。
其中,邏輯左移、邏輯右移均在空位補0。 - 對於加減法,overflow = 1表示有溢位。
(二)運算說明
輸出的計算結果result用33位二進位制有符號數表示,其中最高位為符號位。
(1)表示有符號數運算結果時:result = SsSs S30S29…S1S0(雙符號位+31位數值位)
(2)表示無符號數運算結果時:result = 0S31 S30S29…S1S0(符號位恆置0+32位數值位)
有符號數、無符號數的運算均視作有符號數補碼運算。
減法運算:減數補碼取反加1後,與被減數做加法運算。
- 兩個32位有符號數加減:
[X]補 = Xs X30X29…X1X0
[Y]補 = Ys Y30Y29…Y1Y0
其和(差)為:[S]補 = Ss S30S29
當 Xs = Ys = 0,Ss = 1時,產生正溢。
當 Xs = Ys = 1,Ss = 0時,產生負溢。
result次高位與S符號位保持一致,result = SsSs S30S29…S1S0。 - 兩個32位無符號數加減
[X]補 = 0X31X30X29…X1X0
[Y]補 = 0Y31Y30Y29…Y1Y0
[-Y]補 = 1Y31’Y30’Y29’…Y1’Y0’
其和(差)為:[S]補 = Ss S31S30S29…S1S0
加法:當 Ss = 1時,產生正溢。
減法:當 Ss = 0時,產生正溢。
result最高位符號位恆置0,result = 0S31S30S29…S1S0。 - X邏輯左移/右移Y位
均在空位補0。
result = 0S31S30S29…S1S0
若Y<0:overflow = 1。
二 verilog程式碼
(一)程式程式碼變數說明
input [31:0] X,Y, // 2個運算元
input [2:0] OP, // 操作型別
output reg [32:0] result, // 33位補碼錶示的有符號數結果
output reg overflow); // 溢位
reg [31:0] _Y,S; // [-Y]補,有符號數運算的中間結果
reg [32:0] SS; // 無符號數運算的中間結果
(二)程式程式碼
軟體:Quartus II 9.0
module ALU(
input [31:0] X,Y, // OP = 0/1:signed add/subtract;
input [2:0] OP, // OP = 2/3:unsigned add/subtract;
output reg [32:0] result, // OP = 4/5:move left/right
output reg overflow);
reg [31:0] _Y,S;
reg [32:0] SS;
always @(*)
begin
case(OP)
0: // signed add
begin
S = X + Y;
if(!X[31]&&!Y[31]&&S[31] || X[31]&&Y[31]&&!S[31])
overflow = 1;
else
overflow = 0;
result = {S[31],S};
end
1: // signed subtract
begin
_Y = ~Y + 1'b1;
S = X + _Y;
if(!X[31]&&!_Y[31]&&S[31] || X[31]&&_Y[31]&&!S[31])
overflow = 1;
else
overflow = 0;
result = {S[31],S};
end
2: // unsigned add
begin
SS = X + Y;
if(SS[32])
overflow = 1;
else
overflow = 0;
result = {1'b0,SS[31:0]};
end
3: // unsigned substract
begin
_Y = ~Y + 1'b1;
SS = X + _Y;
if(SS[32])
overflow = 0;
else
overflow = 1;
result = {1'b0,SS[31:0]};
end
4: // move left
begin
if(Y[31] == 1)
overflow = 1;
else
begin
overflow = 0;
S = X<<Y;
result = {1'b0,S};
end
end
5: // move right
begin
if(Y[31] == 1)
overflow = 1;
else
begin
overflow = 0;
S = X>>Y;
result = {1'b0,S};
end
end
endcase
end
endmodule
(三)時序模擬圖
- OP = 0:有符號數相加,result = X + Y
32位X | 32位Y | 溢位 | 33位result |
---|---|---|---|
22 | 33 | 無 | 55 |
-22 | -33 | 無 | -55 |
二進位制1,00…00 | 二進位制0,00…01 | 無 | 二進位制11,00…01 |
二進位制1,00…00 | 二進位制1,11…11 | 有 | 二進位制00,11…11 |
說明:對於有符號數的運算結果,result相當於雙符號位補碼,最高位與次高位均為符號位,實際表示有符號補碼的僅僅是後32位。
用33位僅僅是方便同時表示有符號數和無符號數的運算結果:
有符號數result:雙符號位+31位數值位
無符號數result:單符號位(恆置0)+32位數值位
- OP = 1:有符號數相減,result = X - Y
32位X | 32位Y | 溢位 | 33位result |
---|---|---|---|
22 | 33 | 無 | -11 |
22 | -33 | 無 | 55 |
-22 | 33 | 無 | -55 |
-22 | -33 | 無 | 11 |
二進位制1,00…00 | 二進位制0,00…01 | 有 | 二進位制00,11…11 |
二進位制1,00…00 | 二進位制1,11…11 | 無 | 二進位制11,00…01 |
第五組:1,00…00 - 0,00…01 = 1,00…00 + 1,11…11 = (1)0,11…11,產生溢位
第六組:1,00…00 - 1,11…11 = 1,00…00 + 0,00…01 = (0)1,00…01,無溢位
- OP = 2:無符號數相加,result = X + Y
32位X | 32位Y | 溢位 | 33位result |
---|---|---|---|
22 | 33 | 無 | 55 |
二進位制100…00 | 二進位制000…01 | 無 | 二進位制0,100…01 |
二進位制100…00 | 二進位制100…00 | 有 | 二進位制0,000…00 |
第二組:相當於 231 + 20 = 2147483649
第三組:10…00 + 10…00 = (1) 00…00,產生溢位
- OP = 3:無符號數相減,result = X - Y
32位X | 32位Y | 溢位 | 33位result |
---|---|---|---|
22 | 11 | 無 | 11 |
22 | 33 | 有 | |
二進位制100…00 | 二進位制000…01 | 無 | 二進位制0,011…11 |
二進位制100…00 | 二進位制100…00 | 無 | 0 |
第三組:相當於 231 - 20 = 2147483647
- OP = 4:邏輯左移
OP = 5:邏輯右移
3 = 00…0011
邏輯左移1位:000…0110 = 6
邏輯左移2位:000…1100 = 12
邏輯左移40位:000…0000 = 0
邏輯右移1位:000…0001 = 1
邏輯右移2位:000…0000 = 0
邏輯左移40位:000…0000 = 0