📄 alu.v
字号:
//--------------------------------------------------------------------------------
// Design Name: ALU32
// File Name: alu.v
// Function: The following program implements a 32-Bit Integer Arithmetic-Logic Unit
// for the following operations:
// ADD, ADDI, ADDIU, ADDU, SUB, SUBU, MULT, MULTU, DIV, DIVU, NOP,
// AND, ANDI, OR, ORI, NOR, XOR, XORI, SLL, SLLV, SRA, SRAV, SRL, and SRLV
// by checking the operand code received and doing the respective operations.
// Date: October 06th, 2007
//---------------------------------------------------------------------------------
module ALU32 (
AInput, // Input port of 32 bits A
BInput, // Input port of 32 bits B
OpCode, // Operation code of 6 bits
Clock, // Sincronous Clock
Reset, // Reset
Output, // Operation Output of 32 bits
Overflow, // Overflow indicator of 1 bit
Zero // Zero indicator of 1 bit
);
// ---------------------------- Input ports ----------------------------
input OpCode;
input AInput;
input BInput;
input Clock;
input Reset;
// ---------------------------- Output ports ----------------------------
output Overflow;
output Zero;
output Output;
// ---------------------------- Type of Input ports ----------------------------
wire [5:0] OpCode;
wire [31:0] AInput;
wire [31:0] BInput;
wire Clock;
wire Reset;
// ---------------------------- Type of Output ports ----------------------------
reg Overflow;
reg Zero;
reg [31:0] Output;
// -------------------------- Temporaries --------------------------
reg [32:0] res;
reg [63:0] res1;
reg [31:0] res2;
reg [31:0] ext;
reg [31:0] reg1;
reg [31:0] reg2;
// ----------------------------------------------------
// Code Starts Here
// ----------------------------------------------------
// Include the definition of all the ALU Operations
`include "Operations.v" // File "Operations.v" contains all operation codes
always @ (posedge Clock)
begin: ALU // Begin ALU block
if(Reset == 1)
begin
// If the reset is on, it will clear each output
Output = 0;
Overflow = 0;
Zero = 0;
end
else
begin
case(OpCode)
// ################ Arithmetic Operations ################
S_ADD: begin // ADD
res = AInput + BInput; // Result is stored in a temporal of 33 bits
Output = res[31:0]; // Keep the low 32 bits
Overflow = ((AInput[31] == BInput[31]) && (res[31] != AInput[31])); //If signs are same and sign of result different, overflow
Zero = (Output == 0) ? 1 : 0; // If Output = 0, then Activate Zero flag, otherwise is 0
end // case: S_ADD
ADDI: begin // INMEDIATE ADD
res = AInput + BInput; // Result is stored in a temporal of 33 bits
Output = res[31:0]; // Keep the low 32 bits
Overflow = ((AInput[31] == BInput[31]) && (res[31] != AInput[31])); //If signs are same and sign of result different, overflow
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: ADDI
ADDIU: begin // INMEDIATE ADD WITHOUT SIGN
res = AInput + BInput;
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: ADDIU
S_ADDU: begin // UNSIGNED ADD
res = AInput + BInput;
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_ADDU
S_SUB: begin // SUBTRACTION
res = AInput + (BInput^32'hFFFFFFFF) + 1; // A - B is equivalent to A + (B'+1)
Output = res[31:0]; // Mantain low 32 bits
Overflow = ((AInput[31] != BInput[31]) && (res[31] != AInput[31])); //If signs are different and sign of result different, overflow
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_SUB
S_SUBU: begin // UNSIGNED SUBTRACTION
res = AInput - BInput;
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0;
end // case: S_SUBU
S_MULT: begin // MULTIPLICATION
if(AInput[31] == 0)
begin
if(BInput[31] == 0)
begin
res1 = AInput * BInput;
end
else
begin
res1 = ((AInput * ((BInput - 1) ^ 32'hFFFFFFFF)) ^ 32'hFFFFFFFF) + 1;
end
end // if (AInput[31] == 0)
else
begin
if(BInput[31] == 0)
begin
res1 = ((((AInput - 1) ^ 32'hFFFFFFFF) * BInput) ^ 32'hFFFFFFFF) + 1;
end
else
begin
res1 = ((AInput - 1) ^ 32'hFFFFFFFF) * ((BInput - 1) ^ 32'hFFFFFFFF);
end
end // else: !if(AInput[31] == 0)
Output = res1[31:0]; // Keep low 32 bits
Overflow = ((res1[63:32] != 0) || (res1[31] != (AInput[31] ^ BInput[31])));
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_MULT
S_MULTU: begin // UNSIGNED MULTIPLICATION
res1 = AInput * BInput;
Output = res1[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_MULTU
S_DIV: begin // DIVISION
if(AInput[31] == 0)
begin
if(BInput[31] == 0)
begin
if(BInput == 0)
begin
if(AInput == 0)
begin
Output = 32'hFFFFFFFF;
Overflow = 1;
end
else
begin
Output = 0;
Overflow = 0;
end
end // if (BInput == 0)
else
begin
res = AInput / BInput;
Output = res[31:0];
Overflow = 0;
end // else: !if(BInput == 0)
end // if (BInput[31] == 0)
else
begin
res = ((AInput / ((BInput - 1) ^ 32'hFFFFFFFF)) ^ 32'hFFFFFFFF) + 1;
Output = res[31:0];
Overflow = 0;
end // else: !if(BInput[31] == 0)
end // if (AInput[31] == 0)
else
begin
if(BInput[31] == 0)
begin
res = ((((AInput - 1) ^ 32'hFFFFFFFF) / BInput) ^ 32'hFFFFFFFF) + 1;
Output = res[31:0];
Overflow = 0;
end
else
begin
if((AInput == 32'h80000000) && (BInput == 32'hFFFFFFFF))
begin
Output = AInput;
Overflow = 1;
end
else
begin
Output = ((AInput - 1) ^ 32'hFFFFFFFF) / ((BInput - 1) ^ 32'hFFFFFFFF);
Overflow = 0;
end
end // else: !if(BInput[31] == 0)
end // else: !if(AInput[31] == 0)
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_DIV
S_DIVU: begin // UNSIGNED DIVISION
if(BInput == 0)
begin
if(AInput == 0)
begin
Output = 32'hFFFFFFFF;
Overflow = 1;
end
else
begin
Output = 0;
Overflow = 0;
end
end // if (BInput == 0)
else
begin
res = AInput / BInput;
Output = res[31:0];
Overflow = 0;
end // else: !if(BInput == 0)
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_DIVU
NOP: begin // NO Operation
Overflow = 0;
Zero = 0;
end // case: NOP
// ################ Logic Operations ################
S_AND: begin // LOGIC AND
res = AInput & BInput;
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_AND
ANDI: begin // LOGIC INMEDIATE AND
res = AInput & BInput;
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: ANDI
S_OR: begin // LOGIC OR
res = AInput | BInput;
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_OR
ORI: begin // LOGIC INMEDIATE OR
res = AInput | BInput;
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: ORI
S_NOR: begin // LOGIC NOR
res = ~(AInput | BInput);
Output = res[31:0];
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_NOR
S_XOR: begin // LOGIC XOR
res = AInput ^ BInput;
Output = res;
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_XOR
XORI: begin // LOGIC INMEDIATE XOR
res = AInput ^ BInput;
Output = res;
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: XORI
// ################ Shift Operations ################
S_SLL: begin // LEFT LOGICAL SHIFT
res2 = AInput << BInput;
Output = res2;
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_SLL
S_SLLV: begin // LEFT LOGICAL VARIABLE SHIFT
res2 = AInput << BInput;
Output = res2;
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: SLLV
S_SRA: begin // RIGHT ARITHMETIC SHIFT
if(AInput[31] == 0)
begin
res2 = AInput >> BInput;
Output = res2;
end
else
begin
reg1 = AInput >> BInput;
ext = 32'hFFFFFFFF;
reg2 = ext << (31 - BInput);
Output = reg1 | reg2;
end // else: !if(AInput[31] == 0)
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_SRA
S_SRAV: begin // RIGHT ARITHMETIC VARIABLE SHIFT
if(AInput[31] == 0)
begin
res2 = AInput >> BInput;
Output = res2;
end
else
begin
reg1 = AInput >> BInput;
ext = 32'hFFFFFFFF;
reg2 = ext << (31-BInput);
Output = reg1 | reg2;
end // else: !if(AInput[31] == 0)
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_SRAV
S_SRL: begin // RIGHT LOGICAL SHIFT
res2 = AInput >> BInput;
Output = res2;
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: S_SRL
S_SRLV: begin // RIGHT LOGICAL VARIABLE SHIFT
res2 = AInput >> BInput;
Output = res2;
Overflow = 0;
Zero = (Output == 0) ? 1 : 0; // If Output = 0, Zero flag = 1, otherwise 0
end // case: SRLV
endcase // case(Opcode)
end // else: !if(Reset == 1)
end // block: ALU
endmodule // ALU32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -