diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index f36dbdc0..106dac84 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -20,6 +20,7 @@ case class RocketTileParams( dataScratchpadBytes: Int = 0, boundaryBuffers: Boolean = false, trace: Boolean = false, + hcfOnUncorrectable: Boolean = false, name: Option[String] = Some("tile"), externalMasterBuffers: Int = 0, externalSlaveBuffers: Int = 0) extends TileParams { @@ -131,6 +132,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p class RocketTileBundle(outer: RocketTile) extends BaseTileBundle(outer) with HasExternalInterruptsBundle with CanHaveScratchpadBundle + with CanHaltAndCatchFire class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => new RocketTileBundle(outer)) with HasExternalInterruptsModule @@ -138,9 +140,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne with CanHaveScratchpadModule { val core = Module(p(BuildCore)(outer.p)) + val uncorrectable = RegInit(Bool(false)) + decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector core.io.hartid := io.hartid // Pass through the hartid io.trace.foreach { _ := core.io.trace } + io.halt_and_catch_fire := (if(outer.rocketParams.hcfOnUncorrectable) uncorrectable else false.B) outer.frontend.module.io.cpu <> core.io.imem outer.frontend.module.io.reset_vector := io.reset_vector outer.frontend.module.io.hartid := io.hartid @@ -154,6 +159,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne core.io.rocc.busy := roccCore.busy core.io.rocc.interrupt := roccCore.interrupt + when(!uncorrectable) { uncorrectable := + List(outer.frontend.module.io.errors, outer.dcache.module.io.errors) + .flatMap { e => e.uncorrectable.map(_.valid) } + .reduceOption(_||_) + .getOrElse(false.B) + } // TODO eliminate this redundancy val h = dcachePorts.size @@ -207,7 +218,10 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: } lazy val module = new LazyModuleImp(this) { - val io = new CoreBundle with HasExternallyDrivenTileConstants with CanHaveInstructionTracePort { + val io = new CoreBundle + with HasExternallyDrivenTileConstants + with CanHaveInstructionTracePort + with CanHaltAndCatchFire { val master = masterNode.bundleOut val slave = slaveNode.bundleIn val outputInterrupts = intOutputNode.map(_.bundleOut) @@ -219,6 +233,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: rocket.module.io.hartid := io.hartid rocket.module.io.reset_vector := io.reset_vector io.trace.foreach { _ := rocket.module.io.trace.get } + io.halt_and_catch_fire := rocket.module.io.halt_and_catch_fire } } diff --git a/src/main/scala/util/Misc.scala b/src/main/scala/util/Misc.scala index 16fb4f98..39469330 100644 --- a/src/main/scala/util/Misc.scala +++ b/src/main/scala/util/Misc.scala @@ -26,6 +26,10 @@ trait Clocked extends Bundle { val reset = Bool() } +trait CanHaltAndCatchFire extends Bundle { + val halt_and_catch_fire = Bool(OUTPUT) +} + object DecoupledHelper { def apply(rvs: Bool*) = new DecoupledHelper(rvs) }