1
0
Fork 0

Use correct interrupt priority order

This commit is contained in:
Andrew Waterman 2017-04-21 18:01:32 -07:00 committed by Andrew Waterman
parent bf861293d9
commit c36c171202
2 changed files with 20 additions and 4 deletions

View File

@ -300,10 +300,10 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
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 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 interruptCause = UInt(interruptMSB) + PriorityEncoder(all_interrupts)
io.interrupt := all_interrupts.orR && !reg_debug && !io.singleStep || reg_singleStepped
val interruptCause = UInt(interruptMSB) + whichInterrupt
io.interrupt := anyInterrupt && !reg_debug && !io.singleStep || reg_singleStepped
io.interrupt_cause := interruptCause
io.bp := reg_bp take nBreakpoints
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) =
(Mux(cmd.isOneOf(CSR.S, CSR.C), rdata, UInt(0)) | wdata) & ~Mux(cmd === CSR.C, wdata, UInt(0))

View File

@ -38,9 +38,17 @@ package object util {
implicit def wcToUInt(c: WideCounter): UInt = c.value
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
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 = {
if (hi == lo-1) UInt(0)