diff --git a/src/main/scala/coreplex/FrontBus.scala b/src/main/scala/coreplex/FrontBus.scala new file mode 100644 index 00000000..e51732a0 --- /dev/null +++ b/src/main/scala/coreplex/FrontBus.scala @@ -0,0 +1,60 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +case class FrontBusParams( + beatBytes: Int, + blockBytes: Int, + masterBuffering: BufferParams = BufferParams.default, + slaveBuffering: BufferParams = BufferParams.default +) extends TLBusParams + +case object FrontBusParams extends Field[FrontBusParams] + +class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "FrontBus") { + + private val master_buffer = LazyModule(new TLBuffer(params.masterBuffering)) + private val master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) + + master_buffer.suggestName(s"${busName}_master_TLBuffer") + master_fixer.suggestName(s"${busName}_master_TLFIFOFixer") + + master_fixer.node :=* master_buffer.node + inwardNode :=* master_fixer.node + + def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = { + val (in, out) = bufferChain(addBuffers, name) + master_buffer.node :=* out + in + } + + def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = { + val (in, out) = bufferChain(addBuffers, name) + master_buffer.node :=* out + in + } + + def fromCoherentChip: TLInwardNode = inwardNode + + def toSystemBus : TLOutwardNode = outwardBufNode + +} + +/** Provides buses that serve as attachment points, + * for use in traits that connect individual devices or external ports. + */ +trait HasFrontBus extends HasSystemBus { + private val frontbusParams = p(FrontBusParams) + val frontbusBeatBytes = frontbusParams.beatBytes + + val fbus = new FrontBus(frontbusParams) + + sbus.fromFrontBus := fbus.toSystemBus + +} diff --git a/src/main/scala/coreplex/MemoryBus.scala b/src/main/scala/coreplex/MemoryBus.scala index d71507ba..277b54c3 100644 --- a/src/main/scala/coreplex/MemoryBus.scala +++ b/src/main/scala/coreplex/MemoryBus.scala @@ -43,9 +43,7 @@ case class MemoryBusParams( case object MemoryBusParams extends Field[MemoryBusParams] /** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */ -class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params)(p) { - xbar.suggestName("MemoryBus") - +class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p) { def fromCoherenceManager: TLInwardNode = inwardBufNode def toDRAMController: TLOutwardNode = outwardBufNode def toVariableWidthSlave: TLOutwardNode = outwardFragNode diff --git a/src/main/scala/coreplex/PeripheryBus.scala b/src/main/scala/coreplex/PeripheryBus.scala index 02d098c2..04ec0338 100644 --- a/src/main/scala/coreplex/PeripheryBus.scala +++ b/src/main/scala/coreplex/PeripheryBus.scala @@ -21,8 +21,7 @@ case class PeripheryBusParams( case object PeripheryBusParams extends Field[PeripheryBusParams] -class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params) { - xbar.suggestName("PeripheryBus") +class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus") { def toFixedWidthSingleBeatSlave(widthBytes: Int) = { TLFragmenter(widthBytes, params.blockBytes)(outwardWWNode) @@ -49,5 +48,5 @@ trait HasPeripheryBus extends HasSystemBus { val pbus = new PeripheryBus(pbusParams) // The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL - pbus.fromSystemBus := sbus.toPeripheryBus + pbus.fromSystemBus := sbus.toPeripheryBus() } diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index a30cdad5..d1e7fd0c 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -35,34 +35,34 @@ trait HasRocketTiles extends HasSystemBus // Make a wrapper for each tile that will wire it to coreplex devices and crossbars, // according to the specified type of clock crossing. val wiringTuple = localIntNodes.zip(tileParams).zipWithIndex - val rocket_tiles: Seq[RocketTileWrapper] = wiringTuple.map { case ((lip, c), i) => + val rocket_tiles: Seq[RocketTileWrapper] = wiringTuple.map { case ((lip, tp), i) => val pWithExtra = p.alterPartial { - case TileKey => c - case BuildRoCC => c.rocc + case TileKey => tp + case BuildRoCC => tp.rocc case SharedMemoryTLEdge => sharedMemoryTLEdge } val wrapper = crossing match { case SynchronousCrossing(params) => { - val wrapper = LazyModule(new SyncRocketTile(c, i)(pWithExtra)) - sbus.fromSyncTiles(params) :=* wrapper.masterNode + val wrapper = LazyModule(new SyncRocketTile(tp, i)(pWithExtra)) + sbus.fromSyncTiles(params, tp.externalBuffers, tp.name) :=* wrapper.masterNode wrapper.slaveNode :*= pbus.bufferToSlaves wrapper } case AsynchronousCrossing(depth, sync) => { - val wrapper = LazyModule(new AsyncRocketTile(c, i)(pWithExtra)) - sbus.fromAsyncTiles(depth, sync) :=* wrapper.masterNode - wrapper.slaveNode :*= pbus.toAsyncSlaves(sync) + val wrapper = LazyModule(new AsyncRocketTile(tp, i)(pWithExtra)) + sbus.fromAsyncTiles(depth, sync, tp.externalBuffers, tp.name) :=* wrapper.masterNode + wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name) wrapper } case RationalCrossing(direction) => { - val wrapper = LazyModule(new RationalRocketTile(c, i)(pWithExtra)) - sbus.fromRationalTiles(direction) :=* wrapper.masterNode - wrapper.slaveNode :*= pbus.toRationalSlaves + val wrapper = LazyModule(new RationalRocketTile(tp, i)(pWithExtra)) + sbus.fromRationalTiles(direction, tp.externalBuffers, tp.name) :=* wrapper.masterNode + wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name) wrapper } } - wrapper.suggestName("tile") // Try to stabilize this name for downstream tools + tp.name.foreach(wrapper.suggestName) // Try to stabilize this name for downstream tools // Local Interrupts must be synchronized to the core clock // before being passed into this module. @@ -77,7 +77,7 @@ trait HasRocketTiles extends HasSystemBus val periphIntXbar = LazyModule(new IntXbar) periphIntXbar.intnode := clint.intnode // msip+mtip periphIntXbar.intnode := plic.intnode // meip - if (c.core.useVM) periphIntXbar.intnode := plic.intnode // seip + if (tp.core.useVM) periphIntXbar.intnode := plic.intnode // seip wrapper.periphIntNode := periphIntXbar.intnode val coreIntXbar = LazyModule(new IntXbar) diff --git a/src/main/scala/coreplex/SystemBus.scala b/src/main/scala/coreplex/SystemBus.scala index 30cd999c..94db58db 100644 --- a/src/main/scala/coreplex/SystemBus.scala +++ b/src/main/scala/coreplex/SystemBus.scala @@ -12,15 +12,15 @@ case class SystemBusParams( beatBytes: Int, blockBytes: Int, masterBuffering: BufferParams = BufferParams.default, - slaveBuffering: BufferParams = BufferParams.flow // TODO should be BufferParams.none on BCE + slaveBuffering: BufferParams = BufferParams.default ) extends TLBusParams case object SystemBusParams extends Field[SystemBusParams] -class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params) { - xbar.suggestName("SystemBus") +class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus") { private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks + master_splitter.suggestName(s"${busName}_master_TLSplitter") inwardNode :=* master_splitter.node def busView = master_splitter.node.edgesIn.head @@ -28,13 +28,24 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr protected def outwardSplitNode: TLOutwardNode = master_splitter.node private val tile_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable)) - private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) + tile_fixer.suggestName(s"${busName}_tile_TLFIFOFixer") master_splitter.node :=* tile_fixer.node + + private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) + port_fixer.suggestName(s"${busName}_port_TLFIFOFixer") master_splitter.node :=* port_fixer.node + private val pbus_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) + pbus_fixer.suggestName(s"${busName}_pbus_TLFIFOFixer") + pbus_fixer.node :*= outwardWWNode + def toSplitSlaves: TLOutwardNode = outwardSplitNode - val toPeripheryBus: TLOutwardNode = outwardWWNode + def toPeripheryBus(addBuffers: Int = 0): TLOutwardNode = { + val (in, out) = bufferChain(addBuffers, name = Some("pbus")) + in := pbus_fixer.node + out + } val toMemoryBus: TLOutwardNode = outwardNode @@ -42,27 +53,41 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr def fromCoherentChip: TLInwardNode = inwardNode - def fromSyncTiles(params: BufferParams): TLInwardNode = { - val buf = LazyModule(new TLBuffer(params)) - tile_fixer.node :=* buf.node - buf.node + def fromFrontBus: TLInwardNode = master_splitter.node + + def fromSyncTiles(params: BufferParams, addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = { + val tile_buf = LazyModule(new TLBuffer(params)) + name.foreach { n => tile_buf.suggestName(s"${busName}_${n}_TLBuffer") } + val (in, out) = bufferChain(addBuffers, name = name) + + tile_fixer.node :=* out + in :=* tile_buf.node + tile_buf.node } - def fromRationalTiles(dir: RationalDirection): TLRationalInwardNode = { - val sink = LazyModule(new TLRationalCrossingSink(direction = dir)) - tile_fixer.node :=* sink.node - sink.node + def fromRationalTiles(dir: RationalDirection, addBuffers: Int = 0, name: Option[String] = None): TLRationalInwardNode = { + val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir)) + name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") } + val (in, out) = bufferChain(addBuffers, name = name) + + tile_fixer.node :=* out + in :=* tile_sink.node + tile_sink.node } - def fromAsyncTiles(depth: Int, sync: Int): TLAsyncInwardNode = { - val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) - tile_fixer.node :=* sink.node - sink.node + def fromAsyncTiles(depth: Int, sync: Int, addBuffers: Int = 0, name: Option[String] = None): TLAsyncInwardNode = { + val tile_sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) + name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLAsyncCrossingSink") } + val (in, out) = bufferChain(addBuffers, name = name) + + tile_fixer.node :=* out + in :=* tile_sink.node + tile_sink.node } def fromSyncPorts(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = { val buffer = LazyModule(new TLBuffer(params)) - name.foreach{ n => buffer.suggestName(s"${n}_TLBuffer") } + name.foreach { n => buffer.suggestName(s"${busName}_${n}_TLBuffer") } port_fixer.node :=* buffer.node buffer.node } @@ -71,21 +96,23 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr fromSyncPorts(params, name) } - def fromAsyncPorts(depth: Int = 8, sync: Int = 3): TLAsyncInwardNode = { + def fromAsyncPorts(depth: Int = 8, sync: Int = 3, name : Option[String] = None): TLAsyncInwardNode = { val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) + name.foreach { n => sink.suggestName(s"${busName}_${n}_TLAsyncCrossingSink") } port_fixer.node :=* sink.node sink.node } - def fromAsyncFIFOMaster(depth: Int = 8, sync: Int = 3): TLAsyncInwardNode = fromAsyncPorts(depth, sync) + def fromAsyncFIFOMaster(depth: Int = 8, sync: Int = 3, name: Option[String] = None): TLAsyncInwardNode = fromAsyncPorts(depth, sync, name) - def fromRationalPorts(dir: RationalDirection): TLRationalInwardNode = { + def fromRationalPorts(dir: RationalDirection, name: Option[String] = None): TLRationalInwardNode = { val sink = LazyModule(new TLRationalCrossingSink(dir)) + name.foreach{ n => sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") } port_fixer.node :=* sink.node sink.node } - def fromRationalFIFOMaster(dir: RationalDirection): TLRationalInwardNode = fromRationalPorts(dir) + def fromRationalFIFOMaster(dir: RationalDirection, name: Option[String] = None): TLRationalInwardNode = fromRationalPorts(dir, name) } /** Provides buses that serve as attachment points, diff --git a/src/main/scala/devices/tilelink/Error.scala b/src/main/scala/devices/tilelink/Error.scala index bc43b4ff..d054922e 100644 --- a/src/main/scala/devices/tilelink/Error.scala +++ b/src/main/scala/devices/tilelink/Error.scala @@ -97,5 +97,5 @@ trait HasSystemErrorSlave extends HasSystemBus { private val params = p(ErrorParams) val error = LazyModule(new TLError(params, sbus.beatBytes)) - error.node := TLBuffer(BufferParams.pipe)(sbus.toSlave) + error.node := sbus.toSlave } diff --git a/src/main/scala/diplomacy/Parameters.scala b/src/main/scala/diplomacy/Parameters.scala index a16f70aa..f7273e6a 100644 --- a/src/main/scala/diplomacy/Parameters.scala +++ b/src/main/scala/diplomacy/Parameters.scala @@ -279,6 +279,9 @@ case class BufferParams(depth: Int, flow: Boolean, pipe: Boolean) sq.io.enq <> x sq.io.deq } + + override def toString() = "BufferParams:%d%s%s".format(depth, if (flow) "F" else "", if (pipe) "P" else "") + } object BufferParams diff --git a/src/main/scala/jtag/JtagTap.scala b/src/main/scala/jtag/JtagTap.scala index 8470e9d9..78468582 100644 --- a/src/main/scala/jtag/JtagTap.scala +++ b/src/main/scala/jtag/JtagTap.scala @@ -100,7 +100,7 @@ class JtagTapController(irLength: Int, initialInstruction: BigInt) extends Modul val nextActiveInstruction = Wire(UInt(irLength.W)) val activeInstruction = NegativeEdgeLatch(clock, nextActiveInstruction, updateInstruction, name = Some("irReg")) // 7.2.1d active instruction output latches on TCK falling edge - when (reset) { + when (reset.toBool) { nextActiveInstruction := initialInstruction.U(irLength.W) updateInstruction := true.B } .elsewhen (currState === JtagState.UpdateIR.U) { diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 3490b6c9..4b2ff7ca 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -18,7 +18,9 @@ case class RocketTileParams( rocc: Seq[RoCCParams] = Nil, btb: Option[BTBParams] = Some(BTBParams()), dataScratchpadBytes: Int = 0, - boundaryBuffers: Boolean = false) extends TileParams { + boundaryBuffers: Boolean = false, + name: Option[String] = Some("tile"), + externalBuffers: Int = 0) extends TileParams { require(icache.isDefined) require(dcache.isDefined) } diff --git a/src/main/scala/tilelink/Buffer.scala b/src/main/scala/tilelink/Buffer.scala index 9a741ab3..3a8869de 100644 --- a/src/main/scala/tilelink/Buffer.scala +++ b/src/main/scala/tilelink/Buffer.scala @@ -8,6 +8,19 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import scala.math.{min,max} +class TLBufferNode ( + a: BufferParams, + b: BufferParams, + c: BufferParams, + d: BufferParams, + e: BufferParams)(implicit p: Parameters) extends TLAdapterNode( + clientFn = { p => p.copy(minLatency = p.minLatency + b.latency + c.latency) }, + managerFn = { p => p.copy(minLatency = p.minLatency + a.latency + d.latency) } +) { + override lazy val nodedebugstring = s"a:${a.toString}, b:${b.toString}, c:${c.toString}, d:${d.toString}, e:${e.toString}" + +} + class TLBuffer( a: BufferParams, b: BufferParams, @@ -19,9 +32,7 @@ class TLBuffer( def this(abcde: BufferParams)(implicit p: Parameters) = this(abcde, abcde) def this()(implicit p: Parameters) = this(BufferParams.default) - val node = TLAdapterNode( - clientFn = { p => p.copy(minLatency = p.minLatency + b.latency + c.latency) }, - managerFn = { p => p.copy(minLatency = p.minLatency + a.latency + d.latency) }) + val node = new TLBufferNode(a, b, c, d, e) lazy val module = new LazyModuleImp(this) { val io = new Bundle { @@ -66,3 +77,28 @@ object TLBuffer buffer.node } } + +class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule { + + val nodeIn = TLInputNode() + val nodeOut = TLOutputNode() + + val buf_chain = if (depth > 0) { + val chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default))) + + (chain.init zip chain.tail) foreach { case(prev, next) => next.node :=* prev.node } + chain + } else { + List(LazyModule(new TLBuffer(BufferParams.none))) + } + + buf_chain.head.node :=* nodeIn + nodeOut :=* buf_chain.last.node + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = nodeIn.bundleIn + val out = nodeOut.bundleOut + } + } +} diff --git a/src/main/scala/tilelink/Bus.scala b/src/main/scala/tilelink/Bus.scala index 9d72ad7c..d9a7f364 100644 --- a/src/main/scala/tilelink/Bus.scala +++ b/src/main/scala/tilelink/Bus.scala @@ -21,7 +21,8 @@ trait TLBusParams { def blockOffset: Int = log2Up(blockBytes) } -abstract class TLBusWrapper(params: TLBusParams)(implicit p: Parameters) extends TLBusParams { +abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p: Parameters) extends TLBusParams { + val beatBytes = params.beatBytes val blockBytes = params.blockBytes val masterBuffering = params.masterBuffering @@ -30,10 +31,17 @@ abstract class TLBusWrapper(params: TLBusParams)(implicit p: Parameters) extends private val delayProb = p(TLBusDelayProbability) protected val xbar = LazyModule(new TLXbar) + xbar.suggestName(busName) + private val master_buffer = LazyModule(new TLBuffer(masterBuffering)) + master_buffer.suggestName(s"${busName}_master_TLBuffer") private val slave_buffer = LazyModule(new TLBuffer(slaveBuffering)) + slave_buffer.suggestName(s"${busName}_slave_TLBuffer") private val slave_frag = LazyModule(new TLFragmenter(beatBytes, blockBytes)) + slave_frag.suggestName(s"${busName}_slave_TLFragmenter") + private val slave_ww = LazyModule(new TLWidthWidget(beatBytes)) + slave_ww.suggestName(s"${busName}_slave_TLWidthWidget") private val delayedNode = if (delayProb > 0.0) { val firstDelay = LazyModule(new TLDelayer(delayProb)) @@ -59,46 +67,58 @@ abstract class TLBusWrapper(params: TLBusParams)(implicit p: Parameters) extends protected def inwardNode: TLInwardNode = xbar.node protected def inwardBufNode: TLInwardNode = master_buffer.node + protected def bufferChain(depth: Int, name: Option[String] = None): (TLInwardNode, TLOutwardNode) = { + val chain = LazyModule(new TLBufferChain(depth)) + name.foreach { n => chain.suggestName(s"${busName}_${n}_TLBufferChain")} + (chain.nodeIn, chain.nodeOut) + } + def bufferFromMasters: TLInwardNode = inwardBufNode def bufferToSlaves: TLOutwardNode = outwardBufNode - def toAsyncSlaves(sync: Int = 3): TLAsyncOutwardNode = { + def toAsyncSlaves(sync: Int = 3, name: Option[String] = None): TLAsyncOutwardNode = { val source = LazyModule(new TLAsyncCrossingSource(sync)) + name.foreach{ n => source.suggestName(s"${busName}_${n}_TLAsyncCrossingSource")} source.node :*= outwardNode source.node } - def toRationalSlaves: TLRationalOutwardNode = { + def toRationalSlaves(name: Option[String] = None): TLRationalOutwardNode = { val source = LazyModule(new TLRationalCrossingSource()) + name.foreach{ n => source.suggestName(s"${busName}_${n}_TLRationalCrossingSource")} source.node :*= outwardNode source.node } def toVariableWidthSlaves: TLOutwardNode = outwardFragNode - def toAsyncVariableWidthSlaves(sync: Int = 3): TLAsyncOutwardNode = { + def toAsyncVariableWidthSlaves(sync: Int = 3, name: Option[String] = None): TLAsyncOutwardNode = { val source = LazyModule(new TLAsyncCrossingSource(sync)) + name.foreach {n => source.suggestName(s"${busName}_${name}_TLAsyncCrossingSource")} source.node :*= outwardFragNode source.node } - def toRationalVariableWidthSlaves: TLRationalOutwardNode = { + def toRationalVariableWidthSlaves(name: Option[String] = None): TLRationalOutwardNode = { val source = LazyModule(new TLRationalCrossingSource()) + name.foreach {n => source.suggestName(s"${busName}_${name}_TLRationalCrossingSource")} source.node :*= outwardFragNode source.node } def toFixedWidthSlaves: TLOutwardNode = outwardWWNode - def toAsyncFixedWidthSlaves(sync: Int = 3): TLAsyncOutwardNode = { + def toAsyncFixedWidthSlaves(sync: Int = 3, name: Option[String] = None): TLAsyncOutwardNode = { val source = LazyModule(new TLAsyncCrossingSource(sync)) + name.foreach { n => source.suggestName(s"${busName}_${name}_TLAsyncCrossingSource")} source.node := outwardWWNode source.node } - def toRationalFixedWidthSlaves: TLRationalOutwardNode = { + def toRationalFixedWidthSlaves(name: Option[String] = None): TLRationalOutwardNode = { val source = LazyModule(new TLRationalCrossingSource()) + name.foreach {n => source.suggestName(s"${busName}_${name}_TLRationalCrossingSource")} source.node :*= outwardWWNode source.node }