From 06209c417fb93568ee1ea6e5b2752c776bea5d02 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 28 Jan 2022 13:19:24 -0600 Subject: [PATCH] Cleaned up the InstrMisalignedFault. --- pipelined/src/ifu/ifu.sv | 23 ++++++++++------------- pipelined/src/privileged/trap.sv | 15 +++------------ 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 16505782..2c5ced40 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -85,7 +85,7 @@ module ifu ( ); (* mark_debug = "true" *) logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; - logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; + logic BranchMisalignedFaultE; logic PrivilegedChangePCM; logic IllegalCompInstrD; logic [`XLEN-1:0] PCPlus2or4F, PCLinkD; @@ -401,22 +401,19 @@ module ifu ( // Misaligned PC logic + // Instruction address misalignement only from br/jal(r) instructions. // instruction address misalignment is generated by the target of control flow instructions, not // the fetch itself. - assign misaligned = PCNextF[0] | (PCNextF[1] & ~`C_SUPPORTED); - // do we really need to have check if the instruction is control flow? Yes - // Branches are updated in the execution stage but traps are updated in the memory stage. - - // pipeline misaligned faults to M stage - assign BranchMisalignedFaultE = misaligned & PCSrcE; // E-stage (Branch/Jump) misaligned - flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, BranchMisalignedFaultM); + // xret and Traps both cannot produce instruction misaligned. + // xret: mepc is an MXLEN-bit read/write register formatted as shown in Figure 3.21. + // The low bit of mepc (mepc[0]) is always zero. On implementations that support + // only IALIGN=32, the two low bits (mepc[1:0]) are always zero. + // Spec 3.1.14 + // Traps: Can’t happen. The bottom two bits of MTVEC are ignored so the trap always is to a multiple of 4. See 3.1.7 of the privileged spec. + assign BranchMisalignedFaultE = (IEUAdrE[1] & ~`C_SUPPORTED) & PCSrcE; + flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM); // *** Ross Thompson. Check InstrMisalignedAdrM as I believe it is the same as PCF. Should be able to remove. flopenr #(`XLEN) InstrMisalignedAdrReg(clk, reset, ~StallM, PCNextF, InstrMisalignedAdrM); - assign TrapMisalignedFaultM = misaligned & PrivilegedChangePCM; - assign InstrMisalignedFaultM = BranchMisalignedFaultM; // | TrapMisalignedFaultM; *** put this back in without causing a cyclic path - // *** likely leave TrapMisalignedFaultM out of here. Don't implement full spec because - // *** it seems silly to have a misaligned trap handler and it adds to the critical path. - // ***later revisit more detail // Instruction and PC/PCLink pipeline registers flopenr #(32) InstrEReg(clk, reset, ~StallE, FlushE ? nop : InstrD, InstrE); diff --git a/pipelined/src/privileged/trap.sv b/pipelined/src/privileged/trap.sv index d3876915..be38baaf 100644 --- a/pipelined/src/privileged/trap.sv +++ b/pipelined/src/privileged/trap.sv @@ -72,25 +72,16 @@ module trap ( assign PendingIntsM = ((MIP_REGW & MIE_REGW) & ({12{MIntGlobalEnM}} & 12'h888)) | ((SIP_REGW & SIE_REGW) & ({12{SIntGlobalEnM}} & 12'h222)); assign PendingInterruptM = (|PendingIntsM) & InstrValidM; assign InterruptM = PendingInterruptM & ~(CommittedM); // *** RT. temporary hack to prevent integer division from having an interrupt during divide. - // ideally this should be disabled for all but the first cycle. However I'm not familar with the internals of the integer divider. This should (could) be an issue for - // floating point and integer multiply. - //assign ExceptionM = TrapM; - assign ExceptionM = Exception1M; - // *** as of 7/17/21, the system passes with this definition of ExceptionM as being all traps and fails if ExceptionM = Exception1M - // with no interrupts. However, Ross intended the datacache to use Exception without interrupts, so there is something subtle - // to sort out here. - // *** as of 8/13/21, switching to Exception1M does not seem to cause any failures. It's possible the bug was - // fixed inadvertantly as the dcache was debugged. - + // Trigger Traps and RET // 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. - assign Exception1M = InstrMisalignedFaultM | InstrAccessFaultM | IllegalInstrFaultM | + assign ExceptionM = InstrMisalignedFaultM | InstrAccessFaultM | IllegalInstrFaultM | LoadMisalignedFaultM | StoreAmoMisalignedFaultM | InstrPageFaultM | LoadPageFaultM | StoreAmoPageFaultM | BreakpointFaultM | EcallFaultM | LoadAccessFaultM | StoreAmoAccessFaultM; - assign TrapM = Exception1M | InterruptM; // *** clean this up later DH + assign TrapM = ExceptionM | InterruptM; // *** clean this up later DH assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE); assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED; assign UTrapM = TrapM & (NextPrivilegeModeM == `U_MODE) & `N_SUPPORTED;