Gated floating-point load/stores with STATUS_FS and added initial decoding for Cache Management Operations

This commit is contained in:
David Harris 2023-07-02 00:34:30 -07:00
parent 41e9f20943
commit 15314a9c9a
4 changed files with 52 additions and 38 deletions

View File

@ -32,6 +32,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
// Decode stage control signals
input logic StallD, FlushD, // Stall, flush Decode stage
input logic [31:0] InstrD, // Instruction in Decode stage
input logic [1:0] STATUS_FS, // is FPU enabled?
output logic [2:0] ImmSrcD, // Type of immediate extension
input logic IllegalIEUFPUInstrD, // Illegal IEU and FPU instruction
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
@ -60,6 +61,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage
output logic BMUActiveE, // Bit manipulation instruction being executed
output logic MDUActiveE, // Mul/Div instruction being executed
output logic CMOE, // Cache Management operation being executed
// Memory stage control signals
input logic StallM, FlushM, // Stall, flush Memory stage
@ -85,7 +87,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs1D, Rs2D, RdD; // Rs1/2 source register / dest reg in Decode stage
`define CTRLW 23
`define CTRLW 24
// pipelined control signals
logic RegWriteD, RegWriteE; // RegWrite (register will be written)
@ -103,6 +105,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic CSRReadD; // CSR read instruction
logic [1:0] AtomicD; // Atomic (AMO) instruction
logic FenceXD; // Fence instruction
logic CMOD; // Cache management instruction
logic InvalidateICacheD, FlushDCacheD;// Invalidate I$, flush D$
logic CSRWriteD, CSRWriteE; // CSR write
logic PrivilegedD, PrivilegedE; // Privileged instruction
@ -129,6 +132,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic FLSFunctD; // Detect floating-point loads and stores
logic JRFunctD; // detect jalr instruction
logic FenceFunctD; // Detect fence instruction
logic CMOFunctD;
logic AFunctD, AMOFunctD; // Detect atomic instructions
logic RWFunctD, MWFunctD; // detect RW/MW instructions
logic PFunctD, CSRFunctD; // detect privileged / CSR instruction
@ -163,9 +167,13 @@ module controller import cvw::*; #(parameter cvw_t P) (
assign MFunctD = (Funct7D == 7'b0000001) & (P.M_SUPPORTED | (P.ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
assign LFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 |
((P.XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110));
assign FLSFunctD = (Funct3D == 3'b010 & P.F_SUPPORTED) | (Funct3D == 3'b011 & P.D_SUPPORTED) |
(Funct3D == 3'b100 & P.Q_SUPPORTED) | (Funct3D == 3'b001 & P.ZFH_SUPPORTED);
assign FLSFunctD = (STATUS_FS != 2'b00) & ((Funct3D == 3'b010 & P.F_SUPPORTED) | (Funct3D == 3'b011 & P.D_SUPPORTED) |
(Funct3D == 3'b100 & P.Q_SUPPORTED) | (Funct3D == 3'b001 & P.ZFH_SUPPORTED));
assign FenceFunctD = (Funct3D == 3'b000) | (P.ZIFENCEI_SUPPORTED & Funct3D == 3'b001);
assign CMOFunctD = (Funct3D == 3'b010 & RdD == 5'b0) &
((P.ZICBOZ_SUPPORTED & InstrD[31:20] == 12'd4) |
(P.ZICBOM_SUPPORTED & (InstrD[31:20] == 12'd0 | InstrD[31:20] == 12'd1 | InstrD[31:20] == 12'd2)));
// *** need to get with enable bits such as MENVCFG_CBZE
assign AFunctD = (Funct3D == 3'b010) | (P.XLEN == 64 & Funct3D == 3'b011);
assign AMOFunctD = (InstrD[31:27] == 5'b00001) |
(InstrD[31:27] == 5'b00000) |
@ -193,6 +201,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
assign LFunctD = 1; // don't bother to check Funct3 for loads
assign FLSFunctD = 1; // don't bother to check Func3 for floating-point loads/stores
assign FenceFunctD = 1; // don't bother to check fields for fences
assign CMOFunctD = 1; // don't bother to check fields for CMO instructions
assign AFunctD = 1; // don't bother to check fields for atomics
assign AMOFunctD = 1; // don't bother to check Funct7 for AMO operations
assign RWFunctD = 1; // don't bother to check fields for RW instructions
@ -208,55 +217,57 @@ module controller import cvw::*; #(parameter cvw_t P) (
// Main Instruction Decoder
/* verilator lint_off CASEINCOMPLETE */
always_comb begin
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // default: Illegal instruction
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0_1; // default: Illegal instruction
case(OpD)
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_CMO_Illegal
7'b0000011: if (LFunctD)
ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // loads
ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0_0; // loads
7'b0000111: if (FLSFunctD)
ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported
ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0_1; // flw - only legal if FP supported
7'b0001111: if (FenceFunctD) begin
if (P.ZIFENCEI_SUPPORTED)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0_0; // fence
else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0_0; // fence treated as nop
end else if (CMOFunctD) begin
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1_0; // CMO Instruction
end
7'b0010011: if (IFunctD)
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0_0; // I-type ALU
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0_0; // auipc
7'b0011011: if (IFunctD & IWValidFunct3D & P.XLEN == 64)
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0_0; // IW-type ALU for RV64i
7'b0100011: if (SFunctD)
ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // stores
ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0_0; // stores
7'b0100111: if (FLSFunctD)
ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_1; // fsw - only legal if FP supported
ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0_1; // fsw - only legal if FP supported
7'b0101111: if (P.A_SUPPORTED & AFunctD) begin
if (InstrD[31:27] == 5'b00010 & Rs2D == 5'b0)
ControlsD = `CTRLW'b1_000_00_10_001_0_0_0_0_0_0_0_0_0_01_0; // lr
ControlsD = `CTRLW'b1_000_00_10_001_0_0_0_0_0_0_0_0_0_01_0_0; // lr
else if (InstrD[31:27] == 5'b00011)
ControlsD = `CTRLW'b1_101_01_01_100_0_0_0_0_0_0_0_0_0_01_0; // sc
ControlsD = `CTRLW'b1_101_01_01_100_0_0_0_0_0_0_0_0_0_01_0_0; // sc
else if (AMOFunctD)
ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo
ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0_0; // amo
end
7'b0110011: if (RFunctD)
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0_0; // R-type
else if (MFunctD)
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0_0; // Multiply/divide
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0_0; // lui
7'b0111011: if (RWFunctD)
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0_0; // R-type W instructions for RV64i
else if (MWFunctD)
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0_0; // W-type Multiply/Divide
7'b1100011: if (BFunctD)
ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches
ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0_0; // branches
7'b1100111: if (JRFunctD)
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
ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0_0; // jalr
7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0_0; // jal
7'b1110011: if (P.ZICSR_SUPPORTED) begin
if (PFunctD)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in privdec modules
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0_0; // privileged; decoded further in privdec modules
else if (CSRFunctD)
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0_0; // csrs
end
endcase
end
@ -269,7 +280,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
//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;
PrivilegedD, FenceXD, MDUD, AtomicD, CMOD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD;
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
@ -341,9 +352,9 @@ module controller import cvw::*; #(parameter cvw_t P) (
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
// Execute stage pipeline control register and logic
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});
flopenrc #(30) 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, CMOD, InstrValidD},
{ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOE, InstrValidE});
// Branch Logic
// The comparator handles both signed and unsigned branches using BranchSignedE

View File

@ -30,6 +30,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
input logic clk, reset,
// Decode stage signals
input logic [31:0] InstrD, // Instruction
input logic [1:0] STATUS_FS, // is FPU enabled?
input logic IllegalIEUFPUInstrD, // Illegal instruction
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
// Execute stage signals
@ -43,6 +44,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B
output logic [4:0] RdE, // Destination register
output logic MDUActiveE, // Mul/Div instruction being executed
output logic CMOE, // Cache management instruction being executed
// Memory stage signals
input logic SquashSCW, // Squash store conditional, from LSU
output logic [1:0] MemRWM, // Read/write control goes to LSU
@ -97,11 +99,11 @@ module ieu import cvw::*; #(parameter cvw_t P) (
logic BMUActiveE; // Bit manipulation instruction being executed
controller #(P) c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
.clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ImmSrcD,
.IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE,
.BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .MDUActiveE,
.BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .MDUActiveE, .CMOE,
.StallM, .FlushM, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD);

View File

@ -197,10 +197,10 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign MENVCFG_STCE = MENVCFG_REGW[63];
// Uncomment these other fields when they are defined
// assign MENVCFG_PBMTE = MENVCFG_REGW[62];
// assign MENVCFG_CBZE = MENVCFG_REGW[7];
// assign MENVCFG_CBZE = MENVCFG_REGW[7];
// assign MENVCFG_CBCFE = MENVCFG_REGW[6];
// assign MENVCFG_CBIE = MENVCFG_REGW[5:4];
// assign MENVCFG_FIOM = MENVCFG_REGW[0];
// assign MENVCFG_CBIE = MENVCFG_REGW[5:4];
// assign MENVCFG_FIOM = MENVCFG_REGW[0];
// Read machine mode CSRs
// verilator lint_off WIDTH

View File

@ -78,6 +78,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
logic SquashSCW;
logic MDUActiveE; // Mul/Div instruction being executed
logic CMOE; // Cache management instruction being executed
// floating point unit signals
logic [2:0] FRM_REGW;
@ -188,10 +189,10 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
// integer execution unit: integer register file, datapath and controller
ieu #(P) ieu(.clk, .reset,
// Decode Stage interface
.InstrD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD,
.InstrD, .STATUS_FS, .IllegalIEUFPUInstrD, .IllegalBaseInstrD,
// Execute Stage interface
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, .MDUActiveE,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, .MDUActiveE, .CMOE,
// Memory stage interface
.SquashSCW, // from LSU
.MemRWM, // read/write control goes to LSU