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 d1ef3b8981
commit 2935188035
3 changed files with 13 additions and 16 deletions

View File

@ -99,13 +99,14 @@ module privileged (
logic STATUS_MIE, STATUS_SIE; logic STATUS_MIE, STATUS_SIE;
logic [11:0] MIP_REGW, MIE_REGW; logic [11:0] MIP_REGW, MIE_REGW;
logic [1:0] NextPrivilegeModeM; logic [1:0] NextPrivilegeModeM;
logic DelegateM;
/////////////////////////////////////////// ///////////////////////////////////////////
// track the current privilege level // track the current privilege level
/////////////////////////////////////////// ///////////////////////////////////////////
privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .InterruptM, .CauseM, privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,
.MEDELEG_REGW, .MIDELEG_REGW, .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
/////////////////////////////////////////// ///////////////////////////////////////////
// decode privileged instructions // decode privileged instructions
@ -158,11 +159,11 @@ module privileged (
.LoadPageFaultM, .StoreAmoPageFaultM, .LoadPageFaultM, .StoreAmoPageFaultM,
.mretM, .sretM, .mretM, .sretM,
.PrivilegeModeW, .PrivilegeModeW,
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MIE, .STATUS_SIE,
.InstrValidM, .CommittedM, .InstrValidM, .CommittedM,
.TrapM, .RetM, .TrapM, .RetM,
.InterruptM, .IntPendingM, .InterruptM, .IntPendingM, .DelegateM,
.CauseM); .CauseM);
endmodule endmodule

View File

@ -33,25 +33,18 @@
module privmode ( module privmode (
input logic clk, reset, input logic clk, reset,
input logic StallW, TrapM, mretM, sretM, InterruptM, input logic StallW, TrapM, mretM, sretM,
input logic [`LOG_XLEN-1:0] CauseM, input logic DelegateM,
input logic [`XLEN-1:0] MEDELEG_REGW,
input logic [11:0] MIDELEG_REGW,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic STATUS_SPP, input logic STATUS_SPP,
output logic [1:0] NextPrivilegeModeM, PrivilegeModeW output logic [1:0] NextPrivilegeModeM, PrivilegeModeW
); );
if (`U_SUPPORTED) begin:privmode 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 // PrivilegeMode FSM
always_comb begin always_comb begin
if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8) 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; NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE; else NextPrivilegeModeM = `M_MODE;
end else if (mretM) NextPrivilegeModeM = STATUS_MPP; end else if (mretM) NextPrivilegeModeM = STATUS_MPP;

View File

@ -40,10 +40,11 @@ module trap (
(* mark_debug = "true" *) input logic mretM, sretM, (* mark_debug = "true" *) input logic mretM, sretM,
input logic [1:0] PrivilegeModeW, 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 STATUS_MIE, STATUS_SIE,
input logic InstrValidM, CommittedM, input logic InstrValidM, CommittedM,
output logic TrapM, RetM, output logic TrapM, RetM,
output logic InterruptM, IntPendingM, output logic InterruptM, IntPendingM, DelegateM,
output logic [`LOG_XLEN-1:0] CauseM output logic [`LOG_XLEN-1:0] CauseM
); );
@ -63,6 +64,8 @@ module trap (
assign IntPendingM = |PendingIntsM; assign IntPendingM = |PendingIntsM;
assign ValidIntsM = {12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW; 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 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 // Trigger Traps and RET