WISC-SP22-5-Stage-Pipelined-Processor / verilog / alu.v
alu.v
Raw
/*
    CS/ECE 552 Spring '22
    Homework #2, Problem 2

    A multi-bit ALU module (defaults to 16-bit). It is designed to choose
    the correct operation to perform on 2 multi-bit numbers from rotate
    left, shift left, shift right arithmetic, shift right logical, add,
    or, xor, & and.  Upon doing this, it should output the multi-bit result
    of the operation, as well as drive the output signals Zero and Overflow
    (OFL).
*/
module alu (InA, InB, Cin, Oper, invA, invB, sign, Out, Zero, Ofl, Lt, Lte, SLBI, carry_temp, err);

    parameter OPERAND_WIDTH = 16;    
    parameter NUM_OPERATIONS = 3;
       
    input  [OPERAND_WIDTH -1:0] InA ; // Input operand A
    input  [OPERAND_WIDTH -1:0] InB ; // Input operand B
    input                       Cin ; // Carry in
    input  [NUM_OPERATIONS-1:0] Oper; // Operation type
    input                       invA; // Signal to invert A
    input                       invB; // Signal to invert B
    input                       SLBI; // Signal to SLBI
    input                       sign; // Signal for signed operation
    output [OPERAND_WIDTH -1:0] Out ; // Result of computation
    output                      Ofl ; // Signal if overflow occured
    output                      Zero; // Signal if Out is 0
    output                      Lt  ; // Signal if Rs < Rt
    output                      Lte ; //Signal if Rs <= Rt
    output                      err;
    output                      carry_temp;
 
    /* YOUR CODE HERE */
	
    wire [3:0] BorSLBI;
    
	//shift storage
	wire [15:0] shift_out;
	
	//inverse storage
	wire [15:0] A;
	wire [15:0] B;
	
	//cla storage
	wire [15:0] sum_temp;
	wire carry_temp;
    wire [15:0] Out_temp;
    wire [2:0] ALUOpORSLBI;
	
	//logical operation storage
	wire [15:0] and_temp;
	wire [15:0] xor_temp;
	
	//flag storage
	wire [15:0] mux_temp;
	wire ifADD;
	wire Ofl_temp;
	
	//whether to invert inputs or not
	assign A = invA ? (~InA) : InA;
	assign B = invB ? (~InB) : InB;
	
    assign BorSLBI = SLBI ? 4'b1000 : B[3:0];
    
    assign ALUOpORSLBI = SLBI ? 3'b001 : Oper[2:0];
    
	//shifter for op codes 000 to 011
    shifter iSHIFTER(.Out(shift_out), .In(A), .ShAmt(BorSLBI), .Oper(ALUOpORSLBI[1:0]));
	
	//CLA for add
    cla_16b iCLA(.S(sum_temp), .C_out(carry_temp), .A(A), .B(B), .C_in(Cin), .err(err));

    //logical operations
	assign and_temp = A & B;
	 
	assign xor_temp = A ^ B;
	
	//muxes
    assign mux_temp = Oper[1] ? (Oper[0] ? and_temp : xor_temp) : (Oper[0] ? sum_temp : sum_temp);
	
	assign Out_temp = Oper[2] ? mux_temp : shift_out;
    
    assign Out = SLBI ? shift_out : Out_temp;
	
	//to find zero flag using reduction
	assign Zero = ~|Out;
	
	//checks if an add operation occured
    assign ifADD = (Oper[2] & ~Oper[1] & ~Oper[0]) ;
	
	//checks the signed overflow
	assign ifSIGN = (A[15] & B[15] & ~Out[15]) | (~A[15] & ~B[15] & Out[15]);
	
	//figues out whether it was a signed or unsigned overflow
	assign Ofl_temp = sign ? ifSIGN : carry_temp;
	
	//finds the overflow flag
	assign Ofl = ifADD ? (Ofl_temp) : 1'b0;
    
    assign Lt = (InA[15] & ~InB[15]) | (~InA[15] & ~InB[15] & Out[15]) | (InA[15] & InB[15] & Out[15]);
    
    assign Lte = Lt | Zero;
	
	
	
	
	
    
endmodule