/* 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