subsystem: new bus attachment api
This commit is contained in:
		| @@ -31,7 +31,7 @@ trait HasPeripheryDebug extends HasPeripheryBus { | |||||||
|  |  | ||||||
|   val debug = LazyModule(new TLDebugModule(pbus.beatBytes)) |   val debug = LazyModule(new TLDebugModule(pbus.beatBytes)) | ||||||
|  |  | ||||||
|   debug.node := pbus.toVariableWidthSlaves |   pbus.toVariableWidthSlave(Some("Debug")){ debug.node } | ||||||
| } | } | ||||||
|  |  | ||||||
| trait HasPeripheryDebugBundle { | trait HasPeripheryDebugBundle { | ||||||
|   | |||||||
| @@ -71,7 +71,7 @@ trait HasPeripheryBootROM extends HasPeripheryBus { | |||||||
|  |  | ||||||
|   val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes)) |   val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes)) | ||||||
|  |  | ||||||
|   bootrom.node := pbus.toVariableWidthSlaves |   pbus.toVariableWidthSlave(Some("BootROM")){ bootrom.node } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Subsystem will power-on running at 0x10040 (BootROM) */ | /** Subsystem will power-on running at 0x10040 (BootROM) */ | ||||||
|   | |||||||
| @@ -93,5 +93,5 @@ class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends | |||||||
| /** Trait that will connect a CLINT to a subsystem */ | /** Trait that will connect a CLINT to a subsystem */ | ||||||
| trait HasPeripheryCLINT extends HasPeripheryBus { | trait HasPeripheryCLINT extends HasPeripheryBus { | ||||||
|   val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes)) |   val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes)) | ||||||
|   clint.node := pbus.toVariableWidthSlaves |   pbus.toVariableWidthSlave(Some("CLINT")) { clint.node } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -121,6 +121,5 @@ class DeadlockDevice(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parame | |||||||
| trait HasSystemErrorSlave extends HasSystemBus { | trait HasSystemErrorSlave extends HasSystemBus { | ||||||
|   private val params = p(ErrorParams) |   private val params = p(ErrorParams) | ||||||
|   val error = LazyModule(new TLError(params, sbus.beatBytes)) |   val error = LazyModule(new TLError(params, sbus.beatBytes)) | ||||||
|  |   sbus.toSlave(Some("Error")){ error.node } | ||||||
|   error.node := sbus.toSlave |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ trait HasPeripheryMaskROMSlave extends HasPeripheryBus { | |||||||
|   val maskROMParams = p(PeripheryMaskROMKey) |   val maskROMParams = p(PeripheryMaskROMKey) | ||||||
|   val maskROMs = maskROMParams map { params => |   val maskROMs = maskROMParams map { params => | ||||||
|     val maskROM = LazyModule(new TLMaskROM(params)) |     val maskROM = LazyModule(new TLMaskROM(params)) | ||||||
|     maskROM.node := pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes) |     pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes, Some("MaskROM")) { maskROM.node } | ||||||
|     maskROM |     maskROM | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -270,7 +270,7 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends | |||||||
|  |  | ||||||
| /** Trait that will connect a PLIC to a subsystem */ | /** Trait that will connect a PLIC to a subsystem */ | ||||||
| trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus { | trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus { | ||||||
|   val plic  = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes)) |   val plic  = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes))) | ||||||
|   plic.node := pbus.toVariableWidthSlaves |   pbus.toVariableWidthSlave(Some("PLIC")) { plic.node } | ||||||
|   plic.intnode := ibus.toPLIC |   plic.intnode := ibus.toPLIC | ||||||
| } | } | ||||||
|   | |||||||
| @@ -50,13 +50,16 @@ trait HasMemoryZeroSlave extends HasMemoryBus { | |||||||
|   private val params = p(ZeroParams) |   private val params = p(ZeroParams) | ||||||
|   private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0")) |   private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0")) | ||||||
|  |  | ||||||
|   val zeros = memBuses.map(_.toVariableWidthSlave).zipWithIndex.map { case (node, channel) => |   val zeros = memBuses | ||||||
|  |                 .map(m => m.toVariableWidthSlave(Some("Zero"))(_)) | ||||||
|  |                 .zipWithIndex | ||||||
|  |                 .map { case (attach, channel) => | ||||||
|     val channels = memBuses.size |     val channels = memBuses.size | ||||||
|     val base = AddressSet(params.base, params.size-1) |     val base = AddressSet(params.base, params.size-1) | ||||||
|     val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes)) |     val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes)) | ||||||
|     val address = base.intersect(filter).get |     val address = base.intersect(filter).get | ||||||
|     val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem"))) |     val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem"))) | ||||||
|     zero.node := node |     attach { zero.node } | ||||||
|     zero |     zero | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,15 +28,12 @@ class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem | |||||||
|   )} |   )} | ||||||
|  |  | ||||||
|   tiles.flatMap(_.dcacheOpt).foreach { dc => |   tiles.flatMap(_.dcacheOpt).foreach { dc => | ||||||
|     sbus.fromTile(None) { implicit p => TileMasterPortParams(addBuffers = 1).adapt(this)(dc.node) } |     sbus.fromTile(None, buffers = 1){ dc.node } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // No PLIC in ground test; so just sink the interrupts to nowhere |   // No PLIC in ground test; so just sink the interrupts to nowhere | ||||||
|   IntSinkNode(IntSinkPortSimple()) := ibus.toPLIC |   IntSinkNode(IntSinkPortSimple()) := ibus.toPLIC | ||||||
|  |  | ||||||
|   val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), true, false, pbus.beatBytes)) |  | ||||||
|   pbusRAM.node := pbus.toVariableWidthSlaves |  | ||||||
|  |  | ||||||
|   override lazy val module = new GroundTestSubsystemModule(this) |   override lazy val module = new GroundTestSubsystemModule(this) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -53,11 +50,11 @@ class GroundTestSubsystemModule[+L <: GroundTestSubsystem](_outer: L) extends Ba | |||||||
| /** Adds a SRAM to the system for testing purposes. */ | /** Adds a SRAM to the system for testing purposes. */ | ||||||
| trait HasPeripheryTestRAMSlave extends HasPeripheryBus { | trait HasPeripheryTestRAMSlave extends HasPeripheryBus { | ||||||
|   val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, true, pbus.beatBytes)) |   val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, true, pbus.beatBytes)) | ||||||
|   testram.node := pbus.toVariableWidthSlaves |   pbus.toVariableWidthSlave(Some("TestRAM")) { testram.node } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Adds a fuzzing master to the system for testing purposes. */ | /** Adds a fuzzing master to the system for testing purposes. */ | ||||||
| trait HasPeripheryTestFuzzMaster extends HasPeripheryBus { | trait HasPeripheryTestFuzzMaster extends HasPeripheryBus { | ||||||
|   val fuzzer = LazyModule(new TLFuzzer(5000)) |   val fuzzer = LazyModule(new TLFuzzer(5000)) | ||||||
|   pbus.bufferFromMasters := fuzzer.node |   pbus.fromOtherMaster(Some("Fuzzer")) { fuzzer.node } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -270,10 +270,6 @@ class WithJtagDTM extends Config ((site, here, up) => { | |||||||
|   case IncludeJtagDTM => true |   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) => { | class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => { | ||||||
|   case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8) |   case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8) | ||||||
| }) | }) | ||||||
|   | |||||||
| @@ -8,38 +8,40 @@ import freechips.rocketchip.diplomacy._ | |||||||
| import freechips.rocketchip.tilelink._ | import freechips.rocketchip.tilelink._ | ||||||
| import freechips.rocketchip.util._ | import freechips.rocketchip.util._ | ||||||
|  |  | ||||||
| case class FrontBusParams( | case class FrontBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams | ||||||
|   beatBytes: Int, |  | ||||||
|   blockBytes: Int, |  | ||||||
|   masterBuffering: BufferParams = BufferParams.default, |  | ||||||
|   slaveBuffering: BufferParams = BufferParams.default |  | ||||||
| ) extends TLBusParams |  | ||||||
|  |  | ||||||
| case object FrontBusKey extends Field[FrontBusParams] | 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)) |   def fromPort[D,U,E,B <: Data]( | ||||||
|   private val master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) |         name: Option[String] = None, | ||||||
|  |         buffers: Int = 1) | ||||||
|   master_buffer.suggestName(s"${busName}_master_TLBuffer") |       (gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle]): InwardNodeHandle[D,U,E,B] = { | ||||||
|   master_fixer.suggestName(s"${busName}_master_TLFIFOFixer") |     from(s"Port${name.getOrElse("")}") { | ||||||
|  |       val nodes = TLFIFOFixer(TLFIFOFixer.all) +: TLBuffer.chain(buffers) | ||||||
|   master_fixer.node :=* master_buffer.node |       inwardNode :=* nodes.reduce(_ :=* _) :=* gen | ||||||
|   inwardNode :=* master_fixer.node |     } | ||||||
|  |  | ||||||
|   def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = { |  | ||||||
|     TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = { |   def fromMaster(name: Option[String] = None, buffers: Int = 1) | ||||||
|     TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _) |                 (gen: => TLNode): TLInwardNode = { | ||||||
|  |     from(s"Master${name.getOrElse("")}") { | ||||||
|  |       inwardNode :=* TLBuffer.chain(buffers).reduce(_ :=* _) :=* gen | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def fromCoherentChip: TLInwardNode = inwardNode |   def fromCoherentChip(gen: => TLNode): TLInwardNode = { | ||||||
|  |     from("CoherentChip") { inwardNode :=* gen } | ||||||
|   def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node |   } | ||||||
|  |  | ||||||
|  |   def toSystemBus(buffer: BufferParams = BufferParams.none) | ||||||
|  |                  (gen: => TLInwardNode) { | ||||||
|  |     to("SystemBus") { gen :*= TLBuffer(buffer) :*= outwardNode } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Provides buses that serve as attachment points, | /** Provides buses that serve as attachment points, | ||||||
| @@ -51,5 +53,7 @@ trait HasFrontBus extends HasSystemBus { | |||||||
|  |  | ||||||
|   val fbus = LazyModule(new FrontBus(frontbusParams)) |   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()) | case object BankedL2Key extends Field(BankedL2Params()) | ||||||
|  |  | ||||||
| /** Parameterization of the memory-side bus created for each memory channel */ | /** Parameterization of the memory-side bus created for each memory channel */ | ||||||
| case class MemoryBusParams( | case class MemoryBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams | ||||||
|   beatBytes: Int, |  | ||||||
|   blockBytes: Int, |  | ||||||
|   masterBuffering: BufferParams = BufferParams.none, |  | ||||||
|   slaveBuffering: BufferParams = BufferParams.none |  | ||||||
| ) extends TLBusParams |  | ||||||
|  |  | ||||||
| case object MemoryBusKey extends Field[MemoryBusParams] | case object MemoryBusKey extends Field[MemoryBusParams] | ||||||
|  |  | ||||||
| /** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */ | /** 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) { | class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p) | ||||||
|   def fromCoherenceManager: TLInwardNode = inwardBufNode |     with HasTLXbarPhy { | ||||||
|   def toDRAMController: TLOutwardNode = outwardBufNode |  | ||||||
|   def toVariableWidthSlave: TLOutwardNode = outwardFragNode |   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 { | trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus { | ||||||
|   private val mbusParams = p(MemoryBusKey) |   private val mbusParams = p(MemoryBusKey) | ||||||
|   private val l2Params = p(BankedL2Key) |   private val l2Params = p(BankedL2Key) | ||||||
|   val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams |   val MemoryBusParams(memBusBeatBytes, memBusBlockBytes) = mbusParams | ||||||
|   val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params |   val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params | ||||||
|   val nBanks = l2Params.nBanks |   val nBanks = l2Params.nBanks | ||||||
|   val cacheBlockBytes = memBusBlockBytes |   val cacheBlockBytes = memBusBlockBytes | ||||||
| @@ -71,8 +92,8 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu | |||||||
|     val mbus = LazyModule(new MemoryBus(mbusParams)) |     val mbus = LazyModule(new MemoryBus(mbusParams)) | ||||||
|     for (bank <- 0 until nBanksPerChannel) { |     for (bank <- 0 until nBanksPerChannel) { | ||||||
|       val offset = (bank * nMemoryChannels) + channel |       val offset = (bank * nMemoryChannels) + channel | ||||||
|       ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus } |       ForceFanout(a = true) { implicit p => sbus.toMemoryBus { in } } | ||||||
|       mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) := out |       mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out | ||||||
|     } |     } | ||||||
|     mbus |     mbus | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -7,41 +7,97 @@ import freechips.rocketchip.config.{Field, Parameters} | |||||||
| import freechips.rocketchip.diplomacy._ | import freechips.rocketchip.diplomacy._ | ||||||
| import freechips.rocketchip.tilelink._ | import freechips.rocketchip.tilelink._ | ||||||
|  |  | ||||||
| import freechips.rocketchip.config.Field |  | ||||||
|  |  | ||||||
| case class PeripheryBusParams( | case class PeripheryBusParams( | ||||||
|   beatBytes: Int, |   beatBytes: Int, | ||||||
|   blockBytes: Int, |   blockBytes: Int, | ||||||
|   masterBuffering: BufferParams = BufferParams.default, |  | ||||||
|   slaveBuffering: BufferParams = BufferParams.none, |  | ||||||
|   arithmetic: Boolean = true, |  | ||||||
|   frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency |   frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency | ||||||
| ) extends TLBusParams { | ) extends HasTLBusParams | ||||||
| } |  | ||||||
|  |  | ||||||
| case object PeripheryBusKey extends Field[PeripheryBusParams] | 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) = { |   private def bufferTo(buffer: BufferParams): TLOutwardNode = | ||||||
|     TLFragmenter(widthBytes, params.blockBytes) := outwardWWNode |     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) = { |   def toVariableWidthSlave( | ||||||
|     TLFragmenter(params.beatBytes, maxXferBytes) := outwardBufNode |         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 = { |   def toFixedWidthSlave( | ||||||
|     val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic)) |         name: Option[String] = None, | ||||||
|     xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node |         buffer: BufferParams = BufferParams.none) | ||||||
|  |       (gen: => TLNode): TLOutwardNode = { | ||||||
|  |     to(s"Slave${name.getOrElse("")}") { | ||||||
|  |       gen :*= fixedWidthTo(buffer) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) { |   def toFixedWidthSingleBeatSlave( | ||||||
|     this { |         widthBytes: Int, | ||||||
|       LazyScope(s"${busName}ToTile${name.getOrElse("")}") { |         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 => |       FlipRendering { implicit p => | ||||||
|           gen(p) :*= outwardNode |         gen :*= delayNode :*= outwardNode | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -57,5 +113,5 @@ trait HasPeripheryBus extends HasSystemBus { | |||||||
|   val pbus = LazyModule(new PeripheryBus(pbusParams)) |   val pbus = LazyModule(new PeripheryBus(pbusParams)) | ||||||
|  |  | ||||||
|   // The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL |   // 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) |       beatBytes = params.beatBytes) | ||||||
|   }) |   }) | ||||||
|  |  | ||||||
|   val converter = LazyModule(new TLToAXI4()) |   memBuses.map { m => | ||||||
|   val trim = LazyModule(new AXI4IdIndexer(params.idBits)) |     mem_axi4 := m.toDRAMController(Some("AXI4DRAM")) { | ||||||
|   val yank = LazyModule(new AXI4UserYanker) |       (AXI4UserYanker() := AXI4IdIndexer(params.idBits) := TLToAXI4()) | ||||||
|   val buffer = LazyModule(new AXI4Buffer) |     } | ||||||
|  |  | ||||||
|   memBuses.map(_.toDRAMController).foreach { case node => |  | ||||||
|     mem_axi4 := buffer.node := yank.node := trim.node := converter.node := node |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -93,13 +90,13 @@ trait HasMasterAXI4MMIOPort extends HasSystemBus { | |||||||
|       supportsRead  = TransferSizes(1, params.maxXferBytes))), |       supportsRead  = TransferSizes(1, params.maxXferBytes))), | ||||||
|     beatBytes = params.beatBytes))) |     beatBytes = params.beatBytes))) | ||||||
|  |  | ||||||
|   (mmio_axi4 |   mmio_axi4 := sbus.toFixedWidthPort(Some("AXI4MMIO")) { | ||||||
|     := AXI4Buffer() |     (AXI4Buffer() | ||||||
|       := AXI4UserYanker() |       := AXI4UserYanker() | ||||||
|       := AXI4Deinterleaver(sbus.blockBytes) |       := AXI4Deinterleaver(sbus.blockBytes) | ||||||
|       := AXI4IdIndexer(params.idBits) |       := AXI4IdIndexer(params.idBits) | ||||||
|     := TLToAXI4() |       := TLToAXI4()) | ||||||
|     := sbus.toFixedWidthPorts) |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Common io name and methods for propagating or tying off the port bundle */ | /** 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)))))) |       id   = IdRange(0, 1 << params.idBits)))))) | ||||||
|  |  | ||||||
|   private val fifoBits = 1 |   private val fifoBits = 1 | ||||||
|   (sbus.fromSyncPorts() |   sbus.fromPort(Some("AXI4Front")) { | ||||||
|     := TLWidthWidget(params.beatBytes) |     (TLWidthWidget(params.beatBytes) | ||||||
|       := AXI4ToTL() |       := AXI4ToTL() | ||||||
|       := AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1))) |       := AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1))) | ||||||
|       := AXI4Fragmenter() |       := AXI4Fragmenter() | ||||||
|     := AXI4IdIndexer(fifoBits) |       := AXI4IdIndexer(fifoBits)) | ||||||
|     := l2FrontendAXI4Node) |   } := l2FrontendAXI4Node | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Common io name and methods for propagating or tying off the port bundle */ | /** 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))), |       supportsPutPartial = TransferSizes(1, sbus.blockBytes))), | ||||||
|     beatBytes = params.beatBytes))) |     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 */ | /** 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)", |       name     = "Front Port (TL)", | ||||||
|       sourceId = IdRange(0, 1 << params.idBits)))))) |       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 */ | /** 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? | // TODO: how specific are these to RocketTiles? | ||||||
| case class TileMasterPortParams( | case class TileMasterPortParams( | ||||||
|     addBuffers: Int = 0, |     buffers: Int = 0, | ||||||
|     cork: Option[Boolean] = None) { |     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)(_ :=* _) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| case class TileSlavePortParams( | case class TileSlavePortParams( | ||||||
|     addBuffers: Int = 0, |     addBuffers: Int = 0, | ||||||
| @@ -41,7 +30,10 @@ case class TileSlavePortParams( | |||||||
|         .map(BasicBusBlockerParams(_, subsystem.pbus.beatBytes, subsystem.sbus.beatBytes)) |         .map(BasicBusBlockerParams(_, subsystem.pbus.beatBytes, subsystem.sbus.beatBytes)) | ||||||
|         .map(bp => LazyModule(new BasicBusBlocker(bp))) |         .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)) |     (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 |     // 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 => |     DisableMonitors { implicit p => | ||||||
|       tileSlaveBuffering :*= rocket.crossTLIn |       tileSlaveBuffering :*= pbus.toTile(tp.name) { rocket.crossTLIn } | ||||||
|     })} |     } | ||||||
|  |  | ||||||
|     // Handle all the different types of interrupts crossing to or from the tile: |     // Handle all the different types of interrupts crossing to or from the tile: | ||||||
|     // 1. Debug interrupt is definitely asynchronous in all cases. |     // 1. Debug interrupt is definitely asynchronous in all cases. | ||||||
|   | |||||||
| @@ -8,65 +8,94 @@ import freechips.rocketchip.diplomacy._ | |||||||
| import freechips.rocketchip.tilelink._ | import freechips.rocketchip.tilelink._ | ||||||
| import freechips.rocketchip.util._ | import freechips.rocketchip.util._ | ||||||
|  |  | ||||||
| case class SystemBusParams( | case class SystemBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams | ||||||
|   beatBytes: Int, |  | ||||||
|   blockBytes: Int, |  | ||||||
|   masterBuffering: BufferParams = BufferParams.default, |  | ||||||
|   slaveBuffering: BufferParams = BufferParams.default |  | ||||||
| ) extends TLBusParams |  | ||||||
|  |  | ||||||
| case object SystemBusKey extends Field[SystemBusParams] | 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 |   private val master_splitter = LazyModule(new TLSplitter) | ||||||
|   master_splitter.suggestName(s"${busName}_master_TLSplitter") |  | ||||||
|   inwardNode :=* master_splitter.node |   inwardNode :=* master_splitter.node | ||||||
|  |  | ||||||
|   def busView = master_splitter.node.edges.in.head |   def busView = master_splitter.node.edges.in.head | ||||||
|  |  | ||||||
|   protected def inwardSplitNode: TLInwardNode = master_splitter.node |   private def bufferTo(buffer: BufferParams): TLOutwardNode = | ||||||
|   protected def outwardSplitNode: TLOutwardNode = master_splitter.node |     TLBuffer(buffer) :*= delayNode :*= outwardNode | ||||||
|  |  | ||||||
|  |   def toPeripheryBus(buffer: BufferParams = BufferParams.none) | ||||||
|   private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) |                     (gen: => TLNode): TLOutwardNode = { | ||||||
|   port_fixer.suggestName(s"${busName}_port_TLFIFOFixer") |     to("PeripheryBus") { | ||||||
|   master_splitter.node :=* port_fixer.node |       (gen | ||||||
|  |         := TLFIFOFixer(TLFIFOFixer.all) | ||||||
|   private val pbus_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) |         := TLWidthWidget(params.beatBytes) | ||||||
|   pbus_fixer.suggestName(s"${busName}_pbus_TLFIFOFixer") |         := bufferTo(buffer)) | ||||||
|   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 toMemoryBus(gen: => TLInwardNode) { | ||||||
|  |     to("MemoryBus") { gen :*= delayNode :*= outwardNode } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def fromSyncPorts(params: BufferParams =  BufferParams.default, name: Option[String] = None): TLInwardNode = { |   def toSlave(name: Option[String] = None, buffer: BufferParams = BufferParams.default) | ||||||
|     val buffer = LazyModule(new TLBuffer(params)) |              (gen: => TLNode): TLOutwardNode = { | ||||||
|     name.foreach { n => buffer.suggestName(s"${busName}_${n}_TLBuffer") } |     to(s"Slave${name.getOrElse("")}") { gen :*= bufferTo(buffer) } | ||||||
|     port_fixer.node :=* buffer.node |  | ||||||
|     buffer.node |  | ||||||
|   } |   } | ||||||
|   |   | ||||||
|   def fromSyncFIFOMaster(params: BufferParams =  BufferParams.default, name: Option[String] = None): TLInwardNode = { |   def toSplitSlave(name: Option[String] = None) | ||||||
|     fromSyncPorts(params, name) |                   (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 | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,85 +0,0 @@ | |||||||
| // See LICENSE.SiFive for license details. |  | ||||||
|  |  | ||||||
| package freechips.rocketchip.tilelink |  | ||||||
|  |  | ||||||
| import Chisel._ |  | ||||||
| import freechips.rocketchip.config.{Field, Parameters} |  | ||||||
| import freechips.rocketchip.diplomacy._ |  | ||||||
|  |  | ||||||
| case object TLBusDelayProbability extends Field[Double](0.0) |  | ||||||
|  |  | ||||||
| /** Specifies widths of various attachement points in the SoC */ |  | ||||||
| trait TLBusParams { |  | ||||||
|   val beatBytes: Int |  | ||||||
|   val blockBytes: Int |  | ||||||
|   val masterBuffering: BufferParams |  | ||||||
|   val slaveBuffering: BufferParams |  | ||||||
|  |  | ||||||
|   def beatBits: Int = beatBytes * 8 |  | ||||||
|   def blockBits: Int = blockBytes * 8 |  | ||||||
|   def blockBeats: Int = blockBytes / beatBytes |  | ||||||
|   def blockOffset: Int = log2Up(blockBytes) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p: Parameters) |  | ||||||
|     extends SimpleLazyModule with LazyScope with TLBusParams { |  | ||||||
|  |  | ||||||
|   val beatBytes = params.beatBytes |  | ||||||
|   val blockBytes = params.blockBytes |  | ||||||
|   val masterBuffering = params.masterBuffering |  | ||||||
|   val slaveBuffering = params.slaveBuffering |  | ||||||
|   require(blockBytes % beatBytes == 0) |  | ||||||
|   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)) |  | ||||||
|     val flowDelay = LazyModule(new TLBuffer(BufferParams.flow)) |  | ||||||
|     val secondDelay = LazyModule(new TLDelayer(delayProb)) |  | ||||||
|     firstDelay.node :*= xbar.node |  | ||||||
|     flowDelay.node :*= firstDelay.node |  | ||||||
|     secondDelay.node :*= flowDelay.node |  | ||||||
|     secondDelay.node |  | ||||||
|   } else { |  | ||||||
|     xbar.node |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   xbar.node :=* master_buffer.node |  | ||||||
|   slave_buffer.node :*= delayedNode |  | ||||||
|   slave_frag.node :*= slave_buffer.node |  | ||||||
|   slave_ww.node :*= slave_buffer.node |  | ||||||
|  |  | ||||||
|   protected def outwardNode: TLOutwardNode = delayedNode |  | ||||||
|   protected def outwardBufNode: TLOutwardNode = slave_buffer.node |  | ||||||
|   protected def outwardFragNode: TLOutwardNode = slave_frag.node |  | ||||||
|   protected def outwardWWNode: TLOutwardNode = slave_ww.node |  | ||||||
|   protected def inwardNode: TLInwardNode = xbar.node |  | ||||||
|   protected def inwardBufNode: TLInwardNode = master_buffer.node |  | ||||||
|  |  | ||||||
|   def bufferFromMasters: TLInwardNode = inwardBufNode |  | ||||||
|  |  | ||||||
|   def bufferToSlaves: TLOutwardNode = outwardBufNode  |  | ||||||
|  |  | ||||||
|   def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = { |  | ||||||
|     TLBuffer.chain(addBuffers).foldRight(outwardBufNode)(_ :*= _) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   def toVariableWidthSlaves: TLOutwardNode = outwardFragNode |  | ||||||
|  |  | ||||||
|   def toFixedWidthSlaves: TLOutwardNode = outwardWWNode |  | ||||||
|  |  | ||||||
|   def toFixedWidthPorts: TLOutwardNode = outwardWWNode // TODO, do/don't buffer here; knowing we will after the necessary port conversions |  | ||||||
|  |  | ||||||
| } |  | ||||||
							
								
								
									
										57
									
								
								src/main/scala/tilelink/BusWrapper.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/main/scala/tilelink/BusWrapper.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | // See LICENSE.SiFive for license details. | ||||||
|  |  | ||||||
|  | package freechips.rocketchip.tilelink | ||||||
|  |  | ||||||
|  | import Chisel._ | ||||||
|  | import freechips.rocketchip.config.{Field, Parameters} | ||||||
|  | import freechips.rocketchip.diplomacy._ | ||||||
|  |  | ||||||
|  | case object TLBusDelayProbability extends Field[Double](0.0) | ||||||
|  |  | ||||||
|  | /** Specifies widths of various attachement points in the SoC */ | ||||||
|  | trait HasTLBusParams { | ||||||
|  |   val beatBytes: Int | ||||||
|  |   val blockBytes: Int | ||||||
|  |  | ||||||
|  |   def beatBits: Int = beatBytes * 8 | ||||||
|  |   def blockBits: Int = blockBytes * 8 | ||||||
|  |   def blockBeats: Int = blockBytes / beatBytes | ||||||
|  |   def blockOffset: Int = log2Up(blockBytes) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implicit p: Parameters) | ||||||
|  |     extends SimpleLazyModule with LazyScope with HasTLBusParams { | ||||||
|  |  | ||||||
|  |   val beatBytes = params.beatBytes | ||||||
|  |   val blockBytes = params.blockBytes | ||||||
|  |   require(blockBytes % beatBytes == 0) | ||||||
|  |  | ||||||
|  |   protected def inwardNode: TLInwardNode | ||||||
|  |   protected def outwardNode: TLOutwardNode | ||||||
|  |  | ||||||
|  |   protected def delayNode(implicit p: Parameters): TLNode = { | ||||||
|  |     val delayProb = p(TLBusDelayProbability) | ||||||
|  |     if (delayProb > 0.0) { | ||||||
|  |       TLDelayer(delayProb) :*=* TLBuffer(BufferParams.flow) :*=* TLDelayer(delayProb) | ||||||
|  |     } else { | ||||||
|  |       val nodelay = TLIdentityNode() | ||||||
|  |       nodelay | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected def to[T](name: String)(body: => T): T = { | ||||||
|  |     this { LazyScope(s"${busName}To${name}") { body } } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected def from[T](name: String)(body: => T): T = { | ||||||
|  |     this { LazyScope(s"${busName}From${name}") { body } } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | trait HasTLXbarPhy { this: TLBusWrapper => | ||||||
|  |   private val xbar = LazyModule(new TLXbar) | ||||||
|  |   xbar.suggestName(busName) | ||||||
|  |  | ||||||
|  |   protected def inwardNode: TLInwardNode = xbar.node | ||||||
|  |   protected def outwardNode: TLOutwardNode = xbar.node | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user