diff --git a/pipelined/src/privileged/privileged.sv b/pipelined/src/privileged/privileged.sv index 43e2f8f0..a65039bf 100644 --- a/pipelined/src/privileged/privileged.sv +++ b/pipelined/src/privileged/privileged.sv @@ -99,13 +99,14 @@ module privileged ( logic STATUS_MIE, STATUS_SIE; logic [11:0] MIP_REGW, MIE_REGW; logic [1:0] NextPrivilegeModeM; + logic DelegateM; /////////////////////////////////////////// // track the current privilege level /////////////////////////////////////////// - privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .InterruptM, .CauseM, - .MEDELEG_REGW, .MIDELEG_REGW, .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); + privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM, + .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); /////////////////////////////////////////// // decode privileged instructions @@ -158,11 +159,11 @@ module privileged ( .LoadPageFaultM, .StoreAmoPageFaultM, .mretM, .sretM, .PrivilegeModeW, - .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, + .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .InstrValidM, .CommittedM, .TrapM, .RetM, - .InterruptM, .IntPendingM, + .InterruptM, .IntPendingM, .DelegateM, .CauseM); endmodule diff --git a/pipelined/src/privileged/privmode.sv b/pipelined/src/privileged/privmode.sv index 9446c08c..768d8a36 100644 --- a/pipelined/src/privileged/privmode.sv +++ b/pipelined/src/privileged/privmode.sv @@ -33,25 +33,18 @@ module privmode ( input logic clk, reset, - input logic StallW, TrapM, mretM, sretM, InterruptM, - input logic [`LOG_XLEN-1:0] CauseM, - input logic [`XLEN-1:0] MEDELEG_REGW, - input logic [11:0] MIDELEG_REGW, + input logic StallW, TrapM, mretM, sretM, + input logic DelegateM, input logic [1:0] STATUS_MPP, input logic STATUS_SPP, output logic [1:0] NextPrivilegeModeM, PrivilegeModeW ); if (`U_SUPPORTED) begin:privmode - logic md; - - // get bits of DELEG registers based on CAUSE - assign md = InterruptM ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM]; - // PrivilegeMode FSM always_comb begin if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8) - if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE)) + if (`S_SUPPORTED & DelegateM) NextPrivilegeModeM = `S_MODE; else NextPrivilegeModeM = `M_MODE; end else if (mretM) NextPrivilegeModeM = STATUS_MPP; diff --git a/pipelined/src/privileged/trap.sv b/pipelined/src/privileged/trap.sv index 6225b9c0..7bee52a0 100644 --- a/pipelined/src/privileged/trap.sv +++ b/pipelined/src/privileged/trap.sv @@ -39,11 +39,12 @@ module trap ( (* mark_debug = "true" *) input logic LoadPageFaultM, StoreAmoPageFaultM, (* mark_debug = "true" *) input logic mretM, sretM, input logic [1:0] PrivilegeModeW, - (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, + (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, + input logic [`XLEN-1:0] MEDELEG_REGW, input logic STATUS_MIE, STATUS_SIE, input logic InstrValidM, CommittedM, output logic TrapM, RetM, - output logic InterruptM, IntPendingM, + output logic InterruptM, IntPendingM, DelegateM, output logic [`LOG_XLEN-1:0] CauseM ); @@ -63,6 +64,8 @@ module trap ( assign IntPendingM = |PendingIntsM; assign ValidIntsM = {12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW; assign InterruptM = (|ValidIntsM) && InstrValidM && ~(CommittedM); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide. + assign DelegateM = (InterruptM ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM]) & + (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE); /////////////////////////////////////////// // Trigger Traps and RET