diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 4d2f0b59..d3062d83 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -46,10 +46,14 @@ case object BootROMFile extends Field[String] trait HasCoreplexParameters { implicit val p: Parameters lazy val tilesParams = p(RocketTilesKey) - lazy val cbusConfig = p(CBusConfig) - lazy val l1tol2Config = p(L1toL2Config) + lazy val sbusConfig = p(L1toL2Config) + lazy val pbusConfig = p(CBusConfig) lazy val nTiles = tilesParams.size lazy val l2Config = p(BankedL2Config) + def sbusBeatBytes = sbusConfig.beatBytes + def sbusBlockBytes = p(CacheBlockBytes) + def pbusBeatBytes = pbusConfig.beatBytes + def pbusBlockBytes = sbusBlockBytes } case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 3a3bb958..35dce9e3 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -21,11 +21,12 @@ class BaseCoreplexConfig extends Config ((site, here, up) => { case XLen => 64 // Applies to all cores case ResetVectorBits => site(PAddrBits) case MaxHartIdBits => log2Up(site(NTiles)) - case MaxPriorityLevels => 7 case BuildCore => (p: Parameters) => new Rocket()(p) case RocketCrossing => SynchronousCrossing() case RocketTilesKey => Nil case DMKey => DefaultDebugModuleConfig(site(XLen)) + case PLICKey => PLICParams() + case ClintKey => ClintParams() case NTiles => site(RocketTilesKey).size case CBusConfig => TLBusConfig(beatBytes = site(XLen)/8) case L1toL2Config => TLBusConfig(beatBytes = site(XLen)/8) // increase for more PCIe bandwidth diff --git a/src/main/scala/coreplex/CoreplexNetwork.scala b/src/main/scala/coreplex/CoreplexNetwork.scala index 7d64ec8c..70eb30e4 100644 --- a/src/main/scala/coreplex/CoreplexNetwork.scala +++ b/src/main/scala/coreplex/CoreplexNetwork.scala @@ -13,46 +13,40 @@ trait CoreplexNetwork extends HasCoreplexParameters { val module: CoreplexNetworkModule def bindingTree: ResourceMap - val tile_splitter = LazyModule(new TLSplitter) + // TODO: do we need one of these? val cbus = LazyModule(new TLXbar) // Locally-visible peripheral devices + val sbus = LazyModule(new TLXbar) // Globally-visible high-bandwidth devices + val pbus = LazyModule(new TLXbar) // Globally-visible low-bandwidth devices + val tile_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks + val int_xbar = LazyModule(new IntXbar) // Interrupt crossbar - val l1tol2 = LazyModule(new TLXbar) - val l1tol2_beatBytes = l1tol2Config.beatBytes - val l1tol2_lineBytes = p(CacheBlockBytes) + val mmio = TLOutputNode() // Exernal memory-mapped IO slaves + val mmioInt = IntInputNode() // Exernal devices' interrupts + val l2in = TLInputNode() // External masters talking to the frontside of the shared cache + val l2out = TLOutputNode() // External slaves hanging off the backside of the shared cache - val cbus = LazyModule(new TLXbar) - val cbus_beatBytes = cbusConfig.beatBytes - val cbus_lineBytes = l1tol2_lineBytes - - val intBar = LazyModule(new IntXbar) - - val mmio = TLOutputNode() - val mmioInt = IntInputNode() - val l2in = TLInputNode() - val l2out = TLOutputNode() - - intBar.intnode := mmioInt + int_xbar.intnode := mmioInt // Allows a variable number of inputs from outside to the Xbar private val l2in_buffer = LazyModule(new TLBuffer) private val l2in_fifo = LazyModule(new TLFIFOFixer) - l1tol2.node :=* l2in_fifo.node - l1tol2.node :=* tile_splitter.node + sbus.node :=* l2in_fifo.node + sbus.node :=* tile_splitter.node l2in_fifo.node :=* l2in_buffer.node l2in_buffer.node :=* l2in private val l2out_buffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none)) l2out :*= l2out_buffer.node - l2out_buffer.node :*= l1tol2.node + l2out_buffer.node :*= sbus.node - cbus.node := + pbus.node := TLBuffer()( TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata - TLWidthWidget(l1tol2_beatBytes)( - l1tol2.node))) + TLWidthWidget(sbusBeatBytes)( + sbus.node))) mmio := - TLWidthWidget(l1tol2_beatBytes)( - l1tol2.node) + TLWidthWidget(sbusBeatBytes)( + sbus.node) val root = new Device { def describe(resources: ResourceBindings): Description = { @@ -168,16 +162,16 @@ trait BankedL2CoherenceManagers extends CoreplexNetwork { require (isPow2(l2Config.nMemoryChannels) || l2Config.nMemoryChannels == 0) require (isPow2(l2Config.nBanksPerChannel)) - require (isPow2(l1tol2_lineBytes)) + require (isPow2(sbusBlockBytes)) private val (in, out) = l2Config.coherenceManager(p, this) - private val mask = ~BigInt((l2Config.nBanks-1) * l1tol2_lineBytes) + private val mask = ~BigInt((l2Config.nBanks-1) * sbusBlockBytes) val mem = Seq.tabulate(l2Config.nMemoryChannels) { channel => val node = TLOutputNode() for (bank <- 0 until l2Config.nBanksPerChannel) { val offset = (bank * l2Config.nMemoryChannels) + channel - in := l1tol2.node - node := TLFilter(AddressSet(offset * l1tol2_lineBytes, mask))(out) + in := sbus.node + node := TLFilter(AddressSet(offset * sbusBlockBytes, mask))(out) } node } diff --git a/src/main/scala/coreplex/ISPPort.scala b/src/main/scala/coreplex/ISPPort.scala index 4296cd20..eb60873f 100644 --- a/src/main/scala/coreplex/ISPPort.scala +++ b/src/main/scala/coreplex/ISPPort.scala @@ -27,7 +27,7 @@ trait HasISPPort extends CoreplexNetwork { private val in_async = LazyModule(new TLAsyncCrossingSink) in_async.node :=* isp_in - l1tol2.node :=* in_async.node + sbus.node :=* in_async.node } trait HasISPPortBundle extends CoreplexNetworkBundle { diff --git a/src/main/scala/coreplex/RISCVPlatform.scala b/src/main/scala/coreplex/RISCVPlatform.scala index ec65c192..e52af304 100644 --- a/src/main/scala/coreplex/RISCVPlatform.scala +++ b/src/main/scala/coreplex/RISCVPlatform.scala @@ -10,20 +10,23 @@ import uncore.tilelink2._ import uncore.devices._ import util._ -case object MaxPriorityLevels extends Field[Int] +/** Number of tiles */ +case object NTiles extends Field[Int] +case object PLICKey extends Field[PLICParams] +case object ClintKey extends Field[ClintParams] trait CoreplexRISCVPlatform extends CoreplexNetwork { val module: CoreplexRISCVPlatformModule val debug = LazyModule(new TLDebugModule()) - val plic = LazyModule(new TLPLIC(maxPriorities = p(MaxPriorityLevels))) - val clint = LazyModule(new CoreplexLocalInterrupter) + debug.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) - debug.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) - plic.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) - clint.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) + val plic = LazyModule(new TLPLIC(p(PLICKey))) + plic.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) + plic.intnode := int_xbar.intnode - plic.intnode := intBar.intnode + val clint = LazyModule(new CoreplexLocalInterrupter(nTiles, p(ClintKey))) + clint.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) lazy val dts = DTS(bindingTree) lazy val dtb = DTB(dts) diff --git a/src/main/scala/coreplex/RocketTiles.scala b/src/main/scala/coreplex/RocketTiles.scala index 2e8e9562..4b619017 100644 --- a/src/main/scala/coreplex/RocketTiles.scala +++ b/src/main/scala/coreplex/RocketTiles.scala @@ -65,7 +65,7 @@ trait HasRocketTiles extends CoreplexRISCVPlatform { buffer.node :=* wrapper.masterNode fixer.node :=* buffer.node tile_splitter.node :=* fixer.node - wrapper.slaveNode :*= cbus.node + wrapper.slaveNode :*= pbus.node wrapper.asyncIntNode := asyncIntXbar.intnode wrapper.periphIntNode := periphIntXbar.intnode wrapper.coreIntNode := coreIntXbar.intnode @@ -87,7 +87,7 @@ trait HasRocketTiles extends CoreplexRISCVPlatform { wrapper.asyncIntNode := asyncIntXbar.intnode wrapper.periphIntNode := periphIntXbar.intnode wrapper.coreIntNode := coreIntXbar.intnode - source.node :*= cbus.node + source.node :*= pbus.node (io: HasRocketTilesBundle) => { wrapper.module.clock := io.tcrs(i).clock wrapper.module.reset := io.tcrs(i).reset @@ -107,7 +107,7 @@ trait HasRocketTiles extends CoreplexRISCVPlatform { wrapper.asyncIntNode := asyncIntXbar.intnode wrapper.periphIntNode := periphIntXbar.intnode wrapper.coreIntNode := coreIntXbar.intnode - source.node :*= cbus.node + source.node :*= pbus.node (io: HasRocketTilesBundle) => { wrapper.module.clock := io.tcrs(i).clock wrapper.module.reset := io.tcrs(i).reset diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 63ba2737..05ad31e1 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -10,7 +10,6 @@ import uncore.tilelink._ import uncore.coherence._ import uncore.agents._ import uncore.util._ -import uncore.devices.NTiles import tile.TileKey import junctions._ import config._ diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index e4b133d0..aa2ec4e9 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -44,8 +44,8 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex { tile_splitter.node :=* fixer.node tiles.foreach { fixer.node :=* _.masterNode } - val cbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, cbus_beatBytes)) - cbusRAM.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) + val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbusBlockBytes)) + pbusRAM.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) override lazy val module = new GroundTestCoreplexModule(this, () => new GroundTestCoreplexBundle(this)) } diff --git a/src/main/scala/groundtest/TraceGen.scala b/src/main/scala/groundtest/TraceGen.scala index 37880862..d2e233bc 100644 --- a/src/main/scala/groundtest/TraceGen.scala +++ b/src/main/scala/groundtest/TraceGen.scala @@ -22,7 +22,7 @@ package groundtest import Chisel._ import uncore.tilelink._ import uncore.constants._ -import uncore.devices.NTiles +import coreplex.NTiles import rocket._ import tile._ import util.{Timer, DynamicTimer} diff --git a/src/main/scala/groundtest/TrafficGenerator.scala b/src/main/scala/groundtest/TrafficGenerator.scala index 2d1c77f1..0eefcd29 100644 --- a/src/main/scala/groundtest/TrafficGenerator.scala +++ b/src/main/scala/groundtest/TrafficGenerator.scala @@ -5,7 +5,7 @@ package groundtest import Chisel._ import uncore.tilelink._ -import uncore.devices.NTiles +import coreplex.NTiles import uncore.constants._ import junctions._ import rocket._ diff --git a/src/main/scala/uncore/devices/Clint.scala b/src/main/scala/uncore/devices/Clint.scala index 673106d8..5a7d3c4e 100644 --- a/src/main/scala/uncore/devices/Clint.scala +++ b/src/main/scala/uncore/devices/Clint.scala @@ -14,9 +14,6 @@ import scala.math.{min,max} import config._ import tile.XLen -/** Number of tiles */ -case object NTiles extends Field[Int] - object ClintConsts { def msipOffset(hart: Int) = hart * msipBytes @@ -30,7 +27,12 @@ object ClintConsts def ints = 2 } -class CoreplexLocalInterrupter(address: BigInt = 0x02000000)(implicit p: Parameters) extends LazyModule +case class ClintParams(baseAddress: BigInt = 0x02000000) +{ + def address = AddressSet(baseAddress, ClintConsts.size-1) +} + +class CoreplexLocalInterrupter(nTiles: Int, params: ClintParams)(implicit p: Parameters) extends LazyModule { import ClintConsts._ @@ -40,7 +42,7 @@ class CoreplexLocalInterrupter(address: BigInt = 0x02000000)(implicit p: Paramet } val node = TLRegisterNode( - address = Seq(AddressSet(address, size-1)), + address = Seq(params.address), device = device, beatBytes = p(XLen)/8) @@ -64,8 +66,8 @@ class CoreplexLocalInterrupter(address: BigInt = 0x02000000)(implicit p: Paramet reg := newTime >> i } - val timecmp = Seq.fill(p(NTiles)) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) } - val ipi = Seq.fill(p(NTiles)) { RegInit(UInt(0, width = 1)) } + val timecmp = Seq.fill(nTiles) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) } + val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) } io.int.zipWithIndex.foreach { case (int, i) => int(0) := ipi(i)(0) // msip diff --git a/src/main/scala/uncore/devices/Plic.scala b/src/main/scala/uncore/devices/Plic.scala index 0c0e26aa..a71b7d5c 100644 --- a/src/main/scala/uncore/devices/Plic.scala +++ b/src/main/scala/uncore/devices/Plic.scala @@ -53,11 +53,15 @@ object PLICConsts require(hartBase >= enableBase(maxHarts)) } -/** Platform-Level Interrupt Controller */ -class TLPLIC(maxPriorities: Int, address: BigInt = 0xC000000)(implicit p: Parameters) extends LazyModule +case class PLICParams(baseAddress: BigInt = 0xC000000, maxPriorities: Int = 7) { require (maxPriorities >= 0) + def address = AddressSet(baseAddress, PLICConsts.size-1) +} +/** Platform-Level Interrupt Controller */ +class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule +{ // plic0 => max devices 1023 val device = new SimpleDevice("interrupt-controller", Seq("riscv,plic0")) { override val alwaysExtended = true @@ -73,7 +77,7 @@ class TLPLIC(maxPriorities: Int, address: BigInt = 0xC000000)(implicit p: Parame } val node = TLRegisterNode( - address = Seq(AddressSet(address, PLICConsts.size-1)), + address = Seq(params.address), device = device, beatBytes = p(XLen)/8, undefZero = false, @@ -87,7 +91,7 @@ class TLPLIC(maxPriorities: Int, address: BigInt = 0xC000000)(implicit p: Parame /* Negotiated sizes */ def nDevices: Int = intnode.edgesIn.map(_.source.num).sum - def nPriorities = min(maxPriorities, nDevices) + def nPriorities = min(params.maxPriorities, nDevices) def nHarts = intnode.edgesOut.map(_.source.num).sum // Assign all the devices unique ranges