// See LICENSE.SiFive for license details. // See LICENSE.Berkeley for license details. package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config._ import freechips.rocketchip.coreplex.CoreplexClockCrossing import freechips.rocketchip.diplomacy._ import freechips.rocketchip.rocket._ import freechips.rocketchip.util._ case class RocketTileParams( core: RocketCoreParams = RocketCoreParams(), icache: Option[ICacheParams] = Some(ICacheParams()), dcache: Option[DCacheParams] = Some(DCacheParams()), rocc: Seq[RoCCParams] = Nil, btb: Option[BTBParams] = Some(BTBParams()), dataScratchpadBytes: Int = 0, trace: Boolean = false, hcfOnUncorrectable: Boolean = false, name: Option[String] = Some("tile"), hartId: Int = 0, blockerCtrlAddr: Option[BigInt] = None, boundaryBuffers: Boolean = false // if synthesized with hierarchical PnR, cut feed-throughs? ) extends TileParams { require(icache.isDefined) require(dcache.isDefined) } class RocketTile( val rocketParams: RocketTileParams, crossing: CoreplexClockCrossing) (implicit p: Parameters) extends BaseTile(rocketParams, crossing)(p) with HasExternalInterrupts with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache with CanHaveScratchpad { // implies CanHavePTW with HasHellaCache with HasICacheFrontend nDCachePorts += 1 // core TODO dcachePorts += () => module.core.io.dmem ?? val dtimProperty = scratch.map(d => Map( "sifive,dtim" -> d.device.asProperty)).getOrElse(Nil) val itimProperty = tileParams.icache.flatMap(_.itimAddr.map(i => Map( "sifive,itim" -> frontend.icache.device.asProperty))).getOrElse(Nil) val cpuDevice = new Device { def describe(resources: ResourceBindings): Description = toDescription(resources)("sifive,rocket0", dtimProperty ++ itimProperty) } ResourceBinding { Resource(cpuDevice, "reg").bind(ResourceInt(BigInt(hartId))) } override lazy val module = new RocketTileModule(this) } class RocketTileBundle(outer: RocketTile) extends BaseTileBundle(outer) with CanHaltAndCatchFire { val halt_and_catch_fire = outer.rocketParams.hcfOnUncorrectable.option(Bool(OUTPUT)) } class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => new RocketTileBundle(outer)) with HasLazyRoCCModule with CanHaveScratchpadModule { val core = Module(p(BuildCore)(outer.p)) val uncorrectable = RegInit(Bool(false)) outer.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 io.trace.foreach { _ := core.io.trace } io.halt_and_catch_fire.foreach { _ := uncorrectable } outer.frontend.module.io.cpu <> core.io.imem outer.frontend.module.io.reset_vector := io.reset_vector outer.frontend.module.io.hartid := io.hartid outer.dcache.module.io.hartid := io.hartid dcachePorts += core.io.dmem // TODO outer.dcachePorts += () => module.core.io.dmem ?? fpuOpt foreach { fpu => core.io.fpu <> fpu.io } core.io.ptw <> ptw.io.dpath roccCore.cmd <> core.io.rocc.cmd roccCore.exception := core.io.rocc.exception core.io.rocc.resp <> roccCore.resp 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 val c = core.dcacheArbPorts val o = outer.nDCachePorts require(h == c, s"port list size was $h, core expected $c") require(h == o, s"port list size was $h, outer counted $o") // TODO figure out how to move the below into their respective mix-ins dcacheArb.io.requestor <> dcachePorts ptw.io.requestor <> ptwPorts }