From c36c171202aedc1c78568aa234c1751a23e23be2 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 21 Apr 2017 18:01:32 -0700 Subject: [PATCH] Use correct interrupt priority order --- src/main/scala/rocket/CSR.scala | 14 +++++++++++--- src/main/scala/util/Package.scala | 10 +++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 1ec4db24..661cb1b8 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -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)) diff --git a/src/main/scala/util/Package.scala b/src/main/scala/util/Package.scala index d0983c40..85667677 100644 --- a/src/main/scala/util/Package.scala +++ b/src/main/scala/util/Package.scala @@ -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)