diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index ddead9738..6c52432d9 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -32,78 +32,31 @@ module alu #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, // Operands input logic [2:0] ALUControl, // With Funct3, indicates operation to perform - input logic [6:0] Funct7, + input logic [6:0] Funct7, // Funct7 from execute stage input logic [2:0] Funct3, // With ALUControl, indicates operation to perform output logic [WIDTH-1:0] Result, // ALU result output logic [WIDTH-1:0] Sum); // Sum of operands - // CondInvB = ~B when subtracting or inverted operand instruction in ZBB, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction. + // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction. // FullResult = ALU result before adjusting for a RV64 w-suffix instruction. - logic [WIDTH-1:0] ZBBResult, ZBSResult; - logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult, CondShiftA, ALUResult; // Intermediate results + logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult; // Intermediate results logic Carry, Neg; // Flags: carry out, negative logic LT, LTU; // Less than, Less than unsigned logic W64; // RV64 W-type instruction logic SubArith; // Performing subtraction or arithmetic right shift logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops logic Asign, Bsign; // Sign bits of A, B - logic InvB; // Is Inverted Operand Instruction (ZBB) - logic Rotate; // Is rotate operation - logic ZbaAdd; // Is ZBA Add Operation + logic rotate; // Extract control signals from ALUControl. assign {W64, SubArith, ALUOp} = ALUControl; - - - // Addition - if (`ZBA_SUPPORTED) - always_comb begin - ZbaAdd = (Funct7 == 7'b0010000 | Funct7 == 7'b0000100); - case({Funct7, Funct3, W64}) - 11'b0010000_010_0: CondShiftA = {A[WIDTH-2:0], {1'b0}}; //sh1add - 11'b0010000_100_0: CondShiftA = {A[WIDTH-3:0], {2'b00}}; //sh2add - 11'b0010000_110_0: CondShiftA = {A[WIDTH-4:0], {3'b000}}; //sh3add - 11'b0000100_000_1: CondShiftA = {{32{1'b0}}, A[31:0]}; //add.uw - 11'b0010000_010_1: CondShiftA = {{31{1'b0}},A[31:0], {1'b0}}; //sh1add.uw - 11'b0010000_100_1: CondShiftA = {{30{1'b0}},A[31:0], {2'b00}}; //sh2add.uw - 11'b0010000_110_1: CondShiftA = {{29{1'b0}},A[31:0], {3'b000}}; //sh3add.uw - default: CondShiftA = A; - endcase - end - else begin - assign CondShiftA = A; - assign ZbaAdd = 0; - end - - if (`ZBB_SUPPORTED) - always_comb begin - case ({Funct7,Funct3}) - 10'b0100000_111: InvB = 1'b0; //andn - 10'b0100000_110: InvB = 1'b0; //orn - 10'b0100000_100: InvB = 1'b0; //xnor - default: InvB = 1'b0; - endcase - - casez ({Funct7, Funct3}) - 10'b011000?_101: Rotate = 1'b1; - 10'b000010?_001: Rotate = 1'b0; - 10'b0110000_001: Rotate = 1'b1; - default: Rotate = 1'b0; - endcase - end - else begin - assign InvB = 1'b0; - assign Rotate = 1'b0; - end - - assign CondInvB = (SubArith | InvB) ? ~B : B; - - assign {Carry, Sum} = CondShiftA + CondInvB + {{(WIDTH-1){1'b0}}, SubArith}; + assign CondInvB = SubArith ? ~B : B; + assign {Carry, Sum} = A + CondInvB + {{(WIDTH-1){1'b0}}, SubArith}; // Shifts - shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .Arith(SubArith), .W64, .Rotate(Rotate), .Y(Shift)); + shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .Arith(SubArith), .W64, .Y(Shift), .Rotate(rotate)); // Condition code flags are based on subtraction output Sum = A-B. // Overflow occurs when the numbers being subtracted have the opposite sign @@ -121,42 +74,18 @@ module alu #(parameter WIDTH=32) ( // Select appropriate ALU Result always_comb - if (~ALUOp | ZbaAdd) FullResult = Sum; // Always add for ALUOp = 0 (address generation) and ZBA - else casez (Funct3) // Otherwise check Funct3 - 3'b000: FullResult = Sum; // add or sub - 3'b?01: FullResult = Shift; // sll, sra, or srl - 3'b010: FullResult = SLT; // slt - 3'b011: FullResult = SLTU; // sltu - 3'b100: FullResult = A ^ CondInvB; // xor - 3'b110: FullResult = A | CondInvB; // or - 3'b111: FullResult = A & CondInvB; // and + if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 (address generation) + else casez (Funct3) // Otherwise check Funct3 + 3'b000: FullResult = Sum; // add or sub + 3'b?01: FullResult = Shift; // sll, sra, or srl + 3'b010: FullResult = SLT; // slt + 3'b011: FullResult = SLTU; // sltu + 3'b100: FullResult = A ^ B; // xor + 3'b110: FullResult = A | B; // or + 3'b111: FullResult = A & B; // and endcase - if (`ZBS_SUPPORTED) - zbs #(WIDTH) zbs(.A, .B, .Funct7, .Funct3, .ZBSResult); - else assign ZBSResult = 0; - - - if (`ZBB_SUPPORTED) - zbb #(WIDTH) zbb(.A, .B, .Funct3, .Funct7, .W64, .ZBBResult); - else assign ZBBResult = 0; - // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits - if (WIDTH == 64) assign ALUResult = (W64 & ~ZbaAdd) ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; - else assign ALUResult = FullResult; - - if (`ZBB_SUPPORTED | `ZBA_SUPPORTED | `ZBS_SUPPORTED | `ZBC_SUPPORTED) begin - always_comb - casez({Funct7}) - 7'b010010?: Result = ZBSResult; - 7'b001010?: Result = ZBSResult; - default: Result = ALUResult; - endcase - end else begin - assign Result = ALUResult; - end - - - -endmodule - + if (WIDTH == 64) assign Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; + else assign Result = FullResult; +endmodule \ No newline at end of file diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index c6879ffd9..aff094820 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -149,7 +149,7 @@ module controller( ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo end else ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction - 7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000 | (Funct7D == 7'b0010000 & `ZBA_SUPPORTED) | (Funct7D == 7'b0100100 & `ZBS_SUPPORTED)) + 7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000) ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type else if (Funct7D == 7'b0000001 & `M_SUPPORTED) ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide @@ -161,10 +161,7 @@ module controller( else if (Funct7D == 7'b0000001 & `M_SUPPORTED & `XLEN == 64) ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide else - if ((Funct7D == 7'b0000100 | Funct7D == 7'b0010000) & `ZBA_SUPPORTED) - ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // adduw, sh1adduw, sh2adduw, sh3adduw - else - ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction + ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction 7'b1100011: ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches 7'b1100111: ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr 7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal @@ -193,23 +190,13 @@ module controller( assign SFenceVmaD = PrivilegedD & (InstrD[31:25] == 7'b0001001); assign FenceD = SFenceVmaD | FenceXD; // possible sfence.vma or fence.i - if (`ZBA_SUPPORTED) begin - // ALU Decoding is more comprehensive when ZBA is supported - assign sltD = (Funct3D == 3'b010 & OpD == 7'b0010011); - assign sltuD = (Funct3D == 3'b011 & OpD == 7'b0010011); - assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi - assign sraD = (Funct3D == 3'b101 & Funct7D[5]); - assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu - assign ALUControlD = {W64D, SubArithD, ALUOpD}; - end else begin - // ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra - assign sltD = (Funct3D == 3'b010); - assign sltuD = (Funct3D == 3'b011); - assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi - assign sraD = (Funct3D == 3'b101 & Funct7D[5]); - assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu - assign ALUControlD = {W64D, SubArithD, ALUOpD}; - end + // ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra + assign sltD = (Funct3D == 3'b010); + assign sltuD = (Funct3D == 3'b011); + assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi + assign sraD = (Funct3D == 3'b101 & Funct7D[5]); + assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu + assign ALUControlD = {W64D, SubArithD, ALUOpD}; // Fences // Ordinary fence is presently a nop @@ -228,9 +215,9 @@ module controller( flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD); // Execute stage pipeline control register and logic - flopenrc #(35) controlregE(clk, reset, FlushE, ~StallE, - {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, Funct7D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD}, - {IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, Funct7E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE}); + flopenrc #(28) controlregE(clk, reset, FlushE, ~StallE, + {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD}, + {IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE}); // Branch Logic // The comparator handles both signed and unsigned branches using BranchSignedE @@ -264,4 +251,4 @@ module controller( // the synchronous DTIM cannot read immediately after write // a cache cannot read or write immediately after a write assign StoreStallD = MemRWE[0] & ((MemRWD[1] | (MemRWD[0] & `DCACHE_SUPPORTED)) | (|AtomicD)); -endmodule +endmodule \ No newline at end of file