1
0

Generate local interrupt #128 on bus errors

It doesn't have a correpsonding bit in mip/mie, so it isn't individually
maskable, nor is it delegable.
This commit is contained in:
Andrew Waterman 2017-11-06 16:54:21 -08:00
parent ac096a89e7
commit be3a3e0187
3 changed files with 19 additions and 11 deletions

View File

@ -121,6 +121,7 @@ object CSR
def R = UInt(5,SZ) def R = UInt(5,SZ)
val ADDRSZ = 12 val ADDRSZ = 12
def busErrorIntCause = 128
def debugIntCause = 14 // keep in sync with MIP.debug def debugIntCause = 14 // keep in sync with MIP.debug
def debugTriggerCause = { def debugTriggerCause = {
val res = debugIntCause val res = debugIntCause
@ -156,7 +157,7 @@ class TracedInstruction(implicit p: Parameters) extends CoreBundle {
val priv = UInt(width = 3) val priv = UInt(width = 3)
val exception = Bool() val exception = Bool()
val interrupt = Bool() val interrupt = Bool()
val cause = UInt(width = log2Ceil(xLen)) val cause = UInt(width = log2Ceil(1 + CSR.busErrorIntCause))
val tval = UInt(width = coreMaxAddrBits max iLen) val tval = UInt(width = coreMaxAddrBits max iLen)
} }
@ -172,7 +173,7 @@ class CSRDecodeIO extends Bundle {
class CSRFileIO(implicit p: Parameters) extends CoreBundle class CSRFileIO(implicit p: Parameters) extends CoreBundle
with HasCoreParameters { with HasCoreParameters {
val interrupts = new TileInterrupts().asInput val interrupts = new CoreInterrupts().asInput
val hartid = UInt(INPUT, hartIdLen) val hartid = UInt(INPUT, hartIdLen)
val rw = new Bundle { val rw = new Bundle {
val addr = UInt(INPUT, CSR.ADDRSZ) val addr = UInt(INPUT, CSR.ADDRSZ)
@ -244,13 +245,14 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
sup.debug := false sup.debug := false
sup.zero2 := false sup.zero2 := false
sup.lip foreach { _ := true } sup.lip foreach { _ := true }
val supported_high_interrupts = if (io.interrupts.buserror.nonEmpty) UInt(BigInt(1) << CSR.busErrorIntCause) else 0.U
val del = Wire(init=sup) val del = Wire(init=sup)
del.msip := false del.msip := false
del.mtip := false del.mtip := false
del.meip := false del.meip := false
(sup.asUInt, del.asUInt) (sup.asUInt | supported_high_interrupts, del.asUInt)
} }
val delegable_exceptions = UInt(Seq( val delegable_exceptions = UInt(Seq(
Causes.misaligned_fetch, Causes.misaligned_fetch,
@ -313,10 +315,11 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
io.interrupts.seip.foreach { mip.seip := reg_mip.seip || RegNext(_) } io.interrupts.seip.foreach { mip.seip := reg_mip.seip || RegNext(_) }
mip.rocc := io.rocc_interrupt mip.rocc := io.rocc_interrupt
val read_mip = mip.asUInt & supported_interrupts val read_mip = mip.asUInt & supported_interrupts
val high_interrupts = io.interrupts.buserror.map(_ << CSR.busErrorIntCause).getOrElse(0.U)
val pending_interrupts = read_mip & reg_mie val pending_interrupts = high_interrupts | (read_mip & reg_mie)
val d_interrupts = io.interrupts.debug << CSR.debugIntCause val d_interrupts = io.interrupts.debug << CSR.debugIntCause
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.mie, ~(~pending_interrupts | reg_mideleg), UInt(0))
val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0)) val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0))
val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts, d_interrupts)) val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts, d_interrupts))
val interruptMSB = BigInt(1) << (xLen-1) val interruptMSB = BigInt(1) << (xLen-1)
@ -633,7 +636,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata } when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata }
if (mtvecWritable) if (mtvecWritable)
when (decoded_addr(CSRs.mtvec)) { reg_mtvec := ~(~wdata | 2.U | Mux(wdata(0), UInt(((BigInt(1) << mtvecInterruptAlign) - 1) << mtvecBaseAlign), 0.U)) } when (decoded_addr(CSRs.mtvec)) { reg_mtvec := ~(~wdata | 2.U | Mux(wdata(0), UInt(((BigInt(1) << mtvecInterruptAlign) - 1) << mtvecBaseAlign), 0.U)) }
when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ } when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + (BigInt(1) << whichInterrupt.getWidth) - 1) }
when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) } when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) }
for (((e, c), i) <- (reg_hpmevent zip reg_hpmcounter) zipWithIndex) { for (((e, c), i) <- (reg_hpmevent zip reg_hpmcounter) zipWithIndex) {
@ -778,14 +781,14 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
t.tval := badaddr_value t.tval := badaddr_value
} }
def chooseInterrupt(masks: Seq[UInt]): (Bool, UInt) = { def chooseInterrupt(masksIn: Seq[UInt]): (Bool, UInt) = {
val nonstandard = supported_interrupts.getWidth-1 to 12 by -1 val nonstandard = supported_interrupts.getWidth-1 to 12 by -1
// MEI, MSI, MTI, SEI, SSI, STI, UEI, USI, UTI // MEI, MSI, MTI, SEI, SSI, STI, UEI, USI, UTI
val standard = Seq(11, 3, 7, 9, 1, 5, 8, 0, 4) val standard = Seq(11, 3, 7, 9, 1, 5, 8, 0, 4)
val priority = nonstandard ++ standard val priority = nonstandard ++ standard
val paddedMasks = masks.reverse.map(_.padTo(xLen)) val masks = masksIn.reverse
val any = paddedMasks.flatMap(m => priority.map(i => m(i))).reduce(_||_) val any = masks.flatMap(m => priority.filter(_ < m.getWidth).map(i => m(i))).reduce(_||_)
val which = PriorityMux(paddedMasks.flatMap(m => priority.map(i => (m(i), i.U)))) val which = PriorityMux(masks.flatMap(m => priority.filter(_ < m.getWidth).map(i => (m(i), i.U))))
(any, which) (any, which)
} }

