Use correct interrupt priority order
This commit is contained in:
parent
bf861293d9
commit
c36c171202
@ -300,10 +300,10 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
val pending_interrupts = read_mip & reg_mie
|
val pending_interrupts = read_mip & reg_mie
|
||||||
val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0))
|
val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0))
|
||||||
val s_interrupts = Mux(m_interrupts === 0 && (reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie)), pending_interrupts & reg_mideleg, UInt(0))
|
val s_interrupts = Mux(m_interrupts === 0 && (reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie)), pending_interrupts & reg_mideleg, UInt(0))
|
||||||
val all_interrupts = m_interrupts | s_interrupts
|
val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts))
|
||||||
val interruptMSB = BigInt(1) << (xLen-1)
|
val interruptMSB = BigInt(1) << (xLen-1)
|
||||||
val interruptCause = UInt(interruptMSB) + PriorityEncoder(all_interrupts)
|
val interruptCause = UInt(interruptMSB) + whichInterrupt
|
||||||
io.interrupt := all_interrupts.orR && !reg_debug && !io.singleStep || reg_singleStepped
|
io.interrupt := anyInterrupt && !reg_debug && !io.singleStep || reg_singleStepped
|
||||||
io.interrupt_cause := interruptCause
|
io.interrupt_cause := interruptCause
|
||||||
io.bp := reg_bp take nBreakpoints
|
io.bp := reg_bp take nBreakpoints
|
||||||
io.pmp := reg_pmp.map(PMP(_))
|
io.pmp := reg_pmp.map(PMP(_))
|
||||||
@ -758,6 +758,14 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def chooseInterrupt(masks: Seq[UInt]) = {
|
||||||
|
// we can't simply choose the highest-numbered interrupt, because timer
|
||||||
|
// interrupts are in the wrong place in mip.
|
||||||
|
val timerMask = UInt(0xF0, xLen)
|
||||||
|
val masked = masks.map(m => Cat(m.padTo(xLen) & ~timerMask, m.padTo(xLen) & timerMask))
|
||||||
|
(masks.map(_.orR).reduce(_||_), Log2(masked.asUInt)(log2Ceil(xLen)-1, 0))
|
||||||
|
}
|
||||||
|
|
||||||
def readModifyWriteCSR(cmd: UInt, rdata: UInt, wdata: UInt) =
|
def readModifyWriteCSR(cmd: UInt, rdata: UInt, wdata: UInt) =
|
||||||
(Mux(cmd.isOneOf(CSR.S, CSR.C), rdata, UInt(0)) | wdata) & ~Mux(cmd === CSR.C, wdata, UInt(0))
|
(Mux(cmd.isOneOf(CSR.S, CSR.C), rdata, UInt(0)) | wdata) & ~Mux(cmd === CSR.C, wdata, UInt(0))
|
||||||
|
|
||||||
|
@ -38,9 +38,17 @@ package object util {
|
|||||||
implicit def wcToUInt(c: WideCounter): UInt = c.value
|
implicit def wcToUInt(c: WideCounter): UInt = c.value
|
||||||
|
|
||||||
implicit class UIntToAugmentedUInt(val x: UInt) extends AnyVal {
|
implicit class UIntToAugmentedUInt(val x: UInt) extends AnyVal {
|
||||||
def sextTo(n: Int): UInt =
|
def sextTo(n: Int): UInt = {
|
||||||
|
require(x.getWidth <= n)
|
||||||
if (x.getWidth == n) x
|
if (x.getWidth == n) x
|
||||||
else Cat(Fill(n - x.getWidth, x(x.getWidth-1)), x)
|
else Cat(Fill(n - x.getWidth, x(x.getWidth-1)), x)
|
||||||
|
}
|
||||||
|
|
||||||
|
def padTo(n: Int): UInt = {
|
||||||
|
require(x.getWidth <= n)
|
||||||
|
if (x.getWidth == n) x
|
||||||
|
else Cat(UInt(0, n - x.getWidth), x)
|
||||||
|
}
|
||||||
|
|
||||||
def extract(hi: Int, lo: Int): UInt = {
|
def extract(hi: Int, lo: Int): UInt = {
|
||||||
if (hi == lo-1) UInt(0)
|
if (hi == lo-1) UInt(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user