From 8eace30f491d4599edfcf53f68ba4d121b678670 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 20 Dec 2023 16:18:31 -0800 Subject: [PATCH] Moved UnalignedPCNextF mux into IFU --- src/ifu/ifu.sv | 26 ++++++++++++++++---------- src/privileged/csr.sv | 14 ++++++-------- src/privileged/privdec.sv | 3 ++- src/privileged/privileged.sv | 19 ++++++++++--------- src/privileged/trap.sv | 5 +---- src/wally/wallypipelinedcore.sv | 16 ++++++++-------- 6 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index d5a73eef9..b38b6d96c 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -56,8 +56,9 @@ module ifu import cvw::*; #(parameter cvw_t P) ( output logic BPWrongM, // Prediction is wrong // Mem output logic CommittedF, // I$ or bus memory operation started, delay interrupts - input logic [P.XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. - output logic [P.XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence + input logic [P.XLEN-1:0] EPCM, // Exception Program counter from privileged unit + input logic [P.XLEN-1:0] TrapVectorM, // Trap vector, from privileged unit + input logic RetM, TrapM, // return instruction, or trap output logic [31:0] InstrD, // The decoded instruction in Decode stage 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 @@ -100,6 +101,9 @@ module ifu import cvw::*; #(parameter cvw_t P) ( localparam [31:0] nop = 32'h00000013; // instruction for NOP logic [P.XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4 + logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF + logic [P.XLEN-1:0] PC2NextF; // Selected PC between branch prediction and next valid PC if CSRWriteFence + logic [P.XLEN-1:0] UnalignedPCNextF; // The next PCF, but not aligned to 2 bytes. logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) logic [P.XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed) logic [P.XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill @@ -128,7 +132,6 @@ module ifu import cvw::*; #(parameter cvw_t P) ( logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation logic GatedStallD; // StallD gated by selected next spill // branch predictor signal - logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF logic BusCommittedF; // Bus memory operation in flight, delay interrupts logic CacheCommittedF; // I$ memory operation started, delay interrupts logic SelIROM; // PMA indicates instruction address is in the IROM @@ -300,20 +303,23 @@ module ifu import cvw::*; #(parameter cvw_t P) ( mux2 #(P.XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF)); else assign PC2NextF = PC1NextF; + mux3 #(P.XLEN) pcmux3(PC2NextF, EPCM, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF); mux2 #(P.XLEN) pcresetmux({UnalignedPCNextF[P.XLEN-1:1], 1'b0}, P.RESET_VECTOR[P.XLEN-1:0], reset, PCNextF); flopen #(P.XLEN) pcreg(clk, ~StallF | reset, PCNextF, PCF); // pcadder // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32 assign PCPlus4F = PCF[P.XLEN-1:2] + 1; // add 4 to PC - // choose PC+2 or PC+4 based on CompressedF, which arrives later. - // Speeds up critical path as compared to selecting adder input based on CompressedF - always_comb - if (CompressedF) // add 2 - if (PCF[1]) PCPlus2or4F = {PCPlus4F, 2'b00}; - else PCPlus2or4F = {PCF[P.XLEN-1:2], 2'b10}; - else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4 + if (P.COMPRESSED_SUPPORTED) + // choose PC+2 or PC+4 based on CompressedF, which arrives later. + // Speeds up critical path as compared to selecting adder input based on CompressedF + always_comb + if (CompressedF) // add 2 + if (PCF[1]) PCPlus2or4F = {PCPlus4F, 2'b00}; + else PCPlus2or4F = {PCF[P.XLEN-1:2], 2'b10}; + else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4 + else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // always add 4 if compressed instructions are not supported //////////////////////////////////////////////////////////////////////////////////////////////// // Branch and Jump Predictor diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index c687b0f1d..edb27155c 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -34,7 +34,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( input logic StallE, StallM, StallW, 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, PC2NextF, // program counter, next PC going to trap/return logic + input logic [P.XLEN-1:0] PCM, // program counter, next PC going to trap/return logic input logic [P.XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring @@ -86,9 +86,11 @@ module csr import cvw::*; #(parameter cvw_t P) ( output logic [3:0] ENVCFG_CBE, output logic ENVCFG_PBMTE, // Page-based memory type enable output logic ENVCFG_ADUE, // HPTW A/D Update enable + // PC logic output from privileged unit to IFU + output logic [P.XLEN-1:0] EPCM, // Exception Program counter to IFU PC logic + output logic [P.XLEN-1:0] TrapVectorM, // Trap vector, to IFU PC logic // output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR - output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level output logic BigEndianM // memory access is big-endian based on privilege mode and STATUS register endian fields ); @@ -117,10 +119,8 @@ module csr import cvw::*; #(parameter cvw_t P) ( logic IllegalCSRMWriteReadonlyM; logic [P.XLEN-1:0] CSRReadVal2M; logic [11:0] MIP_REGW_writeable; - logic [P.XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM; + logic [P.XLEN-1:0] TVecM,NextFaultMtvalM; logic MTrapM, STrapM; - logic [P.XLEN-1:0] EPC; - logic RetM; logic SelMtvecM; logic [P.XLEN-1:0] TVecAlignedM; logic InstrValidNotFlushedM; @@ -168,9 +168,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( // Trap Returns // A trap sets the PC to TrapVector // A return sets the PC to MEPC or SEPC - assign RetM = mretM | sretM; - mux2 #(P.XLEN) epcmux(SEPC_REGW, MEPC_REGW, mretM, EPC); - mux3 #(P.XLEN) pcmux3(PC2NextF, EPC, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF); + mux2 #(P.XLEN) epcmux(SEPC_REGW, MEPC_REGW, mretM, EPCM); /////////////////////////////////////////// // CSRWriteValM diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index 9a4027571..a5bfde1cf 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -38,7 +38,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( input logic STATUS_TSR, STATUS_TVM, STATUS_TW, // status bits output logic IllegalInstrFaultM, // Illegal instruction output logic EcallFaultM, BreakpointFaultM, // Ecall or breakpoint; must retire, so don't flush it when the trap occurs - output logic sretM, mretM, // return instructions + output logic sretM, mretM, RetM, // return instructions output logic wfiM, wfiW, sfencevmaM // wfi / sfence.vma / sinval.vma instructions ); @@ -66,6 +66,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & rs1zeroM & P.S_SUPPORTED & (PrivilegeModeW == P.M_MODE | PrivilegeModeW == P.S_MODE & ~STATUS_TSR); assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) & rs1zeroM & (PrivilegeModeW == P.M_MODE); + assign RetM = sretM | mretM; assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000) & rs1zeroM; assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001) & rs1zeroM; assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101) & rs1zeroM; diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index b7d443fdd..4c27df006 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -37,7 +37,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( input logic [31:0] InstrM, // Instruction input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [P.XLEN-1:0] IEUAdrM, // address from IEU - input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic + input logic [P.XLEN-1:0] PCM, // 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 @@ -85,8 +85,9 @@ module privileged import cvw::*; #(parameter cvw_t P) ( output logic [3:0] ENVCFG_CBE, // Cache block operation enables output logic ENVCFG_PBMTE, // Page-based memory type enable output logic ENVCFG_ADUE, // HPTW A/D Update enable - // PC logic output in privileged unit - output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic + // PC logic output from privileged unit to IFU + output logic [P.XLEN-1:0] EPCM, // Exception Program counter to IFU PC logic + output logic [P.XLEN-1:0] TrapVectorM, // Trap vector, to IFU PC logic // control outputs output logic RetM, TrapM, // return instruction, or trap output logic sfencevmaM, // sfence.vma instruction @@ -125,11 +126,11 @@ module privileged import cvw::*; #(parameter cvw_t P) ( privdec #(P) pmd(.clk, .reset, .StallW, .FlushW, .InstrM(InstrM[31:15]), .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, - .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .wfiW, .sfencevmaM); + .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .RetM, .wfiM, .wfiW, .sfencevmaM); // Control and Status Registers csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, - .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF, + .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, @@ -142,7 +143,8 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .MEDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, - .CSRReadValW,.UnalignedPCNextF, .IllegalCSRAccessM, .BigEndianM); + .EPCM, .TrapVectorM, + .CSRReadValW, .IllegalCSRAccessM, .BigEndianM); // pipeline early-arriving trap sources privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, @@ -154,9 +156,8 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .InstrMisalignedFaultM, .InstrAccessFaultM, .HPTWInstrAccessFaultM, .IllegalInstrFaultM, .BreakpointFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .LoadAccessFaultM, .StoreAmoAccessFaultM, .EcallFaultM, .InstrPageFaultM, - .LoadPageFaultM, .StoreAmoPageFaultM, - .mretM, .sretM, .PrivilegeModeW, + .LoadPageFaultM, .StoreAmoPageFaultM, .PrivilegeModeW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .InstrValidM, .CommittedM, .CommittedF, - .TrapM, .RetM, .wfiM, .wfiW, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); + .TrapM, .wfiM, .wfiW, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); endmodule diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index bec22a92b..4209d0ced 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -32,7 +32,6 @@ module trap import cvw::*; #(parameter cvw_t P) ( input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM, input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM, input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources - input logic mretM, sretM, // return instructions input logic wfiM, wfiW, // wait for interrupt instruction input logic [1:0] PrivilegeModeW, // current privilege mode input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs @@ -41,7 +40,6 @@ module trap import cvw::*; #(parameter cvw_t P) ( input logic InstrValidM, // current instruction is valid, not flushed input logic CommittedM, CommittedF, // LSU/IFU has committed to a bus operation that can't be interrupted output logic TrapM, // Trap is occurring - output logic RetM, // Return instruction being executed output logic InterruptM, // Interrupt is occurring output logic ExceptionM, // exception is occurring output logic IntPendingM, // Interrupt is pending, might occur if enabled @@ -74,7 +72,7 @@ module trap import cvw::*; #(parameter cvw_t P) ( (PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE); /////////////////////////////////////////// - // Trigger Traps and RET + // Trigger Traps // According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous. // Traps are the union of exceptions and interrupts. /////////////////////////////////////////// @@ -89,7 +87,6 @@ module trap import cvw::*; #(parameter cvw_t P) ( LoadAccessFaultM | StoreAmoAccessFaultM; // coverage on assign TrapM = (ExceptionM & ~CommittedF) | InterruptM; // *** RT: review this additional ~CommittedF with DH and update priv chapter. - assign RetM = mretM | sretM; /////////////////////////////////////////// // Cause priority defined in privileged spec diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index e637e4327..f861a08bc 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -48,8 +48,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic StallF, StallD, StallE, StallM, StallW; logic FlushD, FlushE, FlushM, FlushW; - logic RetM; - logic TrapM; + logic TrapM, RetM; // signals that must connect through DP logic IntDivE, W64E; @@ -63,7 +62,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE; logic [P.XLEN-1:0] PCM; logic [P.XLEN-1:0] CSRReadValW, MDUResultW; - logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF; + logic [P.XLEN-1:0] EPCM, TrapVectorM; logic [1:0] MemRWE; logic [1:0] MemRWM; logic InstrValidD, InstrValidE, InstrValidM; @@ -173,13 +172,13 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .InstrValidE, .InstrValidD, .BranchD, .BranchE, .JumpD, .JumpE, .ICacheStallF, // Fetch - .HRDATA, .PCSpillF, .IFUHADDR, .PC2NextF, + .HRDATA, .PCSpillF, .IFUHADDR, .IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE, .ICacheAccess, .ICacheMiss, // Execute .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPWrongE, .BPWrongM, // Mem - .CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM, + .CommittedF, .EPCM, .TrapVectorM, .RetM, .TrapM, .InvalidateICacheM, .CSRWriteFenceM, .InstrD, .InstrM, .InstrOrigM, .PCM, .InstrClassM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, // Faults out @@ -281,8 +280,8 @@ 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, .PC2NextF, - .InstrM, .InstrOrigM, .CSRReadValW, .UnalignedPCNextF, + .CSRReadM, .CSRWriteM, .SrcAM, .PCM, + .InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM, .RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF, .InstrValidM, .CommittedM, .CommittedF, .FRegWriteM, .LoadStallD, .StoreStallD, @@ -301,7 +300,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM); end else begin assign CSRReadValW = 0; - assign UnalignedPCNextF = PC2NextF; + assign EPCM = 0; + assign TrapVectorM = 0; assign RetM = 0; assign TrapM = 0; assign wfiM = 0;