From 2679f06a00bf6ae98ba70c278ce6ab4dbad1cddf Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Mon, 13 Feb 2023 16:36:17 -0800 Subject: [PATCH] Shadd instructions pass tests --- src/ieu/alu.sv | 21 +++++++++++++-------- src/ieu/controller.sv | 30 ++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 911fc0873..7e06ee6e9 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -49,27 +49,32 @@ module alu #(parameter WIDTH=32) ( 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 // 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-1:1], {1'b0}}; //sh1add - 11'b0010000_100_0: CondShiftA = {A[WIDTH-1:2], {2'b00}}; //sh2add - 11'b0010000_110_0: CondShiftA = {A[WIDTH-1:3], {3'b000}}; //sh3add - 11'b0000100_000_0: CondShiftA = {{32{1'b0}}, A[31:0]}; //add.uw + 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'b0}}; //sh2add.uw - 11'b0010000_110_1: CondShiftA = {{29{1'b0}},A[31:0], {3'b0}}; //sh3add.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) @@ -116,7 +121,7 @@ module alu #(parameter WIDTH=32) ( // Select appropriate ALU Result always_comb - if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 (address generation) + 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 @@ -137,7 +142,7 @@ module alu #(parameter WIDTH=32) ( 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 Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; + if (WIDTH == 64) assign Result = (W64 & ~ZbaAdd) ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; else assign Result = FullResult; endmodule diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 4d8ba0c65..1188fe0a6 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) + 7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000 | (Funct7D == 7'b0010000 & `ZBA_SUPPORTED)) 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,8 +161,8 @@ 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 & `ZBA_SUPPORTED) - ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // adduw + 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 7'b1100011: ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches @@ -193,13 +193,23 @@ module controller( assign SFenceVmaD = PrivilegedD & (InstrD[31:25] == 7'b0001001); assign FenceD = SFenceVmaD | FenceXD; // possible sfence.vma or fence.i - // 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}; + 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 // Fences // Ordinary fence is presently a nop