From abc5be8ef1dc9bb5614ef81fbb021b51a21679dd Mon Sep 17 00:00:00 2001 From: Abraham Gonzalez Date: Sun, 28 Feb 2021 22:26:12 +0000 Subject: [PATCH 01/12] Add OffchipAXI network port --- src/main/scala/SerialAdapter.scala | 122 ++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 2 deletions(-) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index 772a5959..bf878ef9 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -2,15 +2,16 @@ package testchipip import chisel3._ import chisel3.util._ -import chisel3.experimental.IO +import chisel3.experimental.{IO, DataMirror} import freechips.rocketchip.config.{Parameters, Field} import freechips.rocketchip.subsystem._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.devices.debug.HasPeripheryDebug import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -import freechips.rocketchip.prci.{ClockSinkDomain} +import freechips.rocketchip.prci.{ClockSourceNode, ClockSourceParameters, ClockSinkDomain, ClockBundle, ClockBundleParameters} import scala.math.min +import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4SlavePortParameters, AXI4SlaveParameters, AXI4UserYanker, AXI4IdIndexer} case object SerialAdapter { val SERIAL_TSI_WIDTH = 32 // hardcoded in FESVR @@ -32,6 +33,32 @@ case object SerialAdapter { ram } + def connectOffChipNetwork(serdesser: TLSerdesser, port: ClockedAndResetIO[ClockedIO[SerialIO]], reset: Reset): OffchipNetwork = { + implicit val p: Parameters = serdesser.p + + val net = LazyModule(new OffchipNetwork( + p(SerialTLKey).get.width, + p(SerialTLKey).get.memParams, + managerEdge = serdesser.managerNode.edges.in(0), + clientEdge = serdesser.clientNode.edges.out(0) + )) + + val serial_io = port.bits + + withClockAndReset(serial_io.clock, reset) { + val module = Module(net.module) + module.io.ser <> serial_io.bits + + module.io.offchipClkRst.clock := port.clock + module.io.offchipClkRst.reset := port.reset + } + + require(net.serdesser.module.mergedParams == serdesser.module.mergedParams, + "Mismatch between chip-side diplomatic params and harness-side diplomatic params") + + net + } + def connectSimSerial(serial: Option[SerialIO], clock: Clock, reset: Reset): Bool = { serial.map { s => val sim = Module(new SimSerial(s.w)) @@ -341,3 +368,94 @@ class SerialRAM( io.tsi_ser <> adapter.module.io.serial } } + +class OffchipNetwork( + w: Int, + memParams: MasterPortParams, + managerEdge: TLEdgeParameters, + clientEdge: TLEdgeParameters)(implicit p: Parameters) extends LazyModule { + val managerParams = clientEdge.slave // the managerParams are the chip-side clientParams + val clientParams = managerEdge.master // The clientParams are the chip-side managerParams + val adapter = LazyModule(new SerialAdapter) + val serdesser = LazyModule(new TLSerdesser( + w, + clientParams, + managerParams + )) + + val axiDomain = LazyModule(new ClockSinkDomain(name=Some("axi-domain"))) + val axiClkSource = ClockSourceNode(Seq(ClockSourceParameters())) + axiDomain.clockNode := axiClkSource + + // connect the axi port + val axiXbar = axiDomain { TLXbar() } + + val memPortParamsOpt = Some(MemoryPortParams(memParams, 1)) + val portName = "axi4" + val device = new MemoryDevice + val idBits = memPortParamsOpt.map(_.master.idBits).getOrElse(1) + val memBusParams = p(MemoryBusKey) + + val memAXI4Node = axiDomain { AXI4SlaveNode(memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels) => + Seq.tabulate(nMemoryChannels) { channel => + val base = AddressSet.misaligned(memPortParams.base, memPortParams.size) + val filter = AddressSet(channel * memBusParams.blockBytes, ~((nMemoryChannels-1) * memBusParams.blockBytes)) + + AXI4SlavePortParameters( + slaves = Seq(AXI4SlaveParameters( + address = base.flatMap(_.intersect(filter)), + resources = device.reg, + regionType = RegionType.UNCACHED, // cacheable + executable = true, + supportsWrite = TransferSizes(1, memBusParams.blockBytes), + supportsRead = TransferSizes(1, memBusParams.blockBytes), + interleavedId = Some(0))), // slave does not interleave read responses + beatBytes = memPortParams.beatBytes) + } + }).toList.flatten) } + + // connect xbar to serdes + ((axiDomain.crossIn(axiXbar)(ValName("AXIXbarCrossing")))(AsynchronousCrossing()) + := serdesser.clientNode) + + val hUserYanker = axiDomain { AXI4UserYanker() } + val hIdIdxer = axiDomain { AXI4IdIndexer(idBits) } + val hTLToAXI4 = axiDomain { TLToAXI4() } + val hWidWidget = axiDomain { TLWidthWidget(memBusParams.beatBytes) } + + (memAXI4Node + :*= hUserYanker + :*= hIdIdxer + :*= hTLToAXI4 + :*= hWidWidget + :*= axiXbar) + + // doesn't need to be in axiDomain since it is unclocked + val mem_axi4_domain = axiDomain { InModuleBody { memAXI4Node.makeIOs() } } + val mem_axi4 = InModuleBody { + val ports: Seq[AXI4Bundle] = mem_axi4_domain.zipWithIndex.map({ case (m, i) => + val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mem_${i}") + p <> m + p + }) + ports + } + + // connect the serial adapter + serdesser.managerNode := TLBuffer() := adapter.node + + lazy val module = new LazyModuleImp(this) { + val io = IO(new Bundle { + val ser = Flipped(new SerialIO(w)) + val tsi_ser = new SerialIO(SERIAL_TSI_WIDTH) + val offchipClkRst = Flipped(new ClockBundle(ClockBundleParameters())) + }) + + axiClkSource.out.head._1.clock := io.offchipClkRst.clock + axiClkSource.out.head._1.reset := io.offchipClkRst.reset + + serdesser.module.io.ser.in <> io.ser.out + io.ser.in <> serdesser.module.io.ser.out + io.tsi_ser <> adapter.module.io.serial + } +} From b66dd655a3605ff0b3327b133513e27b590d926e Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Tue, 2 Mar 2021 22:49:47 -0800 Subject: [PATCH 02/12] Cleanup | Add freq to SerialTLKey --- src/main/scala/Configs.scala | 3 ++ src/main/scala/SerialAdapter.scala | 71 ++++++++++++++++-------------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index d9aa87f2..4e2d6c8a 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -68,6 +68,9 @@ class WithSerialTLWidth(width: Int) extends Config((site, here, up) => { case SerialTLKey => up(SerialTLKey).map(k => k.copy(width=width)) }) +class WithAXIDomainFreq(axiDomainClockFreqMHz: Double) extends Config((site, here, up) => { + case SerialTLKey => up(SerialTLKey).map(k => k.copy(axiDomainClockFreqMHz=Some(axiDomainClockFreqMHz))) +}) class WithSerialPBusMem extends Config((site, here, up) => { case SerialTLAttachKey => up(SerialTLAttachKey, site).copy(slaveWhere = PBUS) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index bf878ef9..e056ee0e 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -13,6 +13,11 @@ import freechips.rocketchip.prci.{ClockSourceNode, ClockSourceParameters, ClockS import scala.math.min import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4SlavePortParameters, AXI4SlaveParameters, AXI4UserYanker, AXI4IdIndexer} +class SerialAndPassthroughClockResetIO(w: Int) extends Bundle { + val clocked_serial = new ClockedIO(new SerialIO(w)) + val passthrough_clock_reset = new ClockBundle(ClockBundleParameters()) +} + case object SerialAdapter { val SERIAL_TSI_WIDTH = 32 // hardcoded in FESVR @@ -33,30 +38,28 @@ case object SerialAdapter { ram } - def connectOffChipNetwork(serdesser: TLSerdesser, port: ClockedAndResetIO[ClockedIO[SerialIO]], reset: Reset): OffchipNetwork = { + def connectHarnessMultiClockAXIRAM(serdesser: TLSerdesser, port: SerialAndPassthroughClockResetIO, reset: Reset): MultiClockSerialAXIRAM = { implicit val p: Parameters = serdesser.p - val net = LazyModule(new OffchipNetwork( + val ram = LazyModule(new MultiClockSerialAXIRAM( p(SerialTLKey).get.width, p(SerialTLKey).get.memParams, managerEdge = serdesser.managerNode.edges.in(0), clientEdge = serdesser.clientNode.edges.out(0) )) - val serial_io = port.bits + val serial_io = port.clocked_serial withClockAndReset(serial_io.clock, reset) { - val module = Module(net.module) + val module = Module(ram.module) module.io.ser <> serial_io.bits - - module.io.offchipClkRst.clock := port.clock - module.io.offchipClkRst.reset := port.reset + module.io.passthrough_clock_reset <> port.passthrough_clock_reset } - require(net.serdesser.module.mergedParams == serdesser.module.mergedParams, + require(ram.serdesser.module.mergedParams == serdesser.module.mergedParams, "Mismatch between chip-side diplomatic params and harness-side diplomatic params") - net + ram } def connectSimSerial(serial: Option[SerialIO], clock: Clock, reset: Reset): Bool = { @@ -255,7 +258,8 @@ class SimSerial(w: Int) extends BlackBox with HasBlackBoxResource { addResource("/testchipip/csrc/testchip_tsi.h") } -case class SerialTLParams(memParams: MasterPortParams, isMemoryDevice: Boolean = false, width: Int = 4) +// axi domain freq matches FireSim default 1GHz +case class SerialTLParams(memParams: MasterPortParams, isMemoryDevice: Boolean = false, width: Int = 4, axiDomainClockFreqMHz: Option[Double] = Some(1000.0)) case object SerialTLKey extends Field[Option[SerialTLParams]](None) case class SerialTLAttachParams( @@ -369,11 +373,12 @@ class SerialRAM( } } -class OffchipNetwork( +class MultiClockSerialAXIRAM( w: Int, memParams: MasterPortParams, managerEdge: TLEdgeParameters, clientEdge: TLEdgeParameters)(implicit p: Parameters) extends LazyModule { + val managerParams = clientEdge.slave // the managerParams are the chip-side clientParams val clientParams = managerEdge.master // The clientParams are the chip-side managerParams val adapter = LazyModule(new SerialAdapter) @@ -390,6 +395,7 @@ class OffchipNetwork( // connect the axi port val axiXbar = axiDomain { TLXbar() } + // TODO: Currently only supports single-channel memory val memPortParamsOpt = Some(MemoryPortParams(memParams, 1)) val portName = "axi4" val device = new MemoryDevice @@ -414,26 +420,29 @@ class OffchipNetwork( } }).toList.flatten) } - // connect xbar to serdes - ((axiDomain.crossIn(axiXbar)(ValName("AXIXbarCrossing")))(AsynchronousCrossing()) - := serdesser.clientNode) - - val hUserYanker = axiDomain { AXI4UserYanker() } - val hIdIdxer = axiDomain { AXI4IdIndexer(idBits) } - val hTLToAXI4 = axiDomain { TLToAXI4() } - val hWidWidget = axiDomain { TLWidthWidget(memBusParams.beatBytes) } + val axiWidgets = axiDomain { + (AXI4UserYanker() + :*= AXI4IdIndexer(idBits) + :*= TLToAXI4() + :*= TLWidthWidget(memBusParams.beatBytes)) + } + // connect axi mem to axi xbar (memAXI4Node - :*= hUserYanker - :*= hIdIdxer - :*= hTLToAXI4 - :*= hWidWidget + :*= axiWidgets :*= axiXbar) - // doesn't need to be in axiDomain since it is unclocked - val mem_axi4_domain = axiDomain { InModuleBody { memAXI4Node.makeIOs() } } + // connect axi xbar (i.e. axi mem) to serdes client + ((axiDomain.crossIn(axiXbar)(ValName("AXIXbarCrossing")))(AsynchronousCrossing()) + := serdesser.clientNode) + + // connect the serial adapter to serdes manager + serdesser.managerNode := TLBuffer() := adapter.node + + // create axi io port + val memAXI4Port = axiDomain { InModuleBody { memAXI4Node.makeIOs() } } val mem_axi4 = InModuleBody { - val ports: Seq[AXI4Bundle] = mem_axi4_domain.zipWithIndex.map({ case (m, i) => + val ports: Seq[AXI4Bundle] = memAXI4Port.zipWithIndex.map({ case (m, i) => val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mem_${i}") p <> m p @@ -441,19 +450,17 @@ class OffchipNetwork( ports } - // connect the serial adapter - serdesser.managerNode := TLBuffer() := adapter.node - lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { val ser = Flipped(new SerialIO(w)) val tsi_ser = new SerialIO(SERIAL_TSI_WIDTH) - val offchipClkRst = Flipped(new ClockBundle(ClockBundleParameters())) + val passthrough_clock_reset = Flipped(new ClockBundle(ClockBundleParameters())) }) - axiClkSource.out.head._1.clock := io.offchipClkRst.clock - axiClkSource.out.head._1.reset := io.offchipClkRst.reset + // setup the axi4 clock domain + axiClkSource.out.head._1 <> io.passthrough_clock_reset + // connect the serdes+serial adapter in the main clock domain serdesser.module.io.ser.in <> io.ser.out io.ser.in <> serdesser.module.io.ser.out io.tsi_ser <> adapter.module.io.serial From 531ffb7020ef012c5d9dd8642df515d2fbadd7a8 Mon Sep 17 00:00:00 2001 From: Abraham Gonzalez Date: Wed, 3 Mar 2021 19:44:01 +0000 Subject: [PATCH 03/12] Add ability to change BlockDevice location --- src/main/scala/Configs.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 4e2d6c8a..6fb64436 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -44,6 +44,10 @@ class WithBlockDevice extends Config((site, here, up) => { case BlockDeviceKey => Some(BlockDeviceConfig()) }) +class WithBlockDeviceLocations(slaveWhere: TLBusWrapperLocation = PBUS, masterWhere: TLBusWrapperLocation = FBUS) extends Config((site, here, up) => { + case BlockDeviceAttachKey => BlockDeviceAttachParams(slaveWhere, masterWhere) +}) + class WithNBlockDeviceTrackers(n: Int) extends Config((site, here, up) => { case BlockDeviceKey => up(BlockDeviceKey, site) match { case Some(a) => Some(a.copy(nTrackers = n)) From 3de5c07d054ec301499e75374f3ae2c2cea3930c Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Wed, 3 Mar 2021 22:38:21 -0800 Subject: [PATCH 04/12] Slightly cleaner implementation --- src/main/scala/Configs.scala | 4 +- src/main/scala/SerialAdapter.scala | 128 ++++++++++++++++++----------- 2 files changed, 82 insertions(+), 50 deletions(-) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 6fb64436..59b1b21b 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -72,8 +72,8 @@ class WithSerialTLWidth(width: Int) extends Config((site, here, up) => { case SerialTLKey => up(SerialTLKey).map(k => k.copy(width=width)) }) -class WithAXIDomainFreq(axiDomainClockFreqMHz: Double) extends Config((site, here, up) => { - case SerialTLKey => up(SerialTLKey).map(k => k.copy(axiDomainClockFreqMHz=Some(axiDomainClockFreqMHz))) +class WithAXIMemOverSerialTLChanges(axiMemOverSerialTLParams: AXIMemOverSerialTLClockParams) extends Config((site, here, up) => { + case SerialTLKey => up(SerialTLKey).map(k => k.copy(axiMemOverSerialTLParams=Some(axiMemOverSerialTLParams))) }) class WithSerialPBusMem extends Config((site, here, up) => { diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index e056ee0e..1e67dfe2 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -44,6 +44,7 @@ case object SerialAdapter { val ram = LazyModule(new MultiClockSerialAXIRAM( p(SerialTLKey).get.width, p(SerialTLKey).get.memParams, + p(SerialTLKey).get.axiMemOverSerialTLParams.get, managerEdge = serdesser.managerNode.edges.in(0), clientEdge = serdesser.clientNode.edges.out(0) )) @@ -258,8 +259,19 @@ class SimSerial(w: Int) extends BlackBox with HasBlackBoxResource { addResource("/testchipip/csrc/testchip_tsi.h") } -// axi domain freq matches FireSim default 1GHz -case class SerialTLParams(memParams: MasterPortParams, isMemoryDevice: Boolean = false, width: Int = 4, axiDomainClockFreqMHz: Option[Double] = Some(1000.0)) +case class AXIClockParams( + clockFreqMHz: Double = 1000.0, // Match FireSim's 1GHz MBUS freq. + crossingType: ClockCrossingType = AsynchronousCrossing() // Default to async crossing +) +case class AXIMemOverSerialTLClockParams( + axiClockParams: Option[AXIClockParams] = Some(AXIClockParams()) // if set, axi port in different clk domain +) +case class SerialTLParams( + memParams: MasterPortParams, + isMemoryDevice: Boolean = false, + width: Int = 4, + axiMemOverSerialTLParams: Option[AXIMemOverSerialTLClockParams] = Some(AXIMemOverSerialTLClockParams()) // if enabled, expose axi port instead of TL RAM +) case object SerialTLKey extends Field[Option[SerialTLParams]](None) case class SerialTLAttachParams( @@ -376,9 +388,11 @@ class SerialRAM( class MultiClockSerialAXIRAM( w: Int, memParams: MasterPortParams, + axiMemOverSerialTLParams: AXIMemOverSerialTLClockParams, managerEdge: TLEdgeParameters, clientEdge: TLEdgeParameters)(implicit p: Parameters) extends LazyModule { + // setup serdes and serial adapter val managerParams = clientEdge.slave // the managerParams are the chip-side clientParams val clientParams = managerEdge.master // The clientParams are the chip-side managerParams val adapter = LazyModule(new SerialAdapter) @@ -388,12 +402,25 @@ class MultiClockSerialAXIRAM( managerParams )) - val axiDomain = LazyModule(new ClockSinkDomain(name=Some("axi-domain"))) - val axiClkSource = ClockSourceNode(Seq(ClockSourceParameters())) - axiDomain.clockNode := axiClkSource + // connect the serial adapter to serdes manager + serdesser.managerNode := TLBuffer() := adapter.node + + val memClkRstDomain = LazyModule(new ClockSinkDomain(name=Some("mem-over-serialtl-domain"))) + val memClkRstSource = ClockSourceNode(Seq(ClockSourceParameters())) + memClkRstDomain.clockNode := memClkRstSource + + val memCrossing = axiMemOverSerialTLParams.axiClockParams match { + case Some(params) => { + params.crossingType + } + case None => { + SynchronousCrossing() + } + } + + val memXbar = memClkRstDomain { TLXbar() } - // connect the axi port - val axiXbar = axiDomain { TLXbar() } + (memClkRstDomain.crossIn(memXbar)(ValName("MemPortCrossing")))(memCrossing) := serdesser.clientNode // TODO: Currently only supports single-channel memory val memPortParamsOpt = Some(MemoryPortParams(memParams, 1)) @@ -402,50 +429,45 @@ class MultiClockSerialAXIRAM( val idBits = memPortParamsOpt.map(_.master.idBits).getOrElse(1) val memBusParams = p(MemoryBusKey) - val memAXI4Node = axiDomain { AXI4SlaveNode(memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels) => - Seq.tabulate(nMemoryChannels) { channel => - val base = AddressSet.misaligned(memPortParams.base, memPortParams.size) - val filter = AddressSet(channel * memBusParams.blockBytes, ~((nMemoryChannels-1) * memBusParams.blockBytes)) - - AXI4SlavePortParameters( - slaves = Seq(AXI4SlaveParameters( - address = base.flatMap(_.intersect(filter)), - resources = device.reg, - regionType = RegionType.UNCACHED, // cacheable - executable = true, - supportsWrite = TransferSizes(1, memBusParams.blockBytes), - supportsRead = TransferSizes(1, memBusParams.blockBytes), - interleavedId = Some(0))), // slave does not interleave read responses - beatBytes = memPortParams.beatBytes) - } - }).toList.flatten) } + val memNode = memClkRstDomain { + AXI4SlaveNode(memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels) => + Seq.tabulate(nMemoryChannels) { channel => + val base = AddressSet.misaligned(memPortParams.base, memPortParams.size) + val filter = AddressSet(channel * memBusParams.blockBytes, ~((nMemoryChannels-1) * memBusParams.blockBytes)) + + AXI4SlavePortParameters( + slaves = Seq(AXI4SlaveParameters( + address = base.flatMap(_.intersect(filter)), + resources = device.reg, + regionType = RegionType.UNCACHED, // cacheable + executable = true, + supportsWrite = TransferSizes(1, memBusParams.blockBytes), + supportsRead = TransferSizes(1, memBusParams.blockBytes), + interleavedId = Some(0))), // slave does not interleave read responses + beatBytes = memPortParams.beatBytes) + } + }).toList.flatten) + } - val axiWidgets = axiDomain { - (AXI4UserYanker() + val memPort = memClkRstDomain { + // connect axi mem to axi widgets to mem xbar + (memNode + :*= AXI4UserYanker() :*= AXI4IdIndexer(idBits) :*= TLToAXI4() - :*= TLWidthWidget(memBusParams.beatBytes)) - } - - // connect axi mem to axi xbar - (memAXI4Node - :*= axiWidgets - :*= axiXbar) - - // connect axi xbar (i.e. axi mem) to serdes client - ((axiDomain.crossIn(axiXbar)(ValName("AXIXbarCrossing")))(AsynchronousCrossing()) - := serdesser.clientNode) + :*= TLWidthWidget(memBusParams.beatBytes) + :*= memXbar) - // connect the serial adapter to serdes manager - serdesser.managerNode := TLBuffer() := adapter.node + InModuleBody { memNode.makeIOs() } + } - // create axi io port - val memAXI4Port = axiDomain { InModuleBody { memAXI4Node.makeIOs() } } val mem_axi4 = InModuleBody { - val ports: Seq[AXI4Bundle] = memAXI4Port.zipWithIndex.map({ case (m, i) => - val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mem_${i}") - p <> m - p + val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = memPort.zipWithIndex.map({ case (m, i) => + val port = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}") + port.bits <> m + port.clock := memClkRstSource.out.head._1.clock + port.reset := memClkRstSource.out.head._1.reset + port }) ports } @@ -457,10 +479,20 @@ class MultiClockSerialAXIRAM( val passthrough_clock_reset = Flipped(new ClockBundle(ClockBundleParameters())) }) - // setup the axi4 clock domain - axiClkSource.out.head._1 <> io.passthrough_clock_reset + // setup clock domain + axiMemOverSerialTLParams.axiClockParams match { + case Some(params) => { + // setup the clock domain to be the passthrough clock + memClkRstSource.out.head._1 <> io.passthrough_clock_reset + } + case None => { + // connect to implicit clock/reset + memClkRstSource.out.head._1.clock <> clock + memClkRstSource.out.head._1.reset <> reset + } + } - // connect the serdes+serial adapter in the main clock domain + // connect the serdes and serial adapter in the serdes clock domain serdesser.module.io.ser.in <> io.ser.out io.ser.in <> serdesser.module.io.ser.out io.tsi_ser <> adapter.module.io.serial From 927709c09e404c64108bb909f894e35c9a63396c Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Fri, 5 Mar 2021 00:06:57 -0800 Subject: [PATCH 05/12] Add config to disable block device | Split multiclock RAM ports --- src/main/scala/Configs.scala | 4 ++++ src/main/scala/SerialAdapter.scala | 10 ++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 59b1b21b..52747c1a 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -44,6 +44,10 @@ class WithBlockDevice extends Config((site, here, up) => { case BlockDeviceKey => Some(BlockDeviceConfig()) }) +class WithNoBlockDevice extends Config((site, here, up) => { + case BlockDeviceKey => None +}) + class WithBlockDeviceLocations(slaveWhere: TLBusWrapperLocation = PBUS, masterWhere: TLBusWrapperLocation = FBUS) extends Config((site, here, up) => { case BlockDeviceAttachKey => BlockDeviceAttachParams(slaveWhere, masterWhere) }) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index 1e67dfe2..4a006f0c 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -38,7 +38,7 @@ case object SerialAdapter { ram } - def connectHarnessMultiClockAXIRAM(serdesser: TLSerdesser, port: SerialAndPassthroughClockResetIO, reset: Reset): MultiClockSerialAXIRAM = { + def connectHarnessMultiClockAXIRAM(serdesser: TLSerdesser, serial_port: ClockedIO[SerialIO], mem_clock_port: ClockBundle, reset: Reset): MultiClockSerialAXIRAM = { implicit val p: Parameters = serdesser.p val ram = LazyModule(new MultiClockSerialAXIRAM( @@ -49,12 +49,10 @@ case object SerialAdapter { clientEdge = serdesser.clientNode.edges.out(0) )) - val serial_io = port.clocked_serial - - withClockAndReset(serial_io.clock, reset) { + withClockAndReset(serial_port.clock, reset) { val module = Module(ram.module) - module.io.ser <> serial_io.bits - module.io.passthrough_clock_reset <> port.passthrough_clock_reset + module.io.ser <> serial_port.bits + module.io.passthrough_clock_reset <> mem_clock_port } require(ram.serdesser.module.mergedParams == serdesser.module.mergedParams, From 03c4ac486209253aaa20a702842fba511cfeac04 Mon Sep 17 00:00:00 2001 From: Abraham Gonzalez Date: Mon, 8 Mar 2021 22:01:32 +0000 Subject: [PATCH 06/12] Disable BlockDevice with single frag. --- src/main/scala/Configs.scala | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 52747c1a..619ee3d6 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -40,12 +40,11 @@ class TestChipUnitTestConfig extends Config( class ClockUtilTestConfig extends Config( new WithClockUtilTests ++ new BaseConfig) -class WithBlockDevice extends Config((site, here, up) => { - case BlockDeviceKey => Some(BlockDeviceConfig()) -}) - -class WithNoBlockDevice extends Config((site, here, up) => { - case BlockDeviceKey => None +class WithBlockDevice(enable: Boolean = true) extends Config((site, here, up) => { + case BlockDeviceKey => enable match { + case true => Some(BlockDeviceConfig()) + case false => None + } }) class WithBlockDeviceLocations(slaveWhere: TLBusWrapperLocation = PBUS, masterWhere: TLBusWrapperLocation = FBUS) extends Config((site, here, up) => { From 6b082f1edb6c8e4342587ca80aefd8af6e6e8a53 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Mon, 15 Mar 2021 16:53:15 -0700 Subject: [PATCH 07/12] Add function to determine mem clock freq --- src/main/scala/SerialAdapter.scala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index 4a006f0c..15baeca0 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -263,7 +263,17 @@ case class AXIClockParams( ) case class AXIMemOverSerialTLClockParams( axiClockParams: Option[AXIClockParams] = Some(AXIClockParams()) // if set, axi port in different clk domain -) +) { + def getMemFrequency(system: HasTileLinkLocations)(implicit p: Parameters): Double = { + axiClockParams match { + case Some(clkParams) => clkParams.clockFreqMHz * (1000 * 1000) + case None => { + // get freq. from what the master of the serial link specifies + system.locateTLBusWrapper(p(SerialTLAttachKey).masterWhere).dtsFrequency.get.toDouble + } + } + } +} case class SerialTLParams( memParams: MasterPortParams, isMemoryDevice: Boolean = false, From b014c24e7a14d71d20ecae38928294b7ecaa082b Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Fri, 19 Mar 2021 17:32:27 -0700 Subject: [PATCH 08/12] Enforce that tiles come out of reset after rest of system --- src/main/scala/TileResetCtrl.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/TileResetCtrl.scala b/src/main/scala/TileResetCtrl.scala index 607a0028..e18a0d35 100644 --- a/src/main/scala/TileResetCtrl.scala +++ b/src/main/scala/TileResetCtrl.scala @@ -61,7 +61,8 @@ class TLTileResetCtrl(w: Int, params: TileResetCtrlParams, tile_prci_domains: Se // clocked to the bus this is attached to, not the clock in this // clock bundle. We expect a ClockGroupResetSynchronizer downstream // to synchronize the resets - oD.reset := r.asBool.asAsyncReset + // Also, this or enforces that the tiles come out of reset after the reset of the system + oD.reset := (r.asBool || asyncResetSinkNode.in.head._1.reset.asBool).asAsyncReset } } } From 289ad47e6c22f4aed3cbe79f58193a227047728e Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Fri, 19 Mar 2021 18:42:54 -0700 Subject: [PATCH 09/12] Expand on serdess require print | Remove unused IO --- src/main/scala/Configs.scala | 2 +- src/main/scala/SerialAdapter.scala | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 619ee3d6..e928c0ce 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -75,7 +75,7 @@ class WithSerialTLWidth(width: Int) extends Config((site, here, up) => { case SerialTLKey => up(SerialTLKey).map(k => k.copy(width=width)) }) -class WithAXIMemOverSerialTLChanges(axiMemOverSerialTLParams: AXIMemOverSerialTLClockParams) extends Config((site, here, up) => { +class WithAXIMemOverSerialTL(axiMemOverSerialTLParams: AXIMemOverSerialTLClockParams) extends Config((site, here, up) => { case SerialTLKey => up(SerialTLKey).map(k => k.copy(axiMemOverSerialTLParams=Some(axiMemOverSerialTLParams))) }) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index 15baeca0..322e0d12 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -13,11 +13,6 @@ import freechips.rocketchip.prci.{ClockSourceNode, ClockSourceParameters, ClockS import scala.math.min import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4SlavePortParameters, AXI4SlaveParameters, AXI4UserYanker, AXI4IdIndexer} -class SerialAndPassthroughClockResetIO(w: Int) extends Bundle { - val clocked_serial = new ClockedIO(new SerialIO(w)) - val passthrough_clock_reset = new ClockBundle(ClockBundleParameters()) -} - case object SerialAdapter { val SERIAL_TSI_WIDTH = 32 // hardcoded in FESVR @@ -34,7 +29,9 @@ case object SerialAdapter { module.io.ser <> port.bits } require(ram.serdesser.module.mergedParams == serdesser.module.mergedParams, - "Mismatch between chip-side diplomatic params and harness-side diplomatic params") + "Mismatch between chip-side diplomatic params and harness-side diplomatic params:\n" + + s"Harness-side params: ${ram.serdesser.module.mergedParams}\n" + + s"Chip-side params: ${ram.serdesser.module.mergedParams}") ram } @@ -56,7 +53,9 @@ case object SerialAdapter { } require(ram.serdesser.module.mergedParams == serdesser.module.mergedParams, - "Mismatch between chip-side diplomatic params and harness-side diplomatic params") + "Mismatch between chip-side diplomatic params and harness-side diplomatic params:\n" + + s"Harness-side params: ${ram.serdesser.module.mergedParams}\n" + + s"Chip-side params: ${ram.serdesser.module.mergedParams}") ram } From ef59e54c42eb990036f13378dea5900713154228 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Fri, 19 Mar 2021 20:48:58 -0700 Subject: [PATCH 10/12] Clock all non-axi components by the harness clock --- src/main/scala/SerialAdapter.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index c2e389db..af0fa031 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -48,12 +48,14 @@ case object SerialAdapter { def connectHarnessRAM(serdesser: TLSerdesser, port: SerialIO, reset: Reset): SerialRAM = { implicit val p: Parameters = serdesser.p + val ram = LazyModule(new SerialRAM( p(SerialTLKey).get.width, p(SerialTLKey).get.memParams, managerEdge = serdesser.managerNode.edges.in(0), clientEdge = serdesser.clientNode.edges.out(0) )) + val module = Module(ram.module) module.io.ser <> port @@ -61,10 +63,11 @@ case object SerialAdapter { "Mismatch between chip-side diplomatic params and harness-side diplomatic params:\n" + s"Harness-side params: ${ram.serdesser.module.mergedParams}\n" + s"Chip-side params: ${ram.serdesser.module.mergedParams}") + ram } - def connectHarnessMultiClockAXIRAM(serdesser: TLSerdesser, serial_port: ClockedIO[SerialIO], mem_clock_port: ClockBundle, reset: Reset): MultiClockSerialAXIRAM = { + def connectHarnessMultiClockAXIRAM(serdesser: TLSerdesser, serial_port: SerialIO, mem_clock_port: ClockBundle, reset: Reset): MultiClockSerialAXIRAM = { implicit val p: Parameters = serdesser.p val ram = LazyModule(new MultiClockSerialAXIRAM( @@ -75,11 +78,9 @@ case object SerialAdapter { clientEdge = serdesser.clientNode.edges.out(0) )) - withClockAndReset(serial_port.clock, reset) { - val module = Module(ram.module) - module.io.ser <> serial_port.bits - module.io.passthrough_clock_reset <> mem_clock_port - } + val module = Module(ram.module) + module.io.ser <> serial_port + module.io.passthrough_clock_reset <> mem_clock_port require(ram.serdesser.module.mergedParams == serdesser.module.mergedParams, "Mismatch between chip-side diplomatic params and harness-side diplomatic params:\n" + From 1d2ac9c13bd1d4c053bbf9c7d57436f0113c39fd Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Sun, 21 Mar 2021 15:33:42 -0700 Subject: [PATCH 11/12] Fix require printing --- src/main/scala/SerialAdapter.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index af0fa031..ba0f5943 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -62,7 +62,7 @@ case object SerialAdapter { require(ram.serdesser.module.mergedParams == serdesser.module.mergedParams, "Mismatch between chip-side diplomatic params and harness-side diplomatic params:\n" + s"Harness-side params: ${ram.serdesser.module.mergedParams}\n" + - s"Chip-side params: ${ram.serdesser.module.mergedParams}") + s"Chip-side params: ${serdesser.module.mergedParams}") ram } @@ -85,7 +85,7 @@ case object SerialAdapter { require(ram.serdesser.module.mergedParams == serdesser.module.mergedParams, "Mismatch between chip-side diplomatic params and harness-side diplomatic params:\n" + s"Harness-side params: ${ram.serdesser.module.mergedParams}\n" + - s"Chip-side params: ${ram.serdesser.module.mergedParams}") + s"Chip-side params: ${serdesser.module.mergedParams}") ram } From fd7760e2862661bf6277acfeeb42644797e876d0 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Mon, 22 Mar 2021 11:23:51 -0700 Subject: [PATCH 12/12] Update comment [ci skip] --- src/main/scala/SerialAdapter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/SerialAdapter.scala b/src/main/scala/SerialAdapter.scala index ba0f5943..46b78433 100644 --- a/src/main/scala/SerialAdapter.scala +++ b/src/main/scala/SerialAdapter.scala @@ -297,7 +297,7 @@ case class AXIMemOverSerialTLClockParams( axiClockParams match { case Some(clkParams) => clkParams.clockFreqMHz * (1000 * 1000) case None => { - // get freq. from what the master of the serial link specifies + // get the freq. from what the serial link masters system.locateTLBusWrapper(p(SerialTLAttachKey).masterWhere).dtsFrequency.get.toDouble } }