ALUControl Elimination

This commit is contained in:
David Harris 2023-03-24 08:10:48 -07:00
parent ac0b669518
commit d04f4cedf6
6 changed files with 52 additions and 61 deletions

View File

@ -31,11 +31,12 @@
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 W64, // W64-type instruction
input logic SubArith, // Subtraction or arithmetic shift
input logic [2:0] ALUSelect, // ALU mux select signal
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal
input logic [2:0] Funct3, // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect
input logic [2:0] Funct3, // For BMU decoding
input logic [1:0] CompFlags, // Comparator flags
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
output logic [WIDTH-1:0] Result, // ALU result
@ -49,21 +50,15 @@ module alu #(parameter WIDTH=32) (
logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux
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 shSignA;
// Extract control signals from ALUControl.
assign {W64, SubArith, ALUOp} = ALUControl;
logic ShiftSignA;
// A, A sign bit muxes
if (WIDTH == 64) begin
mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA);
mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, ShiftSignA);
mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, CondExtA); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux
end else begin
mux2 #(1) signmux(1'b0, A[31], SubArith, shSignA);
mux2 #(1) signmux(1'b0, A[31], SubArith, ShiftSignA);
assign CondExtA = A;
end
@ -72,7 +67,7 @@ module alu #(parameter WIDTH=32) (
assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith};
// Shifts (configurable for rotation)
shifter sh(.A(CondExtA), .Sign(shSignA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2]));
shifter sh(.A(CondExtA), .Sign(ShiftSignA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2]));
// Condition code flags are based on subtraction output Sum = A-B.
// Overflow occurs when the numbers being subtracted have the opposite sign
@ -92,7 +87,7 @@ module alu #(parameter WIDTH=32) (
3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt
3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu
3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv
3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift;// bext
3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported)
3'b110: FullResult = A | CondMaskInvB; // or, orn, bset
3'b111: FullResult = A & CondMaskInvB; // and, bclr
endcase
@ -104,8 +99,8 @@ module alu #(parameter WIDTH=32) (
// Final Result B instruction select mux
if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu
bitmanipalu #(WIDTH) balu(.A, .B, .ALUControl, .BSelect, .ZBBSelect,
.Funct3, .CompFlags, .BALUControl, .CondExtA, .ALUResult, .FullResult,
bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect,
.Funct3, .CompFlags, .BALUControl, .CondExtA, .ALUResult, .FullResult,
.CondMaskB, .CondShiftA, .Result);
end else begin
assign Result = ALUResult;

View File

@ -31,7 +31,7 @@
module bitmanipalu #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] ALUControl, // With Funct3, indicates operation to perform
input logic W64, // W64-type instruction
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal
input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform
@ -46,17 +46,11 @@ module bitmanipalu #(parameter WIDTH=32) (
logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result
logic [WIDTH-1:0] MaskB; // BitMask of B
logic [WIDTH-1:0] RevA; // Bit-reversed A
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 Rotate; // Indicates if it is Rotate instruction
logic Mask; // Indicates if it is ZBS instruction
logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
// Extract control signals from ALUControl.
assign {W64, SubArith, ALUOp} = ALUControl;
// Extract control signals from bitmanip ALUControl.
assign {Mask, PreShift} = BALUControl[1:0];

View File

