⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alu.v

📁 MIPS CPU tested in Icarus Verilog
💻 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 + -