1
0
rocket-chip/src/main/scala/coreplex/RocketTiles.scala
2017-03-21 11:16:51 -07:00

118 lines
4.2 KiB
Scala

// See LICENSE.SiFive for license details.
package coreplex
import Chisel._
import config._
import diplomacy._
import rocket._
import tile._
import uncore.tilelink2._
sealed trait ClockCrossing
case object Synchronous extends ClockCrossing
case object Rational extends ClockCrossing
case class Asynchronous(depth: Int, sync: Int = 2) extends ClockCrossing
case object RocketTilesKey extends Field[Seq[RocketTileParams]]
case object RocketCrossing extends Field[ClockCrossing]
trait HasRocketTiles extends CoreplexRISCVPlatform {
val module: HasRocketTilesModule
private val crossing = p(RocketCrossing)
private val configs = p(RocketTilesKey)
// TODO: hack to fix deduplication; see PR https://github.com/ucb-bar/berkeley-hardfloat/pull/14
hardfloat.consts
val rocketWires: Seq[HasRocketTilesBundle => Unit] = configs.zipWithIndex.map { case (c, i) =>
val pWithExtra = p.alterPartial {
case TileKey => c
case BuildRoCC => c.rocc
case SharedMemoryTLEdge => l1tol2.node.edgesIn(0)
case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits
}
// Hack debug interrupt into a node (future debug module should use diplomacy)
val debugNode = IntInternalInputNode(IntSourcePortSimple())
val intBar = LazyModule(new IntXbar)
intBar.intnode := debugNode
intBar.intnode := clint.intnode // msip+mtip
intBar.intnode := plic.intnode // meip
if (c.core.useVM) intBar.intnode := plic.intnode // seip
crossing match {
case Synchronous => {
val tile = LazyModule(new RocketTile(c, i)(pWithExtra))
val buffer = LazyModule(new TLBuffer)
val fixer = LazyModule(new TLFIFOFixer)
buffer.node :=* tile.masterNode
fixer.node :=* buffer.node
l1tol2.node :=* fixer.node
tile.slaveNode :*= cbus.node
tile.intNode := intBar.intnode
(io: HasRocketTilesBundle) => {
// leave clock as default (simpler for hierarchical PnR)
tile.module.io.hartid := UInt(i)
tile.module.io.resetVector := io.resetVector
debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i)
}
}
case Asynchronous(depth, sync) => {
val wrapper = LazyModule(new AsyncRocketTile(c, i)(pWithExtra))
val sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
val source = LazyModule(new TLAsyncCrossingSource(sync))
val fixer = LazyModule(new TLFIFOFixer)
sink.node :=* wrapper.masterNode
fixer.node :=* sink.node
l1tol2.node :=* fixer.node
wrapper.slaveNode :*= source.node
wrapper.intNode := intBar.intnode
source.node :*= cbus.node
(io: HasRocketTilesBundle) => {
wrapper.module.clock := io.tcrs(i).clock
wrapper.module.reset := io.tcrs(i).reset
wrapper.module.io.hartid := UInt(i)
wrapper.module.io.resetVector := io.resetVector
debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i)
}
}
case Rational => {
val wrapper = LazyModule(new RationalRocketTile(c, i)(pWithExtra))
val sink = LazyModule(new TLRationalCrossingSink(util.FastToSlow))
val source = LazyModule(new TLRationalCrossingSource)
val fixer = LazyModule(new TLFIFOFixer)
sink.node :=* wrapper.masterNode
fixer.node :=* sink.node
l1tol2.node :=* fixer.node
wrapper.slaveNode :*= source.node
wrapper.intNode := intBar.intnode
source.node :*= cbus.node
(io: HasRocketTilesBundle) => {
wrapper.module.clock := io.tcrs(i).clock
wrapper.module.reset := io.tcrs(i).reset
wrapper.module.io.hartid := UInt(i)
wrapper.module.io.resetVector := io.resetVector
debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i)
}
}
}
}
}
trait HasRocketTilesBundle extends CoreplexRISCVPlatformBundle {
val outer: HasRocketTiles
val tcrs = Vec(p(RocketTilesKey).size, new Bundle {
val clock = Clock(INPUT)
val reset = Bool(INPUT)
})
}
trait HasRocketTilesModule extends CoreplexRISCVPlatformModule {
val outer: HasRocketTiles
val io: HasRocketTilesBundle
outer.rocketWires.foreach { _(io) }
}