From 57d15539a230897fe07d626c68561fa917a46564 Mon Sep 17 00:00:00 2001 From: Ibrahim Date: Wed, 2 Dec 2020 12:51:53 +0000 Subject: [PATCH] Done expect for j type, LWL/R & MLT --- rtl/mips_cpu_alu.v | 247 +++++++++++++++++++++++++++++++++------------ 1 file changed, 180 insertions(+), 67 deletions(-) diff --git a/rtl/mips_cpu_alu.v b/rtl/mips_cpu_alu.v index e2a1844..80d9232 100644 --- a/rtl/mips_cpu_alu.v +++ b/rtl/mips_cpu_alu.v @@ -1,40 +1,22 @@ -/* Questions/Todos: - --how to implement mult signed vs unsigned? --Need to clarify How many ALU ctrl flags there are --Need to go through & check special cases for each instruction --In the process of manually checking if every instruction has been accounted for in the actual enum --Right what your final set of different opeators each do (easy but somewhat tedious) :( -*/ - - - - module mips_cpu_alu( - input logic[31:0] A, B,//alu_in1, alu_in2 -The two ALU inputs + input signed logic[31:0] A, B,//alu_in1, alu_in2 -The two ALU inputs - input logic [5:0] ALUFlags, //Output from ALU control - 6bits as there are 48 different instructions in our ISA that we need to implement + input logic [5:0] ALUFlags, //Output from ALU control - 6bits as there are 48 different instructions in our ISA that we need to implement /* The ALU Flags is 6 bits for now update when reduced */ - output logic ALUZero, //Is the output of the ALU 0? - used to check result + output logic ALUZero, //Is the output of the ALU 0? - used to check result - output logic[31:0] ALUOut, // The ouput of the ALU + output logic[31:0] ALUOut, // The ouput of the ALU + input [15:0] immediate; + + reg [31:0] SignExtend, ZeroExtend; + + input logic[10:6] shamt = instr_readdata[10:6]; ); - /* - - I have listed all of the instructions - reducing this set to figure out the size - of ALUFlag/enum also need to go through the IS again and find special cases - (like over/underflow) for each instruction & to note them - - i.e. for the instruction SLT (set on less than): - ALUOut is '32'h000000001' if A < B - - */ - // Instructions commented out have been accounted for /* Using an enum to define constants */ @@ -43,25 +25,25 @@ module mips_cpu_alu( //ADDU = 6'd1, //Add unsigned (no overflow) //AND = 6'd2, //Bitwise and //ANDI = 6'd3, //Bitwise and immediate - BEQ = 6'd4, //Branch on equal - BGEZ = 6'd5, //Branch on greater than or equal to zero - BGEZAL = 6'd6, //Branch on non-negative (>=0) and link - BGTZ = 6'd7, //Branch on greater than zero - BLEZ = 6'd8, //Branch on less than or equal to zero - BLTZ = 6'd9, //Branch on less than zero - BLTZAL = 6'd10, //Branch on less than zero and link - BNE = 6'd11, //Branch on not equal + //BEQ = 6'd4, //Branch on equal + //BGEZ = 6'd5, //Branch on greater than or equal to zero + //BGEZAL = 6'd6, //Branch on non-negative (>=0) and link + //BGTZ = 6'd7, //Branch on greater than zero + //BLEZ = 6'd8, //Branch on less than or equal to zero + //BLTZ = 6'd9, //Branch on less than zero + //BLTZAL = 6'd10, //Branch on less than zero and link + //BNE = 6'd11, //Branch on not equal //DIV = 6'd12, //Divide //DIVU = 6'd13, //Divide unsigned J = 6'd14, //Jump JALR = 6'd15, //Jump and link register JAL = 6'd16, //Jump and link JR = 6'd17, //Jump register - LB = 6'd18, //Load byte - LBU = 6'd19, //Load byte unsigned - LH = 6'd20, //Load half-word - LHU = 6'd21, //Load half-word unsigned - LUI = 6'd22, //Load upper immediate + //LB = 6'd18, //Load byte + //LBU = 6'd19, //Load byte unsigned + //LH = 6'd20, //Load half-word + //LHU = 6'd21, //Load half-word unsigned + //LUI = 6'd22, //Load upper immediate LW = 6'd23, //Load word LWL = 6'd24, //Load word left LWR = 6'd25, //Load word right @@ -71,55 +53,186 @@ module mips_cpu_alu( //MULTU = 6'd29, //Multiply unsigned //OR = 6'd30, //Bitwise or //ORI = 6'd31, //Bitwise or immediate - SB = 6'd32, //Store byte - SH = 6'd33, //Store half-word - SLL = 6'd34, //Shift left logical - SLLV = 6'd35, //Shift left logical variable - SLT = 6'd36, //Set on less than (signed) - SLTI = 6'd37, //Set on less than immediate (signed) - SLTIU = 6'd38, //Set on less than immediate unsigned - SLTU = 6'd39, //Set on less than unsigned - SRA = 6'd40, //Shift right arithmetic - SRAV = 6'd41, //Shift right arithmetic - SRL = 6'd42, //Shift right logical - SRLV = 6'd43, //Shift right logical variable + //SB = 6'd32, //Store byte + //SH = 6'd33, //Store half-word + //SLL = 6'd34, //Shift left logical + //SLLV = 6'd35, //Shift left logical variable + //SLT = 6'd36, //Set on less than (signed) + //SLTI = 6'd37, //Set on less than immediate (signed) + //SLTIU = 6'd38, //Set on less than immediate unsigned + //SLTU = 6'd39, //Set on less than unsigned + //SRA = 6'd40, //Shift right arithmetic + // SRAV = 6'd41, //Shift right arithmetic + //SRL = 6'd42, //Shift right logical + //SRLV = 6'd43, //Shift right logical variable //SUBU = 6'd44, //Subtract unsigned - SW = 6'd45, //Store word - XOR = 6'd46, //Bitwise exclusive or - XORI = 6'd47, //Bitwise exclusive or immediate + //SW = 6'd45, //Store word + //XOR = 6'd46, //Bitwise exclusive or + //XORI = 6'd47, //Bitwise exclusive or immediate //} ALUFlags; /* This is how I believe our ctrl flags should be arranged */ - typedef enum logic [/* ? */ : 0]{ - ADD = - SUB = - MULT = - DIV = - //logical - AND = 'd - OR = 'd - SLL = 'd + typedef enum logic [6:0]{ + } ALUFlags; always @(alu_in1, alu_in2, ALUFlags) begin + + SignExtend = {{16{immediate[15]}}, immediate}; + ZeroExtend = {{16{1'b0}}, immediate}; + case(ALUFlags) ADD: begin - ALUOut = A & B; // is it = or <= ?? + ALUOut = A + B; // is it = or <= ?? + end + + SUB: begin + ALUOut = A - B; + end + + MULT: begin + ALUOut = A * B; + end + + DIV: begin + ALUOut = A / B; + end + + + XOR: begin + ALUOut = A^B; end OR: begin ALUOut = A | B; end - + SLL: begin - ALUOut = b >> shamt //Shamt is instruction read data [10:6] + ALUOut = B << shamt //Shamt is instruction read data [10:6] + end + + SRL: begin + ALUOut = B >> shamt //Shamt is instruction read data [10:6] + end + + SLLV: begin + ALUOut = B << A + end + + SRLV: begin + ALUOut = B >> A + end + + AND: begin + ALUOut = A & B; + end + + BEQ: begin + if A = B begin + ALUOut = 0; + end + else begin + ALUOut; + end + + end + + BGEZ: begin + if A>=0 begin + ALUOut = 0; + end + else begin + ALUOut; + end + end + + BGEZAL: begin + if A>=0 begin + ALUOut = 0; + end + else begin + ALUOut; + end + end + + BGTZ: begin + if A>0 begin + ALUOut = 0; + end + else begin + AlUOut; + end end + BLEZ: begin + if A<=0 begin + ALUOut = 0; + end + else begin + AlUOut; + end + end + BNE: begin + if A<=0 begin + ALUOut = 0; + end + else begin + AlUOut; + end + end + + LB: begin + ALUOut = A + SignExtend + end + + LBU: begin + ALUOut = A + ZeroExtend + end + + LH: begin + ALUOut = A + SignExtend + end + + LHU: begin + ALUOut = A + ZeroExtend + end + + LUI: begin + ALUOut = {immediate, {16{1'b0}}}; + end + + SB: begin + ALUOut = A + SignExtend + end + + SH: begin + ALUOut = A + SignExtend + end + + SLT: begin + ALUOut = $signed(A) < $signed(B) ? 1 : 0; + end + + SLTU: begin + ALUOut = A < B ? 1 : 0; + end + + SRA: begin + ALUOut = $signed($signed(B) >>> shamt); + end + + SRAV: begin + ALUOut = $signed($signed(B) >>> A); + end + + SW: begin + ALUOut = A + SignExtend + end end