//****************************************************************************** // Copyright (c) 2019 - 2019, The Regents of the University of California (Regents). // All Rights Reserved. See LICENSE and LICENSE.SiFive for license details. //------------------------------------------------------------------------------ package utilities import chisel3._ import chisel3.internal.sourceinfo.{SourceInfo} import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomaticobjectmodel.model.{OMInterrupt} import freechips.rocketchip.diplomaticobjectmodel.logicaltree.{RocketTileLogicalTreeNode, LogicalModuleTree} import freechips.rocketchip.tile._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ import freechips.rocketchip.subsystem._ import freechips.rocketchip.amba.axi4._ import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} trait HasBoomAndRocketTiles extends HasTiles with CanHavePeripheryPLIC with CanHavePeripheryCLINT with HasPeripheryDebug { this: BaseSubsystem => val module: HasBoomAndRocketTilesModuleImp protected val rocketTileParams = p(RocketTilesKey) protected val boomTileParams = p(BoomTilesKey) // crossing can either be per tile or global (aka only 1 crossing specified) private val rocketCrossings = perTileOrGlobalSetting(p(RocketCrossingKey), rocketTileParams.size) private val boomCrossings = perTileOrGlobalSetting(p(BoomCrossingKey), boomTileParams.size) val allTilesInfo = (rocketTileParams ++ boomTileParams) zip (rocketCrossings ++ boomCrossings) // Make a tile and wire its nodes into the system, // according to the specified type of clock crossing. // Note that we also inject new nodes into the tile itself, // also based on the crossing type. // This MUST be performed in order of hartid // There is something weird with registering tile-local interrupt controllers to the CLINT. // TODO: investigate why val tiles = allTilesInfo.sortWith(_._1.hartId < _._1.hartId).map { case (param, crossing) => { val (tile, rocketLogicalTree) = param match { case r: RocketTileParams => { val t = LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) (t, t.rocketLogicalTree) } case b: BoomTileParams => { val t = LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) (t, t.rocketLogicalTree) // TODO FIX rocketLogicalTree is not a member of the superclass, both child classes define it separately } } connectMasterPortsToSBus(tile, crossing) connectSlavePortsToCBus(tile, crossing) def treeNode: RocketTileLogicalTreeNode = new RocketTileLogicalTreeNode(rocketLogicalTree.getOMInterruptTargets) LogicalModuleTree.add(logicalTreeNode, rocketLogicalTree) connectInterrupts(tile, Some(debug), clintOpt, plicOpt) tile } } def coreMonitorBundles = tiles.map { case r: RocketTile => r.module.core.rocketImpl.coreMonitorBundle case b: BoomTile => b.module.core.coreMonitorBundle }.toList } trait HasBoomAndRocketTilesModuleImp extends HasTilesModuleImp with HasPeripheryDebugModuleImp { val outer: HasBoomAndRocketTiles } class Subsystem(implicit p: Parameters) extends BaseSubsystem with HasBoomAndRocketTiles { override lazy val module = new SubsystemModuleImp(this) def getOMInterruptDevice(resourceBindingsMap: ResourceBindingsMap): Seq[OMInterrupt] = Nil } class SubsystemModuleImp[+L <: Subsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) with HasResetVectorWire with HasBoomAndRocketTilesModuleImp { tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) => wire.hartid := i.U wire.reset_vector := global_reset_vector } // create file with boom params ElaborationArtefacts.add("""core.config""", outer.tiles.map(x => x.module.toString).mkString("\n")) }