Shadd instructions pass tests

This commit is contained in:
Kevin Kim 2023-02-13 16:36:17 -08:00
parent 02a7dc45f0
commit 2679f06a00
2 changed files with 33 additions and 18 deletions

View File

@ -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

View File

@ -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