diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 62e81428..fb0bd9f4 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -35,7 +35,6 @@ trait HasCoreplexParameters { lazy val outerMMIOParams = p.alterPartial({ case TLId => "L2toMMIO" }) lazy val globalAddrMap = p(rocketchip.GlobalAddrMap) lazy val nTiles = p(uncore.devices.NTiles) - lazy val nSlaves = p(rocketchip.NCoreplexExtClients) lazy val nMemChannels = p(NMemoryChannels) lazy val hasSupervisor = p(rocket.UseVM) lazy val nTrackersPerBank = p(NTrackersPerBank) @@ -53,7 +52,7 @@ abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L } trait CoreplexNetwork extends HasCoreplexParameters { - this: BareCoreplex => + val module: CoreplexNetworkModule val l1tol2 = LazyModule(new TLXbar) val l1tol2_beatBytes = p(TLKey("L2toMMIO")).dataBitsPerBeat/8 @@ -79,9 +78,7 @@ trait CoreplexNetwork extends HasCoreplexParameters { } trait CoreplexNetworkBundle extends HasCoreplexParameters { - this: { - val outer: CoreplexNetwork - } => + val outer: CoreplexNetwork implicit val p = outer.p val mmio = outer.mmio.bundleOut @@ -89,12 +86,15 @@ trait CoreplexNetworkBundle extends HasCoreplexParameters { } trait CoreplexNetworkModule extends HasCoreplexParameters { - this: BareCoreplexModule[BareCoreplex, BareCoreplexBundle[BareCoreplex]] => + val outer: CoreplexNetwork + val io: CoreplexNetworkBundle + implicit val p = outer.p } -trait BankedL2CoherenceManagers { - this: CoreplexNetwork => +trait BankedL2CoherenceManagers extends CoreplexNetwork { + val module: BankedL2CoherenceManagersModule + require (isPow2(nBanksPerMemChannel)) require (isPow2(l1tol2_lineBytes)) @@ -116,100 +116,28 @@ trait BankedL2CoherenceManagers { } } -trait BankedL2CoherenceManagersBundle { - this: CoreplexNetworkBundle { - val outer: BankedL2CoherenceManagers - } => +trait BankedL2CoherenceManagersBundle extends CoreplexNetworkBundle { + val outer: BankedL2CoherenceManagers require (nMemChannels <= 1, "Seq in Chisel Bundle needed to support > 1") // !!! val mem = outer.mem.map(_.bundleOut).toList.headOption // .headOption should be removed !!! } -trait BankedL2CoherenceManagersModule { - this: CoreplexNetworkModule { - val outer: BankedL2CoherenceManagers - val io: BankedL2CoherenceManagersBundle - } => -} - -trait CoreplexRISCVPlatform { - this: CoreplexNetwork => - - val lazyTiles = List.tabulate(p(NTiles)){ i => LazyModule(new RocketTile(i)) } - val debug = LazyModule(new TLDebugModule()) - val plic = LazyModule(new TLPLIC(hasSupervisor, maxPriorities = 7)) - val clint = LazyModule(new CoreplexLocalInterrupter) - val tileIntNodes = lazyTiles.map { _ => IntInternalOutputNode() } // this should be moved into the Tile... - - 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) - - plic.intnode := mmioInt - tileIntNodes.foreach { _ := plic.intnode } -} - -trait CoreplexRISCVPlatformBundle { - this: CoreplexNetworkBundle { - val outer: CoreplexRISCVPlatform - } => - - val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip - val debug = new DebugBusIO().flip - val rtcTick = Bool(INPUT) - val resetVector = UInt(INPUT, p(XLen)) - val success = Bool(OUTPUT) // used for testing -} - -trait CoreplexRISCVPlatformModule { - this: CoreplexNetworkModule { - val outer: CoreplexNetwork with CoreplexRISCVPlatform - val io: CoreplexRISCVPlatformBundle - } => - - val tiles = outer.lazyTiles.map(_.module) - - // Remaining external coreplex signals - outer.debug.module.io.db <> io.debug - outer.clint.module.io.rtcTick := io.rtcTick - io.success := Bool(false) // Coreplex doesn't know when to stop running - - println("\nGenerated Address Map") - for (entry <- p(rocketchip.GlobalAddrMap).flatten) { - val name = entry.name - val start = entry.region.start - val end = entry.region.start + entry.region.size - 1 - val prot = entry.region.attr.prot - val protStr = (if ((prot & AddrMapProt.R) > 0) "R" else "") + - (if ((prot & AddrMapProt.W) > 0) "W" else "") + - (if ((prot & AddrMapProt.X) > 0) "X" else "") - val cacheable = if (entry.region.attr.cacheable) " [C]" else "" - println(f"\t$name%s $start%x - $end%x, $protStr$cacheable") - } - - // Create and export the ConfigString - val managers = outer.l1tol2.node.edgesIn(0).manager.managers - val configString = rocketchip.GenerateConfigString(p, outer.clint, outer.plic, managers) - // Allow something else to have override the config string - if (!ConfigStringOutput.contents.isDefined) { - ConfigStringOutput.contents = Some(configString) - } - println(s"\nGenerated Configuration String\n${ConfigStringOutput.contents.get}") +trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule { + val outer: BankedL2CoherenceManagers + val io: BankedL2CoherenceManagersBundle } abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex with CoreplexNetwork - with BankedL2CoherenceManagers - with CoreplexRISCVPlatform { + with BankedL2CoherenceManagers { override lazy val module = new BaseCoreplexModule(this, () => new BaseCoreplexBundle(this)) } class BaseCoreplexBundle[+L <: BaseCoreplex](_outer: L) extends BareCoreplexBundle(_outer) with CoreplexNetworkBundle with BankedL2CoherenceManagersBundle - with CoreplexRISCVPlatformBundle class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](_outer: L, _io: () => B) extends BareCoreplexModule(_outer, _io) with CoreplexNetworkModule with BankedL2CoherenceManagersModule - with CoreplexRISCVPlatformModule diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index b659845d..219930d8 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -13,7 +13,7 @@ import uncore.converters._ import rocket._ import util._ import util.ConfigUtils._ -import rocketchip.{GlobalAddrMap, NCoreplexExtClients} +import rocketchip.{GlobalAddrMap} import cde.{Parameters, Config, Dump, Knob, CDEMatchError} class BaseCoreplexConfig extends Config ( @@ -104,7 +104,7 @@ class BaseCoreplexConfig extends Config ( else new MESICoherence(site(L2DirectoryRepresentation))), nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1 /* MMIO */, nCachingClients = 1, - nCachelessClients = site(NCoreplexExtClients) + 1, + nCachelessClients = 1, maxClientXacts = max_int( // L1 cache site(DCacheKey).nMSHRs + 1 /* IOMSHR */, diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 65189b1c..59dc355b 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -10,8 +10,7 @@ import uncore.util._ import util._ import rocket._ -trait BroadcastL2 { - this: CoreplexNetwork => +trait BroadcastL2 extends BankedL2CoherenceManagers { def l2ManagerFactory() = { val bh = LazyModule(new TLBroadcast(l1tol2_lineBytes, nTrackersPerBank)) (bh.node, bh.node) @@ -20,45 +19,23 @@ trait BroadcastL2 { ///// -trait DirectConnection { - this: CoreplexNetwork with CoreplexRISCVPlatform => - - lazyTiles foreach { t => - t.slaveNode.foreach { _ := cbus.node } - l1tol2.node := TLBuffer(1,1,2,2,0)(TLHintHandler()(t.cachedOut)) - l1tol2.node := TLBuffer(1,0,0,2,0)(TLHintHandler()(t.uncachedOut)) - } -} - -trait DirectConnectionModule { - this: CoreplexNetworkModule with CoreplexRISCVPlatformModule { - val outer: CoreplexNetwork with CoreplexRISCVPlatform - val io: CoreplexRISCVPlatformBundle - } => - - // connect coreplex-internal interrupts to tiles - tiles.zipWithIndex.foreach { case (tile, i) => - tile.io.hartid := UInt(i) - tile.io.resetVector := io.resetVector - tile.io.interrupts := outer.clint.module.io.tiles(i) - tile.io.interrupts.debug := outer.debug.module.io.debugInterrupts(i) - tile.io.interrupts.meip := outer.tileIntNodes(i).bundleOut(0)(0) - tile.io.interrupts.seip.foreach(_ := outer.tileIntNodes(i).bundleOut(0)(1)) - } -} - class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex with BroadcastL2 - with DirectConnection { + with CoreplexRISCVPlatform + with RocketPlex { override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this)) } class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) + with CoreplexRISCVPlatformBundle + with RocketPlexBundle class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) - with DirectConnectionModule + with CoreplexRISCVPlatformModule + with RocketPlexModule ///// +/* trait AsyncConnection { this: CoreplexNetwork with CoreplexRISCVPlatform => @@ -149,3 +126,4 @@ class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](_outer: L) extends Base class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) with AsyncConnectionModule +*/ diff --git a/src/main/scala/coreplex/RISCVPlatform.scala b/src/main/scala/coreplex/RISCVPlatform.scala new file mode 100644 index 00000000..dc4fefcc --- /dev/null +++ b/src/main/scala/coreplex/RISCVPlatform.scala @@ -0,0 +1,73 @@ +package coreplex + +import Chisel._ +import cde.{Parameters, Field} +import junctions._ +import diplomacy._ +import uncore.tilelink._ +import uncore.tilelink2._ +import uncore.coherence._ +import uncore.agents._ +import uncore.devices._ +import uncore.util._ +import uncore.converters._ +import rocket._ +import util._ + +trait CoreplexRISCVPlatform extends CoreplexNetwork { + val module: CoreplexRISCVPlatformModule + + val debug = LazyModule(new TLDebugModule()) + val plic = LazyModule(new TLPLIC(hasSupervisor, maxPriorities = 7)) + val clint = LazyModule(new CoreplexLocalInterrupter) + + 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) + + plic.intnode := mmioInt + +} + +trait CoreplexRISCVPlatformBundle extends CoreplexNetworkBundle { + val outer: CoreplexRISCVPlatform + + val debug = new AsyncDebugBusIO().flip + val rtcToggle = Bool(INPUT) + val resetVector = UInt(INPUT, p(XLen)) +} + +trait CoreplexRISCVPlatformModule extends CoreplexNetworkModule { + val outer: CoreplexRISCVPlatform + val io: CoreplexRISCVPlatformBundle + + // Synchronize the debug bus into the coreplex + outer.debug.module.io.db <> FromAsyncDebugBus(io.debug) + + // Synchronize the rtc into the coreplex + val rtcSync = ShiftRegister(io.rtcToggle, 3) + val rtcLast = Reg(init = Bool(false), next=rtcSync) + outer.clint.module.io.rtcTick := Reg(init = Bool(false), next=(rtcSync & (~rtcLast))) + + println("\nGenerated Address Map") + for (entry <- p(rocketchip.GlobalAddrMap).flatten) { + val name = entry.name + val start = entry.region.start + val end = entry.region.start + entry.region.size - 1 + val prot = entry.region.attr.prot + val protStr = (if ((prot & AddrMapProt.R) > 0) "R" else "") + + (if ((prot & AddrMapProt.W) > 0) "W" else "") + + (if ((prot & AddrMapProt.X) > 0) "X" else "") + val cacheable = if (entry.region.attr.cacheable) " [C]" else "" + println(f"\t$name%s $start%x - $end%x, $protStr$cacheable") + } + + // Create and export the ConfigString + val managers = outer.l1tol2.node.edgesIn(0).manager.managers + val configString = rocketchip.GenerateConfigString(p, outer.clint, outer.plic, managers) + // Allow something else to have override the config string + if (!ConfigStringOutput.contents.isDefined) { + ConfigStringOutput.contents = Some(configString) + } + println(s"\nGenerated Configuration String\n${ConfigStringOutput.contents.get}") +} diff --git a/src/main/scala/coreplex/RocketPlex.scala b/src/main/scala/coreplex/RocketPlex.scala new file mode 100644 index 00000000..1477754b --- /dev/null +++ b/src/main/scala/coreplex/RocketPlex.scala @@ -0,0 +1,41 @@ +package coreplex + +import Chisel._ +import cde.{Parameters, Field} +import diplomacy._ +import uncore.tilelink2._ +import uncore.coherence._ +import rocket._ +import uncore.devices.NTiles + +trait RocketPlex extends CoreplexRISCVPlatform { + val module: RocketPlexModule + + val rocketTiles = List.tabulate(p(NTiles)) { i => LazyModule(new RocketTile(i)) } + val tileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() } + + tileIntNodes.foreach { _ := plic.intnode } + rocketTiles.foreach { r => + r.slaveNode.foreach { _ := cbus.node } + l1tol2.node := r.cachedOut + l1tol2.node := r.uncachedOut + } +} + +trait RocketPlexBundle extends CoreplexRISCVPlatformBundle { + val outer: CoreplexRISCVPlatform +} + +trait RocketPlexModule extends CoreplexRISCVPlatformModule { + val outer: RocketPlex + val io: RocketPlexBundle + + outer.rocketTiles.map(_.module).zipWithIndex.foreach { case (tile, i) => + tile.io.hartid := UInt(i) + tile.io.resetVector := io.resetVector + tile.io.interrupts := outer.clint.module.io.tiles(i) + tile.io.interrupts.debug := outer.debug.module.io.debugInterrupts(i) + tile.io.interrupts.meip := outer.tileIntNodes(i).bundleOut(0)(0) + tile.io.interrupts.seip.foreach(_ := outer.tileIntNodes(i).bundleOut(0)(1)) + } +} diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 026fcd72..dcb395fd 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -81,7 +81,7 @@ class WithGroundTest extends Config( else new MESICoherence(site(L2DirectoryRepresentation))), nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1, nCachingClients = 1, - nCachelessClients = site(NCoreplexExtClients) + 1, + nCachelessClients = 1, maxClientXacts = ((site(DCacheKey).nMSHRs + 1) +: site(GroundTestKey).map(_.maxXacts)) .reduce(max(_, _)), diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index 865eb101..2abb21d9 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -9,9 +9,8 @@ import rocket.TileId import uncore.tilelink.TLId class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex - with BroadcastL2 - with DirectConnection { - val tiles = (0 until p(NTiles)).map { i => + with BroadcastL2 { + val tiles = List.tabulate(p(NTiles)) { i => LazyModule(new GroundTestTile()(p.alterPartial({ case TLId => "L1toL2" case TileId => i @@ -21,8 +20,10 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex } class GroundTestCoreplexBundle[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) - -class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) - with DirectConnectionModule { - io.success := outer.tiles.flatMap(_.module.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_) +{ + val success = Bool(OUTPUT) +} + +class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) { + io.success := outer.tiles.map(_.module.io.success).reduce(_&&_) } diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index a3ccf954..aa60e7c4 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -43,7 +43,7 @@ class RocketTile(tileId: Int)(implicit p: Parameters) extends LazyModule { val cachedOut = TLOutputNode() val uncachedOut = TLOutputNode() cachedOut := dcache.node - uncachedOut := ucLegacy.node + uncachedOut := TLHintHandler()(ucLegacy.node) val masterNodes = List(cachedOut, uncachedOut) (slaveNode zip scratch) foreach { case (node, lm) => lm.node := TLFragmenter(p(XLen)/8, p(CacheBlockBytes))(node) } diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 1219d26a..4dd230b4 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -15,16 +15,13 @@ import coreplex._ // the following parameters will be refactored properly with TL2 case object GlobalAddrMap extends Field[AddrMap] -case object NCoreplexExtClients extends Field[Int] /** Enable or disable monitoring of Diplomatic buses */ case object TLEmitMonitors extends Field[Bool] -abstract class BareTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit val q: Parameters) extends LazyModule { +abstract class BareTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit val p: Parameters) extends LazyModule { // Fill in the TL1 legacy parameters; remove these once rocket/groundtest/unittest are TL2 - val pBusMasters = new RangeManager - lazy val legacyAddrMap = GenerateGlobalAddrMap(q, coreplex.l1tol2.node.edgesIn(0).manager.managers) - val coreplex : C = LazyModule(_coreplex(q.alterPartial { - case NCoreplexExtClients => pBusMasters.sum + lazy val legacyAddrMap = GenerateGlobalAddrMap(p, coreplex.l1tol2.node.edgesIn(0).manager.managers) + val coreplex : C = LazyModule(_coreplex(p.alterPartial { case GlobalAddrMap => legacyAddrMap })) @@ -42,8 +39,8 @@ abstract class BareTopModule[+L <: BareTop[BaseCoreplex], +B <: BareTopBundle[L] /** Base Top with no Periphery */ trait TopNetwork extends HasPeripheryParameters { - this: BareTop[BaseCoreplex] => - implicit val p = q + val module: TopNetworkModule + TLImp.emitMonitors = p(TLEmitMonitors) // Add a SoC and peripheral bus @@ -60,26 +57,14 @@ trait TopNetwork extends HasPeripheryParameters { } trait TopNetworkBundle extends HasPeripheryParameters { - this: BareTopBundle[BareTop[BaseCoreplex]] => - implicit val p = outer.q - val success = Bool(OUTPUT) + val outer: TopNetwork + implicit val p = outer.p } trait TopNetworkModule extends HasPeripheryParameters { - this: { - val outer: BareTop[BaseCoreplex] with TopNetwork - val io: TopNetworkBundle - } => + val io: TopNetworkBundle + val outer: TopNetwork implicit val p = outer.p - - val coreplexSlave: Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.slave) - val coreplexDebug: DebugBusIO = Wire(outer.coreplex.module.io.debug) - val coreplexRtc : Bool = Wire(outer.coreplex.module.io.rtcTick) - - io.success := outer.coreplex.module.io.success - - outer.coreplex.module.io.rtcTick := coreplexRtc - coreplexRtc := Counter(p(rocketchip.RTCPeriod)).inc() } /** Base Top with no Periphery */ @@ -94,20 +79,11 @@ class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](_outer: L) extends BareTopBundl class BaseTopModule[+L <: BaseTop[BaseCoreplex], +B <: BaseTopBundle[L]](_outer: L, _io: () => B) extends BareTopModule(_outer, _io) with TopNetworkModule -trait DirectConnection { - this: BareTop[BaseCoreplex] with TopNetwork => +trait DirectConnection extends TopNetwork { + val coreplex: BaseCoreplex socBus.node := coreplex.mmio coreplex.mmioInt := intBus.intnode coreplexMem = coreplex.mem } - -trait DirectConnectionModule { - this: TopNetworkModule { - val outer: BaseTop[BaseCoreplex] - } => - - outer.coreplex.module.io.slave <> coreplexSlave - outer.coreplex.module.io.debug <> coreplexDebug -} diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 92643944..effad0d1 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -62,8 +62,6 @@ class BasePlatformConfig extends Config( case TMemoryChannels => BusType.AXI case ExtMemSize => Dump("MEM_SIZE", 0x10000000L) case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock - case BuildExampleTop => - (p: Parameters) => LazyModule(new ExampleTop(new DefaultCoreplex()(_))(p)) case SimMemLatency => 0 case _ => throw new CDEMatchError } diff --git a/src/main/scala/rocketchip/DebugTransport.scala b/src/main/scala/rocketchip/DebugTransport.scala index 895bd3b7..9a58e58f 100644 --- a/src/main/scala/rocketchip/DebugTransport.scala +++ b/src/main/scala/rocketchip/DebugTransport.scala @@ -1,7 +1,7 @@ package rocketchip import Chisel._ -import uncore.devices.{DebugBusIO, AsyncDebugBusCrossing, DebugBusReq, DebugBusResp, DMKey} +import uncore.devices._ import junctions._ import util._ import cde.{Parameters, Field} @@ -45,13 +45,13 @@ class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters) val io = new Bundle { - val jtag = new JTAGIO(true).flip() - val debug = new DebugBusIO()(p) + val jtag = new JTAGIO(true).flip + val debug = new AsyncDebugBusIO } - val req_width = io.debug.req.bits.getWidth - val resp_width = io.debug.resp.bits.getWidth + val req_width = io.debug.req.mem(0).getWidth + val resp_width = io.debug.resp.mem(0).getWidth val jtag_dtm = Module (new DebugTransportModuleJtag(req_width, resp_width)) @@ -62,7 +62,8 @@ class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters) val io_debug_bus = Wire (new DebugBusIO) - io.debug <> AsyncDebugBusCrossing(io.jtag.TCK, io.jtag.TRST, io_debug_bus, clock, reset, depth, sync) + io.debug.req <> ToAsyncBundle(io_debug_bus.req) + io_debug_bus.resp <> FromAsyncBundle(io.debug.resp) // Translate from straight 'bits' interface of the blackboxes // into the Resp/Req data structures. diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 45e67a03..4b8efbc7 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -12,31 +12,40 @@ import rocketchip._ class ExampleTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends BaseTop(_coreplex) with DirectConnection with PeripheryBootROM - with PeripheryDebug with PeripheryExtInterrupts with PeripheryMasterAXI4Mem - with PeripheryMasterAXI4MMIO - with PeripherySlave { + with PeripheryMasterAXI4MMIO { override lazy val module = new ExampleTopModule(this, () => new ExampleTopBundle(this)) } class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](_outer: L) extends BaseTopBundle(_outer) with PeripheryBootROMBundle - with PeripheryDebugBundle with PeripheryExtInterruptsBundle with PeripheryMasterAXI4MemBundle with PeripheryMasterAXI4MMIOBundle - with PeripherySlaveBundle class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io) - with DirectConnectionModule with PeripheryBootROMModule - with PeripheryDebugModule with PeripheryExtInterruptsModule with PeripheryMasterAXI4MemModule with PeripheryMasterAXI4MMIOModule - with PeripherySlaveModule - with HardwiredResetVector + +class ExampleRocketTop[+C <: DefaultCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(_coreplex) + with PeripheryDTM + with PeripheryCounter + with HardwiredResetVector { + override lazy val module = new ExampleRocketTopModule(this, () => new ExampleRocketTopBundle(this)) +} + +class ExampleRocketTopBundle[+L <: ExampleRocketTop[DefaultCoreplex]](_outer: L) extends ExampleTopBundle(_outer) + with PeripheryDTMBundle + with PeripheryCounterBundle + with HardwiredResetVectorBundle + +class ExampleRocketTopModule[+L <: ExampleRocketTop[DefaultCoreplex], +B <: ExampleRocketTopBundle[L]](_outer: L, _io: () => B) extends ExampleTopModule(_outer, _io) + with PeripheryDTMModule + with PeripheryCounterModule + with HardwiredResetVectorModule /** Example Top with TestRAM */ class ExampleTopWithTestRAM[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(_coreplex) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 1b9a3638..c53b4696 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -92,41 +92,6 @@ trait HasPeripheryParameters { ///// -trait PeripheryDebug { - this: TopNetwork => -} - -trait PeripheryDebugBundle { - this: TopNetworkBundle { - val outer: PeripheryDebug - } => - val debug_clk = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Clock(INPUT)) - val debug_rst = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Bool(INPUT)) - val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip) - val jtag = p(IncludeJtagDTM).option(new JTAGIO(true).flip) -} - -trait PeripheryDebugModule { - this: TopNetworkModule { - val outer: PeripheryDebug - val io: PeripheryDebugBundle - } => - - if (p(IncludeJtagDTM)) { - // JtagDTMWithSync is a wrapper which - // handles the synchronization as well. - val dtm = Module (new JtagDTMWithSync()(p)) - dtm.io.jtag <> io.jtag.get - coreplexDebug <> dtm.io.debug - } else { - coreplexDebug <> - (if (p(AsyncDebugBus)) AsyncDebugBusFrom(io.debug_clk.get, io.debug_rst.get, io.debug.get) - else io.debug.get) - } -} - -///// - trait PeripheryExtInterrupts { this: TopNetwork => @@ -238,48 +203,6 @@ trait PeripheryMasterAXI4MMIOModule { ///// -trait PeripherySlave { - this: TopNetwork { - val pBusMasters: RangeManager - } => - - if (p(NExtBusAXIChannels) > 0) pBusMasters.add("ext", 1) // NExtBusAXIChannels are arbitrated into one TL port -} - -trait PeripherySlaveBundle { - this: TopNetworkBundle { - val outer: PeripherySlave - } => - val bus_clk = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Clock(INPUT))) - val bus_rst = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Bool (INPUT))) - val bus_axi = Vec(p(NExtBusAXIChannels), new NastiIO).flip -} - -trait PeripherySlaveModule { - this: TopNetworkModule { - val outer: PeripherySlave { val pBusMasters: RangeManager } - val io: PeripherySlaveBundle - } => - - if (p(NExtBusAXIChannels) > 0) { - val arb = Module(new NastiArbiter(p(NExtBusAXIChannels))) - ((io.bus_axi zip arb.io.master) zipWithIndex) foreach { case ((bus, port), idx) => - port <> ( - if (!p(AsyncBusChannels)) bus - else AsyncNastiFrom(io.bus_clk.get(idx), io.bus_rst.get(idx), bus) - ) - } - val conv = Module(new TileLinkIONastiIOConverter()(edgeSlaveParams)) - conv.io.nasti <> arb.io.slave - - val (r_start, r_end) = outer.pBusMasters.range("ext") - require(r_end - r_start == 1, "RangeManager should return 1 slot") - TileLinkWidthAdapter(coreplexSlave(r_start), conv.io.tl) - } -} - -///// - trait PeripheryBootROM { this: TopNetwork => @@ -344,12 +267,3 @@ trait PeripheryTestBusMasterModule { val io: PeripheryTestBusMasterBundle } => } - -///// - -trait HardwiredResetVector { - this: TopNetworkModule { - val outer: BaseTop[BaseCoreplex] - } => - outer.coreplex.module.io.resetVector := UInt(0x1000) // boot ROM -} diff --git a/src/main/scala/rocketchip/RISCVPlatform.scala b/src/main/scala/rocketchip/RISCVPlatform.scala new file mode 100644 index 00000000..d3d7f34d --- /dev/null +++ b/src/main/scala/rocketchip/RISCVPlatform.scala @@ -0,0 +1,92 @@ +// See LICENSE for license details. + +package rocketchip + +import Chisel._ +import cde.{Parameters, Field, Dump} +import diplomacy._ +import uncore.tilelink2._ +import uncore.devices._ +import util._ +import junctions.JTAGIO +import coreplex._ + +trait PeripheryJTAG extends TopNetwork { + val module: PeripheryJTAGModule + val coreplex: CoreplexRISCVPlatform +} + +trait PeripheryJTAGBundle extends TopNetworkBundle { + val outer: PeripheryJTAG + + val jtag = new JTAGIO(true).flip +} + +trait PeripheryJTAGModule extends TopNetworkModule { + val outer: PeripheryJTAG + val io: PeripheryJTAGBundle + + val dtm = Module (new JtagDTMWithSync) + dtm.io.jtag <> io.jtag + outer.coreplex.module.io.debug <> dtm.io.debug + + dtm.clock := io.jtag.TCK + dtm.reset := io.jtag.TRST +} + +trait PeripheryDTM extends TopNetwork { + val module: PeripheryDTMModule + val coreplex: CoreplexRISCVPlatform +} + +trait PeripheryDTMBundle extends TopNetworkBundle { + val outer: PeripheryDTM + + val debug = new DebugBusIO().flip +} + +trait PeripheryDTMModule extends TopNetworkModule { + val outer: PeripheryDTM + val io: PeripheryDTMBundle + + outer.coreplex.module.io.debug <> ToAsyncDebugBus(io.debug) +} + +trait PeripheryCounter extends TopNetwork { + val module: PeripheryCounterModule + val coreplex: CoreplexRISCVPlatform +} + +trait PeripheryCounterBundle extends TopNetworkBundle { + val outer: PeripheryCounter +} + +trait PeripheryCounterModule extends TopNetworkModule { + val outer: PeripheryCounter + val io: PeripheryCounterBundle + + { + val period = p(rocketchip.RTCPeriod) + val rtcCounter = RegInit(UInt(0, width = log2Up(period))) + val rtcWrap = rtcCounter === UInt(period-1) + rtcCounter := Mux(rtcWrap, UInt(0), rtcCounter + UInt(1)) + + outer.coreplex.module.io.rtcToggle := rtcCounter(log2Up(period)-1) + } +} + +trait HardwiredResetVector extends TopNetwork { + val module: HardwiredResetVectorModule + val coreplex: CoreplexRISCVPlatform +} + +trait HardwiredResetVectorBundle extends TopNetworkBundle { + val outer: HardwiredResetVector +} + +trait HardwiredResetVectorModule extends TopNetworkModule { + val outer: HardwiredResetVector + val io: HardwiredResetVectorBundle + + outer.coreplex.module.io.resetVector := UInt(0x1000) // boot ROM +} diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index f760b260..da74e787 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -5,6 +5,8 @@ package rocketchip import Chisel._ import cde.{Parameters, Field} import junctions._ +import diplomacy._ +import coreplex._ import junctions.NastiConstants._ import util.LatencyPipe @@ -15,12 +17,8 @@ class TestHarness(q: Parameters) extends Module { val io = new Bundle { val success = Bool(OUTPUT) } - val dut = Module(q(BuildExampleTop)(q).module) - implicit val p = dut.p - - // This test harness isn't especially flexible yet - require(dut.io.bus_clk.isEmpty) - require(dut.io.bus_rst.isEmpty) + implicit val p = q + val dut = Module(LazyModule(new ExampleRocketTop(new DefaultCoreplex()(_))).module) for (int <- dut.io.interrupts(0)) int := Bool(false) @@ -38,26 +36,7 @@ class TestHarness(q: Parameters) extends Module { } } - if (!p(IncludeJtagDTM)) { - // Todo: enable the usage of different clocks - // to test the synchronizer more aggressively. - val dtm_clock = clock - val dtm_reset = reset - if (dut.io.debug_clk.isDefined) dut.io.debug_clk.get := dtm_clock - if (dut.io.debug_rst.isDefined) dut.io.debug_rst.get := dtm_reset - val dtm = Module(new SimDTM).connect(dtm_clock, dtm_reset, dut.io.debug.get, - dut.io.success, io.success) - } else { - val jtag = Module(new JTAGVPI).connect(dut.io.jtag.get, reset, io.success) - } - - for (bus_axi <- dut.io.bus_axi) { - bus_axi.ar.valid := Bool(false) - bus_axi.aw.valid := Bool(false) - bus_axi.w.valid := Bool(false) - bus_axi.r.ready := Bool(false) - bus_axi.b.ready := Bool(false) - } + val dtm = Module(new SimDTM).connect(clock, reset, dut.io.debug, io.success) for (mmio_axi <- dut.io.mmio_axi) { val slave = Module(new NastiErrorSlave) @@ -128,13 +107,12 @@ class SimDTM(implicit p: Parameters) extends BlackBox { val exit = UInt(OUTPUT, 32) } - def connect(tbclk: Clock, tbreset: Bool, dutio: uncore.devices.DebugBusIO, - dutsuccess: Bool, tbsuccess: Bool) = { + def connect(tbclk: Clock, tbreset: Bool, dutio: uncore.devices.DebugBusIO, tbsuccess: Bool) = { io.clk := tbclk io.reset := tbreset dutio <> io.debug - tbsuccess := dutsuccess || io.exit === UInt(1) + tbsuccess := io.exit === UInt(1) when (io.exit >= UInt(2)) { printf("*** FAILED *** (exit code = %d)\n", io.exit >> UInt(1)) stop(1) diff --git a/src/main/scala/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index 3ee83e9a..6b1eec0f 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -306,6 +306,31 @@ class DebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p val resp = new DecoupledIO(new DebugBusResp).flip() } +class AsyncDebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p) { + val req = new AsyncBundle(1, new DebugBusReq(p(DMKey).nDebugBusAddrSize)) + val resp = new AsyncBundle(1, new DebugBusResp).flip +} + +object FromAsyncDebugBus +{ + def apply(x: AsyncDebugBusIO) = { + val out = Wire(new DebugBusIO()(x.p)) + out.req <> FromAsyncBundle(x.req) + x.resp <> ToAsyncBundle(out.resp, 1) + out + } +} + +object ToAsyncDebugBus +{ + def apply(x: DebugBusIO) = { + val out = Wire(new AsyncDebugBusIO()(x.p)) + out.req <> ToAsyncBundle(x.req, 1) + x.resp <> FromAsyncBundle(out.resp) + out + } +} + trait HasDebugModuleParameters { val params : Parameters implicit val p = params diff --git a/src/main/scala/uncore/tilelink2/Bundles.scala b/src/main/scala/uncore/tilelink2/Bundles.scala index 46dc8c24..9575741b 100644 --- a/src/main/scala/uncore/tilelink2/Bundles.scala +++ b/src/main/scala/uncore/tilelink2/Bundles.scala @@ -5,7 +5,7 @@ package uncore.tilelink2 import Chisel._ import chisel3.util.{ReadyValidIO} import diplomacy._ -import util.{AsyncQueueSource, AsyncQueueSink, GenericParameterizedBundle} +import util._ abstract class TLBundleBase(params: TLBundleParameters) extends GenericParameterizedBundle(params) @@ -241,58 +241,6 @@ object TLBundleSnoop } } -final class AsyncBundle[T <: Data](val depth: Int, gen: T) extends Bundle -{ - require (isPow2(depth)) - val mem = Vec(depth, gen) - val ridx = UInt(width = log2Up(depth)+1).flip - val widx = UInt(width = log2Up(depth)+1) - val ridx_valid = Bool().flip - val widx_valid = Bool() - val source_reset_n = Bool() - val sink_reset_n = Bool().flip - - override def cloneType: this.type = new AsyncBundle(depth, gen).asInstanceOf[this.type] -} - -object FromAsyncBundle -{ - def apply[T <: Data](x: AsyncBundle[T], sync: Int = 3): DecoupledIO[T] = { - val sink = Module(new AsyncQueueSink(x.mem(0), x.depth, sync)) - x.ridx := sink.io.ridx - x.ridx_valid := sink.io.ridx_valid - sink.io.widx := x.widx - sink.io.widx_valid := x.widx_valid - sink.io.mem := x.mem - sink.io.source_reset_n := x.source_reset_n - x.sink_reset_n := !sink.reset - val out = Wire(Decoupled(x.mem(0))) - out.valid := sink.io.deq.valid - out.bits := sink.io.deq.bits - sink.io.deq.ready := out.ready - out - } -} - -object ToAsyncBundle -{ - def apply[T <: Data](x: ReadyValidIO[T], depth: Int = 8, sync: Int = 3): AsyncBundle[T] = { - val source = Module(new AsyncQueueSource(x.bits, depth, sync)) - source.io.enq.valid := x.valid - source.io.enq.bits := x.bits - x.ready := source.io.enq.ready - val out = Wire(new AsyncBundle(depth, x.bits)) - source.io.ridx := out.ridx - source.io.ridx_valid := out.ridx_valid - out.mem := source.io.mem - out.widx := source.io.widx - out.widx_valid := source.io.widx_valid - source.io.sink_reset_n := out.sink_reset_n - out.source_reset_n := !source.reset - out - } -} - class TLAsyncBundleBase(params: TLAsyncBundleParameters) extends GenericParameterizedBundle(params) class TLAsyncBundle(params: TLAsyncBundleParameters) extends TLAsyncBundleBase(params) diff --git a/src/main/scala/uncore/tilelink2/Isolation.scala b/src/main/scala/uncore/tilelink2/Isolation.scala index 3be5caca..6f592218 100644 --- a/src/main/scala/uncore/tilelink2/Isolation.scala +++ b/src/main/scala/uncore/tilelink2/Isolation.scala @@ -5,6 +5,7 @@ package uncore.tilelink2 import Chisel._ import chisel3.internal.sourceinfo.SourceInfo import diplomacy._ +import util.AsyncBundle // READ the comments in the TLIsolation object before you instantiate this module class TLIsolation(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt) extends LazyModule diff --git a/src/main/scala/unittest/Configs.scala b/src/main/scala/unittest/Configs.scala index e968da04..39f4adf7 100644 --- a/src/main/scala/unittest/Configs.scala +++ b/src/main/scala/unittest/Configs.scala @@ -20,7 +20,6 @@ class JunctionsUnitTestConfig extends Config(new WithJunctionsUnitTests ++ new B class WithUncoreUnitTests extends Config( (pname, site, here) => pname match { - case rocketchip.NCoreplexExtClients => 0 case uncore.tilelink.TLId => "L1toL2" case UnitTests => (p: Parameters) => Seq( Module(new uncore.devices.ROMSlaveTest()(p)), diff --git a/src/main/scala/util/AsyncBundle.scala b/src/main/scala/util/AsyncBundle.scala new file mode 100644 index 00000000..fb178666 --- /dev/null +++ b/src/main/scala/util/AsyncBundle.scala @@ -0,0 +1,59 @@ +// See LICENSE for license details. + +package util + +import Chisel._ +import chisel3.util.{ReadyValidIO} + +final class AsyncBundle[T <: Data](val depth: Int, gen: T) extends Bundle +{ + require (isPow2(depth)) + val mem = Vec(depth, gen) + val ridx = UInt(width = log2Up(depth)+1).flip + val widx = UInt(width = log2Up(depth)+1) + val ridx_valid = Bool().flip + val widx_valid = Bool() + val source_reset_n = Bool() + val sink_reset_n = Bool().flip + + override def cloneType: this.type = new AsyncBundle(depth, gen).asInstanceOf[this.type] +} + +object FromAsyncBundle +{ + def apply[T <: Data](x: AsyncBundle[T], sync: Int = 3): DecoupledIO[T] = { + val sink = Module(new AsyncQueueSink(x.mem(0), x.depth, sync)) + x.ridx := sink.io.ridx + x.ridx_valid := sink.io.ridx_valid + sink.io.widx := x.widx + sink.io.widx_valid := x.widx_valid + sink.io.mem := x.mem + sink.io.source_reset_n := x.source_reset_n + x.sink_reset_n := !sink.reset + val out = Wire(Decoupled(x.mem(0))) + out.valid := sink.io.deq.valid + out.bits := sink.io.deq.bits + sink.io.deq.ready := out.ready + out + } +} + +object ToAsyncBundle +{ + def apply[T <: Data](x: ReadyValidIO[T], depth: Int = 8, sync: Int = 3): AsyncBundle[T] = { + val source = Module(new AsyncQueueSource(x.bits, depth, sync)) + source.io.enq.valid := x.valid + source.io.enq.bits := x.bits + x.ready := source.io.enq.ready + val out = Wire(new AsyncBundle(depth, x.bits)) + source.io.ridx := out.ridx + source.io.ridx_valid := out.ridx_valid + out.mem := source.io.mem + out.widx := source.io.widx + out.widx_valid := source.io.widx_valid + source.io.sink_reset_n := out.sink_reset_n + out.source_reset_n := !source.reset + out + } +} +