From 17cd5cddaaa3345b76d10c364689b453e6eb1b13 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 8 May 2025 12:31:28 -0500 Subject: [PATCH] A little cheaper implementation. Uses 3 extra 1 bit registers, 1 XLEN-bit incrementer, and 1 XLEN-mux, rather than 3 XLEN registers. --- src/ifu/ifu.sv | 13 ++++++++++++- src/ifu/spill.sv | 2 +- src/privileged/csr.sv | 3 ++- src/privileged/privileged.sv | 3 ++- src/wally/wallypipelinedcore.sv | 6 +++--- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index cc4576fd2..69d9dafc5 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -64,6 +64,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( output logic [31:0] InstrM, // The decoded instruction in Memory stage output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL output logic [P.XLEN-1:0] PCM, // Memory stage instruction address + output logic [P.XLEN-1:0] PCSpillM, // Memory stage instruction address // branch predictor output logic [3:0] IClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic BPDirWrongM, // Prediction direction is wrong @@ -149,13 +150,23 @@ module ifu import cvw::*; #(parameter cvw_t P) ( ///////////////////////////////////////////////////////////////////////////////////////////// if(P.ZCA_SUPPORTED) begin : Spill + logic [P.XLEN-1:0] PCSpillD, PCSpillE; + logic [P.XLEN-1:0] PCIncrM; + logic SelSpillF, SelSpillD, SelSpillE, SelSpillM; spill #(P) spill(.clk, .reset, .StallF, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, .CacheableF, - .IFUCacheBusStallF, .ITLBMissOrUpdateAF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); + .IFUCacheBusStallF, .ITLBMissOrUpdateAF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .SelSpillF, .PostSpillInstrRawF, .CompressedF); + flopenr #(1) SpillDReg(clk, reset, ~StallD, SelSpillF, SelSpillD); + flopenr #(1) SpillEReg(clk, reset, ~StallE, SelSpillD, SelSpillE); + flopenr #(1) SpillMReg(clk, reset, ~StallM, SelSpillE, SelSpillM); + assign PCIncrM = PCM + 'd2; + mux2 #(P.XLEN) pcspillmmux(PCM, PCIncrM, SelSpillM, PCSpillM); + end else begin : NoSpill assign PCSpillNextF = PCNextF; assign PCSpillF = PCF; assign PostSpillInstrRawF = InstrRawF; assign {SelSpillNextF, CompressedF} = '0; + assign PCSpillM = PCM; end //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/ifu/spill.sv b/src/ifu/spill.sv index f073398f3..e4c8a61a1 100644 --- a/src/ifu/spill.sv +++ b/src/ifu/spill.sv @@ -44,6 +44,7 @@ module spill import cvw::*; #(parameter cvw_t P) ( output logic [P.XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill output logic [P.XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline + output logic SelSpillF, // Select incremented PC on a spill output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction output logic CompressedF); // The fetched instruction is compressed @@ -54,7 +55,6 @@ module spill import cvw::*; #(parameter cvw_t P) ( logic [P.XLEN-1:0] PCPlus2NextF, PCPlus2F; logic TakeSpillF; logic SpillF; - logic SelSpillF; logic SpillSaveF; logic [15:0] InstrFirstHalfF; logic EarlyCompressedF; diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 3a5edf2ea..fd7271379 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -36,6 +36,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( input logic [31:0] InstrM, // current instruction input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [P.XLEN-1:0] PCM, // program counter, next PC going to trap/return logic + input logic [P.XLEN-1:0] PCSpillM, // program counter, next PC going to trap/return logic aligned after an instruction spill input logic [P.XLEN-1:0] SrcAM, IEUAdrxTvalM, // SrcA and memory address from IEU input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring @@ -140,7 +141,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( always_comb if (InterruptM) NextFaultMtvalM = '0; else case (CauseM) - 12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint + 12, 1, 3: NextFaultMtvalM = PCSpillM; // Instruction page/access faults, breakpoint 2: NextFaultMtvalM = {{(P.XLEN-32){1'b0}}, InstrOrigM}; // Illegal instruction fault 0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrxTvalM; // Instruction misaligned, Load/Store Misaligned/page/access faults default: NextFaultMtvalM = '0; // Ecall, interrupts diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 36cc33026..aed065691 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -39,6 +39,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [P.XLEN-1:0] IEUAdrxTvalM, // address from IEU input logic [P.XLEN-1:0] PCM, // program counter + input logic [P.XLEN-1:0] PCSpillM, // program counter // control signals input logic InstrValidM, // Current instruction is valid (not flushed) input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt @@ -133,7 +134,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( // Control and Status Registers csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, - .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrxTvalM, + .InstrM, .InstrOrigM, .PCM, .PCSpillM, .SrcAM, .IEUAdrxTvalM, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 4c8fd1cfe..a27b40f1f 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -62,7 +62,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic [31:0] InstrD; logic [31:0] InstrM, InstrOrigM; logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE; - logic [P.XLEN-1:0] PCM; + logic [P.XLEN-1:0] PCM, PCSpillM; logic [P.XLEN-1:0] CSRReadValW, MDUResultW; logic [P.XLEN-1:0] EPCM, TrapVectorM; logic [1:0] MemRWE; @@ -184,7 +184,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPWrongE, .BPWrongM, // Mem .CommittedF, .EPCM, .TrapVectorM, .RetM, .TrapM, .InvalidateICacheM, .CSRWriteFenceM, - .InstrD, .InstrM, .InstrOrigM, .PCM, .IClassM, .BPDirWrongM, + .InstrD, .InstrM, .InstrOrigM, .PCM, .PCSpillM, .IClassM, .BPDirWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, // Faults out .IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, @@ -289,7 +289,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( privileged #(P) priv( .clk, .reset, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, - .CSRReadM, .CSRWriteM, .SrcAM, .PCM, + .CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PCSpillM, .InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM, .RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF, .InstrValidM, .CommittedM, .CommittedF,