From 56cc04316c01d7f1e2a8a41c6ec7e401fa870626 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 2 Oct 2022 16:21:21 -0500 Subject: [PATCH] Fixed a very subtle bug in the trap handler. It was possible to select the wrong cause if an interrupt was pending, but it was supressed by Committed and another exception triggered. --- pipelined/src/privileged/trap.sv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pipelined/src/privileged/trap.sv b/pipelined/src/privileged/trap.sv index 2c3c0f21e..039944919 100644 --- a/pipelined/src/privileged/trap.sv +++ b/pipelined/src/privileged/trap.sv @@ -50,6 +50,8 @@ module trap ( logic MIntGlobalEnM, SIntGlobalEnM; logic ExceptionM; + logic Committed; + (* mark_debug = "true" *) logic [11:0] PendingIntsM, ValidIntsM; /////////////////////////////////////////// @@ -62,8 +64,9 @@ module trap ( assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9 assign PendingIntsM = MIP_REGW & MIE_REGW; assign IntPendingM = |PendingIntsM; - assign ValidIntsM = {12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW; - assign InterruptM = (|ValidIntsM) && InstrValidM && ~(CommittedM | CommittedF); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide. + assign Committed = CommittedM | CommittedF; + assign ValidIntsM = {12{~Committed}} & ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); + assign InterruptM = (|ValidIntsM) && InstrValidM && ~Committed; // suppress interrupt if the memory system has partially processed a request. assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE);