From 644f8fe974d8bf8d86192eeea6de23c4450e5cb5 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 14 Sep 2016 18:09:27 -0700 Subject: [PATCH] rocketchip: switch to TL2 mmio + port PRCI --- src/main/scala/coreplex/Configs.scala | 2 +- src/main/scala/rocketchip/Periphery.scala | 70 ++++++-------- src/main/scala/rocketchip/Top.scala | 15 ++- src/main/scala/rocketchip/Utils.scala | 10 +- src/main/scala/uncore/devices/Prci.scala | 113 ++++++++-------------- 5 files changed, 87 insertions(+), 123 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 8d8d87ad..79e4652b 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -177,7 +177,7 @@ class BaseCoreplexConfig extends Config ( TileLinkParameters( coherencePolicy = new MICoherence( new NullRepresentation(site(NBanksPerMemoryChannel))), - nManagers = site(GlobalAddrMap).get.subMap("io").numSlaves, + nManagers = 1, nCachingClients = 0, nCachelessClients = 1, maxClientXacts = 4, diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 5fd15e97..cdc0275e 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -7,7 +7,7 @@ import cde.{Parameters, Field} import junctions._ import junctions.NastiConstants._ import uncore.tilelink._ -import uncore.tilelink2.{LazyModule, LazyModuleImp} +import uncore.tilelink2._ import uncore.converters._ import uncore.devices._ import uncore.util._ @@ -202,10 +202,10 @@ trait PeripheryMasterMMIOModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripheryMasterMMIO val io: PeripheryMasterMMIOBundle - val mmioNetwork: Option[TileLinkRecursiveInterconnect] + val mmioNetwork: TileLinkRecursiveInterconnect val mmio_ports = p(ExtMMIOPorts) map { port => - TileLinkWidthAdapter(mmioNetwork.get.port(port.name), "MMIO_Outermost") + TileLinkWidthAdapter(mmioNetwork.port(port.name), "MMIO_Outermost") } val mmio_axi_start = 0 @@ -278,11 +278,16 @@ trait PeripherySlaveModule extends HasPeripheryParameters { ///// /** Always-ON block */ -trait PeripheryAON extends LazyModule { +trait PeripheryAON extends LazyModule with HasPeripheryParameters { implicit val p: Parameters - val pDevices: ResourceManager[AddrMapEntry] + val peripheryBus: TLXbar - pDevices.add(AddrMapEntry("prci", MemSize(0x4000000, MemAttr(AddrMapProt.RW)))) + val prci = LazyModule(new PRCI()(innerMMIOParams)) + prci.node := TLFragmenter(peripheryBus.node, 4, 256) + + // TL1 legacy + val pDevices: ResourceManager[AddrMapEntry] + pDevices.add(AddrMapEntry("prci", MemRange(prci.base, prci.size, MemAttr(AddrMapProt.RW)))) } trait PeripheryAONBundle { @@ -293,21 +298,23 @@ trait PeripheryAONModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripheryAON val io: PeripheryAONBundle - val mmioNetwork: Option[TileLinkRecursiveInterconnect] val coreplex: Coreplex - val prci = Module(new PRCI()(innerMMIOParams)) - prci.io.rtcTick := Counter(p(RTCPeriod)).inc() - prci.io.tl <> mmioNetwork.get.port("prci") - coreplex.io.prci <> prci.io.tiles + outer.prci.module.io.rtcTick := Counter(p(RTCPeriod)).inc() + coreplex.io.prci <> outer.prci.module.io.tiles } ///// trait PeripheryBootROM extends LazyModule { implicit val p: Parameters - val pDevices: ResourceManager[AddrMapEntry] + val peripheryBus: TLXbar + val rom = LazyModule(new TLROM(0x1000, 0x1000, GenerateBootROM(p))) + rom.node := TLFragmenter(peripheryBus.node, 4, 256) + + // TL1 legacy address map + val pDevices: ResourceManager[AddrMapEntry] pDevices.add(AddrMapEntry("bootrom", MemRange(0x1000, 4096, MemAttr(AddrMapProt.RX)))) } @@ -319,20 +326,23 @@ trait PeripheryBootROMModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripheryBootROM val io: PeripheryBootROMBundle - val mmioNetwork: Option[TileLinkRecursiveInterconnect] - - val bootROM = Module(new ROMSlave(GenerateBootROM(p))(innerMMIOParams)) - bootROM.io <> mmioNetwork.get.port("bootrom") } ///// trait PeripheryTestRAM extends LazyModule { implicit val p: Parameters - val pDevices: ResourceManager[AddrMapEntry] + val peripheryBus: TLXbar + val ramBase = 0x52000000 val ramSize = 0x1000 - pDevices.add(AddrMapEntry("testram", MemSize(ramSize, MemAttr(AddrMapProt.RW)))) + + val sram = LazyModule(new TLRAM(AddressSet(ramBase, ramSize-1))) + sram.node := TLFragmenter(peripheryBus.node, 4, 256) + + // TL1 legacy address map + val pDevices: ResourceManager[AddrMapEntry] + pDevices.add(AddrMapEntry("testram", MemRange(ramBase, ramSize, MemAttr(AddrMapProt.RW)))) } trait PeripheryTestRAMBundle { @@ -342,22 +352,16 @@ trait PeripheryTestRAMBundle { trait PeripheryTestRAMModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripheryTestRAM - val io: PeripheryTestRAMBundle - val mmioNetwork: Option[TileLinkRecursiveInterconnect] - - val testram = Module(new TileLinkTestRAM(outer.ramSize)(innerMMIOParams)) - testram.io <> mmioNetwork.get.port("testram") } ///// trait PeripheryTestBusMaster extends LazyModule { implicit val p: Parameters - val pBusMasters: RangeManager - val pDevices: ResourceManager[AddrMapEntry] + val peripheryBus: TLXbar - pBusMasters.add("busmaster", 1) - pDevices.add(AddrMapEntry("busmaster", MemSize(4096, MemAttr(AddrMapProt.RW)))) + val fuzzer = LazyModule(new TLFuzzer(5000)) + peripheryBus.node := fuzzer.node } trait PeripheryTestBusMasterBundle { @@ -367,16 +371,4 @@ trait PeripheryTestBusMasterBundle { trait PeripheryTestBusMasterModule { implicit val p: Parameters val outer: PeripheryTestBusMaster - val io: PeripheryTestBusMasterBundle - val mmioNetwork: Option[TileLinkRecursiveInterconnect] - val coreplex: Coreplex - - val busmaster = Module(new groundtest.ExampleBusMaster()(p)) - busmaster.io.mmio <> mmioNetwork.get.port("busmaster") - - { - val r = outer.pBusMasters.range("busmaster") - require(r._2 - r._1 == 1, "RangeManager should return 1 slot") - coreplex.io.slave(r._1) <> busmaster.io.mem - } } diff --git a/src/main/scala/rocketchip/Top.scala b/src/main/scala/rocketchip/Top.scala index c56ffc46..8e723d97 100644 --- a/src/main/scala/rocketchip/Top.scala +++ b/src/main/scala/rocketchip/Top.scala @@ -6,7 +6,7 @@ import Chisel._ import cde.{Parameters, Field} import junctions._ import uncore.tilelink._ -import uncore.tilelink2.{LazyModule, LazyModuleImp} +import uncore.tilelink2._ import uncore.devices._ import util.ParameterizedBundle import rocket._ @@ -26,6 +26,10 @@ abstract class BaseTop(val p: Parameters) extends LazyModule { val pInterrupts = new RangeManager val pBusMasters = new RangeManager val pDevices = new ResourceManager[AddrMapEntry] + val peripheryBus = LazyModule(new TLXbar) + val legacy = LazyModule(new TLLegacy()(p.alterPartial({ case TLId => "L2toMMIO" }))) + + peripheryBus.node := TLBuffer(TLWidthWidget(TLHintHandler(legacy.node), legacy.tlDataBytes)) } class BaseTopBundle(val p: Parameters, val c: Coreplex) extends ParameterizedBundle()(p) { @@ -41,7 +45,7 @@ class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, nSlaves = outer.pBusMasters.sum, nMemChannels = p(NMemoryChannels), hasSupervisor = p(UseVM), - hasExtMMIOPort = !(outer.pDevices.get.isEmpty && p(ExtMMIOPorts).isEmpty) + hasExtMMIOPort = true ) def genGlobalAddrMap = GenerateGlobalAddrMap(p, outer.pDevices.get) @@ -67,10 +71,11 @@ class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, io.success zip coreplex.io.success map { case (x, y) => x := y } - val mmioNetwork = c.hasExtMMIOPort.option( + val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, p(GlobalAddrMap).get.subMap("io:ext"))( - p.alterPartial({ case TLId => "L2toMMIO" })))) - mmioNetwork.foreach { _.io.in.head <> coreplex.io.master.mmio.get } + p.alterPartial({ case TLId => "L2toMMIO" }))) + mmioNetwork.io.in.head <> coreplex.io.master.mmio.get + outer.legacy.module.io.legacy <> mmioNetwork.port("TL2") } /** Example Top with Periphery */ diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index fb0d8676..1813713c 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -64,10 +64,8 @@ object GenerateGlobalAddrMap { new AddrMap(entries) } - lazy val extIOAddrMap = new AddrMap( - pDevicesEntries ++ p(ExtMMIOPorts), - start = BigInt("50000000", 16), - collapse = true) + lazy val tl2AddrMap = new AddrMap(pDevicesEntries, collapse = true) + lazy val extIOAddrMap = new AddrMap(AddrMapEntry("TL2", tl2AddrMap) +: p(ExtMMIOPorts), collapse = true) val memBase = 0x80000000L val memSize = p(ExtMemSize) @@ -85,7 +83,7 @@ object GenerateConfigString { def apply(p: Parameters, c: CoreplexConfig, pDevicesEntries: Seq[AddrMapEntry]) = { val addrMap = p(GlobalAddrMap).get val plicAddr = addrMap("io:int:plic").start - val prciAddr = addrMap("io:ext:prci").start + val prciAddr = addrMap("io:ext:TL2:prci").start val xLen = p(XLen) val res = new StringBuilder res append "plic {\n" @@ -138,7 +136,7 @@ object GenerateConfigString { } res append "};\n" pDevicesEntries foreach { entry => - val region = addrMap("io:ext:" + entry.name) + val region = addrMap("io:ext:TL2:" + entry.name) res append s"${entry.name} {\n" res append s" addr 0x${region.start.toString(16)};\n" res append s" size 0x${region.size.toString(16)}; \n" diff --git a/src/main/scala/uncore/devices/Prci.scala b/src/main/scala/uncore/devices/Prci.scala index d607be91..22b45425 100644 --- a/src/main/scala/uncore/devices/Prci.scala +++ b/src/main/scala/uncore/devices/Prci.scala @@ -6,7 +6,7 @@ import Chisel._ import rocket.Util._ import junctions._ import junctions.NastiConstants._ -import uncore.tilelink._ +import uncore.tilelink2._ import uncore.util._ import cde.{Parameters, Field} @@ -32,45 +32,28 @@ object PRCI { def size = 0xc000 } -/** Power, Reset, Clock, Interrupt */ -class PRCI(implicit val p: Parameters) extends Module - with HasTileLinkParameters - with HasAddrMapParameters { - val io = new Bundle { - val tl = new ClientUncachedTileLinkIO().flip - val tiles = Vec(p(NTiles), new PRCITileIO) - val rtcTick = Bool(INPUT) - } +case class PRCIConfig(address: BigInt = 0x44000000, beatBytes: Int = 4) + +trait MixPRCIParameters { + val params: (PRCIConfig, Parameters) + val c = params._1 + implicit val p = params._2 +} + +trait PRCIBundle extends Bundle with MixPRCIParameters { + val tiles = Vec(p(NTiles), new PRCITileIO) + val rtcTick = Bool(INPUT) +} + +trait PRCIModule extends Module with HasRegMap with MixPRCIParameters { + val io: PRCIBundle val timeWidth = 64 - val timecmp = Reg(Vec(p(NTiles), UInt(width = timeWidth))) val time = Reg(init=UInt(0, timeWidth)) when (io.rtcTick) { time := time + UInt(1) } - val ipi = Reg(init=Vec.fill(p(NTiles))(UInt(0, 32))) - - val acq = Queue(io.tl.acquire, 1) - val addr = acq.bits.full_addr()(log2Ceil(PRCI.size)-1,0) - val read = acq.bits.isBuiltInType(Acquire.getType) - val rdata = Wire(init=UInt(0)) - io.tl.grant.valid := acq.valid - acq.ready := io.tl.grant.ready - io.tl.grant.bits := Grant( - is_builtin_type = Bool(true), - g_type = acq.bits.getBuiltInGrantType(), - client_xact_id = acq.bits.client_xact_id, - manager_xact_id = UInt(0), - addr_beat = UInt(0), - data = rdata) - - when (addr(log2Floor(PRCI.time))) { - require(log2Floor(PRCI.timecmp(p(NTiles)-1)) < log2Floor(PRCI.time)) - rdata := store(Seq(time), acq.bits, io.tl.grant.fire()) - }.elsewhen (addr >= PRCI.timecmp(0)) { - rdata := store(timecmp, acq.bits, io.tl.grant.fire()) - }.otherwise { - rdata := store(ipi, acq.bits, io.tl.grant.fire()) & Fill(tlDataBits/32, UInt(1, 32)) - } + val timecmp = Seq.fill(p(NTiles)) { Reg(UInt(width = timeWidth)) } + val ipi = Seq.fill(p(NTiles)) { RegInit(UInt(0, width = 1)) } for ((tile, i) <- io.tiles zipWithIndex) { tile.interrupts.msip := ipi(i)(0) @@ -78,42 +61,28 @@ class PRCI(implicit val p: Parameters) extends Module tile.reset := reset } - // TODO generalize these to help other TL slaves - def load(v: Seq[UInt], acq: Acquire): UInt = { - val w = v.head.getWidth - val a = acq.full_addr() - require(isPow2(w) && w >= 8) - if (w > tlDataBits) { - (v(a.extract(log2Ceil(w/8*v.size)-1,log2Ceil(w/8))) >> a.extract(log2Ceil(w/8)-1,log2Ceil(tlDataBytes)))(tlDataBits-1,0) - } else { - val row: Seq[UInt] = for (i <- 0 until v.size by tlDataBits/w) - yield Cat(v.slice(i, i + tlDataBits/w).reverse) - if (row.size == 1) row.head - else row(a(log2Ceil(w/8*v.size)-1,log2Ceil(tlDataBytes))) - } - } + /* 0000 msip hart 0 + * 0004 msip hart 1 + * 4000 mtimecmp hart 0 lo + * 4004 mtimecmp hart 0 hi + * 4008 mtimecmp hart 1 lo + * 400c mtimecmp hart 1 hi + * bff8 mtime lo + * bffc mtime hi + */ - def store(v: Seq[UInt], acq: Acquire, en: Bool): UInt = { - val w = v.head.getWidth - require(isPow2(w) && w >= 8) - val a = acq.full_addr() - val rdata = load(v, acq) - val wdata = (acq.data & acq.full_wmask()) | (rdata & ~acq.full_wmask()) - when (en && acq.isBuiltInType(Acquire.putType)) { - if (w <= tlDataBits) { - val word = - if (tlDataBits/w >= v.size) UInt(0) - else a(log2Up(w/8*v.size)-1,log2Up(tlDataBytes)) - for (i <- 0 until v.size) when (word === i/(tlDataBits/w)) { - val base = i % (tlDataBits/w) - v(i) := wdata >> (w * (i % (tlDataBits/w))) - } - } else { - val i = a.extract(log2Ceil(w/8*v.size)-1,log2Ceil(w/8)) - val mask = FillInterleaved(tlDataBits, UIntToOH(a.extract(log2Ceil(w/8)-1,log2Ceil(tlDataBytes)))) - v(i) := (wdata & mask) | (v(i) & ~mask) - } - } - rdata - } + val timecmp_regs = timecmp.zipWithIndex.map { case (reg, i) => + RegField.bytes(reg, PRCI.timecmp(i)/c.beatBytes, c.beatBytes) + }.flatten + val time_reg = RegField.bytes(time, PRCI.time/c.beatBytes, c.beatBytes) + val ipi_regs = ipi.zipWithIndex.map { case (reg, i) => (i -> Seq(RegField(1, reg))) } + + regmap((timecmp_regs ++ time_reg ++ ipi_regs):_*) } + +/** Power, Reset, Clock, Interrupt */ +// Magic TL2 Incantation to create a TL2 Slave +class PRCI(c: PRCIConfig = PRCIConfig())(implicit val p: Parameters) + extends TLRegisterRouter(c.address, 0, 0x10000, None, c.beatBytes)( + new TLRegBundle((c, p), _) with PRCIBundle)( + new TLRegModule((c, p), _, _) with PRCIModule)