Files
chipyard/generators/utilities/src/main/scala/Subsystem.scala
2019-10-07 17:27:47 -07:00

108 lines
4.1 KiB
Scala

//******************************************************************************
// 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"))
}