subsystem: new bus attachment api
This commit is contained in:
		| @@ -270,10 +270,6 @@ class WithJtagDTM extends Config ((site, here, up) => { | ||||
|   case IncludeJtagDTM => true | ||||
| }) | ||||
|  | ||||
| class WithNoPeripheryArithAMO extends Config ((site, here, up) => { | ||||
|   case PeripheryBusKey => up(PeripheryBusKey, site).copy(arithmetic = false) | ||||
| }) | ||||
|  | ||||
| class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => { | ||||
|   case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8) | ||||
| }) | ||||
|   | ||||
| @@ -8,38 +8,40 @@ 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 class FrontBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams | ||||
|  | ||||
| case object FrontBusKey extends Field[FrontBusParams] | ||||
|  | ||||
| class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "FrontBus") { | ||||
| class FrontBus(params: FrontBusParams, val crossing: SubsystemClockCrossing = SynchronousCrossing()) | ||||
|               (implicit p: Parameters) extends TLBusWrapper(params, "FrontBus") | ||||
|     with HasTLXbarPhy | ||||
|     with HasCrossing { | ||||
|  | ||||
|   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 = { | ||||
|     TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _) | ||||
|   def fromPort[D,U,E,B <: Data]( | ||||
|         name: Option[String] = None, | ||||
|         buffers: Int = 1) | ||||
|       (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle]): InwardNodeHandle[D,U,E,B] = { | ||||
|     from(s"Port${name.getOrElse("")}") { | ||||
|       val nodes = TLFIFOFixer(TLFIFOFixer.all) +: TLBuffer.chain(buffers) | ||||
|       inwardNode :=* nodes.reduce(_ :=* _) :=* gen | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = { | ||||
|     TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _) | ||||
|   def fromMaster(name: Option[String] = None, buffers: Int = 1) | ||||
|                 (gen: => TLNode): TLInwardNode = { | ||||
|     from(s"Master${name.getOrElse("")}") { | ||||
|       inwardNode :=* TLBuffer.chain(buffers).reduce(_ :=* _) :=* gen | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def fromCoherentChip: TLInwardNode = inwardNode | ||||
|  | ||||
|   def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node | ||||
|   def fromCoherentChip(gen: => TLNode): TLInwardNode = { | ||||
|     from("CoherentChip") { inwardNode :=* gen } | ||||
|   } | ||||
|  | ||||
|   def toSystemBus(buffer: BufferParams = BufferParams.none) | ||||
|                  (gen: => TLInwardNode) { | ||||
|     to("SystemBus") { gen :*= TLBuffer(buffer) :*= outwardNode } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** Provides buses that serve as attachment points, | ||||
| @@ -51,5 +53,7 @@ trait HasFrontBus extends HasSystemBus { | ||||
|  | ||||
|   val fbus = LazyModule(new FrontBus(frontbusParams)) | ||||
|  | ||||
|   FlipRendering { implicit p => sbus.fromFrontBus :=* fbus.toSystemBus } | ||||
|   FlipRendering { implicit p => | ||||
|     fbus.toSystemBus() { sbus.fromFrontBus { fbus.crossTLOut } } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -36,26 +36,47 @@ case class BankedL2Params( | ||||
| case object BankedL2Key extends Field(BankedL2Params()) | ||||
|  | ||||
| /** Parameterization of the memory-side bus created for each memory channel */ | ||||
| case class MemoryBusParams( | ||||
|   beatBytes: Int, | ||||
|   blockBytes: Int, | ||||
|   masterBuffering: BufferParams = BufferParams.none, | ||||
|   slaveBuffering: BufferParams = BufferParams.none | ||||
| ) extends TLBusParams | ||||
| case class MemoryBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams | ||||
|  | ||||
| case object MemoryBusKey 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, "MemoryBus")(p) { | ||||
|   def fromCoherenceManager: TLInwardNode = inwardBufNode | ||||
|   def toDRAMController: TLOutwardNode = outwardBufNode | ||||
|   def toVariableWidthSlave: TLOutwardNode = outwardFragNode | ||||
| class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p) | ||||
|     with HasTLXbarPhy { | ||||
|  | ||||
|   private def bufferTo(buffer: BufferParams): TLOutwardNode = | ||||
|     TLBuffer(buffer) :*= delayNode :*= outwardNode | ||||
|  | ||||
|   def fromCoherenceManager( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLInwardNode = { | ||||
|     from(s"CoherenceManager${name.getOrElse("")}") { | ||||
|       inwardNode :*= TLBuffer(buffer) :*= gen | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def toDRAMController[D,U,E,B <: Data]( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B]): OutwardNodeHandle[D,U,E,B] = { | ||||
|     to(s"DRAMController${name.getOrElse("")}") { gen := bufferTo(buffer) } | ||||
|   } | ||||
|  | ||||
|   def toVariableWidthSlave( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { | ||||
|       gen :*= TLFragmenter(params.beatBytes, params.blockBytes) :*= bufferTo(buffer) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus { | ||||
|   private val mbusParams = p(MemoryBusKey) | ||||
|   private val l2Params = p(BankedL2Key) | ||||
|   val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams | ||||
|   val MemoryBusParams(memBusBeatBytes, memBusBlockBytes) = mbusParams | ||||
|   val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params | ||||
|   val nBanks = l2Params.nBanks | ||||
|   val cacheBlockBytes = memBusBlockBytes | ||||
| @@ -71,8 +92,8 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu | ||||
|     val mbus = LazyModule(new MemoryBus(mbusParams)) | ||||
|     for (bank <- 0 until nBanksPerChannel) { | ||||
|       val offset = (bank * nMemoryChannels) + channel | ||||
|       ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus } | ||||
|       mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) := out | ||||
|       ForceFanout(a = true) { implicit p => sbus.toMemoryBus { in } } | ||||
|       mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out | ||||
|     } | ||||
|     mbus | ||||
|   } | ||||
|   | ||||
| @@ -7,41 +7,97 @@ import freechips.rocketchip.config.{Field, Parameters} | ||||
| import freechips.rocketchip.diplomacy._ | ||||
| import freechips.rocketchip.tilelink._ | ||||
|  | ||||
| import freechips.rocketchip.config.Field | ||||
|  | ||||
| case class PeripheryBusParams( | ||||
|   beatBytes: Int, | ||||
|   blockBytes: Int, | ||||
|   masterBuffering: BufferParams = BufferParams.default, | ||||
|   slaveBuffering: BufferParams = BufferParams.none, | ||||
|   arithmetic: Boolean = true, | ||||
|   frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency | ||||
| ) extends TLBusParams { | ||||
| } | ||||
| ) extends HasTLBusParams | ||||
|  | ||||
| case object PeripheryBusKey extends Field[PeripheryBusParams] | ||||
|  | ||||
| class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus") { | ||||
| class PeripheryBus(params: PeripheryBusParams, val crossing: SubsystemClockCrossing = SynchronousCrossing()) | ||||
|                   (implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus") | ||||
|     with HasTLXbarPhy | ||||
|     with HasCrossing { | ||||
|  | ||||
|   def toFixedWidthSingleBeatSlave(widthBytes: Int) = { | ||||
|     TLFragmenter(widthBytes, params.blockBytes) := outwardWWNode | ||||
|   private def bufferTo(buffer: BufferParams): TLOutwardNode = | ||||
|     TLBuffer(buffer) :*= delayNode :*= outwardNode | ||||
|  | ||||
|   private def fragmentTo(minSize: Int, maxSize: Int, buffer: BufferParams): TLOutwardNode = | ||||
|     TLFragmenter(minSize, maxSize) :*= bufferTo(buffer) | ||||
|  | ||||
|   private def fixedWidthTo(buffer: BufferParams): TLOutwardNode = | ||||
|     TLWidthWidget(params.beatBytes) :*= bufferTo(buffer) | ||||
|  | ||||
|   def toSlave( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { gen :*= bufferTo(buffer) } | ||||
|   } | ||||
|  | ||||
|   def toLargeBurstSlave(maxXferBytes: Int) = { | ||||
|     TLFragmenter(params.beatBytes, maxXferBytes) := outwardBufNode | ||||
|   def toVariableWidthSlave( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { | ||||
|       gen :*= fragmentTo(params.beatBytes, params.blockBytes, buffer) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   val fromSystemBus: TLInwardNode = { | ||||
|     val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic)) | ||||
|     xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node | ||||
|   def toFixedWidthSlave( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { | ||||
|       gen :*= fixedWidthTo(buffer) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) { | ||||
|     this { | ||||
|       LazyScope(s"${busName}ToTile${name.getOrElse("")}") { | ||||
|         FlipRendering { implicit p => | ||||
|           gen(p) :*= outwardNode | ||||
|         } | ||||
|   def toFixedWidthSingleBeatSlave( | ||||
|         widthBytes: Int, | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { | ||||
|       gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def toLargeBurstSlave( | ||||
|         maxXferBytes: Int, | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { | ||||
|       gen :*= fragmentTo(params.beatBytes, maxXferBytes, buffer) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def fromSystemBus( | ||||
|         arithmetic: Boolean = true, | ||||
|         buffer: BufferParams = BufferParams.default) | ||||
|       (gen: => TLOutwardNode) { | ||||
|     from("SystemBus") { | ||||
|       (inwardNode | ||||
|         :*= TLBuffer(buffer) | ||||
|         :*= TLAtomicAutomata(arithmetic = arithmetic) | ||||
|         :*= gen) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def fromOtherMaster( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.none) | ||||
|       (gen: => TLNode): TLInwardNode = { | ||||
|     from(s"OtherMaster${name.getOrElse("")}") { inwardNode :*= TLBuffer(buffer) :*= gen } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   def toTile(name: Option[String] = None)(gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Tile${name.getOrElse("")}") { | ||||
|       FlipRendering { implicit p => | ||||
|         gen :*= delayNode :*= outwardNode | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| @@ -57,5 +113,5 @@ trait HasPeripheryBus extends HasSystemBus { | ||||
|   val pbus = LazyModule(new PeripheryBus(pbusParams)) | ||||
|  | ||||
|   // The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL | ||||
|   pbus.fromSystemBus :*= sbus.toPeripheryBus() | ||||
|   pbus.fromSystemBus() { sbus.toPeripheryBus() { pbus.crossTLIn } } | ||||
| } | ||||
|   | ||||
| @@ -49,13 +49,10 @@ trait HasMasterAXI4MemPort extends HasMemoryBus { | ||||
|       beatBytes = params.beatBytes) | ||||
|   }) | ||||
|  | ||||
|   val converter = LazyModule(new TLToAXI4()) | ||||
|   val trim = LazyModule(new AXI4IdIndexer(params.idBits)) | ||||
|   val yank = LazyModule(new AXI4UserYanker) | ||||
|   val buffer = LazyModule(new AXI4Buffer) | ||||
|  | ||||
|   memBuses.map(_.toDRAMController).foreach { case node => | ||||
|     mem_axi4 := buffer.node := yank.node := trim.node := converter.node := node | ||||
|   memBuses.map { m => | ||||
|     mem_axi4 := m.toDRAMController(Some("AXI4DRAM")) { | ||||
|       (AXI4UserYanker() := AXI4IdIndexer(params.idBits) := TLToAXI4()) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -93,13 +90,13 @@ trait HasMasterAXI4MMIOPort extends HasSystemBus { | ||||
|       supportsRead  = TransferSizes(1, params.maxXferBytes))), | ||||
|     beatBytes = params.beatBytes))) | ||||
|  | ||||
|   (mmio_axi4 | ||||
|     := AXI4Buffer() | ||||
|     := AXI4UserYanker() | ||||
|     := AXI4Deinterleaver(sbus.blockBytes) | ||||
|     := AXI4IdIndexer(params.idBits) | ||||
|     := TLToAXI4() | ||||
|     := sbus.toFixedWidthPorts) | ||||
|   mmio_axi4 := sbus.toFixedWidthPort(Some("AXI4MMIO")) { | ||||
|     (AXI4Buffer() | ||||
|       := AXI4UserYanker() | ||||
|       := AXI4Deinterleaver(sbus.blockBytes) | ||||
|       := AXI4IdIndexer(params.idBits) | ||||
|       := TLToAXI4()) | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** Common io name and methods for propagating or tying off the port bundle */ | ||||
| @@ -128,13 +125,13 @@ trait HasSlaveAXI4Port extends HasSystemBus { | ||||
|       id   = IdRange(0, 1 << params.idBits)))))) | ||||
|  | ||||
|   private val fifoBits = 1 | ||||
|   (sbus.fromSyncPorts() | ||||
|     := TLWidthWidget(params.beatBytes) | ||||
|     := AXI4ToTL() | ||||
|     := AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1))) | ||||
|     := AXI4Fragmenter() | ||||
|     := AXI4IdIndexer(fifoBits) | ||||
|     := l2FrontendAXI4Node) | ||||
|   sbus.fromPort(Some("AXI4Front")) { | ||||
|     (TLWidthWidget(params.beatBytes) | ||||
|       := AXI4ToTL() | ||||
|       := AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1))) | ||||
|       := AXI4Fragmenter() | ||||
|       := AXI4IdIndexer(fifoBits)) | ||||
|   } := l2FrontendAXI4Node | ||||
| } | ||||
|  | ||||
| /** Common io name and methods for propagating or tying off the port bundle */ | ||||
| @@ -173,7 +170,9 @@ trait HasMasterTLMMIOPort extends HasSystemBus { | ||||
|       supportsPutPartial = TransferSizes(1, sbus.blockBytes))), | ||||
|     beatBytes = params.beatBytes))) | ||||
|  | ||||
|   mmio_tl := TLBuffer() := TLSourceShrinker(1 << params.idBits) := sbus.toFixedWidthPorts | ||||
|   mmio_tl := sbus.toFixedWidthPort(Some("TLMMIO")) { | ||||
|     TLBuffer() := TLSourceShrinker(1 << params.idBits) | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** Common io name and methods for propagating or tying off the port bundle */ | ||||
| @@ -208,7 +207,9 @@ trait HasSlaveTLPort extends HasSystemBus { | ||||
|       name     = "Front Port (TL)", | ||||
|       sourceId = IdRange(0, 1 << params.idBits)))))) | ||||
|  | ||||
|   sbus.fromSyncPorts() := TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes) := l2FrontendTLNode | ||||
|   sbus.fromPort(Some("TLFront")) { | ||||
|     TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes) | ||||
|   } := l2FrontendTLNode | ||||
| } | ||||
|  | ||||
| /** Common io name and methods for propagating or tying off the port bundle */ | ||||
|   | ||||
| @@ -15,19 +15,8 @@ import freechips.rocketchip.util._ | ||||
|  | ||||
| // TODO: how specific are these to RocketTiles? | ||||
| case class TileMasterPortParams( | ||||
|     addBuffers: Int = 0, | ||||
|     cork: Option[Boolean] = None) { | ||||
|  | ||||
|   def adapt(subsystem: HasPeripheryBus) | ||||
|            (masterNode: TLOutwardNode) | ||||
|            (implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = { | ||||
|     val tile_master_cork = cork.map(u => (LazyModule(new TLCacheCork(unsafe = u)))) | ||||
|     val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable)) | ||||
|  | ||||
|     (Seq(tile_master_fixer.node) ++ TLBuffer.chain(addBuffers) ++ tile_master_cork.map(_.node)) | ||||
|       .foldRight(masterNode)(_ :=* _) | ||||
|   } | ||||
| } | ||||
|     buffers: Int = 0, | ||||
|     cork: Option[Boolean] = None) | ||||
|  | ||||
| case class TileSlavePortParams( | ||||
|     addBuffers: Int = 0, | ||||
| @@ -41,9 +30,12 @@ case class TileSlavePortParams( | ||||
|         .map(BasicBusBlockerParams(_, subsystem.pbus.beatBytes, subsystem.sbus.beatBytes)) | ||||
|         .map(bp => LazyModule(new BasicBusBlocker(bp))) | ||||
|  | ||||
|     tile_slave_blocker.foreach { _.controlNode := subsystem.pbus.toVariableWidthSlaves } | ||||
|     tile_slave_blocker.foreach { b => | ||||
|       subsystem.pbus.toVariableWidthSlave(Some("TileSlavePortBusBlocker")) { b.controlNode } | ||||
|     } | ||||
|  | ||||
|     (Seq() ++ tile_slave_blocker.map(_.node) ++ TLBuffer.chain(addBuffers)) | ||||
|     .foldLeft(slaveNode)(_ :*= _) | ||||
|       .foldLeft(slaveNode)(_ :*= _) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -111,7 +103,9 @@ trait HasRocketTiles extends HasTiles | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(rocket.crossTLOut :=* tileMasterBuffering) } | ||||
|     sbus.fromTile(tp.name, crossing.master.buffers, crossing.master.cork) { | ||||
|       rocket.crossTLOut | ||||
|     } :=* tileMasterBuffering | ||||
|  | ||||
|     // Connect the slave ports of the tile to the periphery bus | ||||
|  | ||||
| @@ -123,9 +117,9 @@ trait HasRocketTiles extends HasTiles | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)( DisableMonitors { implicit p => | ||||
|       tileSlaveBuffering :*= rocket.crossTLIn | ||||
|     })} | ||||
|     DisableMonitors { implicit p => | ||||
|       tileSlaveBuffering :*= pbus.toTile(tp.name) { rocket.crossTLIn } | ||||
|     } | ||||
|  | ||||
|     // Handle all the different types of interrupts crossing to or from the tile: | ||||
|     // 1. Debug interrupt is definitely asynchronous in all cases. | ||||
|   | ||||
| @@ -8,65 +8,94 @@ import freechips.rocketchip.diplomacy._ | ||||
| import freechips.rocketchip.tilelink._ | ||||
| import freechips.rocketchip.util._ | ||||
|  | ||||
| case class SystemBusParams( | ||||
|   beatBytes: Int, | ||||
|   blockBytes: Int, | ||||
|   masterBuffering: BufferParams = BufferParams.default, | ||||
|   slaveBuffering: BufferParams = BufferParams.default | ||||
| ) extends TLBusParams | ||||
| case class SystemBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams | ||||
|  | ||||
| case object SystemBusKey extends Field[SystemBusParams] | ||||
|  | ||||
| class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus") { | ||||
| class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus") | ||||
|     with HasTLXbarPhy { | ||||
|  | ||||
|   private val master_splitter = LazyModule(new TLSplitter)  // Allows cycle-free connection to external networks | ||||
|   master_splitter.suggestName(s"${busName}_master_TLSplitter") | ||||
|   private val master_splitter = LazyModule(new TLSplitter) | ||||
|   inwardNode :=* master_splitter.node | ||||
|  | ||||
|   def busView = master_splitter.node.edges.in.head | ||||
|  | ||||
|   protected def inwardSplitNode: TLInwardNode = master_splitter.node | ||||
|   protected def outwardSplitNode: TLOutwardNode = master_splitter.node | ||||
|   private def bufferTo(buffer: BufferParams): TLOutwardNode = | ||||
|     TLBuffer(buffer) :*= delayNode :*= outwardNode | ||||
|  | ||||
|  | ||||
|   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 | ||||
|  | ||||
|   def toPeripheryBus(addBuffers: Int = 0): TLOutwardNode = { | ||||
|     TLBuffer.chain(addBuffers).foldRight(pbus_fixer.node:TLOutwardNode)(_ :*= _) | ||||
|   } | ||||
|  | ||||
|   val toMemoryBus: TLOutwardNode = outwardNode | ||||
|  | ||||
|   val toSlave: TLOutwardNode = outwardBufNode | ||||
|  | ||||
|   def fromCoherentChip: TLInwardNode = inwardNode | ||||
|  | ||||
|   def fromFrontBus: TLInwardNode = master_splitter.node | ||||
|  | ||||
|   def fromTile(name: Option[String])(gen: Parameters => TLOutwardNode) { | ||||
|     this { | ||||
|       LazyScope(s"${busName}FromTile${name.getOrElse("")}") { | ||||
|         master_splitter.node :=* gen(p) | ||||
|       } | ||||
|   def toPeripheryBus(buffer: BufferParams = BufferParams.none) | ||||
|                     (gen: => TLNode): TLOutwardNode = { | ||||
|     to("PeripheryBus") { | ||||
|       (gen | ||||
|         := TLFIFOFixer(TLFIFOFixer.all) | ||||
|         := TLWidthWidget(params.beatBytes) | ||||
|         := bufferTo(buffer)) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def fromSyncPorts(params: BufferParams =  BufferParams.default, name: Option[String] = None): TLInwardNode = { | ||||
|     val buffer = LazyModule(new TLBuffer(params)) | ||||
|     name.foreach { n => buffer.suggestName(s"${busName}_${n}_TLBuffer") } | ||||
|     port_fixer.node :=* buffer.node | ||||
|     buffer.node | ||||
|   def toMemoryBus(gen: => TLInwardNode) { | ||||
|     to("MemoryBus") { gen :*= delayNode :*= outwardNode } | ||||
|   } | ||||
|  | ||||
|   def fromSyncFIFOMaster(params: BufferParams =  BufferParams.default, name: Option[String] = None): TLInwardNode = { | ||||
|     fromSyncPorts(params, name) | ||||
|   def toSlave(name: Option[String] = None, buffer: BufferParams = BufferParams.default) | ||||
|              (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { gen :*= bufferTo(buffer) } | ||||
|   } | ||||
|   | ||||
|   def toSplitSlave(name: Option[String] = None) | ||||
|                   (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { gen :*= master_splitter.node } | ||||
|   } | ||||
|  | ||||
|   def toVariableWidthSlave( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.default) | ||||
|       (gen: => TLNode): TLOutwardNode = { | ||||
|     to(s"Slave${name.getOrElse("")}") { | ||||
|       gen :*= TLFragmenter(params.beatBytes, params.blockBytes) :*= bufferTo(buffer) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def fromCoherentChip(gen: => TLNode): TLInwardNode = { | ||||
|     from("CoherentChip") { inwardNode :=* gen } | ||||
|   } | ||||
|  | ||||
|   def fromFrontBus(gen: => TLNode): TLInwardNode = { | ||||
|     from("FrontBus") { master_splitter.node :=* gen } | ||||
|   } | ||||
|  | ||||
|   def fromTile( | ||||
|         name: Option[String], | ||||
|         buffers: Int = 0, | ||||
|         cork: Option[Boolean] = None) | ||||
|       (gen: => TLNode): TLInwardNode = { | ||||
|     from(s"Tile${name.getOrElse("")}") { | ||||
|       (List(master_splitter.node, TLFIFOFixer(TLFIFOFixer.allUncacheable)) ++ | ||||
|         TLBuffer.chain(buffers) ++ | ||||
|         cork.map(u => TLCacheCork(unsafe = u)) | ||||
|       ).reduce(_ :=* _) :=* gen | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def toFixedWidthPort[D,U,E,B <: Data]( | ||||
|         name: Option[String] = None, | ||||
|         buffer: BufferParams = BufferParams.default) | ||||
|       (gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B]): OutwardNodeHandle[D,U,E,B] = { | ||||
|     to(s"Port${name.getOrElse("")}") { | ||||
|       gen := TLWidthWidget(params.beatBytes) := bufferTo(buffer) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def fromPort[D,U,E,B <: Data]( | ||||
|         name: Option[String] = None, | ||||
|         buffers: Int = 0) | ||||
|       (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle]): InwardNodeHandle[D,U,E,B] = { | ||||
|     from(s"Port${name.getOrElse("")}") { | ||||
|       (List( | ||||
|         master_splitter.node, | ||||
|         TLFIFOFixer(TLFIFOFixer.all)) ++ | ||||
|         TLBuffer.chain(buffers)).reduce(_ :=* _) :=* gen | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user