@ -44,7 +44,7 @@ module bmuctrl(
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
// Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage
output logic [2:0] ALUSelectE,
output logic [2:0] ALUSelectD, // ALU select
output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
output logic [2:0] ZBBSelectE, // ZBB mux select signal
output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute
@ -61,7 +61,7 @@ module bmuctrl(
logic MaskD; // Indicates if zbs instruction in Decode Stage
logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage
logic [2:0] BALUControlD; // ALU Control signals for B instructions
logic [2:0] BALUSelectD, ALUSelectD; // ALU Mux select signal in Decode Stage
logic [2:0] BALUSelectD; // ALU Mux select signal in Decode Stage for BMU operations
logic BALUOpD; // Indicates if it is an ALU B instruction in Decode Stage
`define BMUCTRLW 17
@ -179,5 +179,5 @@ module bmuctrl(
assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000);
// BMU Execute stage pipieline control register
flopenrc#(13) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {ALUSelectE, BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE});
flopenrc#(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE});
endmodule

View File

@ -45,7 +45,6 @@ module controller(
input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
input logic FWriteIntE, // Write integer register, coming from FPU controller
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
output logic [2:0] ALUControlE, // ALU operation to perform
output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, // Selects result to pass on to Memory stage
output logic [2:0] ALUSelectE, // ALU mux select signal
@ -54,6 +53,7 @@ module controller(
output logic IntDivE, // Integer divide
output logic MDUE, // MDU (multiply/divide) operatio
output logic W64E, // RV64 W-type operation
output logic SubArithE, // Subtraction or arithmetic shift
output logic JumpE, // jump instruction
output logic BranchE, // Branch instruction
output logic SCE, // Store Conditional instruction
@ -93,7 +93,7 @@ module controller(
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file
logic [1:0] MemRWD, MemRWE; // Store (write to memory)
logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
logic BaseALUOpD, BaseW64D; // ALU operation and W64 for Base instructions specifically
logic BaseW64D; // W64 for Base instructions specifically
logic BaseRegWriteD; // Indicates if Base instruction register write instruction
logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu
logic BaseALUSrcBD; // Base instruction ALU B source select signal
@ -111,6 +111,7 @@ module controller(
logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals
logic SubArithD; // TRUE for R-type subtracts and sra, slt, sltu or B-type ext clr, andn, orn, xnor
logic subD, sraD, sltD, sltuD; // Indicates if is one of these instructions
logic ALUOpE; // 0 for address generationm 1 for ALU operations
logic BranchTakenE; // Branch is taken
logic eqE, ltE; // Comparator outputs
logic unused;
@ -118,22 +119,18 @@ module controller(
logic IEURegWriteE; // Register write
logic BRegWriteE; // Register write from BMU controller in Execute Stage
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
logic IllegalBitmanipInstrD; // Unrecognized B instruction
logic [1:0] AtomicE; // Atomic instruction
logic FenceD, FenceE; // Fence instruction
logic SFenceVmaD; // sfence.vma instruction
logic IntDivM; // Integer divide instruction
logic [1:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage
logic [2:0] ZBBSelectD; // ZBB Mux Select Signal
logic BRegWriteD; // Indicates if it is a R type B instruction in decode stage
logic BW64D; // Indicates if it is a W type B instruction in decode stage
logic BSubArithD; // TRUE for B-type ext, clr, andn, orn, xnor
logic BALUSrcBD; // B-type alu src select signal
logic BComparatorSignedE; // Indicates if max, min (signed comarison) instruction in Execute Stage
logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions
logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions
logic JFunctD; // detect jalr instruction
logic FenceM; // Fence.I or sfence.VMA instruction in memory stage
logic [2:0] ALUSelectD; // ALU Output selection mux control
// Extract fields
assign OpD = InstrD[6:0];
@ -231,17 +228,10 @@ module controller(
// Squash control signals if coming from an illegal compressed instruction
// On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them.
assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11];
assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; //NOTE: Do we want to segregate the IllegalBitmanipInstrD into its own output signal
//assign IllegalBaseInstrD = 1'b0;
assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD,
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD,
PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD;
// If either bitmanip signal or base instruction signal
assign RegWriteD = BaseRegWriteD | BRegWriteD;
assign W64D = BaseW64D | BW64D;
assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD;
assign SubArithD = BaseSubArithD | BSubArithD; // TRUE If B-type or R-type instruction involves inverted operand
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
@ -253,34 +243,45 @@ module controller(
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 BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD);
assign ALUControlD = {W64D, SubArithD, ALUOpD};
// bit manipulation Configuration Block
if (`ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags
logic IllegalBitmanipInstrD; // Unrecognized B instruction
logic BRegWriteD; // Indicates if it is a R type BMU instruction in decode stage
logic BW64D; // Indicates if it is a W type BMU instruction in decode stage
logic BSubArithD; // TRUE for BMU ext, clr, andn, orn, xnor
logic BALUSrcBD; // BMU alu src select signal
bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD,
.BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE,
.ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE);
.ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE);
if (`ZBA_SUPPORTED) begin
// ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw
assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ;
end else assign sltD = (Funct3D == 3'b010);
// Combine base and bit manipulation signals
assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ;
assign RegWriteD = BaseRegWriteD | BRegWriteD;
assign W64D = BaseW64D | BW64D;
assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD;
assign SubArithD = BaseSubArithD | BSubArithD; // TRUE If BMU or R-type instruction involves inverted operand
end else begin: bitmanipi
assign ALUSelectE = Funct3E;
assign ALUSelectD = ALUOpD ? Funct3D : 3'b000; // add for address generation when not doing ALU operation
assign sltD = (Funct3D == 3'b010);
assign IllegalBaseInstrD = ControlsD[0] | IllegalERegAdrD ;
assign RegWriteD = BaseRegWriteD;
assign W64D = BaseW64D;
assign ALUSrcBD = BaseALUSrcBD;
assign SubArithD = BaseSubArithD; // TRUE If B-type or R-type instruction involves inverted operand
// tie off unused bit manipulation signals
assign BSelectE = 2'b00;
assign BSelectD = 2'b00;
assign ZBBSelectE = 3'b000;
assign BRegWriteD = 1'b0;
assign BW64D = 1'b0;
assign BRegWriteE = 1'b0;
assign BSubArithD = 1'b0;
assign BComparatorSignedE = 1'b0;
assign BALUControlE = 3'b0;
assign BALUSrcBD = 1'b0;
assign sltD = (Funct3D == 3'b010);
assign IllegalBitmanipInstrD = 1'b1;
end
// Fences
@ -300,9 +301,9 @@ module controller(
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
// Execute stage pipeline control register and logic
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});
flopenrc #(29) controlregE(clk, reset, FlushE, ~StallE,
{ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD},
{ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE});
// Branch Logic
// The comparator handles both signed and unsigned branches using BranchSignedE

View File

@ -40,7 +40,8 @@ module datapath (
input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage
input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages
input logic [2:0] ALUControlE, // Indicate operation ALU performs
input logic W64E, // W64-type instruction
input logic SubArithE, // Subtraction or arithmetic shift
input logic ALUSrcAE, ALUSrcBE, // ALU operands
input logic ALUResultSrcE, // Selects result to pass on to Memory stage
input logic [2:0] ALUSelectE, // ALU mux select signal
@ -113,7 +114,7 @@ module datapath (
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE);
alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);

View File

@ -76,7 +76,6 @@ module ieu (
logic [2:0] ImmSrcD; // Select type of immediate extension
logic [1:0] FlagsE; // Comparison flags ({eq, lt})
logic [2:0] ALUControlE; // ALU control indicates function to perform
logic ALUSrcAE, ALUSrcBE; // ALU source operands
logic [2:0] ResultSrcW; // Selects result in Writeback stage
logic ALUResultSrcE; // Selects ALU result to pass on to Memory stage
@ -87,6 +86,7 @@ module ieu (
logic [1:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
logic [2:0] ZBBSelectE; // ZBB Result Select Signal in Execute Stage
logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage
logic SubArithE; // Subtraction or arithmetic shift
// Forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers
@ -99,15 +99,15 @@ module ieu (
controller c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
.IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD);
datapath dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE,
.Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,