mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-06-28 09:16:22 -04:00
csr_regfile: Fix irq/ex delegation in RVH (#2689)
In RVH, interrupts are currently delegated if hxdeleg is set but mxdeleg is not, violating the spec ("A trap/irq *that has been delegated to HS-mode (using mxdeleg)* is further delegated to VS-mode if the corresponding hxdeleg bit is set"). Fix and simplify the corresponding logic.
This commit is contained in:
parent
bca4e1544f
commit
e55f25d23c
1 changed files with 10 additions and 24 deletions
|
@ -1791,38 +1791,24 @@ module csr_regfile
|
|||
// a m-mode trap might be delegated if we are taking it in S mode
|
||||
// first figure out if this was an exception or an interrupt e.g.: look at bit (XLEN-1)
|
||||
// the cause register can only be $clog2(CVA6Cfg.XLEN) bits long (as we only support XLEN exceptions)
|
||||
if (CVA6Cfg.RVH) begin
|
||||
if (CVA6Cfg.RVS) begin
|
||||
if ((ex_i.cause[CVA6Cfg.XLEN-1] && mideleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]] && ~hideleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && medeleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]] && ~hedeleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]])) begin
|
||||
// traps never transition from a more-privileged mode to a less privileged mode
|
||||
// so if we are already in M mode, stay there
|
||||
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
|
||||
end else if ((ex_i.cause[CVA6Cfg.XLEN-1] && hideleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && hedeleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]])) begin
|
||||
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
|
||||
// trap to VS only if it is the currently active mode
|
||||
trap_to_v = v_q;
|
||||
end
|
||||
end else begin
|
||||
if (CVA6Cfg.RVS) begin
|
||||
if ((ex_i.cause[CVA6Cfg.XLEN-1] && mideleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && medeleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]])) begin
|
||||
// traps never transition from a more-privileged mode to a less privileged mode
|
||||
// so if we are already in M mode, stay there
|
||||
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
|
||||
if (CVA6Cfg.RVH) begin
|
||||
if ((ex_i.cause[CVA6Cfg.XLEN-1] && hideleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && hedeleg_q[ex_i.cause[$clog2(
|
||||
CVA6Cfg.XLEN
|
||||
)-1:0]])) begin
|
||||
// trap to VS only if it is the currently active mode
|
||||
trap_to_v = v_q;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue