Moved delegation logic from privmode to trap to simplify interface

This commit is contained in:
David Harris 2022-05-31 14:58:11 +00:00
parent 0cfe9e3373
commit 788fe406b5
3 changed files with 13 additions and 16 deletions

View File

@ -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

View File

@ -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;

View File

@ -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