View File

@ -81,10 +81,14 @@ abstract class CoreModule(implicit val p: Parameters) extends Module
abstract class CoreBundle(implicit val p: Parameters) extends ParameterizedBundle()(p) abstract class CoreBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
with HasCoreParameters with HasCoreParameters
class CoreInterrupts(implicit p: Parameters) extends TileInterrupts()(p) {
val buserror = coreParams.tileControlAddr.map(a => Bool())
}
trait HasCoreIO extends HasTileParameters { trait HasCoreIO extends HasTileParameters {
implicit val p: Parameters implicit val p: Parameters
val io = new CoreBundle()(p) with HasExternallyDrivenTileConstants { val io = new CoreBundle()(p) with HasExternallyDrivenTileConstants {
val interrupts = new TileInterrupts().asInput val interrupts = new CoreInterrupts().asInput
val imem = new FrontendIO val imem = new FrontendIO
val dmem = new HellaCacheIO val dmem = new HellaCacheIO
val ptw = new DatapathPTWIO().flip val ptw = new DatapathPTWIO().flip

View File

@ -150,6 +150,7 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
val uncorrectable = RegInit(Bool(false)) val uncorrectable = RegInit(Bool(false))
decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector
outer.busErrorUnit.foreach { beu => core.io.interrupts.buserror.get := beu.module.io.interrupt }
core.io.hartid := io.hartid // Pass through the hartid core.io.hartid := io.hartid // Pass through the hartid
io.trace.foreach { _ := core.io.trace } io.trace.foreach { _ := core.io.trace }
io.halt_and_catch_fire.foreach { _ := uncorrectable } io.halt_and_catch_fire.foreach { _ := uncorrectable }