From 02a951703b0d6da5f5bff9118dc10ef49afa6cba Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 2 Jul 2020 00:52:51 -0700 Subject: [PATCH 01/93] Initialize riscv-sodor --- .gitmodules | 3 +++ generators/riscv-sodor | 1 + 2 files changed, 4 insertions(+) create mode 160000 generators/riscv-sodor diff --git a/.gitmodules b/.gitmodules index aab9a8f7..f374fa1f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -128,3 +128,6 @@ [submodule "tools/dromajo/dromajo-src"] path = tools/dromajo/dromajo-src url = https://github.com/riscv-boom/dromajo.git +[submodule "generators/riscv-sodor"] + path = generators/riscv-sodor + url = https://github.com/ucb-bar/riscv-sodor.git diff --git a/generators/riscv-sodor b/generators/riscv-sodor new file mode 160000 index 00000000..73af1b70 --- /dev/null +++ b/generators/riscv-sodor @@ -0,0 +1 @@ +Subproject commit 73af1b7099764350c6dab6c5960334abcb7bdf07 From 85069387c9ccce5b12d86215b3fce10fe6679ea1 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 8 Jul 2020 14:45:12 -0700 Subject: [PATCH 02/93] Base Scratchpad --- build.sbt | 6 +++++- generators/riscv-sodor | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 5d642c1d..750878ab 100644 --- a/build.sbt +++ b/build.sbt @@ -132,7 +132,7 @@ lazy val chipyard = conditionalDependsOn(project in file("generators/chipyard")) .dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, iocell, sha3, // On separate line to allow for cleaner tutorial-setup patches dsptools, `rocket-dsptools`, - gemmini, icenet, tracegen, ariane, nvdla) + gemmini, icenet, tracegen, ariane, nvdla, sodor) .settings(commonSettings) lazy val tracegen = conditionalDependsOn(project in file("generators/tracegen")) @@ -158,6 +158,10 @@ lazy val ariane = (project in file("generators/ariane")) .dependsOn(rocketchip) .settings(commonSettings) +lazy val sodor = (project in file("generators/riscv-sodor")) + .dependsOn(rocketchip) + .settings(commonSettings) + lazy val sha3 = (project in file("generators/sha3")) .dependsOn(rocketchip, chisel_testers, midasTargetUtils) .settings(commonSettings) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 73af1b70..607f346f 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 73af1b7099764350c6dab6c5960334abcb7bdf07 +Subproject commit 607f346ff2e92977dcadda6cbd5b85589edcfbea From 1933fd8cbe21d697fafeebebabe50c775e65c55a Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Tue, 14 Jul 2020 12:10:12 -0700 Subject: [PATCH 03/93] Update sodor package structure --- .../src/main/scala/config/SodorConfigs.scala | 20 +++++++++++++++++++ generators/riscv-sodor | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 generators/chipyard/src/main/scala/config/SodorConfigs.scala diff --git a/generators/chipyard/src/main/scala/config/SodorConfigs.scala b/generators/chipyard/src/main/scala/config/SodorConfigs.scala new file mode 100644 index 00000000..dfcfebe7 --- /dev/null +++ b/generators/chipyard/src/main/scala/config/SodorConfigs.scala @@ -0,0 +1,20 @@ +package chipyard + +import chisel3._ + +import freechips.rocketchip.config.{Config} + +class SodorConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter + new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts + new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) + new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing + new testchipip.WithTSI ++ // use testchipip serial offchip link + new chipyard.config.WithBootROM ++ // use default bootrom + new chipyard.config.WithUART ++ // add a UART + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) + new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts + new sodor.common.WithNSodorCores(1) ++ // single Ariane core + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 + new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 607f346f..5e6a775d 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 607f346ff2e92977dcadda6cbd5b85589edcfbea +Subproject commit 5e6a775ded0c19719f61acbae11874478bc9a8b5 From 7bb1a48b1a5eacfc942d6b3f461823ecb8fd17c8 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 16 Jul 2020 14:12:29 -0700 Subject: [PATCH 04/93] Connect TileLink nodes --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 5e6a775d..fbb9a9df 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 5e6a775ded0c19719f61acbae11874478bc9a8b5 +Subproject commit fbb9a9df0fb33f9228616902c1cf53083a73e6b6 From d56df6252c7d3f5ebe5eb630cf84e156b573d8b9 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 23 Jul 2020 19:24:44 -0700 Subject: [PATCH 05/93] Sync --- .../src/main/scala/config/SodorConfigs.scala | 30 +++++++++++-------- generators/riscv-sodor | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/generators/chipyard/src/main/scala/config/SodorConfigs.scala b/generators/chipyard/src/main/scala/config/SodorConfigs.scala index dfcfebe7..1e1b7e51 100644 --- a/generators/chipyard/src/main/scala/config/SodorConfigs.scala +++ b/generators/chipyard/src/main/scala/config/SodorConfigs.scala @@ -5,16 +5,20 @@ import chisel3._ import freechips.rocketchip.config.{Config} class SodorConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter - new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts - new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) - new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing - new testchipip.WithTSI ++ // use testchipip serial offchip link - new chipyard.config.WithBootROM ++ // use default bootrom - new chipyard.config.WithUART ++ // add a UART - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts - new sodor.common.WithNSodorCores(1) ++ // single Ariane core - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 - new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system + new chipyard.iobinders.WithUARTAdapter ++ + new chipyard.iobinders.WithTieOffInterrupts ++ + new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimSerial ++ + new testchipip.WithTSI ++ + new chipyard.config.WithBootROM ++ + new chipyard.config.WithUART ++ + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new freechips.rocketchip.subsystem.WithNoMemPort ++ + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ + new freechips.rocketchip.subsystem.WithNoSlavePort ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new sodor.common.WithNSodorCores(1) ++ + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + new freechips.rocketchip.system.BaseConfig) \ No newline at end of file diff --git a/generators/riscv-sodor b/generators/riscv-sodor index fbb9a9df..f78d07e3 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit fbb9a9df0fb33f9228616902c1cf53083a73e6b6 +Subproject commit f78d07e387fcb90ae324bfdc5881b7f88e509248 From 14e2a9dbd1be267698f6eb0996a753de2e4f8921 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 24 Jul 2020 14:17:29 -0700 Subject: [PATCH 06/93] Fixed tile_master --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index f78d07e3..c3423720 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit f78d07e387fcb90ae324bfdc5881b7f88e509248 +Subproject commit c34237201ec83c24f33b4b5dbc02bd7f1368dfcd From 6131ab58e5b826598b4fb0b082e033c6235cacb8 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Tue, 28 Jul 2020 13:37:07 -0700 Subject: [PATCH 07/93] Connect cores --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index c3423720..e9b9aa4e 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit c34237201ec83c24f33b4b5dbc02bd7f1368dfcd +Subproject commit e9b9aa4e0150aba1326644318243619c4899c9ae From 98ef89cbde8cd166fe39cfe96f55d45edd58006f Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 29 Jul 2020 15:02:33 -0700 Subject: [PATCH 08/93] Created Internal Tiles --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index e9b9aa4e..a4d5c5c0 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit e9b9aa4e0150aba1326644318243619c4899c9ae +Subproject commit a4d5c5c0e582146ec09d018af466fe5def979f3b From a2bd26b91cbef686d56460dab86861e7e32673c4 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 31 Jul 2020 20:54:42 -0700 Subject: [PATCH 09/93] Finished Sodor Design --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index a4d5c5c0..eed11e8a 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit a4d5c5c0e582146ec09d018af466fe5def979f3b +Subproject commit eed11e8ab242d9144c3c6eb60e3fdd65218ade31 From 7f5b324d0639a058ee86d8066c2df0b9bd997f8e Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 5 Aug 2020 17:16:36 -0700 Subject: [PATCH 10/93] Added interrupt --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index eed11e8a..6c682077 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit eed11e8ab242d9144c3c6eb60e3fdd65218ade31 +Subproject commit 6c682077c1c541d0e66a05631483b76b6ac2d926 From 751215dec1cbfda4e879d77a8b7d5f1c8082fe1c Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 12 Aug 2020 14:26:49 -0700 Subject: [PATCH 11/93] 5-stage core running --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 6c682077..7e7f2d4d 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 6c682077c1c541d0e66a05631483b76b6ac2d926 +Subproject commit 7e7f2d4df1b870b7a877648462b5aa6da0c7e207 From 03e50178f1f74e6f88225f3960749225f2ed0011 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 14 Aug 2020 16:00:38 -0700 Subject: [PATCH 12/93] Add misalignment detection & make M-extension test optional --- generators/chipyard/src/main/scala/TestSuites.scala | 4 ++-- generators/riscv-sodor | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index 9ca2c08c..8cdfd3c9 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -92,8 +92,8 @@ class TestSuiteHelper } if (coreParams.useCompressed) addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) val (rvi, rvu) = - if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u) - else ((if (vm) rv32i else rv32pi), rv32u) + if (xlen == 64) ((if (vm) rv64i else rv64pi), (if (coreParams.mulDiv.isDefined) rv64u else List(rv64ui))) + else ((if (vm) rv32i else rv32pi), (if (coreParams.mulDiv.isDefined) rv32u else List(rv32ui))) addSuites(rvi.map(_("p"))) addSuites(rvu.map(_("p"))) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 7e7f2d4d..f6d5f45e 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 7e7f2d4df1b870b7a877648462b5aa6da0c7e207 +Subproject commit f6d5f45e31cd2f8c4aad64662d7ec0d59545f344 From f6992c61c8bff041f78ca395f61de5048b80a15b Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sat, 15 Aug 2020 00:20:47 -0700 Subject: [PATCH 13/93] 5-stage CPU passed all tests --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index f6d5f45e..cdc1dad8 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit f6d5f45e31cd2f8c4aad64662d7ec0d59545f344 +Subproject commit cdc1dad8b0ef2b08ab595a198d1455cbd05a55d3 From 97f595f41582fcc961274cd2222d68fc4802b24d Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sun, 16 Aug 2020 15:41:44 -0700 Subject: [PATCH 14/93] 1-stage passed all tests --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index cdc1dad8..af19aa2f 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit cdc1dad8b0ef2b08ab595a198d1455cbd05a55d3 +Subproject commit af19aa2fc56a5a2e883b2880608f0e35a5498c49 From 84359abd19c034e42d395b5132a1dbe56ab132a2 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sun, 16 Aug 2020 16:07:38 -0700 Subject: [PATCH 15/93] Isolated master adapter's TileLink valid signals from the core --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index af19aa2f..989c9831 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit af19aa2fc56a5a2e883b2880608f0e35a5498c49 +Subproject commit 989c98313c147b0c91614228dfc8b1dfb78c5200 From b0b09870ddf0ebc543383c1ee64495177d4d7c3c Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 17 Aug 2020 21:11:44 -0700 Subject: [PATCH 16/93] 2-stage core passed all tests --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 989c9831..602ff66b 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 989c98313c147b0c91614228dfc8b1dfb78c5200 +Subproject commit 602ff66b0ef487df1d01c176eb3c62f8443b274e From 27b78f4de21d390cbe6deb24cc2743a63b4a10ca Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 27 Aug 2020 23:48:01 -0700 Subject: [PATCH 17/93] Only punch realistic subset of DebugIO through chiptop --- .../chipyard/src/main/scala/IOBinders.scala | 131 ++++++++++++------ 1 file changed, 90 insertions(+), 41 deletions(-) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 6438801a..1c81f535 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -7,6 +7,7 @@ import chisel3.experimental.{Analog, IO} import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} import freechips.rocketchip.devices.debug._ +import freechips.rocketchip.jtag.{JTAGIO} import freechips.rocketchip.subsystem._ import freechips.rocketchip.system.{SimAXIMem} import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters} @@ -163,30 +164,65 @@ object AddIOCells { } /** - * Add IO cells to a debug module and name the IO ports. - * @param psd A PSDIO bundle + * Add IO cells to a debug module and name the IO ports, for debug IO which must go off-chip + * For on-chip debug IO, drive them appropriately + * @param system A BaseSubsystem that might have a debug module * @param resetctrlOpt An optional ResetCtrlIO bundle * @param debugOpt An optional DebugIO bundle - * @return Returns a tuple3 of (Top-level PSDIO IO; Optional top-level DebugIO IO; a list of IOCell module references) + * @return Returns a tuple2 of (Generated debug io ports, Generated IOCells) */ - def debug(psd: PSDIO, resetctrlOpt: Option[ResetCtrlIO], debugOpt: Option[DebugIO])(implicit p: Parameters): - (PSDIO, Option[ResetCtrlIO], Option[DebugIO], Seq[IOCell]) = { - val (psdPort, psdIOs) = IOCell.generateIOFromSignal( - psd, Some("iocell_psd"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) - val debugTuple = debugOpt.map(d => - IOCell.generateIOFromSignal(d, Some("iocell_debug"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)) - val debugPortOpt: Option[DebugIO] = debugTuple.map(_._1) - val debugIOs: Seq[IOCell] = debugTuple.map(_._2).toSeq.flatten - debugPortOpt.foreach(_.suggestName("debug")) + def debug(system: HasPeripheryDebugModuleImp)(implicit p: Parameters): (Seq[Bundle], Seq[IOCell]) = { + system.debug.map { debug => - val resetctrlTuple = resetctrlOpt.map(d => - IOCell.generateIOFromSignal(d, Some("iocell_resetctrl"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)) - val resetctrlPortOpt: Option[ResetCtrlIO] = resetctrlTuple.map(_._1) - val resetctrlIOs: Seq[IOCell] = resetctrlTuple.map(_._2).toSeq.flatten - resetctrlPortOpt.foreach(_.suggestName("resetctrl")) + // We never use the PSDIO, so tie it off on-chip + system.psd.psd.foreach { _ <> 0.U.asTypeOf(new PSDTestMode) } - psdPort.suggestName("psd") - (psdPort, resetctrlPortOpt, debugPortOpt, psdIOs ++ debugIOs ++ resetctrlIOs) + // Set resetCtrlOpt with the system reset + system.resetctrl.map { rcio => rcio.hartIsInReset.map { _ := system.reset.asBool } } + + system.debug.map { d => + // Tie off extTrigger + d.extTrigger.foreach { t => + t.in.req := false.B + t.out.ack := t.out.req + } + + // Tie off disableDebug + d.disableDebug.foreach { d => d := false.B } + + // Drive JTAG on-chip IOs + d.systemjtag.map { j => + j.reset := system.reset + j.mfr_id := system.p(JtagDTMKey).idcodeManufId.U(11.W) + j.part_number := system.p(JtagDTMKey).idcodePartNum.U(16.W) + j.version := system.p(JtagDTMKey).idcodeVersion.U(4.W) + } + } + + + // Connect DebugClockAndReset to system implicit clock. TODO this should use the clock of the bus the debug module is attached to + Debug.connectDebugClockAndReset(Some(debug), system.clock)(system.p) + + // Add IOCells for the DMI/JTAG/APB ports + + val dmiTuple = debug.clockeddmi.map { d => + IOCell.generateIOFromSignal(d, Some("iocell_dmi"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + } + dmiTuple.map(_._1).foreach(_.suggestName("dmi")) + + val jtagTuple = debug.systemjtag.map { j => + IOCell.generateIOFromSignal(j.jtag, Some("iocell_jtag"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + } + jtagTuple.map(_._1).foreach(_.suggestName("jtag")) + + val apbTuple = debug.apb.map { a => + IOCell.generateIOFromSignal(a, Some("iocell_apb"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + } + apbTuple.map(_._1).foreach(_.suggestName("apb")) + + val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq + (allTuples.map(_._1).toSeq, allTuples.flatMap(_._2).toSeq) + }.getOrElse((Nil, Nil)) } /** @@ -364,40 +400,53 @@ class WithTieOffL2FBusAXI extends OverrideIOBinder({ } }) -// TODO we need to rethink what "Tie-off-debug" means. The current system punches out -// excessive IOs. -class WithTiedOffDebug extends OverrideIOBinder({ +class WithSimDebug extends OverrideIOBinder({ (system: HasPeripheryDebugModuleImp) => { - val (psdPort, resetctrlOpt, debugPortOpt, ioCells) = - AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) + val (ports, iocells) = AddIOCells.debug(system)(system.p) val harnessFn = (th: HasHarnessSignalReferences) => { - Debug.tieoffDebug(debugPortOpt, resetctrlOpt, Some(psdPort))(system.p) - // tieoffDebug doesn't actually tie everything off :/ - debugPortOpt.foreach { d => - d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare; cdmi.dmiClock := th.harnessClock }) - d.dmactiveAck := DontCare - d.clock := th.harnessClock // TODO fix: This should be driven from within the chip + val dtm_success = Wire(Bool()) + when (dtm_success) { th.success := true.B } + ports.map { + case d: ClockedDMIIO => + val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success) + case j: JTAGIO => + val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success) + case _ => + require(false, "We only support DMI or JTAG simulated debug connections") } Nil } - Seq((Seq(psdPort) ++ resetctrlOpt ++ debugPortOpt.toSeq, Nil, Some(harnessFn))) + Seq((ports, iocells, Some(harnessFn))) } }) -// TODO we need to rethink what this does. The current system punches out excessive IOs. -// Some of the debug clock/reset should be driven from on-chip -class WithSimDebug extends OverrideIOBinder({ +class WithTiedOffDebug extends OverrideIOBinder({ (system: HasPeripheryDebugModuleImp) => { - val (psdPort, resetctrlPortOpt, debugPortOpt, ioCells) = - AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) + val (ports, iocells) = AddIOCells.debug(system)(system.p) val harnessFn = (th: HasHarnessSignalReferences) => { - val dtm_success = Wire(Bool()) - Debug.connectDebug(debugPortOpt, resetctrlPortOpt, psdPort, th.harnessClock, th.harnessReset.asBool, dtm_success)(system.p) - when (dtm_success) { th.success := true.B } - th.dutReset := th.harnessReset.asBool | debugPortOpt.map { debug => AsyncResetReg(debug.ndreset).asBool }.getOrElse(false.B) + ports.map { + case d: ClockedDMIIO => + d.dmi.req.valid := false.B + d.dmi.req.bits := DontCare + d.dmi.resp.ready := true.B + d.dmiClock := th.harnessClock + d.dmiReset := th.harnessReset + case j: JTAGIO => + j.TCK := true.B.asClock + j.TMS := true.B + j.TDI := true.B + j.TRSTn.foreach { r => r := true.B } + case a: ClockedAPBBundle => + a.tieoff() + a.clock := false.B.asClock + a.reset := true.B.asAsyncReset + a.psel := false.B + a.penable := false.B + case _ => require(false) + } Nil } - Seq((Seq(psdPort) ++ debugPortOpt.toSeq, ioCells, Some(harnessFn))) + Seq((ports, iocells, Some(harnessFn))) } }) From 5705f2645fac94a4cb416594d3cd4c85d5d56f7e Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 28 Aug 2020 14:21:03 -0700 Subject: [PATCH 18/93] Bump toolchains --- toolchains/esp-tools/riscv-isa-sim | 2 +- toolchains/esp-tools/riscv-tests | 2 +- toolchains/riscv-tools/riscv-isa-sim | 2 +- toolchains/riscv-tools/riscv-openocd | 2 +- toolchains/riscv-tools/riscv-tests | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/toolchains/esp-tools/riscv-isa-sim b/toolchains/esp-tools/riscv-isa-sim index a1ff6b03..aa332c6a 160000 --- a/toolchains/esp-tools/riscv-isa-sim +++ b/toolchains/esp-tools/riscv-isa-sim @@ -1 +1 @@ -Subproject commit a1ff6b03f7f630a06327798238256973568e3837 +Subproject commit aa332c6a9a5ec77a9b97cdb4a1978ad394b17f1e diff --git a/toolchains/esp-tools/riscv-tests b/toolchains/esp-tools/riscv-tests index f1370d05..e116930c 160000 --- a/toolchains/esp-tools/riscv-tests +++ b/toolchains/esp-tools/riscv-tests @@ -1 +1 @@ -Subproject commit f1370d054389fc83974fc820985b5c51693b8f9d +Subproject commit e116930c7d4a30fc2a1378417089a089e9e4cad0 diff --git a/toolchains/riscv-tools/riscv-isa-sim b/toolchains/riscv-tools/riscv-isa-sim index 8d860c19..acd953af 160000 --- a/toolchains/riscv-tools/riscv-isa-sim +++ b/toolchains/riscv-tools/riscv-isa-sim @@ -1 +1 @@ -Subproject commit 8d860c190640e19e0f23a21d2479b4a36d13d342 +Subproject commit acd953afd2f52d64e2264c2c7c713dc0ad614406 diff --git a/toolchains/riscv-tools/riscv-openocd b/toolchains/riscv-tools/riscv-openocd index 7c82a7b9..cbb15587 160000 --- a/toolchains/riscv-tools/riscv-openocd +++ b/toolchains/riscv-tools/riscv-openocd @@ -1 +1 @@ -Subproject commit 7c82a7b9d5b7d8b71e0a66826705ec141db718c3 +Subproject commit cbb15587dc782ac8ade7ae252e7b760cfba4a178 diff --git a/toolchains/riscv-tools/riscv-tests b/toolchains/riscv-tools/riscv-tests index 249796ce..19bfdab4 160000 --- a/toolchains/riscv-tools/riscv-tests +++ b/toolchains/riscv-tools/riscv-tests @@ -1 +1 @@ -Subproject commit 249796cec94d75ff10ca034153e206a319e87158 +Subproject commit 19bfdab48c2a6da4a2c67d5779757da7b073811d From 20013d1348ba67f30c4dc6421f675516726e5a8e Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 28 Aug 2020 14:21:24 -0700 Subject: [PATCH 19/93] Add DTM based bringup to regressions --- .circleci/config.yml | 38 +++++++++++++++++++------------------- .circleci/defaults.sh | 1 + .circleci/run-tests.sh | 3 +++ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 88a20f24..eac8504a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -199,6 +199,11 @@ jobs: steps: - prepare-rtl: project-key: "chipyard-rocket" + prepare-chipyard-dmirocket: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-dmirocket" prepare-chipyard-sha3: executor: main-env steps: @@ -225,11 +230,6 @@ jobs: steps: - prepare-rtl: project-key: "chipyard-boom" - prepare-rocketchip: - executor: main-env - steps: - - prepare-rtl: - project-key: "rocketchip" prepare-chipyard-blkdev: executor: main-env steps: @@ -297,6 +297,11 @@ jobs: steps: - run-tests: project-key: "chipyard-rocket" + chipyard-dmirocket-run-tests: + executor: main-env + steps: + - run-tests: + project-key: "chipyard-dmirocket" chipyard-sha3-run-tests: executor: main-env steps: @@ -323,11 +328,6 @@ jobs: steps: - run-tests: project-key: "chipyard-boom" - rocketchip-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "rocketchip" chipyard-hwacha-run-tests: executor: main-env steps: @@ -451,6 +451,11 @@ workflows: - install-riscv-toolchain - install-verilator + - prepare-chipyard-dmirocket: + requires: + - install-riscv-toolchain + - install-verilator + - prepare-chipyard-sha3: requires: - install-riscv-toolchain @@ -476,11 +481,6 @@ workflows: - install-riscv-toolchain - install-verilator - - prepare-rocketchip: - requires: - - install-riscv-toolchain - - install-verilator - - prepare-chipyard-blkdev: requires: - install-riscv-toolchain @@ -547,6 +547,10 @@ workflows: requires: - prepare-chipyard-rocket + - chipyard-dmirocket-run-tests: + requires: + - prepare-chipyard-dmirocket + - chipyard-sha3-run-tests: requires: - prepare-chipyard-sha3 @@ -567,10 +571,6 @@ workflows: requires: - prepare-chipyard-boom - - rocketchip-run-tests: - requires: - - prepare-rocketchip - - chipyard-hwacha-run-tests: requires: - prepare-chipyard-hwacha diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 7cb8c1e2..7ffb1d3c 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -48,6 +48,7 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim # key value store to get the build strings declare -A mapping mapping["chipyard-rocket"]="" +mapping["chipyard-dmirocket"]=" CONFIG=dmiRocketConfig" mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig" mapping["chipyard-streaming-fir"]=" CONFIG=StreamingFIRRocketConfig" mapping["chipyard-streaming-passthrough"]=" CONFIG=StreamingPassthroughRocketConfig" diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index 08b95e68..3e7b0285 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -32,6 +32,9 @@ case $1 in chipyard-rocket) run_bmark ${mapping[$1]} ;; + chipyard-dmirocket) + run_bmark ${mapping[$1]} + ;; chipyard-boom) run_bmark ${mapping[$1]} ;; From 17239c56f80aa6b2f9c2b8407a09ea22769da7ab Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 28 Aug 2020 14:36:09 -0700 Subject: [PATCH 20/93] Update AddIOCells.debug comment --- generators/chipyard/src/main/scala/IOBinders.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 1c81f535..7f4daea3 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -167,8 +167,6 @@ object AddIOCells { * Add IO cells to a debug module and name the IO ports, for debug IO which must go off-chip * For on-chip debug IO, drive them appropriately * @param system A BaseSubsystem that might have a debug module - * @param resetctrlOpt An optional ResetCtrlIO bundle - * @param debugOpt An optional DebugIO bundle * @return Returns a tuple2 of (Generated debug io ports, Generated IOCells) */ def debug(system: HasPeripheryDebugModuleImp)(implicit p: Parameters): (Seq[Bundle], Seq[IOCell]) = { From 5c5af7bfaded370e08bede3514a557be5841f532 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 28 Aug 2020 18:37:47 -0700 Subject: [PATCH 21/93] Stage 3 passed all tests --- generators/riscv-sodor | 2 +- sims/verilator/Makefile | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 602ff66b..f2f87953 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 602ff66b0ef487df1d01c176eb3c62f8443b274e +Subproject commit f2f879533325964670c3086dfdfa1660e722551b diff --git a/sims/verilator/Makefile b/sims/verilator/Makefile index 3d676efd..531c2dd3 100644 --- a/sims/verilator/Makefile +++ b/sims/verilator/Makefile @@ -150,9 +150,8 @@ $(sim_debug): $(model_mk_debug) $(dramsim_lib) ######################################################################################### .PRECIOUS: $(output_dir)/%.vpd %.vcd $(output_dir)/%.vpd: $(output_dir)/% $(sim_debug) - rm -f $@.vcd && mkfifo $@.vcd - vcd2vpd $@.vcd $@ > /dev/null & - (set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $< >(spike-dasm > $<.out) | tee $<.log) + touch $@.vpd + (set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) -v $@.vcd $(PERMISSIVE_OFF) $< >(spike-dasm > $<.out) | tee $<.log) ######################################################################################### # general cleanup rule From c8448cc3e105c38eac54d1fc78545b8897cbad44 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sun, 30 Aug 2020 18:10:52 -0700 Subject: [PATCH 22/93] Bore out a bus clock to drive DebugIO from ChipTop --- .../chipyard/src/main/scala/IOBinders.scala | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 7f4daea3..f13a6882 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -2,6 +2,7 @@ package chipyard package object iobinders { import chisel3._ +import chisel3.util.experimental.{BoringUtils} import chisel3.experimental.{Analog, IO} import freechips.rocketchip.config.{Field, Config, Parameters} @@ -171,12 +172,19 @@ object AddIOCells { */ def debug(system: HasPeripheryDebugModuleImp)(implicit p: Parameters): (Seq[Bundle], Seq[IOCell]) = { system.debug.map { debug => + val tlbus = system.outer.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere) + val debug_clock = Wire(Clock()).suggestName("debug_clock") + val debug_reset = Wire(Reset()).suggestName("debug_reset") + debug_clock := false.B.asClock + debug_reset := false.B + BoringUtils.bore(tlbus.module.clock, Seq(debug_clock)) + BoringUtils.bore(tlbus.module.reset, Seq(debug_reset)) // We never use the PSDIO, so tie it off on-chip system.psd.psd.foreach { _ <> 0.U.asTypeOf(new PSDTestMode) } // Set resetCtrlOpt with the system reset - system.resetctrl.map { rcio => rcio.hartIsInReset.map { _ := system.reset.asBool } } + system.resetctrl.map { rcio => rcio.hartIsInReset.map { _ := debug_reset.asBool } } system.debug.map { d => // Tie off extTrigger @@ -190,7 +198,7 @@ object AddIOCells { // Drive JTAG on-chip IOs d.systemjtag.map { j => - j.reset := system.reset + j.reset := debug_reset j.mfr_id := system.p(JtagDTMKey).idcodeManufId.U(11.W) j.part_number := system.p(JtagDTMKey).idcodePartNum.U(16.W) j.version := system.p(JtagDTMKey).idcodeVersion.U(4.W) @@ -199,7 +207,9 @@ object AddIOCells { // Connect DebugClockAndReset to system implicit clock. TODO this should use the clock of the bus the debug module is attached to - Debug.connectDebugClockAndReset(Some(debug), system.clock)(system.p) + + + Debug.connectDebugClockAndReset(Some(debug), debug_clock)(system.p) // Add IOCells for the DMI/JTAG/APB ports From bb1d0a10ae12299de5872e93fbc0b76d0fd0f71b Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 31 Aug 2020 18:00:40 -0700 Subject: [PATCH 23/93] Stage 3 (single port) passed all tests --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index f2f87953..477f9a4e 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit f2f879533325964670c3086dfdfa1660e722551b +Subproject commit 477f9a4eb9209cfc8eaae2f8e9f80f951c057342 From 4b304623208b4c0b55f4c2f0f280f2c30011acf4 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 2 Sep 2020 20:19:27 -0700 Subject: [PATCH 24/93] Change default IO set to JTAG+Serial, instead of JTAG+DMI --- docs/Advanced-Concepts/Chip-Communication.rst | 33 +------------------ .../src/main/scala/ConfigFragments.scala | 9 ++++- .../chipyard/src/main/scala/IOBinders.scala | 22 ++++--------- .../main/scala/config/AbstractConfig.scala | 3 +- .../src/main/scala/config/ArianeConfigs.scala | 2 +- .../src/main/scala/config/RocketConfigs.scala | 12 ++----- .../main/scala/config/TutorialConfigs.scala | 19 ++++++++--- 7 files changed, 34 insertions(+), 66 deletions(-) diff --git a/docs/Advanced-Concepts/Chip-Communication.rst b/docs/Advanced-Concepts/Chip-Communication.rst index e36805ec..84bfc5fb 100644 --- a/docs/Advanced-Concepts/Chip-Communication.rst +++ b/docs/Advanced-Concepts/Chip-Communication.rst @@ -130,38 +130,7 @@ Using the JTAG Interface ------------------------ The main way to use JTAG with a Rocket Chip based system is to instantiate the Debug Transfer Module (DTM) -and configure it to use a JTAG interface (by default the DTM is setup to use the DMI interface mentioned above). - -Creating a DTM+JTAG Config -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -First, a DTM config must be created for the system that you want to create. -This step is similar to the DMI simulation section within the :ref:`Starting the TSI or DMI Simulation` section. -The configuration is very similar to a DMI-based configuration. The main difference -is the addition of the ``WithJtagDTM`` config fragment that configures the instantiated DTM to use the JTAG protocol as the -bringup method. - -.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala - :language: scala - :start-after: DOC include start: JtagRocket - :end-before: DOC include end: JtagRocket - -Building a DTM+JTAG Simulator -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -After creating the config, call the ``make`` command like the following to build a simulator for your RTL: - -.. code-block:: bash - - cd sims/verilator - # or - cd sims/vcs - - make CONFIG=jtagRocketConfig - -In this example, the simulation will use the config that you previously specified, as well as set -the other parameters that are needed to satisfy the build system. After that point, you -should have a JTAG enabled simulator that you can attach to using OpenOCD and GDB! +and configure it to use a JTAG interface. The default Chipyard designs configure the DTM to use JTAG. you may attach OpenOCD and GDB to any of the default JTAG-enabled designs. Debugging with JTAG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 6336c05a..cfa465e7 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -7,7 +7,7 @@ import freechips.rocketchip.config.{Field, Parameters, Config} import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy.{LazyModule, ValName} import freechips.rocketchip.devices.tilelink.{BootROMLocated} -import freechips.rocketchip.devices.debug.{Debug} +import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI} import freechips.rocketchip.groundtest.{GroundTestSubsystem} import freechips.rocketchip.tile._ import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams} @@ -163,3 +163,10 @@ class WithTileDividedClock extends Config((site, here, up) => { case ClockingSchemeKey => ClockingSchemeGenerators.harnessDividedClock }) +class WithDMIDTM extends Config((site, here, up) => { + case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI)) +}) + +class WithNoDebug extends Config((site, here, up) => { + case DebugModuleKey => None +}) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index f13a6882..54a0d1dc 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -167,6 +167,7 @@ object AddIOCells { /** * Add IO cells to a debug module and name the IO ports, for debug IO which must go off-chip * For on-chip debug IO, drive them appropriately + * Mostly copied from rocket-chip/src/main/scala/devices/debug/Periphery.scala * @param system A BaseSubsystem that might have a debug module * @return Returns a tuple2 of (Generated debug io ports, Generated IOCells) */ @@ -175,27 +176,22 @@ object AddIOCells { val tlbus = system.outer.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere) val debug_clock = Wire(Clock()).suggestName("debug_clock") val debug_reset = Wire(Reset()).suggestName("debug_reset") - debug_clock := false.B.asClock - debug_reset := false.B + debug_clock := false.B.asClock // must provide default assignment to avoid firrtl unassigned error + debug_reset := false.B // must provide default assignment to avoid firrtl unassigned error BoringUtils.bore(tlbus.module.clock, Seq(debug_clock)) BoringUtils.bore(tlbus.module.reset, Seq(debug_reset)) // We never use the PSDIO, so tie it off on-chip system.psd.psd.foreach { _ <> 0.U.asTypeOf(new PSDTestMode) } - - // Set resetCtrlOpt with the system reset system.resetctrl.map { rcio => rcio.hartIsInReset.map { _ := debug_reset.asBool } } - system.debug.map { d => // Tie off extTrigger d.extTrigger.foreach { t => t.in.req := false.B t.out.ack := t.out.req } - // Tie off disableDebug d.disableDebug.foreach { d => d := false.B } - // Drive JTAG on-chip IOs d.systemjtag.map { j => j.reset := debug_reset @@ -204,15 +200,9 @@ object AddIOCells { j.version := system.p(JtagDTMKey).idcodeVersion.U(4.W) } } - - - // Connect DebugClockAndReset to system implicit clock. TODO this should use the clock of the bus the debug module is attached to - - Debug.connectDebugClockAndReset(Some(debug), debug_clock)(system.p) // Add IOCells for the DMI/JTAG/APB ports - val dmiTuple = debug.clockeddmi.map { d => IOCell.generateIOFromSignal(d, Some("iocell_dmi"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) } @@ -412,7 +402,7 @@ class WithSimDebug extends OverrideIOBinder({ (system: HasPeripheryDebugModuleImp) => { val (ports, iocells) = AddIOCells.debug(system)(system.p) val harnessFn = (th: HasHarnessSignalReferences) => { - val dtm_success = Wire(Bool()) + val dtm_success = WireInit(false.B) when (dtm_success) { th.success := true.B } ports.map { case d: ClockedDMIIO => @@ -437,8 +427,8 @@ class WithTiedOffDebug extends OverrideIOBinder({ d.dmi.req.valid := false.B d.dmi.req.bits := DontCare d.dmi.resp.ready := true.B - d.dmiClock := th.harnessClock - d.dmiReset := th.harnessReset + d.dmiClock := false.B.asClock + d.dmiReset := true.B case j: JTAGIO => j.TCK := true.B.asClock j.TMS := true.B diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 2b9473ed..a925ec56 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -11,13 +11,14 @@ class AbstractConfig extends Config( new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a blackbox DRAMSim model - new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) + new chipyard.iobinders.WithSimDebug ++ // attach SimJTAG new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing new testchipip.WithTSI ++ // use testchipip serial offchip link new chipyard.config.WithBootROM ++ // use default bootrom new chipyard.config.WithUART ++ // add a UART new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs new chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks + new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache diff --git a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala index 7bc985aa..6bc7cf69 100644 --- a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala @@ -14,6 +14,6 @@ class ArianeConfig extends Config( class dmiArianeConfig extends Config( new chipyard.iobinders.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial - new chipyard.iobinders.WithSimDebug ++ // add SimDebug and use it to drive simulation, override default tie-off debug + new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new ariane.WithNArianeCores(1) ++ // single Ariane core new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 07033609..420ba192 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -23,18 +23,10 @@ class GemminiRocketConfig extends Config( new chipyard.config.AbstractConfig) // DOC include end: GemminiRocketConfig -// DOC include start: JtagRocket -class jtagRocketConfig extends Config( - new chipyard.iobinders.WithSimDebug ++ // add SimDebug, in addition to default SimSerial - new freechips.rocketchip.subsystem.WithJtagDTM ++ // sets DTM communication interface to JTAG - new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new chipyard.config.AbstractConfig) -// DOC include end: JtagRocket - // DOC include start: DmiRocket class dmiRocketConfig extends Config( - new chipyard.iobinders.WithTiedOffSerial ++ // tie-off serial, override default add SimSerial - new chipyard.iobinders.WithSimDebug ++ // add SimDebug, override default tie-off debug + new chipyard.iobinders.WithTiedOffSerial ++ // don't use serial to drive the chip, since we use DMI instead + new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: DmiRocket diff --git a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala index 8872ed5e..d501b6c0 100644 --- a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala @@ -23,7 +23,7 @@ class TutorialStarterConfig extends Config( new chipyard.iobinders.WithUARTAdapter ++ // Connect a SimUART adapter to display UART on stdout new chipyard.iobinders.WithBlackBoxSimMem ++ // Connect simulated external memory new chipyard.iobinders.WithTieOffInterrupts ++ // Do not simulate external interrupts - new chipyard.iobinders.WithTiedOffDebug ++ // Disconnect the debug module, since we use TSI for bring-up + new chipyard.iobinders.WithSimDebug ++ // Connect SimJTAG (or SimDTM) widgets to debug ios new chipyard.iobinders.WithSimSerial ++ // Connect external SimSerial widget to drive TSI // Config fragments below this line affect hardware generation @@ -43,13 +43,19 @@ class TutorialStarterConfig extends Config( // Uncomment this line, and specify a size if you want to have a L2 // new freechips.rocketchip.subsystem.WithInclusiveCache(nBanks=1, nWays=4, capacityKB=128) ++ + // Set the debug module to expose an external JTAG port + new freechips.rocketchip.subsystem.WithJtagDTM ++ + // For simpler designs, we want to minimize IOs on // our Top. These config fragments remove unnecessary // ports new freechips.rocketchip.subsystem.WithNoMMIOPort ++ new freechips.rocketchip.subsystem.WithNoSlavePort ++ new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 + + // Use the standard hierarchical bus topology including mbus+l2 + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + // BaseConfig configures "bare" rocketchip system new freechips.rocketchip.system.BaseConfig ) @@ -60,7 +66,7 @@ class TutorialMMIOConfig extends Config( new chipyard.iobinders.WithUARTAdapter ++ new chipyard.iobinders.WithBlackBoxSimMem ++ new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimDebug ++ new chipyard.iobinders.WithSimSerial ++ new testchipip.WithTSI ++ @@ -76,6 +82,7 @@ class TutorialMMIOConfig extends Config( // For this demonstration we assume the base system is a single-core Rocket, for fast elaboration new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new freechips.rocketchip.subsystem.WithInclusiveCache ++ + new freechips.rocketchip.subsystem.WithJtagDTM ++ new freechips.rocketchip.subsystem.WithNoMMIOPort ++ new freechips.rocketchip.subsystem.WithNoSlavePort ++ new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ @@ -88,7 +95,7 @@ class TutorialSha3Config extends Config( new chipyard.iobinders.WithUARTAdapter ++ new chipyard.iobinders.WithBlackBoxSimMem ++ new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimDebug ++ new chipyard.iobinders.WithSimSerial ++ new testchipip.WithTSI ++ @@ -101,6 +108,7 @@ class TutorialSha3Config extends Config( // For this demonstration we assume the base system is a single-core Rocket, for fast elaboration new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new freechips.rocketchip.subsystem.WithJtagDTM ++ new freechips.rocketchip.subsystem.WithInclusiveCache ++ new freechips.rocketchip.subsystem.WithNoMMIOPort ++ new freechips.rocketchip.subsystem.WithNoSlavePort ++ @@ -114,7 +122,7 @@ class TutorialSha3BlackBoxConfig extends Config( new chipyard.iobinders.WithUARTAdapter ++ new chipyard.iobinders.WithBlackBoxSimMem ++ new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimDebug ++ new chipyard.iobinders.WithSimSerial ++ new testchipip.WithTSI ++ @@ -128,6 +136,7 @@ class TutorialSha3BlackBoxConfig extends Config( // For this demonstration we assume the base system is a single-core Rocket, for fast elaboration new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new freechips.rocketchip.subsystem.WithJtagDTM ++ new freechips.rocketchip.subsystem.WithInclusiveCache ++ new freechips.rocketchip.subsystem.WithNoMMIOPort ++ new freechips.rocketchip.subsystem.WithNoSlavePort ++ From 0995f1b04b86d167578925d95da41f79f82fdd23 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 2 Sep 2020 21:25:36 -0700 Subject: [PATCH 25/93] UCode passed all tests --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 477f9a4e..4c3bab58 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 477f9a4eb9209cfc8eaae2f8e9f80f951c057342 +Subproject commit 4c3bab5885b7d9f3ce0d621c0c2918aa853e879c From 23e4c22a44963f03c05eb1687865ca9490c71d25 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 2 Sep 2020 23:52:55 -0700 Subject: [PATCH 26/93] Don't run find in base_dir to avoid slow filesystem search --- common.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 89ebbea3..f8bd4cf4 100644 --- a/common.mk +++ b/common.mk @@ -62,7 +62,8 @@ SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools/barstoo SCALA_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),scala) VLOG_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),sv) $(call lookup_srcs,$(SOURCE_DIRS),v) # This assumes no SBT meta-build sources -SBT_SOURCES = $(call lookup_srcs,$(base_dir),sbt) +SBT_SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools) +SBT_SOURCES = $(call lookup_srcs,$(SBT_SOURCE_DIRS),sbt) $(base_dir)/build.sbt $(base_dir)/project/plugins.sbt ######################################################################################### # jar creation variables and rules From 3258fd8db8021407d24abb37f303e1d2a3dd34d6 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 3 Sep 2020 23:53:51 -0700 Subject: [PATCH 27/93] Remove JTAG from firesim comfigs due to @(posedge ~clk) issue --- docs/Advanced-Concepts/Chip-Communication.rst | 3 ++- generators/firechip/src/main/scala/TargetConfigs.scala | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/Advanced-Concepts/Chip-Communication.rst b/docs/Advanced-Concepts/Chip-Communication.rst index 84bfc5fb..8d63992a 100644 --- a/docs/Advanced-Concepts/Chip-Communication.rst +++ b/docs/Advanced-Concepts/Chip-Communication.rst @@ -130,7 +130,8 @@ Using the JTAG Interface ------------------------ The main way to use JTAG with a Rocket Chip based system is to instantiate the Debug Transfer Module (DTM) -and configure it to use a JTAG interface. The default Chipyard designs configure the DTM to use JTAG. you may attach OpenOCD and GDB to any of the default JTAG-enabled designs. +and configure it to use a JTAG interface. The default Chipyard designs instantiate the DTM and configure it +to use JTAG. You may attach OpenOCD and GDB to any of the default JTAG-enabled designs. Debugging with JTAG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 66a20bce..0d8cd367 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -88,7 +88,9 @@ class WithFireSimConfigTweaks extends Config( // Optional: Removing this will require using an initramfs under linux new testchipip.WithBlockDevice ++ // Required*: Scale default baud rate with periphery bus frequency - new chipyard.config.WithUART(BigInt(3686400L)) + new chipyard.config.WithUART(BigInt(3686400L)) ++ + // Required: Do not support debug module w. JTAG until FIRRTL stops emitting @(posedge ~clock) + new chipyard.config.WithNoDebug ) /******************************************************************************* From 0f50e4d1186323c3de008de55892695039019add Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 4 Sep 2020 13:35:05 -0700 Subject: [PATCH 28/93] Split IOBinders into IOBinders and Harness Binders | punch out clocks to harness for simwidgets and bridges --- build.sbt | 2 +- .../chipyard/src/main/scala/ChipTop.scala | 18 +- .../chipyard/src/main/scala/Clocks.scala | 5 +- .../chipyard/src/main/scala/DigitalTop.scala | 1 - .../src/main/scala/HarnessBinders.scala | 274 ++++++++++ .../chipyard/src/main/scala/IOBinders.scala | 489 +++++++----------- .../chipyard/src/main/scala/TestHarness.scala | 17 +- .../main/scala/config/AbstractConfig.scala | 36 +- .../src/main/scala/config/ArianeConfigs.scala | 2 +- .../src/main/scala/config/BoomConfigs.scala | 4 +- .../src/main/scala/config/RocketConfigs.scala | 17 +- .../main/scala/config/TracegenConfigs.scala | 30 +- .../main/scala/config/TutorialConfigs.scala | 96 +--- .../src/main/scala/BridgeBinders.scala | 150 +++--- .../firechip/src/main/scala/FireSim.scala | 18 +- generators/icenet | 2 +- generators/testchipip | 2 +- sims/firesim | 2 +- tools/barstools | 2 +- 19 files changed, 643 insertions(+), 524 deletions(-) create mode 100644 generators/chipyard/src/main/scala/HarnessBinders.scala diff --git a/build.sbt b/build.sbt index 5d642c1d..3ca021a7 100644 --- a/build.sbt +++ b/build.sbt @@ -211,7 +211,7 @@ lazy val midas = ProjectRef(firesimDir, "midas") lazy val firesimLib = ProjectRef(firesimDir, "firesimLib") lazy val firechip = conditionalDependsOn(project in file("generators/firechip")) - .dependsOn(chipyard, midasTargetUtils, midas, firesimLib % "test->test;compile->compile") + .dependsOn(chipyard, midasTargetUtils, midas, iocell, firesimLib % "test->test;compile->compile") .settings( commonSettings, testGrouping in Test := isolateAllTests( (definedTests in Test).value ), diff --git a/generators/chipyard/src/main/scala/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index cf71987b..6ae63d57 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGr import freechips.rocketchip.config.{Parameters, Field} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, LazyRawModuleImp, LazyModuleImpLike} import freechips.rocketchip.util.{ResetCatchAndSync} -import chipyard.iobinders.{IOBinders, TestHarnessFunction, IOBinderTuple} +import chipyard.iobinders._ import barstools.iocell.chisel._ @@ -26,11 +26,9 @@ case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters) class ChipTop(implicit p: Parameters) extends LazyModule with HasTestHarnessFunctions { // A publicly accessible list of IO cells (useful for a floorplanning tool, for example) val iocells = ArrayBuffer.empty[IOCell] - // A list of functions to call in the test harness - val harnessFunctions = ArrayBuffer.empty[TestHarnessFunction] // The system module specified by BuildSystem - val lSystem = LazyModule(p(BuildSystem)(p)).suggestName("system") + val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system") // The implicitClockSinkNode provides the implicit clock and reset for the System val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters())) @@ -50,15 +48,13 @@ class ChipTop(implicit p: Parameters) extends LazyModule with HasTestHarnessFunc // The implicit clock and reset for the system is also, by convention, used for all the IOBinders // TODO: This may not be the right thing to do in all cases - withClockAndReset(implicit_clock, implicit_reset) { - val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem) ++ f(lSystem.module)).unzip3 - // We ignore _ports for now... - iocells ++= _iocells.flatten - harnessFunctions ++= _harnessFunctions.flatten - } + val (_ports, _iocells, _portMap) = ApplyIOBinders(lazySystem, p(IOBinders)) + // We ignore _ports for now... + iocells ++= _iocells + portMap ++= _portMap // Connect the implicit clock/reset, if present - lSystem.module match { case l: LazyModuleImp => { + lazySystem.module match { case l: LazyModuleImp => { l.clock := implicit_clock l.reset := implicit_reset }} diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 3fa349b5..d6b19e8d 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -91,7 +91,7 @@ object ClockingSchemeGenerators { chiptop.implicitClockSinkNode := implicitClockSourceNode // Drive the diplomaticclock graph of the DigitalTop (if present) - val simpleClockGroupSourceNode = chiptop.lSystem match { + val simpleClockGroupSourceNode = chiptop.lazySystem match { case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) l.asyncClockGroupsNode := n @@ -120,6 +120,7 @@ object ClockingSchemeGenerators { } }} + chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { clock_io := th.harnessClock Nil @@ -137,7 +138,7 @@ object ClockingSchemeGenerators { val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters())) chiptop.implicitClockSinkNode := implicitClockSourceNode - val simpleClockGroupSourceNode = chiptop.lSystem match { + val simpleClockGroupSourceNode = chiptop.lazySystem match { case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) l.asyncClockGroupsNode := n diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index 81d0003d..ddcf66f3 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -33,7 +33,6 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l) with testchipip.CanHaveTraceIOModuleImp with testchipip.CanHavePeripheryBlockDeviceModuleImp - with testchipip.CanHavePeripherySerialModuleImp with sifive.blocks.devices.uart.HasPeripheryUARTModuleImp with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala new file mode 100644 index 00000000..54c99042 --- /dev/null +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -0,0 +1,274 @@ +package chipyard.harness + +import chisel3._ + +import freechips.rocketchip.config.{Field, Config, Parameters} +import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} +import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters} +import freechips.rocketchip.devices.debug._ +import freechips.rocketchip.jtag.{JTAGIO} +import freechips.rocketchip.system.{SimAXIMem} +import freechips.rocketchip.subsystem._ + +import sifive.blocks.devices.gpio._ +import sifive.blocks.devices.uart._ +import sifive.blocks.devices.spi._ + +import barstools.iocell.chisel._ + +import testchipip._ + +import chipyard.HasHarnessSignalReferences + +import tracegen.{TraceGenSystemModuleImp} +import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} + +import scala.reflect.{ClassTag} + +case object HarnessBinders extends Field[Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]]]( + Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]]().withDefaultValue((t: Any, th: HasHarnessSignalReferences, d: Seq[Data]) => Nil) +) + + +object ApplyHarnessBinders { + def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = { + val pm = portMap.withDefaultValue(Nil) + map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) } + } +} + +class OverrideHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { + case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> + ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + t match { + case system: T => fn(system, th, ports) + case _ => Nil + } + }) + ) +}) + +class ComposeHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { + case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> + ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + t match { + case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, ports) ++ fn(system, th, ports) + case _ => Nil + } + }) + ) +}) + +class WithGPIOTiedOff extends OverrideHarnessBinder({ + (system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { case p: GPIOPortIO => p <> AnalogConst(0) } + Nil + } +}) + +class WithUARTAdapter extends OverrideHarnessBinder({ + (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + UARTAdapter.connect(ports.map(_.asInstanceOf[UARTPortIO]))(system.p) + Nil + } +}) + +class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({ + (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + SimSPIFlashModel.connect(ports.map(_.asInstanceOf[SPIChipIO]), th.harnessReset, rdOnly)(system.p) + Nil + } +}) + +class WithSimBlockDevice extends OverrideHarnessBinder({ + (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val clock = WireInit(false.B.asClock) + ports.map { + case p: BlockDeviceIO => SimBlockDevice.connect(clock, th.harnessReset.asBool, Some(p))(system.p) + case c: Clock => clock := c + } + Nil + } +}) + +class WithBlockDeviceModel extends OverrideHarnessBinder({ + (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val clock = WireInit(false.B.asClock) + ports.map { + case p: BlockDeviceIO => withClockAndReset(clock, th.harnessReset) { BlockDeviceModel.connect(Some(p))(system.p) } + case c: Clock => clock := c + } + Nil + } +}) + +class WithLoopbackNIC extends OverrideHarnessBinder({ + (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val clock = WireInit(false.B.asClock) + ports.map { + case p: NICIOvonly => withClockAndReset(clock, th.harnessReset) { + NicLoopback.connect(Some(p), system.p(NICKey)) + } + case c: Clock => clock := c + } + Nil + } +}) + +class WithSimNetwork extends OverrideHarnessBinder({ + (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val clock = WireInit(false.B.asClock) + ports.map { + case p: NICIOvonly => SimNetwork.connect(Some(p), clock, th.harnessReset.asBool) + case c: Clock => clock := c + } + Nil + } +}) + +class WithSimAXIMem extends OverrideHarnessBinder({ + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val p: Parameters = chipyard.iobinders.GetSystemParameters(system) + val clock = WireInit(false.B.asClock) + ports.filter(_.isInstanceOf[Clock]).map { case p: Clock => clock := p } + val axi4_ports = ports.filter(_.isInstanceOf[AXI4Bundle]) + (axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => + val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p)) + withClockAndReset(clock, th.harnessReset) { + Module(mem.module).suggestName("mem") + } + mem.io_axi4.head <> port + } + Nil + } +}) + +class WithBlackBoxSimMem extends OverrideHarnessBinder({ + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val p: Parameters = chipyard.iobinders.GetSystemParameters(system) + val clock = WireInit(false.B.asClock) + ports.filter(_.isInstanceOf[Clock]).map { case p: Clock => clock := p } + val axi4_ports = ports.collect { case p: AXI4Bundle => p } + (axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => + val memSize = p(ExtMem).get.master.size + val lineSize = p(CacheBlockBytes) + val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram") + mem.io.axi <> port + mem.io.clock := clock + mem.io.reset := th.harnessReset + } + Nil + } +}) + +class WithSimAXIMMIO extends OverrideHarnessBinder({ + (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val p: Parameters = chipyard.iobinders.GetSystemParameters(system) + val clock = WireInit(false.B.asClock) + ports.filter(_.isInstanceOf[Clock]).map { case p: Clock => clock := p } + (ports zip system.mmioAXI4Node.edges.in).zipWithIndex.map { case ((port: AXI4Bundle, edge), i) => + val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)(p)) + withClockAndReset(clock, th.harnessReset) { + Module(mmio_mem.module).suggestName(s"mmio_mem_${i}") + } + mmio_mem.io_axi4.head <> port + } + Nil + } +}) + +class WithTieOffInterrupts extends OverrideHarnessBinder({ + (system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { case p: UInt => p := 0.U } + Nil + } +}) + +class WithTieOffL2FBusAXI extends OverrideHarnessBinder({ + (system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { case p: AXI4Bundle => + p := DontCare + p.tieoff() + } + Nil + } +}) + +class WithSimDebug extends OverrideHarnessBinder({ + (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + if (!ports.isEmpty) { + val dtm_success = Wire(Bool()) + when (dtm_success) { th.success := true.B } + ports.map { + case d: ClockedDMIIO => + val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success) + case j: JTAGIO => + val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success) + case _ => + require(false, "We only support DMI or JTAG simulated debug connections") + } + } + Nil + } +}) + +class WithTiedOffDebug extends OverrideHarnessBinder({ + (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { + case d: ClockedDMIIO => + d.dmi.req.valid := false.B + d.dmi.req.bits := DontCare + d.dmi.resp.ready := true.B + d.dmiClock := false.B.asClock + d.dmiReset := true.B + case j: JTAGIO => + j.TCK := true.B.asClock + j.TMS := true.B + j.TDI := true.B + j.TRSTn.foreach { r => r := true.B } + case a: ClockedAPBBundle => + a.tieoff() + a.clock := false.B.asClock + a.reset := true.B.asAsyncReset + a.psel := false.B + a.penable := false.B + case _ => require(false) + } + Nil + } +}) + +class WithTiedOffSerial extends OverrideHarnessBinder({ + (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { case p: SerialIO => SerialAdapter.tieoff(Some(p)) } + Nil + } +}) + +class WithSimSerial extends OverrideHarnessBinder({ + (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val serial_clock = WireInit(false.B.asClock) + ports.map { + case p: SerialIO => + val ser_success = SerialAdapter.connectSimSerial(p, serial_clock, th.harnessReset) + when (ser_success) { th.success := true.B } + case c: Clock => + serial_clock := c + } + Nil + } +}) + +class WithTraceGenSuccess extends OverrideHarnessBinder({ + (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { case p: Bool => when (p) { th.success := true.B } } + Nil + } +}) + +class WithSimDromajoBridge extends ComposeHarnessBinder({ + (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { case p: TraceOutputTop => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } + Nil + } +}) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 54a0d1dc..0dad7e21 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -1,9 +1,8 @@ -package chipyard -package object iobinders { +package chipyard.iobinders import chisel3._ import chisel3.util.experimental.{BoringUtils} -import chisel3.experimental.{Analog, IO} +import chisel3.experimental.{Analog, IO, DataMirror} import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} @@ -23,7 +22,9 @@ import tracegen.{TraceGenSystemModuleImp} import barstools.iocell.chisel._ import testchipip._ -import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey} +import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} + +import chipyard.GlobalResetSchemeKey import scala.reflect.{ClassTag} @@ -43,17 +44,22 @@ import scala.reflect.{ClassTag} // DOC include start: IOBinders // This type describes a function callable on the TestHarness instance. Its return type is unused. -type TestHarnessFunction = (chipyard.HasHarnessSignalReferences) => Seq[Any] -// IOBinders will return a Seq of this tuple, which contains three fields: -// 1. A Seq containing all IO ports created by the IOBinder function -// 2. A Seq containing all IO cell modules created by the IOBinder function -// 3. An optional function to call inside the test harness (e.g. to connect the IOs) -type IOBinderTuple = (Seq[Data], Seq[IOCell], Option[TestHarnessFunction]) -case object IOBinders extends Field[Map[String, (Any) => Seq[IOBinderTuple]]]( - Map[String, (Any) => Seq[IOBinderTuple]]().withDefaultValue((Any) => Nil) + + +case object IOBinders extends Field[Map[String, (Any) => (Seq[Data], Seq[IOCell])]]( + Map[String, (Any) => (Seq[Data], Seq[IOCell])]().withDefaultValue((Any) => (Nil, Nil)) ) +object ApplyIOBinders { + def apply(sys: LazyModule, map: Map[String, (Any) => (Seq[Data], Seq[IOCell])]): + (Iterable[Data], Iterable[IOCell], Map[String, Seq[Data]]) = { + val r = map.map({ case (s,f) => (f(sys), s) }) ++ map.map({ case (s,f) => (f(sys.module), s) }) + (r.flatMap(_._1._1), r.flatMap(_._1._2), r.map { t => t._2 -> t._1._1 }) + } +} + + // Note: The parameters instance is accessible only through LazyModule // or LazyModuleImpLike. The self-type requirement in traits like // CanHaveMasterAXI4MemPort is insufficient to make it accessible to the IOBinder @@ -71,12 +77,12 @@ object GetSystemParameters { // This macro overrides previous matches on some Top mixin. This is useful for // binders which drive IO, since those typically cannot be composed -class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class OverrideIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> ((t: Any) => { t match { case system: T => fn(system) - case _ => Nil + case _ => (Nil, Nil) } }) ) @@ -84,32 +90,44 @@ class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassT // This macro composes with previous matches on some Top mixin. This is useful for // annotation-like binders, since those can typically be composed -class ComposeIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class ComposeIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> ((t: Any) => { t match { - case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system) - ++ fn(system)) - case _ => Nil + case system: T => + val r = up(IOBinders, site)(tag.runtimeClass.toString)(system) + val h = fn(system) + (r._1 ++ h._1, r._2 ++ h._2) + case _ => (Nil, Nil) } }) ) }) +object BoreHelper { + def apply(name: String, source: Clock): Clock = { + val clock_io = IO(Output(Clock())).suggestName(name) + val clock_wire = Wire(Clock()).suggestName(s"chiptop_${name}") + dontTouch(clock_wire) + clock_wire := false.B.asClock // necessary for BoringUtils to work properly + BoringUtils.bore(source, Seq(clock_wire)) + clock_io := clock_wire + clock_io + } +} + // DOC include end: IOBinders -object AddIOCells { - /** - * Add IO cells to a SiFive GPIO devices and name the IO ports. - * @param gpios A Seq of GPIO port bundles - * @param genFn A callable function to generate a DigitalGPIOCell module to use - * @return Returns a tuple of (a 2D Seq of Analog IOs corresponding to individual GPIO pins; a 2D Seq of IOCell module references) - */ - def gpio(gpios: Seq[GPIOPortIO], genFn: () => DigitalGPIOCell = IOCell.genericGPIO): (Seq[Seq[Analog]], Seq[Seq[IOCell]]) = { - gpios.zipWithIndex.map({ case (gpio, i) => + +case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams()) + + +class WithGPIOCells extends OverrideIOBinder({ + (system: HasPeripheryGPIOModuleImp) => { + val (ports2d, cells2d) = system.gpio.zipWithIndex.map({ case (gpio, i) => gpio.pins.zipWithIndex.map({ case (pin, j) => val g = IO(Analog(1.W)).suggestName(s"gpio_${i}_${j}") - val iocell = genFn().suggestName(s"iocell_gpio_${i}_${j}") + val iocell = system.p(IOCellKey).gpio().suggestName(s"iocell_gpio_${i}_${j}") iocell.io.o := pin.o.oval iocell.io.oe := pin.o.oe iocell.io.ie := pin.o.ie @@ -118,40 +136,35 @@ object AddIOCells { (g, iocell) }).unzip }).unzip + (ports2d.flatten, cells2d.flatten) } +}) - /** - * Add IO cells to a SiFive UART devices and name the IO ports. - * @param uartPins A Seq of UART port bundles - * @return Returns a tuple of (A Seq of top-level UARTPortIO IOs; a 2D Seq of IOCell module references) - */ - def uart(uartPins: Seq[UARTPortIO]): (Seq[UARTPortIO], Seq[Seq[IOCell]]) = { - uartPins.zipWithIndex.map({ case (u, i) => - val (port, ios) = IOCell.generateIOFromSignal(u, Some(s"iocell_uart_${i}")) + +class WithUARTIOCells extends OverrideIOBinder({ + (system: HasPeripheryUARTModuleImp) => { + val (ports, cells2d) = system.uart.zipWithIndex.map({ case (u, i) => + val (port, ios) = IOCell.generateIOFromSignal(u, Some(s"iocell_uart_${i}"), system.p(IOCellKey)) port.suggestName(s"uart_${i}") (port, ios) }).unzip + (ports, cells2d.flatten) } +}) - /** - * Add IO cells to a SiFive SPI devices and name the IO ports. - * @param spiPins A Seq of SPI port bundles - * @param basename The base name for this port (defaults to "spi") - * @param genFn A callable function to generate a DigitalGPIOCell module to use - * @return Returns a tuple of (A Seq of top-level SPIChipIO IOs; a 2D Seq of IOCell module references) - */ - def spi(spiPins: Seq[SPIPortIO], basename: String = "spi", genFn: () => DigitalGPIOCell = IOCell.genericGPIO): (Seq[SPIChipIO], Seq[Seq[IOCell]]) = { - spiPins.zipWithIndex.map({ case (s, i) => - val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(s"${basename}_${i}") - val iocellBase = s"iocell_${basename}_${i}" +class WithSPIIOCells extends OverrideIOBinder({ + (system: HasPeripherySPIFlashModuleImp) => { + val (ports, cells2d) = system.qspi.zipWithIndex.map({ case (s, i) => + val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(s"spi_${i}") + val iocellBase = s"iocell_spi_${i}" // SCK and CS are unidirectional outputs - val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck")) - val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs")) + val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"), system.p(IOCellKey)) + val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs"), system.p(IOCellKey)) // DQ are bidirectional, so then need special treatment val dqIOs = s.dq.zip(port.dq).zipWithIndex.map { case ((pin, ana), j) => - val iocell = genFn().suggestName(s"${iocellBase}_dq_${j}") + val iocell = system.p(IOCellKey).gpio().suggestName(s"${iocellBase}_dq_${j}") iocell.io.o := pin.o iocell.io.oe := pin.oe iocell.io.ie := true.B @@ -162,17 +175,27 @@ object AddIOCells { (port, dqIOs ++ csIOs ++ sckIOs) }).unzip + (ports, cells2d.flatten) } +}) - /** - * Add IO cells to a debug module and name the IO ports, for debug IO which must go off-chip - * For on-chip debug IO, drive them appropriately - * Mostly copied from rocket-chip/src/main/scala/devices/debug/Periphery.scala - * @param system A BaseSubsystem that might have a debug module - * @return Returns a tuple2 of (Generated debug io ports, Generated IOCells) - */ - def debug(system: HasPeripheryDebugModuleImp)(implicit p: Parameters): (Seq[Bundle], Seq[IOCell]) = { - system.debug.map { debug => +class WithExtInterruptIOCells extends OverrideIOBinder({ + (system: HasExtInterruptsModuleImp) => { + if (system.outer.nExtInterrupts > 0) { + val (port, cells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"), system.p(IOCellKey)) + port.suggestName("ext_interrupts") + (Seq(port), cells) + } else { + (Nil, Nil) + } + } +}) + + +class WithDebugIOCells extends OverrideIOBinder({ + (system: HasPeripheryDebugModuleImp) => { + system.debug.map({ debug => + val p = system.p val tlbus = system.outer.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere) val debug_clock = Wire(Clock()).suggestName("debug_clock") val debug_reset = Wire(Reset()).suggestName("debug_reset") @@ -204,288 +227,130 @@ object AddIOCells { // Add IOCells for the DMI/JTAG/APB ports val dmiTuple = debug.clockeddmi.map { d => - IOCell.generateIOFromSignal(d, Some("iocell_dmi"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + IOCell.generateIOFromSignal(d, Some("iocell_dmi"), p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) } dmiTuple.map(_._1).foreach(_.suggestName("dmi")) val jtagTuple = debug.systemjtag.map { j => - IOCell.generateIOFromSignal(j.jtag, Some("iocell_jtag"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + IOCell.generateIOFromSignal(j.jtag, Some("iocell_jtag"), p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) } jtagTuple.map(_._1).foreach(_.suggestName("jtag")) val apbTuple = debug.apb.map { a => - IOCell.generateIOFromSignal(a, Some("iocell_apb"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + IOCell.generateIOFromSignal(a, Some("iocell_apb"), p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) } apbTuple.map(_._1).foreach(_.suggestName("apb")) val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq (allTuples.map(_._1).toSeq, allTuples.flatMap(_._2).toSeq) - }.getOrElse((Nil, Nil)) + }).getOrElse((Nil, Nil)) } +}) - /** - * Add IO cells to a serial module and name the IO ports. - * @param serial A SerialIO bundle - * @return Returns a tuple of (Top-level SerialIO IO; a list of IOCell module references) - */ - def serial(serial: SerialIO): (SerialIO, Seq[IOCell]) = { - val (port, ios) = IOCell.generateIOFromSignal(serial, Some("iocell_serial")) +class WithSerialIOCells extends OverrideIOBinder({ + (system: CanHavePeripherySerial) => system.serial.map({ s => + val sys = system.asInstanceOf[BaseSubsystem] + val (port, cells) = IOCell.generateIOFromSignal(s, Some("iocell_serial"), sys.p(IOCellKey)) + val serial_clock = Wire(Output(Clock())).suggestName("chiptop_serial_clock") + serial_clock := false.B.asClock // necessary for BoringUtils to work properly + dontTouch(serial_clock) + BoringUtils.bore(sys.fbus.module.clock, Seq(serial_clock)) + val (serial_clock_io, serial_clock_cell) = IOCell.generateIOFromSignal(serial_clock, Some("serial_clock"), sys.p(IOCellKey)) + serial_clock_io.suggestName("serial_clock") port.suggestName("serial") - (port, ios) - } - - def axi4(io: Seq[AXI4Bundle], node: AXI4SlaveNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = { - io.zip(node.edges.in).zipWithIndex.map{ case ((mem_axi4, edge), i) => { - val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_slave_${i}")) - port.suggestName(s"${name}_axi4_slave_${i}") - (port, edge, ios) - }} - } - def axi4(io: Seq[AXI4Bundle], node: AXI4MasterNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = { - io.zip(node.edges.out).zipWithIndex.map{ case ((mem_axi4, edge), i) => { - //val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_master_${i}")) - val port = IO(Flipped(AXI4Bundle(edge.bundle))) - val ios = IOCell.generateFromSignal(mem_axi4, port, Some(s"iocell_${name}_axi4_master_${i}")) - port.suggestName(s"${name}_axi4_master_${i}") - (port, edge, ios) - }} - } - - def blockDev(bdev: BlockDeviceIO): (BlockDeviceIO, Seq[IOCell]) = { - val (port, ios) = IOCell.generateIOFromSignal(bdev, Some("iocell_bdev")) - port.suggestName("bdev") - (port, ios) - } -} - -// DOC include start: WithGPIOTiedOff -class WithGPIOTiedOff extends OverrideIOBinder({ - (system: HasPeripheryGPIOModuleImp) => { - val (ports2d, ioCells2d) = AddIOCells.gpio(system.gpio) - val harnessFn = (th: HasHarnessSignalReferences) => { ports2d.flatten.foreach(_ <> AnalogConst(0)); Nil } - Seq((ports2d.flatten, ioCells2d.flatten, Some(harnessFn))) - } -}) -// DOC include end: WithGPIOTiedOff - -class WithUARTAdapter extends OverrideIOBinder({ - (system: HasPeripheryUARTModuleImp) => { - val (ports, ioCells2d) = AddIOCells.uart(system.uart) - val harnessFn = (th: HasHarnessSignalReferences) => { UARTAdapter.connect(ports)(system.p); Nil } - Seq((ports, ioCells2d.flatten, Some(harnessFn))) - } + (Seq(port, serial_clock_io), cells ++ serial_clock_cell) + }).getOrElse((Nil, Nil)) }) -class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({ - (system: HasPeripherySPIFlashModuleImp) => { - val (ports, ioCells2d) = AddIOCells.spi(system.qspi, "qspi") - val harnessFn = (th: HasHarnessSignalReferences) => { SimSPIFlashModel.connect(ports, th.harnessReset, rdOnly)(system.p); Nil } - Seq((ports, ioCells2d.flatten, Some(harnessFn))) - } -}) -class WithSimBlockDevice extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => - val (port, ios) = AddIOCells.blockDev(bdev) - val harnessFn = (th: HasHarnessSignalReferences) => { - // TODO: Using harness clock/reset will be incorrect when systemClock =/= harnessClock - SimBlockDevice.connect(th.harnessClock, th.harnessReset.asBool, Some(port))(system.p) - Nil - } - Seq((Seq(port), ios, Some(harnessFn))) - }.getOrElse(Nil) -}) - -class WithBlockDeviceModel extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => - val (port, ios) = AddIOCells.blockDev(bdev) - val harnessFn = (th: HasHarnessSignalReferences) => { - BlockDeviceModel.connect(Some(port))(system.p) - Nil - } - Seq((Seq(port), ios, Some(harnessFn))) - }.getOrElse(Nil) -}) - -class WithLoopbackNIC extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp) => system.connectNicLoopback(); Nil -}) - -class WithSimNIC extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil -}) - -// DOC include start: WithSimAXIMem -class WithSimAXIMem extends OverrideIOBinder({ +class WithAXI4MemPunchthrough extends OverrideIOBinder({ (system: CanHaveMasterAXI4MemPort) => { - implicit val p: Parameters = GetSystemParameters(system) - val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem") - // TODO: we are inlining the connectMem method of SimAXIMem because - // it takes in a dut rather than seq of axi4 ports - val harnessFn = (th: HasHarnessSignalReferences) => { - peiTuples.map { case (port, edge, ios) => - val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size)) - Module(mem.module).suggestName("mem") - mem.io_axi4.head <> port - } - Nil + val clock = if (!system.mem_axi4.isEmpty) { + Some(BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)) + } else { + None } - Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) - } -}) -// DOC include end: WithSimAXIMem - -class WithBlackBoxSimMem extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort) => { - implicit val p: Parameters = GetSystemParameters(system) - val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem") - val harnessFn = (th: HasHarnessSignalReferences) => { - peiTuples.map { case (port, edge, ios) => - val memSize = p(ExtMem).get.master.size - val lineSize = p(CacheBlockBytes) - val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)) - mem.io.axi <> port - // TODO: Using harness clock/reset will be incorrect when systemClock =/= harnessClock - mem.io.clock := th.harnessClock - mem.io.reset := th.harnessReset - } - Nil - } - Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) + val ports = system.mem_axi4.map({ m => + val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName("axi4_mem") + p <> m + p + }) + (ports ++ clock, Nil) } }) -class WithSimAXIMMIO extends OverrideIOBinder({ +class WithAXI4MMIOPunchthrough extends OverrideIOBinder({ (system: CanHaveMasterAXI4MMIOPort) => { - implicit val p: Parameters = GetSystemParameters(system) - val peiTuples = AddIOCells.axi4(system.mmio_axi4, system.mmioAXI4Node, "mmio_mem") - val harnessFn = (th: HasHarnessSignalReferences) => { - peiTuples.zipWithIndex.map { case ((port, edge, ios), i) => - val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)) - Module(mmio_mem.module).suggestName(s"mmio_mem_${i}") - mmio_mem.io_axi4.head <> port - } - Nil + val clock = if (!system.mmio_axi4.isEmpty) { + Some(BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)) + } else { + None } - Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) + val ports = system.mmio_axi4.map({ m => + val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName("axi4_mmio") + p <> m + p + }) + (ports ++ clock, Nil) } }) +class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({ + (system: CanHaveSlaveAXI4Port) => { + val port = system.l2_frontend_bus_axi4.map { m => + val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName("axi4_fbus") + p <> m + p + } + (port, Nil) + } +}) + +class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({ + (system: CanHavePeripheryBlockDeviceModuleImp) => { + val ports = system.bdev.map({ bdev => + val p = IO(new BlockDeviceIO()(system.p)).suggestName("blockdev") + val clock = BoreHelper("blkdev_clk", system.outer.controller.get.module.clock) + p <> bdev + Seq(p, clock) + }).getOrElse(Nil) + (ports, Nil) + } +}) + +class WithNICIOPunchthrough extends OverrideIOBinder({ + (system: CanHavePeripheryIceNICModuleImp) => { + val port = system.net.map({ n => + val p = IO(new NICIOvonly).suggestName("nic") + val clock = BoreHelper("nic_clk", system.outer.icenicOpt.get.module.clock) + p <> n + Seq(p, clock) + }).getOrElse(Nil) + (port.toSeq, Nil) + } +}) + +class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({ + (system: TraceGenSystemModuleImp) => { + val success = IO(Output(Bool())).suggestName("success") + success := system.success + (Seq(success), Nil) + } +}) + +class WithTraceIOPunchthrough extends OverrideIOBinder({ + (system: CanHaveTraceIOModuleImp) => { + val ports = system.traceIO.map { t => + val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace") + trace <> t + trace + } + (ports.toSeq, Nil) + } +}) + + class WithDontTouchPorts extends OverrideIOBinder({ - (system: DontTouch) => system.dontTouchPorts(); Nil + (system: DontTouch) => system.dontTouchPorts(); (Nil, Nil) }) -class WithTieOffInterrupts extends OverrideIOBinder({ - (system: HasExtInterruptsModuleImp) => { - val (port, ioCells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts")) - port.suggestName("interrupts") - val harnessFn = (th: HasHarnessSignalReferences) => { port := 0.U; Nil } - Seq((Seq(port), ioCells, Some(harnessFn))) - } -}) - -class WithTieOffL2FBusAXI extends OverrideIOBinder({ - (system: CanHaveSlaveAXI4Port) => { - val peiTuples = AddIOCells.axi4(system.l2_frontend_bus_axi4, system.l2FrontendAXI4Node, "l2_fbus") - val harnessFn = (th: HasHarnessSignalReferences) => { - peiTuples.zipWithIndex.map { case ((port, edge, ios), i) => - port := DontCare // tieoff doesn't completely tie-off, for some reason - port.tieoff() - } - Nil - } - Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) - } -}) - -class WithSimDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp) => { - val (ports, iocells) = AddIOCells.debug(system)(system.p) - val harnessFn = (th: HasHarnessSignalReferences) => { - val dtm_success = WireInit(false.B) - when (dtm_success) { th.success := true.B } - ports.map { - case d: ClockedDMIIO => - val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success) - case j: JTAGIO => - val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success) - case _ => - require(false, "We only support DMI or JTAG simulated debug connections") - } - Nil - } - Seq((ports, iocells, Some(harnessFn))) - } -}) - -class WithTiedOffDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp) => { - val (ports, iocells) = AddIOCells.debug(system)(system.p) - val harnessFn = (th: HasHarnessSignalReferences) => { - ports.map { - case d: ClockedDMIIO => - d.dmi.req.valid := false.B - d.dmi.req.bits := DontCare - d.dmi.resp.ready := true.B - d.dmiClock := false.B.asClock - d.dmiReset := true.B - case j: JTAGIO => - j.TCK := true.B.asClock - j.TMS := true.B - j.TDI := true.B - j.TRSTn.foreach { r => r := true.B } - case a: ClockedAPBBundle => - a.tieoff() - a.clock := false.B.asClock - a.reset := true.B.asAsyncReset - a.psel := false.B - a.penable := false.B - case _ => require(false) - } - Nil - } - Seq((ports, iocells, Some(harnessFn))) - } -}) - -class WithTiedOffSerial extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => - val (port, ioCells) = AddIOCells.serial(serial) - val harnessFn = (th: HasHarnessSignalReferences) => { - SerialAdapter.tieoff(port) - Nil - } - Seq((Seq(port), ioCells, Some(harnessFn))) - }).getOrElse(Nil) -}) - -class WithSimSerial extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => - val (port, ioCells) = AddIOCells.serial(serial) - val harnessFn = (th: HasHarnessSignalReferences) => { - val ser_success = SerialAdapter.connectSimSerial(port, th.harnessClock, th.harnessReset) - when (ser_success) { th.success := true.B } - Nil - } - Seq((Seq(port), ioCells, Some(harnessFn))) - }).getOrElse(Nil) -}) - -class WithTraceGenSuccessBinder extends OverrideIOBinder({ - (system: TraceGenSystemModuleImp) => { - val (successPort, ioCells) = IOCell.generateIOFromSignal(system.success, Some("iocell_success")) - successPort.suggestName("success") - val harnessFn = (th: HasHarnessSignalReferences) => { when (successPort) { th.success := true.B }; Nil } - Seq((Seq(successPort), ioCells, Some(harnessFn))) - } -}) - -class WithSimDromajoBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp) => { - system.traceIO match { case Some(t) => t.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } - Nil - } -}) - - -} /* end package object */ diff --git a/generators/chipyard/src/main/scala/TestHarness.scala b/generators/chipyard/src/main/scala/TestHarness.scala index b296e328..67cf03bf 100644 --- a/generators/chipyard/src/main/scala/TestHarness.scala +++ b/generators/chipyard/src/main/scala/TestHarness.scala @@ -1,19 +1,22 @@ package chipyard import chisel3._ - +import scala.collection.mutable.{ArrayBuffer} import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.config.{Field, Parameters} -import chipyard.iobinders.{TestHarnessFunction} + +import chipyard.harness.{ApplyHarnessBinders, HarnessBinders} // ------------------------------- // Chipyard Test Harness // ------------------------------- -case object BuildTop extends Field[Parameters => LazyModule with HasTestHarnessFunctions]((p: Parameters) => new ChipTop()(p)) +case object BuildTop extends Field[Parameters => LazyModule]((p: Parameters) => new ChipTop()(p)) trait HasTestHarnessFunctions { - val harnessFunctions: Seq[TestHarnessFunction] + val lazySystem: LazyModule + val harnessFunctions = ArrayBuffer.empty[HasHarnessSignalReferences => Seq[Any]] + val portMap = scala.collection.mutable.Map[String, Seq[Data]]() } trait HasHarnessSignalReferences { @@ -39,7 +42,9 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign // dutReset assignment can be overridden via a harnessFunction, but by default it is just reset val dutReset = WireDefault(if (p(GlobalResetSchemeKey).pinIsAsync) reset.asAsyncReset else reset) - ldut.harnessFunctions.foreach(_(this)) - + ldut match { case d: HasTestHarnessFunctions => + d.harnessFunctions.foreach(_(this)) + ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap) + } } diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index a925ec56..950cb4b4 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -5,14 +5,40 @@ import freechips.rocketchip.config.{Config} // -------------- // Chipyard abstract ("base") configuration // NOTE: This configuration is NOT INSTANTIABLE, as it defines a empty system with no tiles +// +// The default set of IOBinders instantiate IOcells and ChipTop IOs for digital IO bundles. +// The default set of HarnessBinders instantiate TestHarness hardware for interacting with ChipTop IOs // -------------- class AbstractConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter - new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts - new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a blackbox DRAMSim model - new chipyard.iobinders.WithSimDebug ++ // attach SimJTAG - new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing + // The HarnessBinders control generation of hardware in the TestHarness + new chipyard.harness.WithUARTAdapter ++ // add UART adapter to display UART on stdout, if uart is present + new chipyard.harness.WithBlackBoxSimMem ++ // add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled + new chipyard.harness.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled + new chipyard.harness.WithSimSerial ++ // add SimSerial adapter for HTIF, if serial port is present + new chipyard.harness.WithGPIOTiedOff ++ // tie-off chiptop GPIOs, if GPIOs are present + new chipyard.harness.WithSimSPIFlashModel ++ // add simulated SPI flash memory, if SPI is enabled + new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled + new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present + new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present + + // The IOBinders instantiate ChipTop IOs to match desired digital IOs + // IOCells are generated for "Chip-like" IOs, while simulation-only IOs are directly punched through + new chipyard.iobinders.WithAXI4MemPunchthrough ++ + new chipyard.iobinders.WithAXI4MMIOPunchthrough ++ + new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++ + new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++ + new chipyard.iobinders.WithNICIOPunchthrough ++ + new chipyard.iobinders.WithSerialIOCells ++ + new chipyard.iobinders.WithDebugIOCells ++ + new chipyard.iobinders.WithUARTIOCells ++ + new chipyard.iobinders.WithGPIOCells ++ + new chipyard.iobinders.WithUARTIOCells ++ + new chipyard.iobinders.WithSPIIOCells ++ + new chipyard.iobinders.WithTraceIOPunchthrough ++ + new chipyard.iobinders.WithExtInterruptIOCells ++ + + new testchipip.WithTSI ++ // use testchipip serial offchip link new chipyard.config.WithBootROM ++ // use default bootrom new chipyard.config.WithUART ++ // add a UART diff --git a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala index 6bc7cf69..47e7c15b 100644 --- a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala @@ -13,7 +13,7 @@ class ArianeConfig extends Config( new chipyard.config.AbstractConfig) class dmiArianeConfig extends Config( - new chipyard.iobinders.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial + new chipyard.harness.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new ariane.WithNArianeCores(1) ++ // single Ariane core new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/BoomConfigs.scala b/generators/chipyard/src/main/scala/config/BoomConfigs.scala index 575e1f98..9e1f558a 100644 --- a/generators/chipyard/src/main/scala/config/BoomConfigs.scala +++ b/generators/chipyard/src/main/scala/config/BoomConfigs.scala @@ -33,13 +33,13 @@ class HwachaLargeBoomConfig extends Config( new chipyard.config.AbstractConfig) class LoopbackNICLargeBoomConfig extends Config( - new chipyard.iobinders.WithLoopbackNIC ++ // drive NIC IOs with loopback + new chipyard.harness.WithLoopbackNIC ++ // drive NIC IOs with loopback new icenet.WithIceNIC ++ // build a NIC new boom.common.WithNLargeBooms(1) ++ new chipyard.config.AbstractConfig) class DromajoBoomConfig extends Config( - new chipyard.iobinders.WithSimDromajoBridge ++ // attach Dromajo + new chipyard.harness.WithSimDromajoBridge ++ // attach Dromajo new chipyard.config.WithTraceIO ++ // enable the traceio new boom.common.WithNSmallBooms(1) ++ new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 420ba192..a8686961 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -25,7 +25,7 @@ class GemminiRocketConfig extends Config( // DOC include start: DmiRocket class dmiRocketConfig extends Config( - new chipyard.iobinders.WithTiedOffSerial ++ // don't use serial to drive the chip, since we use DMI instead + new chipyard.harness.WithTiedOffSerial ++ // don't use serial to drive the chip, since we use DMI instead new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -46,37 +46,36 @@ class GCDAXI4BlackBoxRocketConfig extends Config( // DOC include end: GCDAXI4BlackBoxRocketConfig class LargeSPIFlashROMRocketConfig extends Config( - new chipyard.iobinders.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only) + new chipyard.harness.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only) new chipyard.config.WithSPIFlash ++ // add the SPI flash controller new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class SmallSPIFlashRocketConfig extends Config( - new chipyard.iobinders.WithSimSPIFlashModel(false) ++ // add the SPI flash model in the harness (writeable) + new chipyard.harness.WithSimSPIFlashModel(false) ++ // add the SPI flash model in the harness (writeable) new chipyard.config.WithSPIFlash(0x100000) ++ // add the SPI flash controller (1 MiB) new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class SimAXIRocketConfig extends Config( - new chipyard.iobinders.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM + new chipyard.harness.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class SimBlockDeviceRocketConfig extends Config( - new chipyard.iobinders.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice + new chipyard.harness.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice new testchipip.WithBlockDevice ++ // add block-device module to peripherybus new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class BlockDeviceModelRocketConfig extends Config( - new chipyard.iobinders.WithBlockDeviceModel ++ // drive block-device IOs with a BlockDeviceModel + new chipyard.harness.WithBlockDeviceModel ++ // drive block-device IOs with a BlockDeviceModel new testchipip.WithBlockDevice ++ // add block-device module to periphery bus new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include start: GPIORocketConfig class GPIORocketConfig extends Config( - new chipyard.iobinders.WithGPIOTiedOff ++ // tie off GPIO inputs into the top new chipyard.config.WithGPIO ++ // add GPIOs to the peripherybus new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -111,7 +110,7 @@ class InitZeroRocketConfig extends Config( // DOC include end: InitZeroRocketConfig class LoopbackNICRocketConfig extends Config( - new chipyard.iobinders.WithLoopbackNIC ++ // drive NIC IOs with loopback + new chipyard.harness.WithLoopbackNIC ++ // drive NIC IOs with loopback new icenet.WithIceNIC ++ // add an IceNIC new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -170,8 +169,6 @@ class LargeNVDLARocketConfig extends Config( new chipyard.config.AbstractConfig) class MMIORocketConfig extends Config( - new chipyard.iobinders.WithTieOffL2FBusAXI ++ // Tie-off the incoming MMIO port - new chipyard.iobinders.WithSimAXIMMIO ++ // Attach a simulated memory to the outwards MMIO port new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port new freechips.rocketchip.subsystem.WithDefaultSlavePort ++ // add default external slave port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ diff --git a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala index 47d567fb..28bc5dcd 100644 --- a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala @@ -4,8 +4,10 @@ import freechips.rocketchip.config.{Config} import freechips.rocketchip.rocket.{DCacheParams} class TraceGenConfig extends Config( - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTraceGenSuccessBinder ++ + new chipyard.harness.WithBlackBoxSimMem ++ + new chipyard.harness.WithTraceGenSuccess ++ + new chipyard.iobinders.WithAXI4MemPunchthrough ++ + new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++ @@ -13,8 +15,10 @@ class TraceGenConfig extends Config( new freechips.rocketchip.groundtest.GroundTestBaseConfig) class NonBlockingTraceGenConfig extends Config( - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTraceGenSuccessBinder ++ + new chipyard.harness.WithBlackBoxSimMem ++ + new chipyard.harness.WithTraceGenSuccess ++ + new chipyard.iobinders.WithAXI4MemPunchthrough ++ + new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++ @@ -22,8 +26,10 @@ class NonBlockingTraceGenConfig extends Config( new freechips.rocketchip.groundtest.GroundTestBaseConfig) class BoomTraceGenConfig extends Config( - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTraceGenSuccessBinder ++ + new chipyard.harness.WithBlackBoxSimMem ++ + new chipyard.harness.WithTraceGenSuccess ++ + new chipyard.iobinders.WithAXI4MemPunchthrough ++ + new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithBoomTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 8, nSets = 16, nWays = 2) }) ++ @@ -32,8 +38,10 @@ class BoomTraceGenConfig extends Config( new freechips.rocketchip.groundtest.GroundTestBaseConfig) class NonBlockingTraceGenL2Config extends Config( - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTraceGenSuccessBinder ++ + new chipyard.harness.WithBlackBoxSimMem ++ + new chipyard.harness.WithTraceGenSuccess ++ + new chipyard.iobinders.WithAXI4MemPunchthrough ++ + new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithL2TraceGen()(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++ @@ -42,8 +50,10 @@ class NonBlockingTraceGenL2Config extends Config( new freechips.rocketchip.groundtest.GroundTestBaseConfig) class NonBlockingTraceGenL2RingConfig extends Config( - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTraceGenSuccessBinder ++ + new chipyard.harness.WithBlackBoxSimMem ++ + new chipyard.harness.WithTraceGenSuccess ++ + new chipyard.iobinders.WithAXI4MemPunchthrough ++ + new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithL2TraceGen()(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++ diff --git a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala index d501b6c0..e7adbdc1 100644 --- a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala @@ -12,27 +12,16 @@ import freechips.rocketchip.config.{Config} // This file was originally developed for the cancelled ASPLOS-2020 // Chipyard tutorial. While the configs here work, the corresponding -// slideware has not yet been created +// slideware has not yet been created. // NOTE: Configs should be read bottom-up, since they are applied bottom-up +// NOTE: The TutorialConfigs build off of the AbstractConfig defined in AbstractConfig.scala +// Users should try to understand the functionality of the AbstractConfig before proceeding +// with the TutorialConfigs below + // Tutorial Phase 1: Configure the cores, caches class TutorialStarterConfig extends Config( - // IOBinders specify how to connect to IOs in our TestHarness - // These config fragments do not affect - new chipyard.iobinders.WithUARTAdapter ++ // Connect a SimUART adapter to display UART on stdout - new chipyard.iobinders.WithBlackBoxSimMem ++ // Connect simulated external memory - new chipyard.iobinders.WithTieOffInterrupts ++ // Do not simulate external interrupts - new chipyard.iobinders.WithSimDebug ++ // Connect SimJTAG (or SimDTM) widgets to debug ios - new chipyard.iobinders.WithSimSerial ++ // Connect external SimSerial widget to drive TSI - - // Config fragments below this line affect hardware generation - // of the Top - new testchipip.WithTSI ++ // Add a TSI (Test Serial Interface) widget to bring-up the core - new chipyard.config.WithBootROM ++ // Use the Chipyard BootROM - new chipyard.config.WithUART ++ // Add a UART - new chipyard.config.WithNoSubsystemDrivenClocks ++ // Don't drive the subsystem clocks from within the subsystem - // CUSTOMIZE THE CORE // Uncomment out one (or multiple) of the lines below, and choose // how many cores you want. @@ -43,36 +32,11 @@ class TutorialStarterConfig extends Config( // Uncomment this line, and specify a size if you want to have a L2 // new freechips.rocketchip.subsystem.WithInclusiveCache(nBanks=1, nWays=4, capacityKB=128) ++ - // Set the debug module to expose an external JTAG port - new freechips.rocketchip.subsystem.WithJtagDTM ++ - - // For simpler designs, we want to minimize IOs on - // our Top. These config fragments remove unnecessary - // ports - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - - // Use the standard hierarchical bus topology including mbus+l2 - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - - // BaseConfig configures "bare" rocketchip system - new freechips.rocketchip.system.BaseConfig + new chipyard.config.AbstractConfig ) - // Tutorial Phase 2: Integrate a TileLink or AXI4 MMIO device class TutorialMMIOConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithSimDebug ++ - new chipyard.iobinders.WithSimSerial ++ - - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithNoSubsystemDrivenClocks ++ // Attach either a TileLink or AXI4 version of GCD // Uncomment one of the below lines @@ -81,66 +45,26 @@ class TutorialMMIOConfig extends Config( // For this demonstration we assume the base system is a single-core Rocket, for fast elaboration new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithJtagDTM ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig + new chipyard.config.AbstractConfig ) -// Tutorial Phase 3: Integrate a SHA3 RoCC accelerator +// // Tutorial Phase 3: Integrate a SHA3 RoCC accelerator class TutorialSha3Config extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithSimDebug ++ - new chipyard.iobinders.WithSimSerial ++ - - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithNoSubsystemDrivenClocks ++ - // Uncomment this line once you added SHA3 to the build.sbt, and cloned the SHA3 repo // new sha3.WithSha3Accel ++ // For this demonstration we assume the base system is a single-core Rocket, for fast elaboration new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithJtagDTM ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig + new chipyard.config.AbstractConfig ) // Tutorial Phase 4: Integrate a Black-box verilog version of the SHA3 RoCC accelerator class TutorialSha3BlackBoxConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithSimDebug ++ - new chipyard.iobinders.WithSimSerial ++ - - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithNoSubsystemDrivenClocks ++ - // Uncomment these lines once SHA3 is integrated // new sha3.WithSha3BlackBox ++ // Specify we want the Black-box verilog version of Sha3 Ctrl // new sha3.WithSha3Accel ++ // For this demonstration we assume the base system is a single-core Rocket, for fast elaboration new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithJtagDTM ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig + new chipyard.config.AbstractConfig ) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index b59d477d..0eb61a05 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -8,13 +8,13 @@ import chisel3.experimental.annotate import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebugModuleImp} +import freechips.rocketchip.amba.axi4.{AXI4Bundle} import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPort, HasExtInterruptsModuleImp, BaseSubsystem, HasTilesModuleImp} import freechips.rocketchip.tile.{RocketTile} -import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp -import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp} +import sifive.blocks.devices.uart._ -import testchipip.{CanHavePeripherySerialModuleImp, CanHavePeripheryBlockDeviceModuleImp} -import icenet.CanHavePeripheryIceNICModuleImp +import testchipip._ +import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} import junctions.{NastiKey, NastiParameters} import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig} @@ -25,73 +25,116 @@ import tracegen.{TraceGenSystemModuleImp} import ariane.ArianeTile import boom.common.{BoomTile} - -import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters} -import testchipip.{CanHaveTraceIOModuleImp} +import barstools.iocell.chisel._ +import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters, IOCellKey} +import chipyard.{HasHarnessSignalReferences} +import chipyard.harness._ object MainMemoryConsts { val regionNamePrefix = "MainMemory" def globalName = s"${regionNamePrefix}_${NodeIdx()}" } -class WithSerialBridge extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp) => - system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(system.p)); Nil +trait Unsupported { + require(false, "We do not support this IOCell type") +} + +class FireSimAnalogIOCell extends RawModule with AnalogIOCell with Unsupported +class FireSimDigitalGPIOCell extends RawModule with DigitalGPIOCell with Unsupported +class FireSimDigitalInIOCell extends RawModule with DigitalInIOCell { io.i := io.pad } +class FireSimDigitalOutIOCell extends RawModule with DigitalOutIOCell { io.pad := io.o } + +case class FireSimIOCellParams() extends IOCellTypeParams { + def analog() = Module(new FireSimAnalogIOCell) + def gpio() = Module(new FireSimDigitalGPIOCell) + def input() = Module(new FireSimDigitalInIOCell) + def output() = Module(new FireSimDigitalOutIOCell) +} + +class WithFireSimIOCellModels extends Config((site, here, up) => { + case IOCellKey => FireSimIOCellParams() }) -class WithNICBridge extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp) => - system.net.foreach(n => NICBridge(system.clock, n)(system.p)); Nil +class WithSerialBridge extends OverrideHarnessBinder({ + (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val clock = ports.collectFirst({case c: Clock => c}) + val p: Parameters = chipyard.iobinders.GetSystemParameters(system) + ports.filter(_.isInstanceOf[SerialIO]).map { + case s: SerialIO => withClockAndReset(clock.get, th.harnessReset) { + SerialBridge(clock.get, s, MainMemoryConsts.globalName)(p) + } + case _ => + } + Nil + } }) -class WithUARTBridge extends OverrideIOBinder({ - (system: HasPeripheryUARTModuleImp) => - system.uart.foreach(u => UARTBridge(system.clock, u)(system.p)); Nil +class WithNICBridge extends OverrideHarnessBinder({ + (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val clock = ports.collectFirst({case c: Clock => c}) + ports.map { + case p: NICIOvonly => withClockAndReset(clock.get, th.harnessReset) { NICBridge(clock.get, p)(system.p) } + case _ => + } + Nil + } }) -class WithBlockDeviceBridge extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp) => - system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(system.p)); Nil +class WithUARTBridge extends OverrideHarnessBinder({ + (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => + ports.map { case p: UARTPortIO => UARTBridge(th.harnessClock, p)(system.p) }; Nil }) +class WithBlockDeviceBridge extends OverrideHarnessBinder({ + (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val clock = ports.collectFirst({case c: Clock => c}) + ports.map { + case p: BlockDeviceIO => BlockDevBridge(clock.get, p, th.harnessReset.toBool)(system.p) + case _ => + } + Nil + } +}) -class WithFASEDBridge extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort) => { +class WithFASEDBridge extends OverrideHarnessBinder({ + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { implicit val p: Parameters = GetSystemParameters(system) - (system.mem_axi4 zip system.memAXI4Node.edges.in).foreach({ case (axi4, edge) => + val clock = ports.collectFirst({case c: Clock => c}) + val axi4_ports = ports.collect { case p: AXI4Bundle => p } + (axi4_ports zip system.memAXI4Node.edges.in).map { case (axi4: AXI4Bundle, edge) => val nastiKey = NastiParameters(axi4.r.bits.data.getWidth, axi4.ar.bits.addr.getWidth, axi4.ar.bits.id.getWidth) system match { - case s: BaseSubsystem => FASEDBridge(s.module.clock, axi4, s.module.reset.toBool, + case s: BaseSubsystem => FASEDBridge(clock.get, axi4, th.harnessReset.asBool, CompleteConfig(p(firesim.configs.MemModelKey), nastiKey, Some(AXI4EdgeSummary(edge)), Some(MainMemoryConsts.globalName))) case _ => throw new Exception("Attempting to attach FASED Bridge to misconfigured design") } - }) + } Nil } }) -class WithTracerVBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp) => - system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p))); Nil -}) - - - -class WithDromajoBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp) => { - system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p))); Nil +class WithTracerVBridge extends ComposeHarnessBinder({ + (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + ports.map { case p: TraceOutputTop => p.traces.map(tileTrace => + withClockAndReset(tileTrace.clock, tileTrace.reset) { TracerVBridge(tileTrace)(system.p) } + )} } }) +class WithDromajoBridge extends ComposeHarnessBinder({ + (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => + ports.map { case p: TraceOutputTop => p.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p)) }; Nil +}) -class WithTraceGenBridge extends OverrideIOBinder({ - (system: TraceGenSystemModuleImp) => - GroundTestBridge(system.clock, system.success)(system.p); Nil + +class WithTraceGenBridge extends OverrideHarnessBinder({ + (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => + ports.map { case p: Bool => GroundTestBridge(th.harnessClock, p)(system.p) }; Nil }) class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ @@ -105,52 +148,25 @@ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ val core = b.module.core core.iregfile match { case irf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(irf.regfile)) - case _ => Nil } if (core.fp_pipeline != null) core.fp_pipeline.fregfile match { case frf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(frf.regfile)) - case _ => Nil } } case _ => } - Nil + (Nil, Nil) } }) -class WithTiedOffSystemGPIO extends OverrideIOBinder({ - (system: HasPeripheryGPIOModuleImp) => - system.gpio.foreach(_.pins.foreach(_.i.ival := false.B)); Nil -}) - -class WithTiedOffSystemDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp) => { - Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(system.p) - // tieoffDebug doesn't actually tie everything off :/ - system.debug.foreach { d => - d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }) - d.dmactiveAck := DontCare - } - Nil - } -}) - -class WithTiedOffSystemInterrupts extends OverrideIOBinder({ - (system: HasExtInterruptsModuleImp) => - system.interrupts := 0.U; Nil -}) - - // Shorthand to register all of the provided bridges above class WithDefaultFireSimBridges extends Config( - new WithTiedOffSystemGPIO ++ - new WithTiedOffSystemDebug ++ - new WithTiedOffSystemInterrupts ++ new WithSerialBridge ++ new WithNICBridge ++ new WithUARTBridge ++ new WithBlockDeviceBridge ++ new WithFASEDBridge ++ new WithFireSimMultiCycleRegfile ++ - new WithTracerVBridge + new WithTracerVBridge ++ + new WithFireSimIOCellModels ) diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index 158674a0..d2ef4e60 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -13,8 +13,9 @@ import freechips.rocketchip.util.{ResetCatchAndSync} import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock} -import chipyard.{BuildSystem, BuildTop, HasHarnessSignalReferences, ChipyardSubsystem, ClockingSchemeKey, ChipTop} -import chipyard.iobinders.{IOBinders} +import chipyard._ +import chipyard.harness._ +import chipyard.iobinders._ // Determines the number of times to instantiate the DUT in the harness. // Subsumes legacy supernode support @@ -50,7 +51,7 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => { chiptop.implicitClockSinkNode := implicitClockSourceNode // Drive the diplomaticclock graph of the DigitalTop (if present) - val simpleClockGroupSourceNode = chiptop.lSystem match { + val simpleClockGroupSourceNode = chiptop.lazySystem match { case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) l.asyncClockGroupsNode := n @@ -93,7 +94,7 @@ class WithFireSimRationalTileDomain(multiplier: Int, divisor: Int) extends Confi chiptop.implicitClockSinkNode := implicitClockSourceNode // Drive the diplomaticclock graph of the DigitalTop (if present) - val simpleClockGroupSourceNode = chiptop.lSystem match { + val simpleClockGroupSourceNode = chiptop.lazySystem match { case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) l.asyncClockGroupsNode := n @@ -159,8 +160,13 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSigna case AsyncClockGroupsKey => p(AsyncClockGroupsKey).copy }))) val module = Module(lazyModule.module) - require(lazyModule.harnessFunctions.size == 1, "There should only be 1 harness function to connect clock+reset") - lazyModule.harnessFunctions.foreach(_(this)) + lazyModule match { case d: HasTestHarnessFunctions => + require(d.harnessFunctions.size == 1, "There should only be 1 harness function to connect clock+reset") + d.harnessFunctions.foreach(_(this)) + ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap) + } + + NodeIdx.increment() } } diff --git a/generators/icenet b/generators/icenet index 705ca506..bb23c81f 160000 --- a/generators/icenet +++ b/generators/icenet @@ -1 +1 @@ -Subproject commit 705ca50690383aa589dc560a5e7c152af04c46ad +Subproject commit bb23c81fcfbdfde6767c5b7daa95f8f9436fb7db diff --git a/generators/testchipip b/generators/testchipip index 1e7373f6..6f4e7ae2 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 1e7373f6398c198e2dee2bcf692917ec2ac21b53 +Subproject commit 6f4e7ae2c94e867f08cd0d408a106fba2f389de2 diff --git a/sims/firesim b/sims/firesim index 05edd6be..069c3c11 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 05edd6be8c0464ea53a664a2164d3eba6a7f62aa +Subproject commit 069c3c111d46a3f3d20b4bd6f17aaa9b23487cc7 diff --git a/tools/barstools b/tools/barstools index aa1c90c4..ba681676 160000 --- a/tools/barstools +++ b/tools/barstools @@ -1 +1 @@ -Subproject commit aa1c90c4ccb73c2c379550f3296892cc81e8a195 +Subproject commit ba681676f338af158023c99b4c802009aa0b601b From b613c14f1c4cee96ee5abf181ee19df54494fd29 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 4 Sep 2020 20:03:12 -0700 Subject: [PATCH 29/93] Fix remaining HarnessBinders bugs --- .circleci/defaults.sh | 4 ++-- .../chipyard/src/main/scala/HarnessBinders.scala | 5 ++++- .../chipyard/src/main/scala/IOBinders.scala | 16 ++++++++-------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 7ffb1d3c..703737cd 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -61,8 +61,8 @@ mapping["chipyard-ariane"]=" CONFIG=ArianeConfig" mapping["chipyard-spiflashread"]=" CONFIG=LargeSPIFlashROMRocketConfig" mapping["chipyard-spiflashwrite"]=" CONFIG=SmallSPIFlashRocketConfig" mapping["chipyard-mmios"]=" CONFIG=MMIORocketConfig verilog" -mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config TOP=TraceGenSystem" -mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig TOP=TraceGenSystem" +mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config" +mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig" mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig" mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests" mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests" diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 54c99042..89017172 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -240,7 +240,10 @@ class WithTiedOffDebug extends OverrideHarnessBinder({ class WithTiedOffSerial extends OverrideHarnessBinder({ (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { case p: SerialIO => SerialAdapter.tieoff(Some(p)) } + ports.map { + case p: SerialIO => SerialAdapter.tieoff(Some(p)) + case _ => + } Nil } }) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 0dad7e21..acd57207 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -270,8 +270,8 @@ class WithAXI4MemPunchthrough extends OverrideIOBinder({ } else { None } - val ports = system.mem_axi4.map({ m => - val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName("axi4_mem") + val ports = system.mem_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mem_${i}") p <> m p }) @@ -286,8 +286,8 @@ class WithAXI4MMIOPunchthrough extends OverrideIOBinder({ } else { None } - val ports = system.mmio_axi4.map({ m => - val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName("axi4_mmio") + val ports = system.mmio_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mmio_${i}") p <> m p }) @@ -297,11 +297,11 @@ class WithAXI4MMIOPunchthrough extends OverrideIOBinder({ class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({ (system: CanHaveSlaveAXI4Port) => { - val port = system.l2_frontend_bus_axi4.map { m => - val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName("axi4_fbus") - p <> m + val port = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_fbus_${i}") + m <> p p - } + }) (port, Nil) } }) From 9eb88c55fca24af5bcc8e1c63647e545fbde006b Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 4 Sep 2020 23:07:23 -0700 Subject: [PATCH 30/93] Fix FireSim submodule --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 069c3c11..7cb10dcb 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 069c3c111d46a3f3d20b4bd6f17aaa9b23487cc7 +Subproject commit 7cb10dcb5eac4f2dc35ca8ee2bb0e1629fedd19b From ab21c53a42a4bd313c86a84b9c67abe7c77ee69d Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 4 Sep 2020 23:49:40 -0700 Subject: [PATCH 31/93] Add documentation on HarnessBinders --- docs/Advanced-Concepts/Debugging-BOOM.rst | 13 +++-- docs/Advanced-Concepts/Top-Testharness.rst | 6 +- docs/Customization/IOBinders.rst | 58 ++++++++++--------- .../src/main/scala/HarnessBinders.scala | 2 + .../chipyard/src/main/scala/IOBinders.scala | 13 +---- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/docs/Advanced-Concepts/Debugging-BOOM.rst b/docs/Advanced-Concepts/Debugging-BOOM.rst index 1e61804c..fd41a9d7 100644 --- a/docs/Advanced-Concepts/Debugging-BOOM.rst +++ b/docs/Advanced-Concepts/Debugging-BOOM.rst @@ -12,11 +12,14 @@ to verify functionality. Setting up Dromajo Co-simulation -------------------------------------- -Dromajo co-simulation is setup to work when two config fragments are added to a BOOM config. -First, a ``chipyard.config.WithTraceIO`` config fragment must be added so that BOOM's traceport is enabled. -Second, a ``chipyard.iobinders.WithSimDromajoBridge`` config fragment must be added to -connect the Dromajo co-simulator to the traceport. -Once both config fragments are added Dromajo should be enabled. +Dromajo co-simulation is setup to work when three config fragments are added to a BOOM config. + + * A ``chipyard.config.WithTraceIO`` config fragment must be added so that BOOM's traceport is enabled. + * A ``chipyard.iobinders.WithTraceIOPunchthrough`` config fragment must be added to add the ``TraceIO`` to the ``ChipTop`` + * A ``chipyard.harness.WithSimDromajoBridge`` config fragment must be added to instantiate a Dromajo cosimulator in the ``TestHarness`` and connect it to the ``ChipTop``'s ``TraceIO`` + + +Once all config fragments are added Dromajo should be enabled. To build/run Dromajo with a BOOM design, run your configuration the following make commands: diff --git a/docs/Advanced-Concepts/Top-Testharness.rst b/docs/Advanced-Concepts/Top-Testharness.rst index ebd5b370..43a8a338 100644 --- a/docs/Advanced-Concepts/Top-Testharness.rst +++ b/docs/Advanced-Concepts/Top-Testharness.rst @@ -14,9 +14,9 @@ ChipTop/DUT ``ChipTop`` is the top-level module that instantiates the ``System`` submodule, usually an instance of the concrete class ``DigitalTop``. The vast majority of the design resides in the ``System``. Other components that exist inside the ``ChipTop`` layer are generally IO cells, clock receivers and multiplexers, reset synchronizers, and other analog IP that needs to exist outside of the ``System``. -The ``IOBinders`` are responsible for instantiating the IO cells and defining the test harness collateral that connects to the top-level ports. -Most of these types of devices can be instantiated using custom ``IOBinders``, so the provided ``ChipTop`` and ``ChipTopCaughtReset`` classes are sufficient. -However, if needed, the ``BaseChipTop`` abstract class can be extended for building more custom ``ChipTop`` designs. +The ``IOBinders`` are responsible for instantiating the IO cells for ``ChipTop`` IO that correspond to IO of the ``System``. +The ``HarnessBinders`` are responsible for instantiating test harness collateral that connects to the ``ChipTop`` ports. +Most types of devices and testing collateral can be instantiated using custom ``IOBinders`` and ``HarnessBinders``. System/DigitalTop diff --git a/docs/Customization/IOBinders.rst b/docs/Customization/IOBinders.rst index 6332d07a..55920cd3 100644 --- a/docs/Customization/IOBinders.rst +++ b/docs/Customization/IOBinders.rst @@ -1,41 +1,45 @@ +IOBinders and HarnessBinders +============================ + +In Chipyard we use special ``Parameters`` keys, ``IOBinders`` and ``HarnessBinders`` to bridge the gap between digital system IOs and TestHarness collateral. + IOBinders ========= -In Chipyard we use a special ``Parameters`` key, ``IOBinders`` to instantiate IO cells in the ``ChipTop`` layer and determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``. +The ``IOBinder`` functions are responsible for instantiating IO cells and IOPorts in the ``ChipTop`` layer. + +``IOBinders`` are typically defined using the ``OverrideIOBinder`` or ``ComposeIOBinder`` macros. An ``IOBInder`` consists of a function matching ``Systems`` with a given trait that generates IO ports and IOCells, and returns a list of generated ports and cells. + +For example, the ``WithUARTIOCells`` IOBinder specifies will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleIMP``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generate IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices. + .. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala :language: scala - :start-after: DOC include start: IOBinders - :end-before: DOC include end: IOBinders + :start-after: DOC include start: WithUARTIOCells + :end-before: DOC include end: WithUARTIOCells +HarnessBinders +============== -This special key solves the problem of duplicating test-harnesses for each different ``System`` type. -You could just as well create a custom harness module that attaches IOs explicitly. -Instead, the ``IOBinders`` key provides a map from Scala traits to attachment behaviors. -Each ``IOBinder`` returns a tuple of three values: the list of ``ChipTop`` ports created by the ``IOBinder``, the list of all IO cell modules instantiated by the ``IOBinder``, and an optional function to be called inside the test harness. -This function is responsible for instantiating logic inside the ``TestHarness`` to appropriately drive the ``ChipTop`` IO ports created by the ``IOBinder``. -Conveniently, because the ``IOBinder`` is generating the port, it may also use the port inside this function, which prevents the ``BaseChipTop`` code from ever needing to access the port ``val``, thus having the ``IOBinder`` house all port specific code. -This scheme prevents the need to have two separate binder functions for each ``System`` trait. -When creating custom ``IOBinders`` it is important to use ``suggestName`` to name ports; otherwise Chisel will raise an exception trying to name the IOs. -The example ``IOBinders`` demonstrate this. +The ``HarnessBinder`` functions determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``. The ``HarnessBinder`` interface is designed to be reused across various simulation modes, enabling decoupling of the target design from simulation and testing concerns. -As an example, the ``WithGPIOTiedOff`` IOBinder creates IO cells for the GPIO module(s) instantiated in the ``System``, then punches out new ``Analog`` ports for each one. -The test harness simply ties these off, but additional logic could be inserted to perform some kind of test in the ``TestHarness``. + * For SW RTL simulations, the default set of ``HarnessBinders`` instantiate software-simulated models of various devices, for example external memory or UART, and connect those models to the IOs of the ``ChipTop``. + * For FireSim simulations, FireSim-specific ``HarnessBinders`` instantiate ``Bridges``, which faciliate cycle-accurate simulation across the simulated chip's IOs. See the FireSim documentation for more details. + * In the future, a Chipyard FPGA prototyping flow may use ``HarnessBinders`` to connect ``ChipTop`` IOs to other devices or IOs in the FPGA harness. -.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala +For FireSim simulations, the ``HarnessBinder`` attach ``Bridge`` modules (See the FireSim documentation for more details). + +Like ``IOBinders``, ``HarnessBinders`` are defined using macros (``OverrideHarnessBinder, ComposeHarnessBinder``), and matches ``Systems`` with a given trait. However, ``HarnessBinders`` are also passed a reference to the ``TestHarness`` (``th: HasHarnessSignalReferences``) and the list of ports generated by the corresponding ``IOBinder`` (``ports: Seq[Data]``). + +For exmaple, the ``WithUARTAdapter`` will connect the UART SW display adapter to the ports generated by the ``WithUARTIOCells`` described earlier, if those ports are present. + +.. literalinclude:: ../../generators/chipyard/src/main/scala/HarnessBinders.scala :language: scala - :start-after: DOC include start: WithGPIOTiedOff - :end-before: DOC include end: WithGPIOTiedOff + :start-after: DOC include start: WithUARTAdapter + :end-before: DOC include end: WithUARTAdapter +The ``IOBinder`` and ``HarnesBinder`` system is designed to enable decoupling of concerns between target design and simulation ssystem. -``IOBinders`` also do not need to create ports. Some ``IOBinders`` can simply insert circuitry inside the ``ChipTop`` layer. -For example, the ``WithSimAXIMemTiedOff`` IOBinder specifies that any ``System`` which matches ``CanHaveMasterAXI4MemPortModuleImp`` will have a ``SimAXIMem`` connected inside ``ChipTop``. +For a given set of chip IOs, there may be not only multiple simulation platforms ("harnesses", so-to-speak), but also multiple simulation strategies. For example, the choice of whether to connect the backing AXI4 memory port to a accurate DRAM model (``SimDRAM``) or a simple simulated memory model (``SimAXIMem``) is isolated in ``HarnessBinders``, and does not affect target RTL generation. -.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala - :language: scala - :start-after: DOC include start: WithSimAXIMem - :end-before: DOC include end: WithSimAXIMem - -These classes are all ``Config`` objects, which can be mixed into the configs to specify IO connection behaviors. - -There are two macros for generating these ``Config``s. ``OverrideIOBinder`` overrides any existing behaviors set for a particular IO in the ``Config`` object. This macro is frequently used because typically top-level IOs drive or are driven by only one source, so a composition of ``IOBinders`` does not make sense. The ``ComposeIOBinder`` macro provides the functionality of not overriding existing behaviors. +Similarly, for a given simulation platform and strategy, there may be multiple strategies for generating the chip IOs. This target-design configuration is isolated in the ``IOBinders``. diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 89017172..a26b5104 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -66,12 +66,14 @@ class WithGPIOTiedOff extends OverrideHarnessBinder({ } }) +// DOC include start: WithUARTAdapter class WithUARTAdapter extends OverrideHarnessBinder({ (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { UARTAdapter.connect(ports.map(_.asInstanceOf[UARTPortIO]))(system.p) Nil } }) +// DOC include end: WithUARTAdapter class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({ (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index acd57207..db5c7008 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -40,13 +40,6 @@ import scala.reflect.{ClassTag} // You can add your own binder by adding a new (key, fn) pair, typically by using // the OverrideIOBinder or ComposeIOBinder macros - - -// DOC include start: IOBinders -// This type describes a function callable on the TestHarness instance. Its return type is unused. - - - case object IOBinders extends Field[Map[String, (Any) => (Seq[Data], Seq[IOCell])]]( Map[String, (Any) => (Seq[Data], Seq[IOCell])]().withDefaultValue((Any) => (Nil, Nil)) ) @@ -59,7 +52,6 @@ object ApplyIOBinders { } } - // Note: The parameters instance is accessible only through LazyModule // or LazyModuleImpLike. The self-type requirement in traits like // CanHaveMasterAXI4MemPort is insufficient to make it accessible to the IOBinder @@ -116,8 +108,6 @@ object BoreHelper { } } -// DOC include end: IOBinders - case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams()) @@ -140,7 +130,7 @@ class WithGPIOCells extends OverrideIOBinder({ } }) - +// DOC include start: WithUARTIOCells class WithUARTIOCells extends OverrideIOBinder({ (system: HasPeripheryUARTModuleImp) => { val (ports, cells2d) = system.uart.zipWithIndex.map({ case (u, i) => @@ -151,6 +141,7 @@ class WithUARTIOCells extends OverrideIOBinder({ (ports, cells2d.flatten) } }) +// DOC include end: WithUARTIOCells class WithSPIIOCells extends OverrideIOBinder({ (system: HasPeripherySPIFlashModuleImp) => { From 927244bf2e724c01b42a59dc297942ba12bdaa39 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sat, 5 Sep 2020 11:16:55 -0700 Subject: [PATCH 32/93] DTM only supports HTIF in DMI mode --- generators/chipyard/src/main/scala/Subsystem.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 7f089ce1..92753db5 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -31,7 +31,7 @@ trait CanHaveHTIF { this: BaseSubsystem => // Advertise HTIF if system can communicate with fesvr if (this match { case _: CanHavePeripherySerial if p(SerialKey) => true - case _: HasPeripheryDebug if p(ExportDebug).protocols.nonEmpty => true + case _: HasPeripheryDebug if p(ExportDebug).dmi => true case _ => false }) { ResourceBinding { From 11dcd71a48161ea1e0fb78225c6fb778ad50936d Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sun, 6 Sep 2020 23:06:00 -0700 Subject: [PATCH 33/93] Clean up 5-stage instruction fetch --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 4c3bab58..e635b4ae 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 4c3bab5885b7d9f3ce0d621c0c2918aa853e879c +Subproject commit e635b4ae41d3d5ac570b8766877003e1c60f48ff From 7ed02a7d385921a22e88fa1e77dc411d16a732c8 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Mon, 7 Sep 2020 11:36:37 -0700 Subject: [PATCH 34/93] Fix Typos --- docs/Customization/IOBinders.rst | 12 ++++++------ generators/chipyard/src/main/scala/TestHarness.scala | 6 +++--- .../src/main/scala/config/TutorialConfigs.scala | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/Customization/IOBinders.rst b/docs/Customization/IOBinders.rst index 55920cd3..adfac22b 100644 --- a/docs/Customization/IOBinders.rst +++ b/docs/Customization/IOBinders.rst @@ -10,7 +10,7 @@ The ``IOBinder`` functions are responsible for instantiating IO cells and IOPort ``IOBinders`` are typically defined using the ``OverrideIOBinder`` or ``ComposeIOBinder`` macros. An ``IOBInder`` consists of a function matching ``Systems`` with a given trait that generates IO ports and IOCells, and returns a list of generated ports and cells. -For example, the ``WithUARTIOCells`` IOBinder specifies will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleIMP``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generate IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices. +For example, the ``WithUARTIOCells`` IOBinder will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleImp``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generated IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices. .. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala @@ -21,15 +21,15 @@ For example, the ``WithUARTIOCells`` IOBinder specifies will, for any ``System`` HarnessBinders ============== -The ``HarnessBinder`` functions determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``. The ``HarnessBinder`` interface is designed to be reused across various simulation modes, enabling decoupling of the target design from simulation and testing concerns. +The ``HarnessBinder`` functions determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``. The ``HarnessBinder`` interface is designed to be reused across various simulation/implementation modes, enabling decoupling of the target design from simulation and testing concerns. * For SW RTL simulations, the default set of ``HarnessBinders`` instantiate software-simulated models of various devices, for example external memory or UART, and connect those models to the IOs of the ``ChipTop``. * For FireSim simulations, FireSim-specific ``HarnessBinders`` instantiate ``Bridges``, which faciliate cycle-accurate simulation across the simulated chip's IOs. See the FireSim documentation for more details. * In the future, a Chipyard FPGA prototyping flow may use ``HarnessBinders`` to connect ``ChipTop`` IOs to other devices or IOs in the FPGA harness. -For FireSim simulations, the ``HarnessBinder`` attach ``Bridge`` modules (See the FireSim documentation for more details). +For FireSim simulations, the ``HarnessBinder`` attaches ``Bridge`` modules (See the FireSim documentation for more details). -Like ``IOBinders``, ``HarnessBinders`` are defined using macros (``OverrideHarnessBinder, ComposeHarnessBinder``), and matches ``Systems`` with a given trait. However, ``HarnessBinders`` are also passed a reference to the ``TestHarness`` (``th: HasHarnessSignalReferences``) and the list of ports generated by the corresponding ``IOBinder`` (``ports: Seq[Data]``). +Like ``IOBinders``, ``HarnessBinders`` are defined using macros (``OverrideHarnessBinder, ComposeHarnessBinder``), and match ``Systems`` with a given trait. However, ``HarnessBinders`` are also passed a reference to the ``TestHarness`` (``th: HasHarnessSignalReferences``) and the list of ports generated by the corresponding ``IOBinder`` (``ports: Seq[Data]``). For exmaple, the ``WithUARTAdapter`` will connect the UART SW display adapter to the ports generated by the ``WithUARTIOCells`` described earlier, if those ports are present. @@ -38,8 +38,8 @@ For exmaple, the ``WithUARTAdapter`` will connect the UART SW display adapter to :start-after: DOC include start: WithUARTAdapter :end-before: DOC include end: WithUARTAdapter -The ``IOBinder`` and ``HarnesBinder`` system is designed to enable decoupling of concerns between target design and simulation ssystem. +The ``IOBinder`` and ``HarnessBinder`` system is designed to enable decoupling of concerns between the target design and the simulation system. -For a given set of chip IOs, there may be not only multiple simulation platforms ("harnesses", so-to-speak), but also multiple simulation strategies. For example, the choice of whether to connect the backing AXI4 memory port to a accurate DRAM model (``SimDRAM``) or a simple simulated memory model (``SimAXIMem``) is isolated in ``HarnessBinders``, and does not affect target RTL generation. +For a given set of chip IOs, there may be not only multiple simulation platforms ("harnesses", so-to-speak), but also multiple simulation strategies. For example, the choice of whether to connect the backing AXI4 memory port to an accurate DRAM model (``SimDRAM``) or a simple simulated memory model (``SimAXIMem``) is isolated in ``HarnessBinders``, and does not affect target RTL generation. Similarly, for a given simulation platform and strategy, there may be multiple strategies for generating the chip IOs. This target-design configuration is isolated in the ``IOBinders``. diff --git a/generators/chipyard/src/main/scala/TestHarness.scala b/generators/chipyard/src/main/scala/TestHarness.scala index 67cf03bf..2faff565 100644 --- a/generators/chipyard/src/main/scala/TestHarness.scala +++ b/generators/chipyard/src/main/scala/TestHarness.scala @@ -31,8 +31,8 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign val success = Output(Bool()) }) - val ldut = LazyModule(p(BuildTop)(p)).suggestName("chiptop") - val dut = Module(ldut.module) + val lazyDut = LazyModule(p(BuildTop)(p)).suggestName("chiptop") + val dut = Module(lazyDut.module) io.success := false.B val harnessClock = clock @@ -42,7 +42,7 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign // dutReset assignment can be overridden via a harnessFunction, but by default it is just reset val dutReset = WireDefault(if (p(GlobalResetSchemeKey).pinIsAsync) reset.asAsyncReset else reset) - ldut match { case d: HasTestHarnessFunctions => + lazyDut match { case d: HasTestHarnessFunctions => d.harnessFunctions.foreach(_(this)) ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap) } diff --git a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala index e7adbdc1..3c64958f 100644 --- a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala @@ -48,7 +48,7 @@ class TutorialMMIOConfig extends Config( new chipyard.config.AbstractConfig ) -// // Tutorial Phase 3: Integrate a SHA3 RoCC accelerator +// Tutorial Phase 3: Integrate a SHA3 RoCC accelerator class TutorialSha3Config extends Config( // Uncomment this line once you added SHA3 to the build.sbt, and cloned the SHA3 repo // new sha3.WithSha3Accel ++ From b4e270219d06f5be568bbc62df362a9c29f98822 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Mon, 7 Sep 2020 14:02:31 -0700 Subject: [PATCH 35/93] Bump firesim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 7cb10dcb..522125da 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 7cb10dcb5eac4f2dc35ca8ee2bb0e1629fedd19b +Subproject commit 522125da5d546544e3ce4492b6f105eeb93fcdf6 From 11a9ad24286e0588e7e7a613d81ac3d8552fbe14 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 8 Sep 2020 15:52:09 -0700 Subject: [PATCH 36/93] Address code review comments --- build.sbt | 2 +- docs/Customization/IOBinders.rst | 6 +-- .../chipyard/src/main/scala/ChipTop.scala | 3 +- .../chipyard/src/main/scala/Clocks.scala | 1 - .../src/main/scala/HarnessBinders.scala | 36 ++++++++----- .../chipyard/src/main/scala/IOBinders.scala | 20 +++++-- .../src/main/scala/config/ArianeConfigs.scala | 2 +- .../src/main/scala/config/RocketConfigs.scala | 54 +++++++++---------- .../main/scala/config/TracegenConfigs.scala | 44 ++++----------- 9 files changed, 81 insertions(+), 87 deletions(-) diff --git a/build.sbt b/build.sbt index 3ca021a7..5d642c1d 100644 --- a/build.sbt +++ b/build.sbt @@ -211,7 +211,7 @@ lazy val midas = ProjectRef(firesimDir, "midas") lazy val firesimLib = ProjectRef(firesimDir, "firesimLib") lazy val firechip = conditionalDependsOn(project in file("generators/firechip")) - .dependsOn(chipyard, midasTargetUtils, midas, iocell, firesimLib % "test->test;compile->compile") + .dependsOn(chipyard, midasTargetUtils, midas, firesimLib % "test->test;compile->compile") .settings( commonSettings, testGrouping in Test := isolateAllTests( (definedTests in Test).value ), diff --git a/docs/Customization/IOBinders.rst b/docs/Customization/IOBinders.rst index adfac22b..ff180bcd 100644 --- a/docs/Customization/IOBinders.rst +++ b/docs/Customization/IOBinders.rst @@ -8,7 +8,7 @@ IOBinders The ``IOBinder`` functions are responsible for instantiating IO cells and IOPorts in the ``ChipTop`` layer. -``IOBinders`` are typically defined using the ``OverrideIOBinder`` or ``ComposeIOBinder`` macros. An ``IOBInder`` consists of a function matching ``Systems`` with a given trait that generates IO ports and IOCells, and returns a list of generated ports and cells. +``IOBinders`` are typically defined using the ``OverrideIOBinder`` or ``ComposeIOBinder`` macros. An ``IOBinder`` consists of a function matching ``Systems`` with a given trait that generates IO ports and IOCells, and returns a list of generated ports and cells. For example, the ``WithUARTIOCells`` IOBinder will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleImp``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generated IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices. @@ -23,12 +23,10 @@ HarnessBinders The ``HarnessBinder`` functions determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``. The ``HarnessBinder`` interface is designed to be reused across various simulation/implementation modes, enabling decoupling of the target design from simulation and testing concerns. - * For SW RTL simulations, the default set of ``HarnessBinders`` instantiate software-simulated models of various devices, for example external memory or UART, and connect those models to the IOs of the ``ChipTop``. + * For SW RTL or GL simulations, the default set of ``HarnessBinders`` instantiate software-simulated models of various devices, for example external memory or UART, and connect those models to the IOs of the ``ChipTop``. * For FireSim simulations, FireSim-specific ``HarnessBinders`` instantiate ``Bridges``, which faciliate cycle-accurate simulation across the simulated chip's IOs. See the FireSim documentation for more details. * In the future, a Chipyard FPGA prototyping flow may use ``HarnessBinders`` to connect ``ChipTop`` IOs to other devices or IOs in the FPGA harness. -For FireSim simulations, the ``HarnessBinder`` attaches ``Bridge`` modules (See the FireSim documentation for more details). - Like ``IOBinders``, ``HarnessBinders`` are defined using macros (``OverrideHarnessBinder, ComposeHarnessBinder``), and match ``Systems`` with a given trait. However, ``HarnessBinders`` are also passed a reference to the ``TestHarness`` (``th: HasHarnessSignalReferences``) and the list of ports generated by the corresponding ``IOBinder`` (``ports: Seq[Data]``). For exmaple, the ``WithUARTAdapter`` will connect the UART SW display adapter to the ports generated by the ``WithUARTIOCells`` described earlier, if those ports are present. diff --git a/generators/chipyard/src/main/scala/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index 6ae63d57..dfe08780 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -46,8 +46,7 @@ class ChipTop(implicit p: Parameters) extends LazyModule with HasTestHarnessFunc val implicit_reset = implicitClockSinkNode.in.head._1.reset - // The implicit clock and reset for the system is also, by convention, used for all the IOBinders - // TODO: This may not be the right thing to do in all cases + // Note: IOBinders cannot rely on the implicit clock/reset, as this is a LazyRawModuleImp val (_ports, _iocells, _portMap) = ApplyIOBinders(lazySystem, p(IOBinders)) // We ignore _ports for now... iocells ++= _iocells diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index d6b19e8d..a1ff1b0f 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -120,7 +120,6 @@ object ClockingSchemeGenerators { } }} - chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { clock_io := th.harnessClock Nil diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index a26b5104..694d45da 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -69,7 +69,7 @@ class WithGPIOTiedOff extends OverrideHarnessBinder({ // DOC include start: WithUARTAdapter class WithUARTAdapter extends OverrideHarnessBinder({ (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - UARTAdapter.connect(ports.map(_.asInstanceOf[UARTPortIO]))(system.p) + UARTAdapter.connect(ports.map({case p: UARTPortIO => p}))(system.p) Nil } }) @@ -77,7 +77,7 @@ class WithUARTAdapter extends OverrideHarnessBinder({ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({ (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - SimSPIFlashModel.connect(ports.map(_.asInstanceOf[SPIChipIO]), th.harnessReset, rdOnly)(system.p) + SimSPIFlashModel.connect(ports.map({case p: SPIChipIO => p}), th.harnessReset, rdOnly)(system.p) Nil } }) @@ -132,8 +132,11 @@ class WithSimAXIMem extends OverrideHarnessBinder({ (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) val clock = WireInit(false.B.asClock) - ports.filter(_.isInstanceOf[Clock]).map { case p: Clock => clock := p } - val axi4_ports = ports.filter(_.isInstanceOf[AXI4Bundle]) + ports.map { + case p: Clock => clock := p + case _ => + } + val axi4_ports = ports.collect { case p: AXI4Bundle => p } (axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p)) withClockAndReset(clock, th.harnessReset) { @@ -149,7 +152,10 @@ class WithBlackBoxSimMem extends OverrideHarnessBinder({ (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) val clock = WireInit(false.B.asClock) - ports.filter(_.isInstanceOf[Clock]).map { case p: Clock => clock := p } + ports.map { + case p: Clock => clock := p + case _ => + } val axi4_ports = ports.collect { case p: AXI4Bundle => p } (axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => val memSize = p(ExtMem).get.master.size @@ -167,11 +173,15 @@ class WithSimAXIMMIO extends OverrideHarnessBinder({ (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) val clock = WireInit(false.B.asClock) - ports.filter(_.isInstanceOf[Clock]).map { case p: Clock => clock := p } - (ports zip system.mmioAXI4Node.edges.in).zipWithIndex.map { case ((port: AXI4Bundle, edge), i) => - val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)(p)) + ports.map { + case p: Clock => clock := p + case _ => + } + val axi4_ports = ports.collect { case p: AXI4Bundle => p } + (axi4_ports zip system.mmioAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => + val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p)) withClockAndReset(clock, th.harnessReset) { - Module(mmio_mem.module).suggestName(s"mmio_mem_${i}") + Module(mmio_mem.module).suggestName("mmio_mem") } mmio_mem.io_axi4.head <> port } @@ -188,9 +198,11 @@ class WithTieOffInterrupts extends OverrideHarnessBinder({ class WithTieOffL2FBusAXI extends OverrideHarnessBinder({ (system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { case p: AXI4Bundle => - p := DontCare - p.tieoff() + ports.map { + case p: AXI4Bundle => + p := DontCare + p.tieoff() + case c: Clock => } Nil } diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index db5c7008..dfcbd8ba 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -47,8 +47,13 @@ case object IOBinders extends Field[Map[String, (Any) => (Seq[Data], Seq[IOCell] object ApplyIOBinders { def apply(sys: LazyModule, map: Map[String, (Any) => (Seq[Data], Seq[IOCell])]): (Iterable[Data], Iterable[IOCell], Map[String, Seq[Data]]) = { - val r = map.map({ case (s,f) => (f(sys), s) }) ++ map.map({ case (s,f) => (f(sys.module), s) }) - (r.flatMap(_._1._1), r.flatMap(_._1._2), r.map { t => t._2 -> t._1._1 }) + val lzy = map.map({ case (s,f) => s -> f(sys) }) + val imp = map.map({ case (s,f) => s -> f(sys.module) }) + + val ports: Iterable[Data] = lzy.values.map(_._1).flatten ++ imp.values.map(_._1).flatten + val cells: Iterable[IOCell] = lzy.values.map(_._2).flatten ++ imp.values.map(_._2).flatten + val portMap: Map[String, Seq[Data]] = map.keys.map(k => k -> (lzy(k)._1 ++ imp(k)._1)).toMap + (ports, cells, portMap) } } @@ -287,13 +292,18 @@ class WithAXI4MMIOPunchthrough extends OverrideIOBinder({ }) class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({ - (system: CanHaveSlaveAXI4Port) => { - val port = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) => + (system: CanHaveSlaveAXI4Port) => { + val clock = if (!system.l2_frontend_bus_axi4.isEmpty) { + Some(BoreHelper("axi4_fbus_clock", system.asInstanceOf[BaseSubsystem].fbus.module.clock)) + } else { + None + } + val ports = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) => val p = IO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_fbus_${i}") m <> p p }) - (port, Nil) + (ports ++ clock, Nil) } }) diff --git a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala index 47e7c15b..9f701331 100644 --- a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala @@ -13,7 +13,7 @@ class ArianeConfig extends Config( new chipyard.config.AbstractConfig) class dmiArianeConfig extends Config( - new chipyard.harness.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial + new chipyard.harness.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new ariane.WithNArianeCores(1) ++ // single Ariane core new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index a8686961..16d298fb 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -12,21 +12,21 @@ class RocketConfig extends Config( class HwachaRocketConfig extends Config( new chipyard.config.WithHwachaTest ++ - new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator + new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include start: GemminiRocketConfig class GemminiRocketConfig extends Config( - new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator + new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: GemminiRocketConfig // DOC include start: DmiRocket class dmiRocketConfig extends Config( - new chipyard.harness.WithTiedOffSerial ++ // don't use serial to drive the chip, since we use DMI instead - new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port + new chipyard.harness.WithTiedOffSerial ++ // don't use serial to drive the chip, since we use DMI instead + new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: DmiRocket @@ -40,53 +40,53 @@ class GCDTLRocketConfig extends Config( // DOC include start: GCDAXI4BlackBoxRocketConfig class GCDAXI4BlackBoxRocketConfig extends Config( - new chipyard.example.WithGCD(useAXI4=true, useBlackBox=true) ++ // Use GCD blackboxed verilog, connect by AXI4->Tilelink + new chipyard.example.WithGCD(useAXI4=true, useBlackBox=true) ++ // Use GCD blackboxed verilog, connect by AXI4->Tilelink new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: GCDAXI4BlackBoxRocketConfig class LargeSPIFlashROMRocketConfig extends Config( - new chipyard.harness.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only) + new chipyard.harness.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only) new chipyard.config.WithSPIFlash ++ // add the SPI flash controller new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class SmallSPIFlashRocketConfig extends Config( - new chipyard.harness.WithSimSPIFlashModel(false) ++ // add the SPI flash model in the harness (writeable) + new chipyard.harness.WithSimSPIFlashModel(false) ++ // add the SPI flash model in the harness (writeable) new chipyard.config.WithSPIFlash(0x100000) ++ // add the SPI flash controller (1 MiB) new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class SimAXIRocketConfig extends Config( - new chipyard.harness.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM + new chipyard.harness.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class SimBlockDeviceRocketConfig extends Config( - new chipyard.harness.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice - new testchipip.WithBlockDevice ++ // add block-device module to peripherybus + new chipyard.harness.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice + new testchipip.WithBlockDevice ++ // add block-device module to peripherybus new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class BlockDeviceModelRocketConfig extends Config( - new chipyard.harness.WithBlockDeviceModel ++ // drive block-device IOs with a BlockDeviceModel - new testchipip.WithBlockDevice ++ // add block-device module to periphery bus + new chipyard.harness.WithBlockDeviceModel ++ // drive block-device IOs with a BlockDeviceModel + new testchipip.WithBlockDevice ++ // add block-device module to periphery bus new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include start: GPIORocketConfig class GPIORocketConfig extends Config( - new chipyard.config.WithGPIO ++ // add GPIOs to the peripherybus + new chipyard.config.WithGPIO ++ // add GPIOs to the peripherybus new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: GPIORocketConfig class QuadRocketConfig extends Config( - new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles) + new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles) new chipyard.config.AbstractConfig) class RV32RocketConfig extends Config( - new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit + new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -104,14 +104,14 @@ class Sha3RocketConfig extends Config( // DOC include start: InitZeroRocketConfig class InitZeroRocketConfig extends Config( - new chipyard.example.WithInitZero(0x88000000L, 0x1000L) ++ // add InitZero + new chipyard.example.WithInitZero(0x88000000L, 0x1000L) ++ // add InitZero new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: InitZeroRocketConfig class LoopbackNICRocketConfig extends Config( - new chipyard.harness.WithLoopbackNIC ++ // drive NIC IOs with loopback - new icenet.WithIceNIC ++ // add an IceNIC + new chipyard.harness.WithLoopbackNIC ++ // drive NIC IOs with loopback + new icenet.WithIceNIC ++ // add an IceNIC new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -126,8 +126,8 @@ class ScratchpadOnlyRocketConfig extends Config( // DOC include end: l1scratchpadrocket class L1ScratchpadRocketConfig extends Config( - new chipyard.config.WithRocketICacheScratchpad ++ // use rocket ICache scratchpad - new chipyard.config.WithRocketDCacheScratchpad ++ // use rocket DCache scratchpad + new chipyard.config.WithRocketICacheScratchpad ++ // use rocket ICache scratchpad + new chipyard.config.WithRocketDCacheScratchpad ++ // use rocket DCache scratchpad new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -141,35 +141,35 @@ class MbusScratchpadRocketConfig extends Config( // DOC include start: RingSystemBusRocket class RingSystemBusRocketConfig extends Config( - new testchipip.WithRingSystemBus ++ // Ring-topology system bus + new testchipip.WithRingSystemBus ++ // Ring-topology system bus new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: RingSystemBusRocket class StreamingPassthroughRocketConfig extends Config( - new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough + new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include start: StreamingFIRRocketConfig class StreamingFIRRocketConfig extends Config ( - new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR + new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) // DOC include end: StreamingFIRRocketConfig class SmallNVDLARocketConfig extends Config( - new nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA + new nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class LargeNVDLARocketConfig extends Config( - new nvidia.blocks.dla.WithNVDLA("large", true) ++ // add a large NVDLA with synth. rams + new nvidia.blocks.dla.WithNVDLA("large", true) ++ // add a large NVDLA with synth. rams new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) class MMIORocketConfig extends Config( - new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port + new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port new freechips.rocketchip.subsystem.WithDefaultSlavePort ++ // add default external slave port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -177,7 +177,7 @@ class MMIORocketConfig extends Config( // NOTE: This config doesn't work yet because SimWidgets in the TestHarness // always get the TestHarness clock. The Tiles and Uncore receive the correct clocks class DividedClockRocketConfig extends Config( - new chipyard.config.WithTileDividedClock ++ // Put the Tile on its own clock domain + new chipyard.config.WithTileDividedClock ++ // Put the Tile on its own clock domain new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala index 28bc5dcd..78cb6851 100644 --- a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala @@ -3,61 +3,37 @@ package chipyard import freechips.rocketchip.config.{Config} import freechips.rocketchip.rocket.{DCacheParams} -class TraceGenConfig extends Config( +class AbstractTraceGenConfig extends Config( new chipyard.harness.WithBlackBoxSimMem ++ new chipyard.harness.WithTraceGenSuccess ++ new chipyard.iobinders.WithAXI4MemPunchthrough ++ new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ - new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++ new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ new freechips.rocketchip.groundtest.GroundTestBaseConfig) + +class TraceGenConfig extends Config( + new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++ + new AbstractTraceGenConfig) + class NonBlockingTraceGenConfig extends Config( - new chipyard.harness.WithBlackBoxSimMem ++ - new chipyard.harness.WithTraceGenSuccess ++ - new chipyard.iobinders.WithAXI4MemPunchthrough ++ - new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ - new chipyard.config.WithTracegenSystem ++ - new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.groundtest.GroundTestBaseConfig) + new AbstractTraceGenConfig) class BoomTraceGenConfig extends Config( - new chipyard.harness.WithBlackBoxSimMem ++ - new chipyard.harness.WithTraceGenSuccess ++ - new chipyard.iobinders.WithAXI4MemPunchthrough ++ - new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ - new chipyard.config.WithTracegenSystem ++ - new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithBoomTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 8, nSets = 16, nWays = 2) }) ++ new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.groundtest.GroundTestBaseConfig) + new AbstractTraceGenConfig) class NonBlockingTraceGenL2Config extends Config( - new chipyard.harness.WithBlackBoxSimMem ++ - new chipyard.harness.WithTraceGenSuccess ++ - new chipyard.iobinders.WithAXI4MemPunchthrough ++ - new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ - new chipyard.config.WithTracegenSystem ++ - new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithL2TraceGen()(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++ new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.groundtest.GroundTestBaseConfig) + new AbstractTraceGenConfig) class NonBlockingTraceGenL2RingConfig extends Config( - new chipyard.harness.WithBlackBoxSimMem ++ - new chipyard.harness.WithTraceGenSuccess ++ - new chipyard.iobinders.WithAXI4MemPunchthrough ++ - new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ - new chipyard.config.WithTracegenSystem ++ - new chipyard.config.WithNoSubsystemDrivenClocks ++ new tracegen.WithL2TraceGen()(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++ new testchipip.WithRingSystemBus ++ new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.groundtest.GroundTestBaseConfig) + new AbstractTraceGenConfig) From 8f9574fd7980f38320bfac8095ce9d3d31d94a70 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 8 Sep 2020 21:52:50 -0700 Subject: [PATCH 37/93] Clean up passing ports from IOBinders to HarnessBinders --- .../src/main/scala/HarnessBinders.scala | 175 +++++++----------- .../chipyard/src/main/scala/IOBinders.scala | 103 +++++------ 2 files changed, 114 insertions(+), 164 deletions(-) diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 694d45da..f427d44e 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -1,6 +1,7 @@ package chipyard.harness import chisel3._ +import chisel3.experimental.{Analog} import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} @@ -19,6 +20,7 @@ import barstools.iocell.chisel._ import testchipip._ import chipyard.HasHarnessSignalReferences +import chipyard.iobinders.ClockedIO import tracegen.{TraceGenSystemModuleImp} import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} @@ -33,26 +35,29 @@ case object HarnessBinders extends Field[Map[String, (Any, HasHarnessSignalRefer object ApplyHarnessBinders { def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = { val pm = portMap.withDefaultValue(Nil) - map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) } + map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) + } } } -class OverrideHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val pts = ports.map(_.asInstanceOf[S]) t match { - case system: T => fn(system, th, ports) + case system: T => fn(system, th, pts) case _ => Nil } }) ) }) -class ComposeHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class ComposeHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + val pts = ports.map(_.asInstanceOf[S]) t match { - case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, ports) ++ fn(system, th, ports) + case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, pts) ++ fn(system, th, pts) case _ => Nil } }) @@ -60,109 +65,83 @@ class ComposeHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data]) }) class WithGPIOTiedOff extends OverrideHarnessBinder({ - (system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { case p: GPIOPortIO => p <> AnalogConst(0) } + (system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Analog]) => { + ports.foreach { _ <> AnalogConst(0) } Nil } }) // DOC include start: WithUARTAdapter class WithUARTAdapter extends OverrideHarnessBinder({ - (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - UARTAdapter.connect(ports.map({case p: UARTPortIO => p}))(system.p) + (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => { + UARTAdapter.connect(ports)(system.p) Nil } }) // DOC include end: WithUARTAdapter class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({ - (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - SimSPIFlashModel.connect(ports.map({case p: SPIChipIO => p}), th.harnessReset, rdOnly)(system.p) + (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => { + SimSPIFlashModel.connect(ports, th.harnessReset, rdOnly)(system.p) Nil } }) class WithSimBlockDevice extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val clock = WireInit(false.B.asClock) - ports.map { - case p: BlockDeviceIO => SimBlockDevice.connect(clock, th.harnessReset.asBool, Some(p))(system.p) - case c: Clock => clock := c - } + (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + ports.map { p => SimBlockDevice.connect(p.clock, th.harnessReset.asBool, Some(p.bits))(system.p) } Nil } }) class WithBlockDeviceModel extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val clock = WireInit(false.B.asClock) - ports.map { - case p: BlockDeviceIO => withClockAndReset(clock, th.harnessReset) { BlockDeviceModel.connect(Some(p))(system.p) } - case c: Clock => clock := c - } + (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + ports.map { p => withClockAndReset(p.clock, th.harnessReset) { BlockDeviceModel.connect(Some(p.bits))(system.p) } } Nil } }) class WithLoopbackNIC extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val clock = WireInit(false.B.asClock) - ports.map { - case p: NICIOvonly => withClockAndReset(clock, th.harnessReset) { - NicLoopback.connect(Some(p), system.p(NICKey)) + (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + ports.map { p => + withClockAndReset(p.clock, th.harnessReset) { + NicLoopback.connect(Some(p.bits), system.p(NICKey)) } - case c: Clock => clock := c } Nil } }) class WithSimNetwork extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val clock = WireInit(false.B.asClock) - ports.map { - case p: NICIOvonly => SimNetwork.connect(Some(p), clock, th.harnessReset.asBool) - case c: Clock => clock := c - } + (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + ports.map { p => SimNetwork.connect(Some(p.bits), p.clock, th.harnessReset.asBool) } Nil } }) class WithSimAXIMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) - val clock = WireInit(false.B.asClock) - ports.map { - case p: Clock => clock := p - case _ => - } - val axi4_ports = ports.collect { case p: AXI4Bundle => p } - (axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => + (ports zip system.memAXI4Node.edges.in).map { case (port, edge) => val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p)) - withClockAndReset(clock, th.harnessReset) { + withClockAndReset(port.clock, th.harnessReset) { Module(mem.module).suggestName("mem") } - mem.io_axi4.head <> port + mem.io_axi4.head <> port.bits } Nil } }) class WithBlackBoxSimMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) - val clock = WireInit(false.B.asClock) - ports.map { - case p: Clock => clock := p - case _ => - } - val axi4_ports = ports.collect { case p: AXI4Bundle => p } - (axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => + (ports zip system.memAXI4Node.edges.in).map { case (port, edge) => val memSize = p(ExtMem).get.master.size val lineSize = p(CacheBlockBytes) val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram") - mem.io.axi <> port - mem.io.clock := clock + mem.io.axi <> port.bits + mem.io.clock := port.clock mem.io.reset := th.harnessReset } Nil @@ -170,57 +149,44 @@ class WithBlackBoxSimMem extends OverrideHarnessBinder({ }) class WithSimAXIMMIO extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) - val clock = WireInit(false.B.asClock) - ports.map { - case p: Clock => clock := p - case _ => - } - val axi4_ports = ports.collect { case p: AXI4Bundle => p } - (axi4_ports zip system.mmioAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) => + (ports zip system.mmioAXI4Node.edges.in).map { case (port, edge) => val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p)) - withClockAndReset(clock, th.harnessReset) { + withClockAndReset(port.clock, th.harnessReset) { Module(mmio_mem.module).suggestName("mmio_mem") } - mmio_mem.io_axi4.head <> port + mmio_mem.io_axi4.head <> port.bits } Nil } }) class WithTieOffInterrupts extends OverrideHarnessBinder({ - (system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { case p: UInt => p := 0.U } + (system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[UInt]) => { + ports.foreach { _ := 0.U } Nil } }) class WithTieOffL2FBusAXI extends OverrideHarnessBinder({ - (system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { - case p: AXI4Bundle => - p := DontCare - p.tieoff() - case c: Clock => - } + (system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + ports.foreach({ p => p := DontCare; p.bits.tieoff() }) Nil } }) class WithSimDebug extends OverrideHarnessBinder({ (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - if (!ports.isEmpty) { - val dtm_success = Wire(Bool()) - when (dtm_success) { th.success := true.B } - ports.map { - case d: ClockedDMIIO => - val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success) - case j: JTAGIO => - val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success) - case _ => - require(false, "We only support DMI or JTAG simulated debug connections") - } + ports.map { + case d: ClockedDMIIO => + val dtm_success = WireInit(false.B) + when (dtm_success) { th.success := true.B } + val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success) + case j: JTAGIO => + val dtm_success = WireInit(false.B) + when (dtm_success) { th.success := true.B } + val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success) } Nil } @@ -229,63 +195,56 @@ class WithSimDebug extends OverrideHarnessBinder({ class WithTiedOffDebug extends OverrideHarnessBinder({ (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { ports.map { + case j: JTAGIO => + j.TCK := true.B.asClock + j.TMS := true.B + j.TDI := true.B + j.TRSTn.foreach { r => r := true.B } case d: ClockedDMIIO => d.dmi.req.valid := false.B d.dmi.req.bits := DontCare d.dmi.resp.ready := true.B d.dmiClock := false.B.asClock d.dmiReset := true.B - case j: JTAGIO => - j.TCK := true.B.asClock - j.TMS := true.B - j.TDI := true.B - j.TRSTn.foreach { r => r := true.B } case a: ClockedAPBBundle => a.tieoff() a.clock := false.B.asClock a.reset := true.B.asAsyncReset a.psel := false.B a.penable := false.B - case _ => require(false) } Nil } }) + class WithTiedOffSerial extends OverrideHarnessBinder({ - (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { - case p: SerialIO => SerialAdapter.tieoff(Some(p)) - case _ => - } + (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + ports.map { p => SerialAdapter.tieoff(Some(p.bits)) } Nil } }) class WithSimSerial extends OverrideHarnessBinder({ - (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val serial_clock = WireInit(false.B.asClock) - ports.map { - case p: SerialIO => - val ser_success = SerialAdapter.connectSimSerial(p, serial_clock, th.harnessReset) - when (ser_success) { th.success := true.B } - case c: Clock => - serial_clock := c + (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + ports.map { p => + val ser_success = SerialAdapter.connectSimSerial(p.bits, p.clock, th.harnessReset) + when (ser_success) { th.success := true.B } } Nil } }) class WithTraceGenSuccess extends OverrideHarnessBinder({ - (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { case p: Bool => when (p) { th.success := true.B } } + (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => { + ports.map { p => when (p) { th.success := true.B } } Nil } }) class WithSimDromajoBridge extends ComposeHarnessBinder({ - (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { case p: TraceOutputTop => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } + (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => { + ports.map { p => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } Nil } }) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index dfcbd8ba..969ad571 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -74,7 +74,7 @@ object GetSystemParameters { // This macro overrides previous matches on some Top mixin. This is useful for // binders which drive IO, since those typically cannot be composed -class OverrideIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> ((t: Any) => { t match { @@ -87,7 +87,7 @@ class OverrideIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag: // This macro composes with previous matches on some Top mixin. This is useful for // annotation-like binders, since those can typically be composed -class ComposeIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> ((t: Any) => { t match { @@ -116,6 +116,11 @@ object BoreHelper { case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams()) +class ClockedIO[T <: Data](gen: T) extends Bundle { + val clock = Output(Clock()) + val bits = gen + override def cloneType: this.type = (new ClockedIO(DataMirror.internal.chiselTypeClone[T](gen))).asInstanceOf[this.type] +} class WithGPIOCells extends OverrideIOBinder({ (system: HasPeripheryGPIOModuleImp) => { @@ -131,14 +136,15 @@ class WithGPIOCells extends OverrideIOBinder({ (g, iocell) }).unzip }).unzip - (ports2d.flatten, cells2d.flatten) + val ports: Seq[Analog] = ports2d.flatten + (ports, cells2d.flatten) } }) // DOC include start: WithUARTIOCells class WithUARTIOCells extends OverrideIOBinder({ (system: HasPeripheryUARTModuleImp) => { - val (ports, cells2d) = system.uart.zipWithIndex.map({ case (u, i) => + val (ports: Seq[UARTPortIO], cells2d) = system.uart.zipWithIndex.map({ case (u, i) => val (port, ios) = IOCell.generateIOFromSignal(u, Some(s"iocell_uart_${i}"), system.p(IOCellKey)) port.suggestName(s"uart_${i}") (port, ios) @@ -150,7 +156,7 @@ class WithUARTIOCells extends OverrideIOBinder({ class WithSPIIOCells extends OverrideIOBinder({ (system: HasPeripherySPIFlashModuleImp) => { - val (ports, cells2d) = system.qspi.zipWithIndex.map({ case (s, i) => + val (ports: Seq[SPIChipIO], cells2d) = system.qspi.zipWithIndex.map({ case (s, i) => val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(s"spi_${i}") val iocellBase = s"iocell_spi_${i}" @@ -178,7 +184,7 @@ class WithSPIIOCells extends OverrideIOBinder({ class WithExtInterruptIOCells extends OverrideIOBinder({ (system: HasExtInterruptsModuleImp) => { if (system.outer.nExtInterrupts > 0) { - val (port, cells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"), system.p(IOCellKey)) + val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"), system.p(IOCellKey)) port.suggestName("ext_interrupts") (Seq(port), cells) } else { @@ -246,94 +252,79 @@ class WithDebugIOCells extends OverrideIOBinder({ class WithSerialIOCells extends OverrideIOBinder({ (system: CanHavePeripherySerial) => system.serial.map({ s => val sys = system.asInstanceOf[BaseSubsystem] - val (port, cells) = IOCell.generateIOFromSignal(s, Some("iocell_serial"), sys.p(IOCellKey)) - val serial_clock = Wire(Output(Clock())).suggestName("chiptop_serial_clock") - serial_clock := false.B.asClock // necessary for BoringUtils to work properly - dontTouch(serial_clock) - BoringUtils.bore(sys.fbus.module.clock, Seq(serial_clock)) - val (serial_clock_io, serial_clock_cell) = IOCell.generateIOFromSignal(serial_clock, Some("serial_clock"), sys.p(IOCellKey)) - serial_clock_io.suggestName("serial_clock") + val clocked_serial = Wire(new ClockedIO(DataMirror.internal.chiselTypeClone[SerialIO](s))).suggestName("serial_wire") + clocked_serial.clock := BoreHelper("serial_clock", sys.fbus.module.clock) + clocked_serial.bits <> s + val (port, cells) = IOCell.generateIOFromSignal(clocked_serial, Some("serial"), sys.p(IOCellKey)) port.suggestName("serial") - (Seq(port, serial_clock_io), cells ++ serial_clock_cell) + (Seq(port), cells) }).getOrElse((Nil, Nil)) }) class WithAXI4MemPunchthrough extends OverrideIOBinder({ (system: CanHaveMasterAXI4MemPort) => { - val clock = if (!system.mem_axi4.isEmpty) { - Some(BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)) - } else { - None - } - val ports = system.mem_axi4.zipWithIndex.map({ case (m, i) => - val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mem_${i}") - p <> m + val ports: Seq[ClockedIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}") + p.bits <> m + p.clock := BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock) p }) - (ports ++ clock, Nil) + (ports, Nil) } }) class WithAXI4MMIOPunchthrough extends OverrideIOBinder({ (system: CanHaveMasterAXI4MMIOPort) => { - val clock = if (!system.mmio_axi4.isEmpty) { - Some(BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)) - } else { - None - } - val ports = system.mmio_axi4.zipWithIndex.map({ case (m, i) => - val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mmio_${i}") - p <> m + val ports: Seq[ClockedIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}") + p.bits <> m + p.clock := BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock) p }) - (ports ++ clock, Nil) + (ports, Nil) } }) class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({ (system: CanHaveSlaveAXI4Port) => { - val clock = if (!system.l2_frontend_bus_axi4.isEmpty) { - Some(BoreHelper("axi4_fbus_clock", system.asInstanceOf[BaseSubsystem].fbus.module.clock)) - } else { - None - } - val ports = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) => - val p = IO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_fbus_${i}") - m <> p + val ports: Seq[ClockedIO[AXI4Bundle]] = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) => + val p = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}") + m <> p.bits + p.clock := BoreHelper("axi4_fbus_clock", system.asInstanceOf[BaseSubsystem].fbus.module.clock) p }) - (ports ++ clock, Nil) + (ports, Nil) } }) class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({ (system: CanHavePeripheryBlockDeviceModuleImp) => { - val ports = system.bdev.map({ bdev => - val p = IO(new BlockDeviceIO()(system.p)).suggestName("blockdev") - val clock = BoreHelper("blkdev_clk", system.outer.controller.get.module.clock) - p <> bdev - Seq(p, clock) - }).getOrElse(Nil) + val ports: Seq[ClockedIO[BlockDeviceIO]] = system.bdev.map({ bdev => + val p = IO(new ClockedIO(new BlockDeviceIO()(system.p))).suggestName("blockdev") + p.clock := BoreHelper("blkdev_clk", system.outer.controller.get.module.clock) + p.bits <> bdev + p + }).toSeq (ports, Nil) } }) class WithNICIOPunchthrough extends OverrideIOBinder({ (system: CanHavePeripheryIceNICModuleImp) => { - val port = system.net.map({ n => - val p = IO(new NICIOvonly).suggestName("nic") - val clock = BoreHelper("nic_clk", system.outer.icenicOpt.get.module.clock) - p <> n - Seq(p, clock) - }).getOrElse(Nil) - (port.toSeq, Nil) + val ports: Seq[ClockedIO[NICIOvonly]] = system.net.map({ n => + val p = IO(new ClockedIO(new NICIOvonly)).suggestName("nic") + p.clock := BoreHelper("nic_clk", system.outer.icenicOpt.get.module.clock) + p.bits <> n + p + }).toSeq + (ports, Nil) } }) class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({ (system: TraceGenSystemModuleImp) => { - val success = IO(Output(Bool())).suggestName("success") + val success: Bool = IO(Output(Bool())).suggestName("success") success := system.success (Seq(success), Nil) } @@ -341,7 +332,7 @@ class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({ class WithTraceIOPunchthrough extends OverrideIOBinder({ (system: CanHaveTraceIOModuleImp) => { - val ports = system.traceIO.map { t => + val ports: Option[TraceOutputTop] = system.traceIO.map { t => val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace") trace <> t trace From facef464e69e786323e22bedc3ed8a60ea1429c6 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 9 Sep 2020 00:15:02 -0700 Subject: [PATCH 38/93] Update BridgeBinders | fix runtime HarnessBinder port type checks --- .../src/main/scala/HarnessBinders.scala | 13 ++-- .../src/main/scala/BridgeBinders.scala | 66 ++++++++----------- 2 files changed, 35 insertions(+), 44 deletions(-) diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index f427d44e..90365b39 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -35,15 +35,15 @@ case object HarnessBinders extends Field[Map[String, (Any, HasHarnessSignalRefer object ApplyHarnessBinders { def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = { val pm = portMap.withDefaultValue(Nil) - map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) - } + map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) } } } -class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => { case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val pts = ports.map(_.asInstanceOf[S]) + val pts = ports.collect({case p: S => p}) + require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}") t match { case system: T => fn(system, th, pts) case _ => Nil @@ -52,10 +52,11 @@ class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, ) }) -class ComposeHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class ComposeHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => { case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val pts = ports.map(_.asInstanceOf[S]) + val pts = ports.collect({case p: S => p}) + require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}") t match { case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, pts) ++ fn(system, th, pts) case _ => Nil diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 0eb61a05..5dcddcfa 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -26,7 +26,7 @@ import ariane.ArianeTile import boom.common.{BoomTile} import barstools.iocell.chisel._ -import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters, IOCellKey} +import chipyard.iobinders.{ClockedIO, IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters, IOCellKey} import chipyard.{HasHarnessSignalReferences} import chipyard.harness._ @@ -56,57 +56,44 @@ class WithFireSimIOCellModels extends Config((site, here, up) => { }) class WithSerialBridge extends OverrideHarnessBinder({ - (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val clock = ports.collectFirst({case c: Clock => c}) - val p: Parameters = chipyard.iobinders.GetSystemParameters(system) - ports.filter(_.isInstanceOf[SerialIO]).map { - case s: SerialIO => withClockAndReset(clock.get, th.harnessReset) { - SerialBridge(clock.get, s, MainMemoryConsts.globalName)(p) + (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + ports.map { p => + withClockAndReset(p.clock, th.harnessReset) { + SerialBridge(p.clock, p.bits, MainMemoryConsts.globalName)(GetSystemParameters(system)) } - case _ => } Nil } }) class WithNICBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val clock = ports.collectFirst({case c: Clock => c}) - ports.map { - case p: NICIOvonly => withClockAndReset(clock.get, th.harnessReset) { NICBridge(clock.get, p)(system.p) } - case _ => - } + (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + ports.map { p => withClockAndReset(p.clock, th.harnessReset) { NICBridge(p.clock, p.bits)(system.p) } } Nil } }) class WithUARTBridge extends OverrideHarnessBinder({ - (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => - ports.map { case p: UARTPortIO => UARTBridge(th.harnessClock, p)(system.p) }; Nil + (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => + ports.map { p => UARTBridge(th.harnessClock, p)(system.p) }; Nil }) class WithBlockDeviceBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val clock = ports.collectFirst({case c: Clock => c}) - ports.map { - case p: BlockDeviceIO => BlockDevBridge(clock.get, p, th.harnessReset.toBool)(system.p) - case _ => - } + (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + ports.map { p => BlockDevBridge(p.clock, p.bits, th.harnessReset.toBool)(system.p) } Nil } }) class WithFASEDBridge extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { implicit val p: Parameters = GetSystemParameters(system) - val clock = ports.collectFirst({case c: Clock => c}) - val axi4_ports = ports.collect { case p: AXI4Bundle => p } - (axi4_ports zip system.memAXI4Node.edges.in).map { case (axi4: AXI4Bundle, edge) => - val nastiKey = NastiParameters(axi4.r.bits.data.getWidth, - axi4.ar.bits.addr.getWidth, - axi4.ar.bits.id.getWidth) + (ports zip system.memAXI4Node.edges.in).map { case (axi4, edge) => + val nastiKey = NastiParameters(axi4.bits.r.bits.data.getWidth, + axi4.bits.ar.bits.addr.getWidth, + axi4.bits.ar.bits.id.getWidth) system match { - case s: BaseSubsystem => FASEDBridge(clock.get, axi4, th.harnessReset.asBool, + case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, th.harnessReset.asBool, CompleteConfig(p(firesim.configs.MemModelKey), nastiKey, Some(AXI4EdgeSummary(edge)), @@ -119,22 +106,25 @@ class WithFASEDBridge extends OverrideHarnessBinder({ }) class WithTracerVBridge extends ComposeHarnessBinder({ - (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - ports.map { case p: TraceOutputTop => p.traces.map(tileTrace => - withClockAndReset(tileTrace.clock, tileTrace.reset) { TracerVBridge(tileTrace)(system.p) } - )} + (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => { + ports.map { p => + p.traces.map( + tileTrace => withClockAndReset(tileTrace.clock, tileTrace.reset) { TracerVBridge(tileTrace)(system.p) } + ) + } + Nil } }) class WithDromajoBridge extends ComposeHarnessBinder({ - (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => - ports.map { case p: TraceOutputTop => p.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p)) }; Nil + (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => + ports.map { p => p.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p)) }; Nil }) class WithTraceGenBridge extends OverrideHarnessBinder({ - (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => - ports.map { case p: Bool => GroundTestBridge(th.harnessClock, p)(system.p) }; Nil + (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => + ports.map { p => GroundTestBridge(th.harnessClock, p)(system.p) }; Nil }) class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ From 15d53e2cda499f46c9f3ddc727ae35a95461ecce Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 9 Sep 2020 15:12:37 -0700 Subject: [PATCH 39/93] Bump to the latest Rocket --- .../src/main/scala/config/SodorConfigs.scala | 101 +++++++++++++++++- generators/riscv-sodor | 2 +- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/generators/chipyard/src/main/scala/config/SodorConfigs.scala b/generators/chipyard/src/main/scala/config/SodorConfigs.scala index 1e1b7e51..335e7c4e 100644 --- a/generators/chipyard/src/main/scala/config/SodorConfigs.scala +++ b/generators/chipyard/src/main/scala/config/SodorConfigs.scala @@ -4,7 +4,7 @@ import chisel3._ import freechips.rocketchip.config.{Config} -class SodorConfig extends Config( +class Sodor1StageConfig extends Config( new chipyard.iobinders.WithUARTAdapter ++ new chipyard.iobinders.WithTieOffInterrupts ++ new chipyard.iobinders.WithTiedOffDebug ++ @@ -19,6 +19,101 @@ class SodorConfig extends Config( new freechips.rocketchip.subsystem.WithNoSlavePort ++ new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new sodor.common.WithNSodorCores(1) ++ + new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage1Factory) ++ new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) \ No newline at end of file + new freechips.rocketchip.system.BaseConfig) + +class Sodor2StageConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ + new chipyard.iobinders.WithTieOffInterrupts ++ + new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimSerial ++ + new testchipip.WithTSI ++ + new chipyard.config.WithBootROM ++ + new chipyard.config.WithUART ++ + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new freechips.rocketchip.subsystem.WithNoMemPort ++ + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ + new freechips.rocketchip.subsystem.WithNoSlavePort ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage2Factory) ++ + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + new freechips.rocketchip.system.BaseConfig) + +class Sodor3StageConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ + new chipyard.iobinders.WithTieOffInterrupts ++ + new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimSerial ++ + new testchipip.WithTSI ++ + new chipyard.config.WithBootROM ++ + new chipyard.config.WithUART ++ + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new freechips.rocketchip.subsystem.WithNoMemPort ++ + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ + new freechips.rocketchip.subsystem.WithNoSlavePort ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 2)) ++ + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + new freechips.rocketchip.system.BaseConfig) + +class Sodor3StageSinglePortConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ + new chipyard.iobinders.WithTieOffInterrupts ++ + new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimSerial ++ + new testchipip.WithTSI ++ + new chipyard.config.WithBootROM ++ + new chipyard.config.WithUART ++ + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new freechips.rocketchip.subsystem.WithNoMemPort ++ + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ + new freechips.rocketchip.subsystem.WithNoSlavePort ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 1)) ++ + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + new freechips.rocketchip.system.BaseConfig) + +class Sodor5StageConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ + new chipyard.iobinders.WithTieOffInterrupts ++ + new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimSerial ++ + new testchipip.WithTSI ++ + new chipyard.config.WithBootROM ++ + new chipyard.config.WithUART ++ + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new freechips.rocketchip.subsystem.WithNoMemPort ++ + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ + new freechips.rocketchip.subsystem.WithNoSlavePort ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage5Factory) ++ + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + new freechips.rocketchip.system.BaseConfig) + +class SodorUCodeConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ + new chipyard.iobinders.WithTieOffInterrupts ++ + new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimSerial ++ + new testchipip.WithTSI ++ + new chipyard.config.WithBootROM ++ + new chipyard.config.WithUART ++ + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new freechips.rocketchip.subsystem.WithNoMemPort ++ + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ + new freechips.rocketchip.subsystem.WithNoSlavePort ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new sodor.common.WithNSodorCores(1, internalTile = sodor.common.UCodeFactory) ++ + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + new freechips.rocketchip.system.BaseConfig) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index e635b4ae..70033f04 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit e635b4ae41d3d5ac570b8766877003e1c60f48ff +Subproject commit 70033f041a5e46fdc2c7c473fb8fa509bddc2e2d From a5385c0a54d9291ba0ec444c58042fdcc387ee98 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 10 Sep 2020 23:20:37 -0700 Subject: [PATCH 40/93] Update testchipip/icenet to use rocket-chip Located API --- .../chipyard/src/main/scala/DigitalTop.scala | 2 - .../src/main/scala/HarnessBinders.scala | 28 ++++++----- .../chipyard/src/main/scala/IOBinders.scala | 48 +++++++++---------- .../src/main/scala/BridgeBinders.scala | 14 +++--- .../src/main/scala/TargetConfigs.scala | 2 +- generators/icenet | 2 +- generators/testchipip | 2 +- 7 files changed, 49 insertions(+), 49 deletions(-) diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index ddcf66f3..a065b6be 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -32,11 +32,9 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l) with testchipip.CanHaveTraceIOModuleImp - with testchipip.CanHavePeripheryBlockDeviceModuleImp with sifive.blocks.devices.uart.HasPeripheryUARTModuleImp with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp - with icenet.CanHavePeripheryIceNICModuleImp with chipyard.example.CanHavePeripheryGCDModuleImp with freechips.rocketchip.util.DontTouch // DOC include end: DigitalTop diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 90365b39..06a3af5d 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -20,10 +20,10 @@ import barstools.iocell.chisel._ import testchipip._ import chipyard.HasHarnessSignalReferences -import chipyard.iobinders.ClockedIO +import chipyard.iobinders.GetSystemParameters import tracegen.{TraceGenSystemModuleImp} -import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} +import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} import scala.reflect.{ClassTag} @@ -89,24 +89,27 @@ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder }) class WithSimBlockDevice extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { - ports.map { p => SimBlockDevice.connect(p.clock, th.harnessReset.asBool, Some(p.bits))(system.p) } + (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + implicit val p: Parameters = GetSystemParameters(system) + ports.map { b => SimBlockDevice.connect(b.clock, th.harnessReset.asBool, Some(b.bits)) } Nil } }) class WithBlockDeviceModel extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { - ports.map { p => withClockAndReset(p.clock, th.harnessReset) { BlockDeviceModel.connect(Some(p.bits))(system.p) } } + (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + implicit val p: Parameters = GetSystemParameters(system) + ports.map { b => withClockAndReset(b.clock, th.harnessReset) { BlockDeviceModel.connect(Some(b.bits)) } } Nil } }) class WithLoopbackNIC extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { - ports.map { p => - withClockAndReset(p.clock, th.harnessReset) { - NicLoopback.connect(Some(p.bits), system.p(NICKey)) + (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + implicit val p: Parameters = GetSystemParameters(system) + ports.map { n => + withClockAndReset(n.clock, th.harnessReset) { + NicLoopback.connect(Some(n.bits), p(NICKey)) } } Nil @@ -114,8 +117,9 @@ class WithLoopbackNIC extends OverrideHarnessBinder({ }) class WithSimNetwork extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { - ports.map { p => SimNetwork.connect(Some(p.bits), p.clock, th.harnessReset.asBool) } + (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + implicit val p: Parameters = GetSystemParameters(system) + ports.map { n => SimNetwork.connect(Some(n.bits), n.clock, th.harnessReset.asBool) } Nil } }) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 969ad571..78233118 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -4,7 +4,7 @@ import chisel3._ import chisel3.util.experimental.{BoringUtils} import chisel3.experimental.{Analog, IO, DataMirror} -import freechips.rocketchip.config.{Field, Config, Parameters} +import freechips.rocketchip.config._ import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} import freechips.rocketchip.devices.debug._ import freechips.rocketchip.jtag.{JTAGIO} @@ -22,7 +22,7 @@ import tracegen.{TraceGenSystemModuleImp} import barstools.iocell.chisel._ import testchipip._ -import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} +import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} import chipyard.GlobalResetSchemeKey @@ -43,15 +43,15 @@ import scala.reflect.{ClassTag} case object IOBinders extends Field[Map[String, (Any) => (Seq[Data], Seq[IOCell])]]( Map[String, (Any) => (Seq[Data], Seq[IOCell])]().withDefaultValue((Any) => (Nil, Nil)) ) - object ApplyIOBinders { def apply(sys: LazyModule, map: Map[String, (Any) => (Seq[Data], Seq[IOCell])]): (Iterable[Data], Iterable[IOCell], Map[String, Seq[Data]]) = { val lzy = map.map({ case (s,f) => s -> f(sys) }) val imp = map.map({ case (s,f) => s -> f(sys.module) }) + val unzipped = (lzy.values ++ imp.values).unzip - val ports: Iterable[Data] = lzy.values.map(_._1).flatten ++ imp.values.map(_._1).flatten - val cells: Iterable[IOCell] = lzy.values.map(_._2).flatten ++ imp.values.map(_._2).flatten + val ports: Iterable[Data] = unzipped._1.flatten + val cells: Iterable[IOCell] = unzipped._2.flatten val portMap: Map[String, Seq[Data]] = map.keys.map(k => k -> (lzy(k)._1 ++ imp(k)._1)).toMap (ports, cells, portMap) } @@ -72,13 +72,17 @@ object GetSystemParameters { } } +class IOBinder(f: (View, View, View) => PartialFunction[Any, Any]) extends Config(f) + // This macro overrides previous matches on some Top mixin. This is useful for // binders which drive IO, since those typically cannot be composed -class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> ((t: Any) => { t match { - case system: T => fn(system) + case system: T => + val (ports, cells) = fn(system) + (ports, cells) case _ => (Nil, Nil) } }) @@ -87,14 +91,16 @@ class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implic // This macro composes with previous matches on some Top mixin. This is useful for // annotation-like binders, since those can typically be composed -class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> ((t: Any) => { t match { case system: T => val r = up(IOBinders, site)(tag.runtimeClass.toString)(system) val h = fn(system) - (r._1 ++ h._1, r._2 ++ h._2) + val ports = r._1 ++ h._1 + val cells = r._2 ++ h._2 + (ports, cells) case _ => (Nil, Nil) } }) @@ -116,11 +122,6 @@ object BoreHelper { case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams()) -class ClockedIO[T <: Data](gen: T) extends Bundle { - val clock = Output(Clock()) - val bits = gen - override def cloneType: this.type = (new ClockedIO(DataMirror.internal.chiselTypeClone[T](gen))).asInstanceOf[this.type] -} class WithGPIOCells extends OverrideIOBinder({ (system: HasPeripheryGPIOModuleImp) => { @@ -252,10 +253,7 @@ class WithDebugIOCells extends OverrideIOBinder({ class WithSerialIOCells extends OverrideIOBinder({ (system: CanHavePeripherySerial) => system.serial.map({ s => val sys = system.asInstanceOf[BaseSubsystem] - val clocked_serial = Wire(new ClockedIO(DataMirror.internal.chiselTypeClone[SerialIO](s))).suggestName("serial_wire") - clocked_serial.clock := BoreHelper("serial_clock", sys.fbus.module.clock) - clocked_serial.bits <> s - val (port, cells) = IOCell.generateIOFromSignal(clocked_serial, Some("serial"), sys.p(IOCellKey)) + val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, Some("serial"), sys.p(IOCellKey)) port.suggestName("serial") (Seq(port), cells) }).getOrElse((Nil, Nil)) @@ -299,11 +297,10 @@ class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({ }) class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp) => { + (system: CanHavePeripheryBlockDevice) => { val ports: Seq[ClockedIO[BlockDeviceIO]] = system.bdev.map({ bdev => - val p = IO(new ClockedIO(new BlockDeviceIO()(system.p))).suggestName("blockdev") - p.clock := BoreHelper("blkdev_clk", system.outer.controller.get.module.clock) - p.bits <> bdev + val p = IO(new ClockedIO(new BlockDeviceIO()(GetSystemParameters(system)))).suggestName("blockdev") + p <> bdev p }).toSeq (ports, Nil) @@ -311,11 +308,10 @@ class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({ }) class WithNICIOPunchthrough extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp) => { - val ports: Seq[ClockedIO[NICIOvonly]] = system.net.map({ n => + (system: CanHavePeripheryIceNIC) => { + val ports: Seq[ClockedIO[NICIOvonly]] = system.icenicOpt.map({ n => val p = IO(new ClockedIO(new NICIOvonly)).suggestName("nic") - p.clock := BoreHelper("nic_clk", system.outer.icenicOpt.get.module.clock) - p.bits <> n + p <> n p }).toSeq (ports, Nil) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 5dcddcfa..f42a1adf 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -14,7 +14,7 @@ import freechips.rocketchip.tile.{RocketTile} import sifive.blocks.devices.uart._ import testchipip._ -import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} +import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} import junctions.{NastiKey, NastiParameters} import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig} @@ -26,7 +26,7 @@ import ariane.ArianeTile import boom.common.{BoomTile} import barstools.iocell.chisel._ -import chipyard.iobinders.{ClockedIO, IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters, IOCellKey} +import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters, IOCellKey} import chipyard.{HasHarnessSignalReferences} import chipyard.harness._ @@ -67,8 +67,9 @@ class WithSerialBridge extends OverrideHarnessBinder({ }) class WithNICBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { - ports.map { p => withClockAndReset(p.clock, th.harnessReset) { NICBridge(p.clock, p.bits)(system.p) } } + (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + val p: Parameters = GetSystemParameters(system) + ports.map { n => withClockAndReset(n.clock, th.harnessReset) { NICBridge(n.clock, n.bits)(p) } } Nil } }) @@ -79,8 +80,9 @@ class WithUARTBridge extends OverrideHarnessBinder({ }) class WithBlockDeviceBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { - ports.map { p => BlockDevBridge(p.clock, p.bits, th.harnessReset.toBool)(system.p) } + (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + implicit val p: Parameters = GetSystemParameters(system) + ports.map { b => BlockDevBridge(b.clock, b.bits, th.harnessReset.toBool) } Nil } }) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 0d8cd367..2dede960 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -13,7 +13,7 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.devices.tilelink.{BootROMLocated, BootROMParams} import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey} import freechips.rocketchip.diplomacy.LazyModule -import testchipip.{BlockDeviceKey, BlockDeviceConfig, SerialKey, TracePortKey, TracePortParams} +import testchipip.{BlockDeviceKey, BlockDeviceConfig, TracePortKey, TracePortParams} import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams} import scala.math.{min, max} diff --git a/generators/icenet b/generators/icenet index bb23c81f..277a9080 160000 --- a/generators/icenet +++ b/generators/icenet @@ -1 +1 @@ -Subproject commit bb23c81fcfbdfde6767c5b7daa95f8f9436fb7db +Subproject commit 277a9080fe92afb25d942f3207252e0ddea1b864 diff --git a/generators/testchipip b/generators/testchipip index 6f4e7ae2..70df93e5 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 6f4e7ae2c94e867f08cd0d408a106fba2f389de2 +Subproject commit 70df93e5867e6676e62bb23b11b9086471fdecf7 From d2b42cee2ce7e5d22d3480ad7e6b9470a2507652 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sat, 12 Sep 2020 23:31:54 -0700 Subject: [PATCH 41/93] Bump testchipip --- generators/testchipip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/testchipip b/generators/testchipip index 70df93e5..a86c827c 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 70df93e5867e6676e62bb23b11b9086471fdecf7 +Subproject commit a86c827ca6e4e9d8320117ef1223da0ff752d064 From be0c04123245a722bc9bd18484fd2cb5d40c1c07 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sun, 13 Sep 2020 06:36:37 +0000 Subject: [PATCH 42/93] Bump Firesim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 522125da..c1cd3e5e 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 522125da5d546544e3ce4492b6f105eeb93fcdf6 +Subproject commit c1cd3e5e7013b30f30508c7f47ff13180949eafe From 6c5bce5430002e60a676a9089f7d5822523e13ff Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sun, 13 Sep 2020 11:59:16 -0700 Subject: [PATCH 43/93] Support Tilelink over serial --- .circleci/config.yml | 19 ++++++++++ .circleci/defaults.sh | 1 + .circleci/run-tests.sh | 3 ++ .../chipyard/src/main/scala/DigitalTop.scala | 3 +- .../src/main/scala/HarnessBinders.scala | 36 ++++++++++++++++--- .../chipyard/src/main/scala/IOBinders.scala | 17 ++++++--- .../chipyard/src/main/scala/Subsystem.scala | 4 +-- .../main/scala/config/AbstractConfig.scala | 7 ++-- .../src/main/scala/config/ArianeConfigs.scala | 2 +- .../src/main/scala/config/RocketConfigs.scala | 10 ++++-- .../src/main/scala/BridgeBinders.scala | 2 +- .../src/main/scala/TargetConfigs.scala | 4 +-- generators/testchipip | 2 +- sims/firesim | 2 +- 14 files changed, 90 insertions(+), 22 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index eac8504a..1b239354 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -204,6 +204,11 @@ jobs: steps: - prepare-rtl: project-key: "chipyard-dmirocket" + prepare-chipyard-tlserial: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-tlserial" prepare-chipyard-sha3: executor: main-env steps: @@ -302,6 +307,11 @@ jobs: steps: - run-tests: project-key: "chipyard-dmirocket" + chipyard-tlserial-run-tests: + executor: main-env + steps: + - run-tests: + project-key: "chipyard-tlserial" chipyard-sha3-run-tests: executor: main-env steps: @@ -456,6 +466,11 @@ workflows: - install-riscv-toolchain - install-verilator + - prepare-chipyard-tlserial: + requires: + - install-riscv-toolchain + - install-verilator + - prepare-chipyard-sha3: requires: - install-riscv-toolchain @@ -551,6 +566,10 @@ workflows: requires: - prepare-chipyard-dmirocket + - chipyard-tlserial-run-tests: + requires: + - prepare-chipyard-tlserial + - chipyard-sha3-run-tests: requires: - prepare-chipyard-sha3 diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 703737cd..2a744e89 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -49,6 +49,7 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim declare -A mapping mapping["chipyard-rocket"]="" mapping["chipyard-dmirocket"]=" CONFIG=dmiRocketConfig" +mapping["chipyard-tlserial"]=" CONFIG=TLSerialRocketConfig" mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig" mapping["chipyard-streaming-fir"]=" CONFIG=StreamingFIRRocketConfig" mapping["chipyard-streaming-passthrough"]=" CONFIG=StreamingPassthroughRocketConfig" diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index 3e7b0285..cee04dd3 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -35,6 +35,9 @@ case $1 in chipyard-dmirocket) run_bmark ${mapping[$1]} ;; + chipyard-tlserial) + run_bmark ${mapping[$1]} + ;; chipyard-boom) run_bmark ${mapping[$1]} ;; diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index a065b6be..f967b8fc 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -16,7 +16,8 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem with testchipip.CanHaveTraceIO // Enables optionally adding trace IO with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device - with testchipip.CanHavePeripherySerial // Enables optionally adding the TSI serial-adapter and port + with testchipip.CanHavePeripheryTLSerial // Enables optionally adding the tilelink-over-serial backing memory + with testchipip.CanHavePeripheryTSISerial // Enables optionally adding the TSI serial-adapter and port with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART with sifive.blocks.devices.gpio.HasPeripheryGPIO // Enables optionally adding the sifive GPIOs with sifive.blocks.devices.spi.HasPeripherySPIFlash // Enables optionally adding the sifive SPI flash controller diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 06a3af5d..c1b57f72 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -223,15 +223,15 @@ class WithTiedOffDebug extends OverrideHarnessBinder({ }) -class WithTiedOffSerial extends OverrideHarnessBinder({ - (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { +class WithTiedOffTSISerial extends OverrideHarnessBinder({ + (system: CanHavePeripheryTSISerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { ports.map { p => SerialAdapter.tieoff(Some(p.bits)) } Nil } }) -class WithSimSerial extends OverrideHarnessBinder({ - (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { +class WithSimTSISerial extends OverrideHarnessBinder({ + (system: CanHavePeripheryTSISerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { ports.map { p => val ser_success = SerialAdapter.connectSimSerial(p.bits, p.clock, th.harnessReset) when (ser_success) { th.success := true.B } @@ -240,6 +240,34 @@ class WithSimSerial extends OverrideHarnessBinder({ } }) +class WithSimTLSerial(withHarnessSerialAdapter: Boolean = false) extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + implicit val p = chipyard.iobinders.GetSystemParameters(system) + ports.map({ port => + withClockAndReset(port.clock, th.harnessReset) { + val lRam = LazyModule(new SerialRAM( + p(SerialTLKey).get.width, + p(SerialTLKey).get.memParams.master.size, + p(SerialTLKey).get.memParams.master.base, + managerEdge = system.serdesser.get.managerNode.edges.in(0), + clientEdge = system.serdesser.get.clientNode.edges.out(0) + )) + val ram = Module(lRam.module) + ram.io.ser <> port.bits + + require(lRam.serdesser.module.mergedParams == system.serdesser.get.module.mergedParams, + "Mismatch between chip-side diplomatic params and testram diplomatic params") + if (withHarnessSerialAdapter) { + val success = SerialAdapter.connectSimSerial(Some(ram.io.tsi_ser), port.clock, th.harnessReset.asBool) + when (success) { th.success := true.B } + } else { + SerialAdapter.tieoff(Some(ram.io.tsi_ser)) + } + } + }) + } +}) + class WithTraceGenSuccess extends OverrideHarnessBinder({ (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => { ports.map { p => when (p) { th.success := true.B } } diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 78233118..03138cc1 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -250,11 +250,20 @@ class WithDebugIOCells extends OverrideIOBinder({ } }) -class WithSerialIOCells extends OverrideIOBinder({ - (system: CanHavePeripherySerial) => system.serial.map({ s => +class WithSerialTSIIOCells extends OverrideIOBinder({ + (system: CanHavePeripheryTSISerial) => system.serial_tsi.map({ s => val sys = system.asInstanceOf[BaseSubsystem] - val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, Some("serial"), sys.p(IOCellKey)) - port.suggestName("serial") + val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, Some("serial_tsi"), sys.p(IOCellKey)) + port.suggestName("serial_tsi") + (Seq(port), cells) + }).getOrElse((Nil, Nil)) +}) + +class WithSerialTLIOCells extends OverrideIOBinder({ + (system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s => + val sys = system.asInstanceOf[BaseSubsystem] + val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, Some("serial_tl"), sys.p(IOCellKey)) + port.suggestName("serial_tl") (Seq(port), cells) }).getOrElse((Nil, Nil)) }) diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 7f089ce1..35c41e0c 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -25,12 +25,12 @@ import freechips.rocketchip.amba.axi4._ import boom.common.{BoomTile} -import testchipip.{DromajoHelper, CanHavePeripherySerial, SerialKey} +import testchipip.{DromajoHelper, CanHavePeripheryTSISerial, SerialTSIKey} trait CanHaveHTIF { this: BaseSubsystem => // Advertise HTIF if system can communicate with fesvr if (this match { - case _: CanHavePeripherySerial if p(SerialKey) => true + case _: CanHavePeripheryTSISerial if p(SerialTSIKey).nonEmpty => true case _: HasPeripheryDebug if p(ExportDebug).protocols.nonEmpty => true case _ => false }) { diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 950cb4b4..aed55d02 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -15,7 +15,7 @@ class AbstractConfig extends Config( new chipyard.harness.WithUARTAdapter ++ // add UART adapter to display UART on stdout, if uart is present new chipyard.harness.WithBlackBoxSimMem ++ // add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled new chipyard.harness.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled - new chipyard.harness.WithSimSerial ++ // add SimSerial adapter for HTIF, if serial port is present + new chipyard.harness.WithSimTSISerial ++ // add SimSerial adapter for HTIF, if serial port is present new chipyard.harness.WithGPIOTiedOff ++ // tie-off chiptop GPIOs, if GPIOs are present new chipyard.harness.WithSimSPIFlashModel ++ // add simulated SPI flash memory, if SPI is enabled new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled @@ -29,7 +29,8 @@ class AbstractConfig extends Config( new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++ new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++ new chipyard.iobinders.WithNICIOPunchthrough ++ - new chipyard.iobinders.WithSerialIOCells ++ + new chipyard.iobinders.WithSerialTSIIOCells ++ + new chipyard.iobinders.WithSerialTLIOCells ++ new chipyard.iobinders.WithDebugIOCells ++ new chipyard.iobinders.WithUARTIOCells ++ new chipyard.iobinders.WithGPIOCells ++ @@ -39,7 +40,7 @@ class AbstractConfig extends Config( new chipyard.iobinders.WithExtInterruptIOCells ++ - new testchipip.WithTSI ++ // use testchipip serial offchip link + new testchipip.WithSerialTSI ++ // use testchipip serial offchip link new chipyard.config.WithBootROM ++ // use default bootrom new chipyard.config.WithUART ++ // add a UART new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs diff --git a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala index 9f701331..b7c347dc 100644 --- a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala @@ -13,7 +13,7 @@ class ArianeConfig extends Config( new chipyard.config.AbstractConfig) class dmiArianeConfig extends Config( - new chipyard.harness.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial + new chipyard.harness.WithTiedOffTSISerial ++ // Tie off the serial port, override default instantiation of SimSerial new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new ariane.WithNArianeCores(1) ++ // single Ariane core new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 16d298fb..9f2a97de 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -25,7 +25,7 @@ class GemminiRocketConfig extends Config( // DOC include start: DmiRocket class dmiRocketConfig extends Config( - new chipyard.harness.WithTiedOffSerial ++ // don't use serial to drive the chip, since we use DMI instead + new chipyard.harness.WithTiedOffTSISerial ++ // don't use serial to drive the chip, since we use DMI instead new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -182,4 +182,10 @@ class DividedClockRocketConfig extends Config( new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) - +class TLSerialRocketConfig extends Config( + new chipyard.harness.WithSimTLSerial(withHarnessSerialAdapter = true) ++ // add external TL backing memory, and external serial adapter + new testchipip.WithDefaultSerialTL ++ // support tilelink-over-serial + new testchipip.WithNoSerialTSI ++ // remove internal serial adapter + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove AXI4 backing memory + new chipyard.config.AbstractConfig) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index f42a1adf..ebd629c7 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -56,7 +56,7 @@ class WithFireSimIOCellModels extends Config((site, here, up) => { }) class WithSerialBridge extends OverrideHarnessBinder({ - (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + (system: CanHavePeripheryTSISerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { ports.map { p => withClockAndReset(p.clock, th.harnessReset) { SerialBridge(p.clock, p.bits, MainMemoryConsts.globalName)(GetSystemParameters(system)) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 2dede960..7df0bf61 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -84,7 +84,7 @@ class WithFireSimConfigTweaks extends Config( // Required: Adds IO to attach SerialBridge. The SerialBridges is responsible // for signalling simulation termination under simulation success. This fragment can // be removed if you supply an auxiliary bridge that signals simulation termination - new testchipip.WithTSI ++ + new testchipip.WithSerialTSI ++ // Optional: Removing this will require using an initramfs under linux new testchipip.WithBlockDevice ++ // Required*: Scale default baud rate with periphery bus frequency @@ -131,7 +131,7 @@ class FireSimSmallSystemConfig extends Config( new WithoutClockGating ++ new WithoutTLMonitors ++ new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++ - new testchipip.WithTSI ++ + new testchipip.WithSerialTSI ++ new testchipip.WithBlockDevice ++ new chipyard.config.WithUART ++ new freechips.rocketchip.subsystem.WithInclusiveCache(nWays = 2, capacityKB = 64) ++ diff --git a/generators/testchipip b/generators/testchipip index a86c827c..6f815737 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit a86c827ca6e4e9d8320117ef1223da0ff752d064 +Subproject commit 6f8157375451fbb32e9dae291f2c65878a2b1dcd diff --git a/sims/firesim b/sims/firesim index c1cd3e5e..2b52057e 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit c1cd3e5e7013b30f30508c7f47ff13180949eafe +Subproject commit 2b52057e158fd91d44c6259aa08869622a88040a From 5506f776796dc54ca301c910dacfc3bbeb21adb4 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 14 Sep 2020 09:14:57 -0700 Subject: [PATCH 44/93] Add CircleCI check and update Sodor config --- .circleci/config.yml | 20 +++ .circleci/run-tests.sh | 3 + .../src/main/scala/config/SodorConfigs.scala | 120 ++++-------------- scripts/tutorial-patches/build.sbt.patch | 2 +- 4 files changed, 48 insertions(+), 97 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index eac8504a..7b09791c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -262,6 +262,11 @@ jobs: steps: - prepare-rtl: project-key: "chipyard-ariane" + prepare-chipyard-sodor: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-sodor" prepare-icenet: executor: main-env steps: @@ -390,6 +395,12 @@ jobs: - run-tests: project-key: "chipyard-ariane" timeout: "30m" + chipyard-sodor-run-tests: + executor: main-env + steps: + - run-tests: + project-key: "chipyard-sodor" + timeout: "20m" chipyard-nvdla-run-tests: executor: main-env steps: @@ -511,6 +522,11 @@ workflows: - install-riscv-toolchain - install-verilator + - prepare-chipyard-sodor: + requires: + - install-riscv-toolchain + - install-verilator + - prepare-icenet: requires: - install-riscv-toolchain @@ -616,6 +632,10 @@ workflows: requires: - prepare-chipyard-ariane + - chipyard-sodor-run-tests: + requires: + - prepare-chipyard-sodor + - chipyard-nvdla-run-tests: requires: - prepare-chipyard-nvdla diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index 3e7b0285..c0b932b6 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -91,6 +91,9 @@ case $1 in chipyard-ariane) make run-binary-fast -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv ;; + chipyard-sodor) + run_asm ${mapping[$1]} + ;; chipyard-nvdla) make -C $LOCAL_CHIPYARD_DIR/tests make -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/nvdla.riscv run-binary diff --git a/generators/chipyard/src/main/scala/config/SodorConfigs.scala b/generators/chipyard/src/main/scala/config/SodorConfigs.scala index 335e7c4e..df386dd9 100644 --- a/generators/chipyard/src/main/scala/config/SodorConfigs.scala +++ b/generators/chipyard/src/main/scala/config/SodorConfigs.scala @@ -5,115 +5,43 @@ import chisel3._ import freechips.rocketchip.config.{Config} class Sodor1StageConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port - new freechips.rocketchip.subsystem.WithNBanks(0) ++ - new freechips.rocketchip.subsystem.WithNoMemPort ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage1Factory) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new chipyard.config.AbstractConfig) class Sodor2StageConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port - new freechips.rocketchip.subsystem.WithNBanks(0) ++ - new freechips.rocketchip.subsystem.WithNoMemPort ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage2Factory) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new chipyard.config.AbstractConfig) class Sodor3StageConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port - new freechips.rocketchip.subsystem.WithNBanks(0) ++ - new freechips.rocketchip.subsystem.WithNoMemPort ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 2)) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new chipyard.config.AbstractConfig) class Sodor3StageSinglePortConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port - new freechips.rocketchip.subsystem.WithNBanks(0) ++ - new freechips.rocketchip.subsystem.WithNoMemPort ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 1)) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new chipyard.config.AbstractConfig) class Sodor5StageConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port - new freechips.rocketchip.subsystem.WithNBanks(0) ++ - new freechips.rocketchip.subsystem.WithNoMemPort ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage5Factory) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new chipyard.config.AbstractConfig) class SodorUCodeConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port - new freechips.rocketchip.subsystem.WithNBanks(0) ++ - new freechips.rocketchip.subsystem.WithNoMemPort ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.UCodeFactory) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithNBanks(0) ++ + new chipyard.config.AbstractConfig) diff --git a/scripts/tutorial-patches/build.sbt.patch b/scripts/tutorial-patches/build.sbt.patch index 6c1e3007..aa7f0bd4 100644 --- a/scripts/tutorial-patches/build.sbt.patch +++ b/scripts/tutorial-patches/build.sbt.patch @@ -9,7 +9,7 @@ index 5d642c1..56f6fda 100644 - sha3, // On separate line to allow for cleaner tutorial-setup patches +// sha3, // On separate line to allow for cleaner tutorial-setup patches dsptools, `rocket-dsptools`, - gemmini, icenet, tracegen, ariane, nvdla) + gemmini, icenet, tracegen, ariane, nvdla, sodor) .settings(commonSettings) @@ -158,9 +158,9 @@ lazy val ariane = (project in file("generators/ariane")) .dependsOn(rocketchip) From 10625a3a6cc72a304a8608134b9d4876b9386e6a Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Mon, 14 Sep 2020 13:27:31 -0700 Subject: [PATCH 45/93] Undo regression in iocells flexibility --- .../src/main/scala/BridgeBinders.scala | 18 ++++++++++++++---- tools/barstools | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index f42a1adf..8a4d0a69 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -39,10 +39,20 @@ trait Unsupported { require(false, "We do not support this IOCell type") } -class FireSimAnalogIOCell extends RawModule with AnalogIOCell with Unsupported -class FireSimDigitalGPIOCell extends RawModule with DigitalGPIOCell with Unsupported -class FireSimDigitalInIOCell extends RawModule with DigitalInIOCell { io.i := io.pad } -class FireSimDigitalOutIOCell extends RawModule with DigitalOutIOCell { io.pad := io.o } +class FireSimAnalogIOCell extends RawModule with AnalogIOCell with Unsupported { + val io = IO(new AnalogIOCellBundle) +} +class FireSimDigitalGPIOCell extends RawModule with DigitalGPIOCell with Unsupported { + val io = IO(new DigitalGPIOCellBundle) +} +class FireSimDigitalInIOCell extends RawModule with DigitalInIOCell { + val io = IO(new DigitalInIOCellBundle) + io.i := io.pad +} +class FireSimDigitalOutIOCell extends RawModule with DigitalOutIOCell { + val io = IO(new DigitalOutIOCellBundle) + io.pad := io.o +} case class FireSimIOCellParams() extends IOCellTypeParams { def analog() = Module(new FireSimAnalogIOCell) diff --git a/tools/barstools b/tools/barstools index ba681676..31590a79 160000 --- a/tools/barstools +++ b/tools/barstools @@ -1 +1 @@ -Subproject commit ba681676f338af158023c99b4c802009aa0b601b +Subproject commit 31590a7948db47fd16beed266c4833579acc305b From 0d8e87126cb4070044a3a86da7fe7bdac125a4fc Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Mon, 14 Sep 2020 19:41:02 -0700 Subject: [PATCH 46/93] Deprecate support for on-chip SerialAdapter --- .../chipyard/src/main/scala/DigitalTop.scala | 1 - .../src/main/scala/HarnessBinders.scala | 50 +++++-------------- .../chipyard/src/main/scala/IOBinders.scala | 9 ---- .../chipyard/src/main/scala/Subsystem.scala | 4 +- .../main/scala/config/AbstractConfig.scala | 6 +-- .../src/main/scala/config/ArianeConfigs.scala | 2 +- .../src/main/scala/config/RocketConfigs.scala | 10 ++-- .../src/main/scala/BridgeBinders.scala | 5 +- .../src/main/scala/TargetConfigs.scala | 4 +- generators/testchipip | 2 +- tools/barstools | 2 +- 11 files changed, 29 insertions(+), 66 deletions(-) diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index f967b8fc..a14a3fbe 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -17,7 +17,6 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device with testchipip.CanHavePeripheryTLSerial // Enables optionally adding the tilelink-over-serial backing memory - with testchipip.CanHavePeripheryTSISerial // Enables optionally adding the TSI serial-adapter and port with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART with sifive.blocks.devices.gpio.HasPeripheryGPIO // Enables optionally adding the sifive GPIOs with sifive.blocks.devices.spi.HasPeripherySPIFlash // Enables optionally adding the sifive SPI flash controller diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index c1b57f72..e5cfacfb 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -223,47 +223,23 @@ class WithTiedOffDebug extends OverrideHarnessBinder({ }) -class WithTiedOffTSISerial extends OverrideHarnessBinder({ - (system: CanHavePeripheryTSISerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { - ports.map { p => SerialAdapter.tieoff(Some(p.bits)) } - Nil - } -}) - -class WithSimTSISerial extends OverrideHarnessBinder({ - (system: CanHavePeripheryTSISerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { - ports.map { p => - val ser_success = SerialAdapter.connectSimSerial(p.bits, p.clock, th.harnessReset) - when (ser_success) { th.success := true.B } - } - Nil - } -}) - -class WithSimTLSerial(withHarnessSerialAdapter: Boolean = false) extends OverrideHarnessBinder({ +class WithSerialAdapterTiedOff extends OverrideHarnessBinder({ (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { implicit val p = chipyard.iobinders.GetSystemParameters(system) ports.map({ port => - withClockAndReset(port.clock, th.harnessReset) { - val lRam = LazyModule(new SerialRAM( - p(SerialTLKey).get.width, - p(SerialTLKey).get.memParams.master.size, - p(SerialTLKey).get.memParams.master.base, - managerEdge = system.serdesser.get.managerNode.edges.in(0), - clientEdge = system.serdesser.get.clientNode.edges.out(0) - )) - val ram = Module(lRam.module) - ram.io.ser <> port.bits + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) + SerialAdapter.tieoff(ram.module.io.tsi_ser) + }) + } +}) - require(lRam.serdesser.module.mergedParams == system.serdesser.get.module.mergedParams, - "Mismatch between chip-side diplomatic params and testram diplomatic params") - if (withHarnessSerialAdapter) { - val success = SerialAdapter.connectSimSerial(Some(ram.io.tsi_ser), port.clock, th.harnessReset.asBool) - when (success) { th.success := true.B } - } else { - SerialAdapter.tieoff(Some(ram.io.tsi_ser)) - } - } +class WithSimSerial extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + implicit val p = chipyard.iobinders.GetSystemParameters(system) + ports.map({ port => + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) + val success = SerialAdapter.connectSimSerial(ram.module.io.tsi_ser, port.clock, th.harnessReset.asBool) + when (success) { th.success := true.B } }) } }) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 03138cc1..73a8acfd 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -250,15 +250,6 @@ class WithDebugIOCells extends OverrideIOBinder({ } }) -class WithSerialTSIIOCells extends OverrideIOBinder({ - (system: CanHavePeripheryTSISerial) => system.serial_tsi.map({ s => - val sys = system.asInstanceOf[BaseSubsystem] - val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, Some("serial_tsi"), sys.p(IOCellKey)) - port.suggestName("serial_tsi") - (Seq(port), cells) - }).getOrElse((Nil, Nil)) -}) - class WithSerialTLIOCells extends OverrideIOBinder({ (system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s => val sys = system.asInstanceOf[BaseSubsystem] diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index c3ca93b7..172be692 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -25,12 +25,12 @@ import freechips.rocketchip.amba.axi4._ import boom.common.{BoomTile} -import testchipip.{DromajoHelper, CanHavePeripheryTSISerial, SerialTSIKey} +import testchipip.{DromajoHelper, CanHavePeripheryTLSerial, SerialTLKey} trait CanHaveHTIF { this: BaseSubsystem => // Advertise HTIF if system can communicate with fesvr if (this match { - case _: CanHavePeripheryTSISerial if p(SerialTSIKey).nonEmpty => true + case _: CanHavePeripheryTKSerial if p(SerialTLKey).nonEmpty => true case _: HasPeripheryDebug if p(ExportDebug).dmi => true case _ => false }) { diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index aed55d02..5b356c74 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -14,8 +14,8 @@ class AbstractConfig extends Config( // The HarnessBinders control generation of hardware in the TestHarness new chipyard.harness.WithUARTAdapter ++ // add UART adapter to display UART on stdout, if uart is present new chipyard.harness.WithBlackBoxSimMem ++ // add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled + new chipyard.harness.WithSimSerial ++ // add external serial-adapter and RAM new chipyard.harness.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled - new chipyard.harness.WithSimTSISerial ++ // add SimSerial adapter for HTIF, if serial port is present new chipyard.harness.WithGPIOTiedOff ++ // tie-off chiptop GPIOs, if GPIOs are present new chipyard.harness.WithSimSPIFlashModel ++ // add simulated SPI flash memory, if SPI is enabled new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled @@ -29,7 +29,6 @@ class AbstractConfig extends Config( new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++ new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++ new chipyard.iobinders.WithNICIOPunchthrough ++ - new chipyard.iobinders.WithSerialTSIIOCells ++ new chipyard.iobinders.WithSerialTLIOCells ++ new chipyard.iobinders.WithDebugIOCells ++ new chipyard.iobinders.WithUARTIOCells ++ @@ -39,8 +38,7 @@ class AbstractConfig extends Config( new chipyard.iobinders.WithTraceIOPunchthrough ++ new chipyard.iobinders.WithExtInterruptIOCells ++ - - new testchipip.WithSerialTSI ++ // use testchipip serial offchip link + new testchipip.WithDefaultSerialTL ++ // use serialized tilelink port to external serialadapter/harnessRAM new chipyard.config.WithBootROM ++ // use default bootrom new chipyard.config.WithUART ++ // add a UART new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs diff --git a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala index b7c347dc..6e75ac54 100644 --- a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala @@ -13,7 +13,7 @@ class ArianeConfig extends Config( new chipyard.config.AbstractConfig) class dmiArianeConfig extends Config( - new chipyard.harness.WithTiedOffTSISerial ++ // Tie off the serial port, override default instantiation of SimSerial + new chipyard.harness.WithSerialAdapterTiedOff ++ // Tie off the serial port, override default instantiation of SimSerial new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new ariane.WithNArianeCores(1) ++ // single Ariane core new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 9f2a97de..42b5f3b0 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -25,7 +25,7 @@ class GemminiRocketConfig extends Config( // DOC include start: DmiRocket class dmiRocketConfig extends Config( - new chipyard.harness.WithTiedOffTSISerial ++ // don't use serial to drive the chip, since we use DMI instead + new chipyard.harness.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -182,10 +182,8 @@ class DividedClockRocketConfig extends Config( new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) -class TLSerialRocketConfig extends Config( - new chipyard.harness.WithSimTLSerial(withHarnessSerialAdapter = true) ++ // add external TL backing memory, and external serial adapter - new testchipip.WithDefaultSerialTL ++ // support tilelink-over-serial - new testchipip.WithNoSerialTSI ++ // remove internal serial adapter +class LBWIFMemoryRocketConfig extends Config( + new testchipip.WithSerialTLMem(isMainMemory=true) ++ // set lbwif memory base to DRAM_BASE, use as main memory + new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove AXI4 backing memory new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove AXI4 backing memory new chipyard.config.AbstractConfig) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 98f672a9..4943e130 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -66,10 +66,11 @@ class WithFireSimIOCellModels extends Config((site, here, up) => { }) class WithSerialBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryTSISerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { ports.map { p => + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, p, th.harnessReset) withClockAndReset(p.clock, th.harnessReset) { - SerialBridge(p.clock, p.bits, MainMemoryConsts.globalName)(GetSystemParameters(system)) + SerialBridge(p.clock, ram.module.io.tsi_ser, MainMemoryConsts.globalName)(GetSystemParameters(system)) } } Nil diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 7df0bf61..678afccf 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -84,7 +84,7 @@ class WithFireSimConfigTweaks extends Config( // Required: Adds IO to attach SerialBridge. The SerialBridges is responsible // for signalling simulation termination under simulation success. This fragment can // be removed if you supply an auxiliary bridge that signals simulation termination - new testchipip.WithSerialTSI ++ + new testchipip.WithDefaultSerialTL ++ // Optional: Removing this will require using an initramfs under linux new testchipip.WithBlockDevice ++ // Required*: Scale default baud rate with periphery bus frequency @@ -131,7 +131,7 @@ class FireSimSmallSystemConfig extends Config( new WithoutClockGating ++ new WithoutTLMonitors ++ new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++ - new testchipip.WithSerialTSI ++ + new testchipip.WithDefaultSerialTL ++ new testchipip.WithBlockDevice ++ new chipyard.config.WithUART ++ new freechips.rocketchip.subsystem.WithInclusiveCache(nWays = 2, capacityKB = 64) ++ diff --git a/generators/testchipip b/generators/testchipip index 6f815737..e845cb3f 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 6f8157375451fbb32e9dae291f2c65878a2b1dcd +Subproject commit e845cb3f50bb141fec7e8291a40d0b46d5ef5c12 diff --git a/tools/barstools b/tools/barstools index 31590a79..847f72ec 160000 --- a/tools/barstools +++ b/tools/barstools @@ -1 +1 @@ -Subproject commit 31590a7948db47fd16beed266c4833579acc305b +Subproject commit 847f72eca0fa3207ab7140c07e980ac9f8cf1251 From 642441e0a27171665ff3a2484b599d94e244f497 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 14 Sep 2020 23:54:52 -0700 Subject: [PATCH 47/93] Replaced memory and fixed 3-stage single port arbiter --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 70033f04..43985218 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 70033f041a5e46fdc2c7c473fb8fa509bddc2e2d +Subproject commit 43985218b8c91c9206018177d81e37e27267dbf6 From aa8b7c15ecfed723d8f01748ebb3af6e64516cde Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Mon, 14 Sep 2020 23:04:58 -0700 Subject: [PATCH 48/93] Reduce CI redundancy by grouping builds --- .circleci/config.yml | 386 ++++++++++++-------------------------- .circleci/defaults.sh | 9 + .circleci/do-rtl-build.sh | 19 +- 3 files changed, 142 insertions(+), 272 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index eac8504a..6ed04488 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,11 +99,10 @@ commands: tools-version: type: string default: "riscv-tools" + group-key: + type: string project-key: type: string - extra-cache-restore: - type: string - default: "" run-script: type: string default: "run-tests.sh" @@ -115,13 +114,7 @@ commands: tools-version: "<< parameters.tools-version >>" - restore_cache: keys: - - << parameters.project-key >>-{{ .Branch }}-{{ .Revision }} - - when: - condition: << parameters.extra-cache-restore >> - steps: - - restore_cache: - keys: - - << parameters.extra-cache-restore >>-{{ .Branch }}-{{ .Revision }} + - << parameters.group-key >>-{{ .Branch }}-{{ .Revision }} - run: name: Run << parameters.project-key >> subproject tests command: .circleci/<< parameters.run-script >> << parameters.project-key >> @@ -194,177 +187,147 @@ jobs: key: extra-tests-{{ .Branch }}-{{ .Revision }} paths: - "/home/riscvuser/project/tests" - prepare-chipyard-rocket: + + prepare-chipyard-cores: executor: main-env steps: - prepare-rtl: - project-key: "chipyard-rocket" - prepare-chipyard-dmirocket: + project-key: "group-cores" + prepare-chipyard-peripherals: executor: main-env steps: - prepare-rtl: - project-key: "chipyard-dmirocket" - prepare-chipyard-sha3: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-sha3" - prepare-chipyard-streaming-fir: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-streaming-fir" - prepare-chipyard-streaming-passthrough: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-streaming-passthrough" - prepare-chipyard-hetero: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-hetero" - timeout: "240m" - prepare-chipyard-boom: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-boom" - prepare-chipyard-blkdev: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-blkdev" - prepare-chipyard-hwacha: + project-key: "group-peripherals" + prepare-chipyard-accels: executor: main-env steps: - prepare-rtl: tools-version: "esp-tools" - project-key: "chipyard-hwacha" - prepare-chipyard-gemmini: + project-key: "group-accels" + prepare-chipyard-tracegen: executor: main-env steps: - prepare-rtl: - tools-version: "esp-tools" - project-key: "chipyard-gemmini" - prepare-tracegen: + project-key: "group-tracegen" + prepare-chipyard-other: executor: main-env steps: - prepare-rtl: - project-key: "tracegen" - prepare-tracegen-boom: - executor: main-env - steps: - - prepare-rtl: - project-key: "tracegen-boom" - prepare-chipyard-ariane: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-ariane" - prepare-icenet: - executor: main-env - steps: - - prepare-rtl: - project-key: "icenet" - prepare-testchipip: - executor: main-env - steps: - - prepare-rtl: - project-key: "testchipip" - prepare-chipyard-nvdla: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-nvdla" - prepare-chipyard-spiflashwrite: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-spiflashwrite" - prepare-chipyard-spiflashread: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-spiflashread" - prepare-chipyard-mmios: - executor: main-env - steps: - - prepare-rtl: - project-key: "chipyard-mmios" + project-key: "group-other" + chipyard-rocket-run-tests: executor: main-env steps: - run-tests: + group-key: "group-cores" project-key: "chipyard-rocket" - chipyard-dmirocket-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "chipyard-dmirocket" - chipyard-sha3-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "chipyard-sha3" - chipyard-streaming-fir-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "chipyard-streaming-fir" - chipyard-streaming-passthrough-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "chipyard-streaming-passthrough" chipyard-hetero-run-tests: executor: main-env steps: - run-tests: + group-key: "group-cores" project-key: "chipyard-hetero" timeout: "15m" chipyard-boom-run-tests: executor: main-env steps: - run-tests: + group-key: "group-cores" project-key: "chipyard-boom" + chipyard-ariane-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-cores" + project-key: "chipyard-ariane" + timeout: "30m" + chipyard-dmirocket-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-peripherals" + project-key: "chipyard-dmirocket" + chipyard-spiflashwrite-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-peripherals" + project-key: "chipyard-spiflashwrite" + chipyard-spiflashread-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-peripherals" + project-key: "chipyard-spiflashread" + chipyard-sha3-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-accels" + project-key: "chipyard-sha3" + chipyard-streaming-fir-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-accels" + project-key: "chipyard-streaming-fir" + chipyard-streaming-passthrough-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-accels" + project-key: "chipyard-streaming-passthrough" chipyard-hwacha-run-tests: executor: main-env steps: - run-tests: tools-version: "esp-tools" + group-key: "group-accels" project-key: "chipyard-hwacha" chipyard-gemmini-run-tests: executor: main-env steps: - run-tests: tools-version: "esp-tools" + group-key: "group-accels" project-key: "chipyard-gemmini" - chipyard-spiflashwrite-run-tests: + chipyard-nvdla-run-tests: executor: main-env steps: - run-tests: - project-key: "chipyard-spiflashwrite" - chipyard-spiflashread-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "chipyard-spiflashread" + group-key: "group-accels" + project-key: "chipyard-nvdla" tracegen-run-tests: executor: main-env steps: - run-tests: + group-key: "group-tracegen" project-key: "tracegen" tracegen-boom-run-tests: executor: main-env steps: - run-tests: + group-key: "group-tracegen" project-key: "tracegen-boom" + icenet-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-other" + project-key: "icenet" + timeout: "30m" + testchipip-run-tests: + executor: main-env + steps: + - run-tests: + group-key: "group-other" + project-key: "testchipip" + timeout: "30m" firesim-run-tests: executor: main-env steps: - run-tests: - extra-cache-restore: "extra-tests" + group-key: "extra-tests" project-key: "firesim" run-script: "run-firesim-scala-tests.sh" timeout: "20m" @@ -372,7 +335,7 @@ jobs: executor: main-env steps: - run-tests: - extra-cache-restore: "extra-tests" + group-key: "extra-tests" project-key: "fireboom" run-script: "run-firesim-scala-tests.sh" timeout: "45m" @@ -380,33 +343,10 @@ jobs: executor: main-env steps: - run-tests: - extra-cache-restore: "extra-tests" + group-key: "extra-tests" project-key: "firesim-multiclock" run-script: "run-firesim-scala-tests.sh" timeout: "20m" - chipyard-ariane-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "chipyard-ariane" - timeout: "30m" - chipyard-nvdla-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "chipyard-nvdla" - icenet-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "icenet" - timeout: "30m" - testchipip-run-tests: - executor: main-env - steps: - - run-tests: - project-key: "testchipip" - timeout: "30m" # Order and dependencies of jobs to run workflows: @@ -446,154 +386,83 @@ workflows: - install-riscv-toolchain # Prepare the verilator builds - - prepare-chipyard-rocket: + - prepare-chipyard-cores: requires: - install-riscv-toolchain - install-verilator - - - prepare-chipyard-dmirocket: + - prepare-chipyard-peripherals: requires: - install-riscv-toolchain - install-verilator - - - prepare-chipyard-sha3: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-streaming-fir: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-streaming-passthrough: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-hetero: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-boom: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-blkdev: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-hwacha: + - prepare-chipyard-accels: requires: - install-esp-toolchain - install-verilator - - - prepare-chipyard-gemmini: - requires: - - install-esp-toolchain - - install-verilator - - - prepare-tracegen: + - prepare-chipyard-tracegen: requires: - install-riscv-toolchain - install-verilator - - - prepare-tracegen-boom: + - prepare-chipyard-other: requires: - install-riscv-toolchain - install-verilator - - prepare-chipyard-ariane: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-icenet: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-testchipip: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-nvdla: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-spiflashwrite: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-spiflashread: - requires: - - install-riscv-toolchain - - install-verilator - - - prepare-chipyard-mmios: - requires: - - install-riscv-toolchain - - # Run the respective tests - # Run the example tests - chipyard-rocket-run-tests: requires: - - prepare-chipyard-rocket + - prepare-chipyard-cores + - chipyard-hetero-run-tests: + requires: + - prepare-chipyard-cores + - chipyard-boom-run-tests: + requires: + - prepare-chipyard-cores + - chipyard-ariane-run-tests: + requires: + - prepare-chipyard-cores - chipyard-dmirocket-run-tests: requires: - - prepare-chipyard-dmirocket + - prepare-chipyard-peripherals + - chipyard-spiflashwrite-run-tests: + requires: + - prepare-chipyard-peripherals + - chipyard-spiflashread-run-tests: + requires: + - prepare-chipyard-peripherals - chipyard-sha3-run-tests: requires: - - prepare-chipyard-sha3 - + - prepare-chipyard-accels - chipyard-streaming-fir-run-tests: requires: - - prepare-chipyard-streaming-fir - + - prepare-chipyard-accels - chipyard-streaming-passthrough-run-tests: requires: - - prepare-chipyard-streaming-passthrough - - - chipyard-hetero-run-tests: - requires: - - prepare-chipyard-hetero - - - chipyard-boom-run-tests: - requires: - - prepare-chipyard-boom - + - prepare-chipyard-accels - chipyard-hwacha-run-tests: requires: - - prepare-chipyard-hwacha - + - prepare-chipyard-accels - chipyard-gemmini-run-tests: requires: - - prepare-chipyard-gemmini + - prepare-chipyard-accels + - chipyard-nvdla-run-tests: + requires: + - prepare-chipyard-accels - tracegen-run-tests: requires: - - prepare-tracegen - + - prepare-chipyard-tracegen - tracegen-boom-run-tests: requires: - - prepare-tracegen-boom + - prepare-chipyard-tracegen - - chipyard-spiflashwrite-run-tests: + - icenet-run-tests: requires: - - prepare-chipyard-spiflashwrite - - - chipyard-spiflashread-run-tests: + - prepare-chipyard-other + - testchipip-run-tests: requires: - - prepare-chipyard-spiflashread + - prepare-chipyard-other # Run the firesim tests - firesim-run-tests: @@ -612,17 +481,4 @@ workflows: - install-verilator - build-extra-tests - - chipyard-ariane-run-tests: - requires: - - prepare-chipyard-ariane - - chipyard-nvdla-run-tests: - requires: - - prepare-chipyard-nvdla - - icenet-run-tests: - requires: - - prepare-icenet - - - testchipip-run-tests: - requires: - - prepare-testchipip diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 703737cd..6f74c26d 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -45,6 +45,14 @@ LOCAL_CHIPYARD_DIR=$LOCAL_CHECKOUT_DIR LOCAL_SIM_DIR=$LOCAL_CHIPYARD_DIR/sims/verilator LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim +# key value store to get the build groups +declare -A grouping +grouping["group-cores"]="chipyard-ariane chipyard-rocket chipyard-hetero chipyard-boom" +grouping["group-peripherals"]="chipyard-dmirocket chipyard-blkdev chipyard-spiflashread chipyard-spiflashwrite chipyard-mmios" +grouping["group-accels"]="chipyard-nvdla chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-streaming-fir chipyard-streaming-passthrough" +grouping["group-tracegen"]="tracegen tracegen-boom" +grouping["group-other"]="icenet testchipip" + # key value store to get the build strings declare -A mapping mapping["chipyard-rocket"]="" @@ -64,6 +72,7 @@ mapping["chipyard-mmios"]=" CONFIG=MMIORocketConfig verilog" mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config" mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig" mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig" + mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests" mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests" mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests" diff --git a/.circleci/do-rtl-build.sh b/.circleci/do-rtl-build.sh index 3973026f..9093b29e 100755 --- a/.circleci/do-rtl-build.sh +++ b/.circleci/do-rtl-build.sh @@ -31,7 +31,7 @@ run "cp -r ~/.sbt $REMOTE_WORK_DIR" TOOLS_DIR=$REMOTE_RISCV_DIR LD_LIB_DIR=$REMOTE_RISCV_DIR/lib -if [ $1 = "chipyard-gemmini" ]; then +if [ $1 = "group-accels" ]; then export RISCV=$LOCAL_ESP_DIR export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib export PATH=$RISCV/bin:$PATH @@ -40,9 +40,7 @@ if [ $1 = "chipyard-gemmini" ]; then git submodule update --init --recursive gemmini-rocc-tests cd gemmini-rocc-tests ./build.sh -fi -if [ $1 = "chipyard-hwacha" ] || [ $1 = "chipyard-gemmini" ]; then TOOLS_DIR=$REMOTE_ESP_DIR LD_LIB_DIR=$REMOTE_ESP_DIR/lib run "mkdir -p $REMOTE_ESP_DIR" @@ -58,12 +56,19 @@ run "export RISCV=\"$TOOLS_DIR\"; \ export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \ export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \ export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \ - make -C $REMOTE_SIM_DIR clean; \ - make -j$REMOTE_MAKE_NPROC -C $REMOTE_SIM_DIR FIRRTL_LOGLEVEL=info JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" ${mapping[$1]}" -run "rm -rf $REMOTE_CHIPYARD_DIR/project" + make -C $REMOTE_SIM_DIR clean;" -# copy back the final build +read -a keys <<< ${grouping[$1]} +for key in "${keys[@]}" +do + run "export RISCV=\"$TOOLS_DIR\"; \ + export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \ + export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \ + export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \ + export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \ + make -j$REMOTE_MAKE_NPROC -C $REMOTE_SIM_DIR FIRRTL_LOGLEVEL=info JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" ${mapping[$key]}" +done run "rm -rf $REMOTE_CHIPYARD_DIR/project" From 36ccb12560ef24eb492b93baf5c2da996badf1b8 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 16 Sep 2020 10:29:03 -0700 Subject: [PATCH 49/93] Bump testchipip --- generators/chipyard/src/main/scala/Subsystem.scala | 2 +- generators/testchipip | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 172be692..5dd6ac18 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -30,7 +30,7 @@ import testchipip.{DromajoHelper, CanHavePeripheryTLSerial, SerialTLKey} trait CanHaveHTIF { this: BaseSubsystem => // Advertise HTIF if system can communicate with fesvr if (this match { - case _: CanHavePeripheryTKSerial if p(SerialTLKey).nonEmpty => true + case _: CanHavePeripheryTLSerial if p(SerialTLKey).nonEmpty => true case _: HasPeripheryDebug if p(ExportDebug).dmi => true case _ => false }) { diff --git a/generators/testchipip b/generators/testchipip index e845cb3f..57cac41f 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit e845cb3f50bb141fec7e8291a40d0b46d5ef5c12 +Subproject commit 57cac41f71653ca2a04d936f36ee8c78ec9919fd From 269af01a70d6fe6411dcc6ba5ef7f5aed5fa4e1d Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 16 Sep 2020 12:06:36 -0700 Subject: [PATCH 50/93] Bump testchipip --- .circleci/defaults.sh | 2 +- generators/testchipip | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 2a744e89..6053b367 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -49,7 +49,7 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim declare -A mapping mapping["chipyard-rocket"]="" mapping["chipyard-dmirocket"]=" CONFIG=dmiRocketConfig" -mapping["chipyard-tlserial"]=" CONFIG=TLSerialRocketConfig" +mapping["chipyard-tlserial"]=" CONFIG=LBWIFMemoryRocketConfig" mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig" mapping["chipyard-streaming-fir"]=" CONFIG=StreamingFIRRocketConfig" mapping["chipyard-streaming-passthrough"]=" CONFIG=StreamingPassthroughRocketConfig" diff --git a/generators/testchipip b/generators/testchipip index 57cac41f..f2efec8e 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 57cac41f71653ca2a04d936f36ee8c78ec9919fd +Subproject commit f2efec8ee7bd6988b94a6fa3615ae7f864714004 From 687430898116d98ff625fa9258ae89473dd26135 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 16 Sep 2020 15:27:43 -0700 Subject: [PATCH 51/93] Address review comments --- .circleci/config.yml | 18 +++++++++--------- .circleci/do-rtl-build.sh | 4 ---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6ed04488..48ed4883 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -73,7 +73,7 @@ commands: tools-version: type: string default: "riscv-tools" - project-key: + group-key: type: string timeout: type: string @@ -85,11 +85,11 @@ commands: - setup-tools: tools-version: "<< parameters.tools-version >>" - run: - name: Building << parameters.project-key >> subproject using Verilator - command: .circleci/<< parameters.build-script >> << parameters.project-key >> + name: Building << parameters.group-key >> subproject using Verilator + command: .circleci/<< parameters.build-script >> << parameters.group-key >> no_output_timeout: << parameters.timeout >> - save_cache: - key: << parameters.project-key >>-{{ .Branch }}-{{ .Revision }} + key: << parameters.group-key >>-{{ .Branch }}-{{ .Revision }} paths: - "/home/riscvuser/project" @@ -192,28 +192,28 @@ jobs: executor: main-env steps: - prepare-rtl: - project-key: "group-cores" + group-key: "group-cores" prepare-chipyard-peripherals: executor: main-env steps: - prepare-rtl: - project-key: "group-peripherals" + group-key: "group-peripherals" prepare-chipyard-accels: executor: main-env steps: - prepare-rtl: tools-version: "esp-tools" - project-key: "group-accels" + group-key: "group-accels" prepare-chipyard-tracegen: executor: main-env steps: - prepare-rtl: - project-key: "group-tracegen" + group-key: "group-tracegen" prepare-chipyard-other: executor: main-env steps: - prepare-rtl: - project-key: "group-other" + group-key: "group-other" chipyard-rocket-run-tests: executor: main-env diff --git a/.circleci/do-rtl-build.sh b/.circleci/do-rtl-build.sh index 9093b29e..784dbc04 100755 --- a/.circleci/do-rtl-build.sh +++ b/.circleci/do-rtl-build.sh @@ -52,10 +52,6 @@ fi # enter the verilator directory and build the specific config on remote server run "export RISCV=\"$TOOLS_DIR\"; \ - export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \ - export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \ - export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \ - export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \ make -C $REMOTE_SIM_DIR clean;" read -a keys <<< ${grouping[$1]} From 895bacea9884248493c0e44d3a4d1ad6b91e786d Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Mon, 24 Aug 2020 11:01:29 -0700 Subject: [PATCH 52/93] WIP - Simple divider-only PLL generation flow --- .../src/main/resources/vsrc/ClockDividerN.sv | 40 +++++++++++ .../chipyard/src/main/scala/Clocks.scala | 36 ++++++++++ .../src/main/scala/ConfigFragments.scala | 27 +++++++- .../src/main/scala/GenericAttachParams.scala | 38 +++++++++++ .../main/scala/clocking/ClockDividerN.scala | 23 +++++++ .../scala/clocking/ClockGroupDealiaser.scala | 51 ++++++++++++++ .../scala/clocking/ClockNodeInjectors.scala | 29 ++++++++ .../main/scala/clocking/IdealizedPLL.scala | 68 +++++++++++++++++++ .../src/main/scala/config/RocketConfigs.scala | 9 ++- 9 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv create mode 100644 generators/chipyard/src/main/scala/GenericAttachParams.scala create mode 100644 generators/chipyard/src/main/scala/clocking/ClockDividerN.scala create mode 100644 generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala create mode 100644 generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala create mode 100644 generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala diff --git a/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv b/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv new file mode 100644 index 00000000..33f7a05b --- /dev/null +++ b/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv @@ -0,0 +1,40 @@ +// See LICENSE for license details. + +/** + * An unsynthesizable divide-by-N clock divider. + * Duty cycle is 100 * (ceil(DIV / 2)) / 2. + */ + +module ClockDividerN #(parameter DIV)(output logic clk_out = 1'b0, input clk_in); + + localparam DIV_COUNTER_WIDTH = $clog2(DIV); + localparam LOW_CYCLES = DIV / 2; + + generate + if (DIV == 1) begin + // This needs to be procedural because of the assignment on declaration + always @(clk_in) begin + clk_out = clk_in; + end + end else begin + reg [DIV_COUNTER_WIDTH - 1: 0] count = '0; + // The blocking assignment to clock out is used to conform what was done + // in RC's clock dividers. + // It should have the effect of preventing registers in the divided clock + // domain latching register updates launched by the fast clock-domain edge + // that occurs at the same simulated time (as the divided clock edge). + always @(posedge clk_in) begin + if (count == (DIV - 1)) begin + clk_out = 1'b0; + count <= '0; + end + else begin + if (count == (LOW_CYCLES - 1)) begin + clk_out = 1'b1; + end + count <= count + 1'b1; + end + end + end + endgenerate +endmodule // ClockDividerN diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index a1ff1b0f..01d6c828 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -12,6 +12,8 @@ import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider} import barstools.iocell.chisel._ +import chipyard.clocking.{IdealizedPLL, ClockGroupDealiaser} + /** * Chipyard provides three baseline, top-level reset schemes, set using the * [[GlobalResetSchemeKey]] in a Parameters instance. These are: @@ -173,6 +175,40 @@ object ClockingSchemeGenerators { Nil }) } + } + val idealizedPLL: ChipTop => Unit = { chiptop => + implicit val p = chiptop.p + + // Requires existence of undriven asyncClockGroups in subsystem + val systemAsyncClockGroup = chiptop.lSystem match { + case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => + l.asyncClockGroupsNode + } + + val aggregator = ClockGroupAggregator() + chiptop.implicitClockSinkNode := ClockGroup() := aggregator + systemAsyncClockGroup := aggregator + + val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) + aggregator := ClockGroupDealiaser() := IdealizedPLL() := referenceClockSource + + InModuleBody { + + val clock_wire = Wire(Input(Clock())) + val reset_wire = GenerateReset(chiptop, clock_wire) + val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, Some("iocell_clock")) + chiptop.iocells ++= clockIOCell + clock_io.suggestName("clock") + + referenceClockSource.out.unzip._1.map { o => + o.clock := clock_wire + o.reset := reset_wire + } + + chiptop.harnessFunctions += ((th: HasHarnessUtils) => { + clock_io := th.harnessClock + Nil }) + } } } diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index cfa465e7..9fb3adb2 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -28,7 +28,11 @@ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem, ClockingSchemeGenerators, ClockingSchemeKey, TestSuitesKey, TestSuiteHelper} - +// Imports for multiclock sketch +import boom.common.{BoomTile, BoomTileParams} +import ariane.{ArianeTile, ArianeTileParams} +import chipyard.{GenericallyAttachableTile, GenericCrossingParams} +import chipyard.clocking.{ClockNodeInjectionUtils } // ----------------------- // Common Config Fragments // ----------------------- @@ -170,3 +174,24 @@ class WithDMIDTM extends Config((site, here, up) => { class WithNoDebug extends Config((site, here, up) => { case DebugModuleKey => None }) + + +// Multiclock sketch +class WithForcedTileFrequency(fMHz: Double) extends Config((site, here, up) => { + case TilesLocated(InSubsystem) => + val genericAttachParams = up(TilesLocated(InSubsystem), site) map { + case b: BoomTileAttachParams => GenericallyAttachableTile[BoomTile]( + b.tileParams, GenericCrossingParams(b.crossingParams), b.lookup) + case r: RocketTileAttachParams => GenericallyAttachableTile[RocketTile]( + r.tileParams, GenericCrossingParams(r.crossingParams), r.lookup) + case a: ArianeTileAttachParams => GenericallyAttachableTile[ArianeTile]( + a.tileParams, GenericCrossingParams(a.crossingParams), a.lookup) + case g: GenericallyAttachableTile[_] => g + } + genericAttachParams.map(p => p.copy(crossingParams = p.crossingParams.copy( + injectClockNodeFunc = ClockNodeInjectionUtils.forceTakeFrequency(fMHz)))) +}) + +class WithIdealizedPLL extends Config((site, here, up) => { + case ChipyardClockKey => ClockDrivers.idealizedPLL +}) diff --git a/generators/chipyard/src/main/scala/GenericAttachParams.scala b/generators/chipyard/src/main/scala/GenericAttachParams.scala new file mode 100644 index 00000000..f90598af --- /dev/null +++ b/generators/chipyard/src/main/scala/GenericAttachParams.scala @@ -0,0 +1,38 @@ + +package chipyard + +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.tile.{LookupByHartIdImpl, TileParams, InstantiableTileParams, BaseTile} + +import chipyard.clocking.ClockNodeInjectionUtils._ + +case class GenericCrossingParams( + crossingType: ClockCrossingType = SynchronousCrossing(), + master: TilePortParamsLike = TileMasterPortParams(), + slave: TilePortParamsLike = TileSlavePortParams(), + mmioBaseAddressPrefixWhere: TLBusWrapperLocation = CBUS, + injectClockNodeFunc: InjectClockNodeFunc = injectIdentityClockNode, + forceSeparateClockReset: Boolean = false) extends TileCrossingParamsLike { + + def injectClockNode(a: Attachable)(implicit p: Parameters) = injectClockNodeFunc(a, p) +} + +object GenericCrossingParams { + def apply(params: TileCrossingParamsLike): GenericCrossingParams = GenericCrossingParams( + params.crossingType, + params.master, + params.slave, + params.mmioBaseAddressPrefixWhere, + (a: Attachable, p: Parameters) => params.injectClockNode(a)(p), + params.forceSeparateClockReset) +} + +case class GenericallyAttachableTile[TT <: BaseTile]( + tileParams: InstantiableTileParams[TT], + crossingParams: GenericCrossingParams, + lookup: LookupByHartIdImpl) extends CanAttachTile { + type TileType = TT +} + diff --git a/generators/chipyard/src/main/scala/clocking/ClockDividerN.scala b/generators/chipyard/src/main/scala/clocking/ClockDividerN.scala new file mode 100644 index 00000000..c9513b88 --- /dev/null +++ b/generators/chipyard/src/main/scala/clocking/ClockDividerN.scala @@ -0,0 +1,23 @@ +// See LICENSE.SiFive for license details. + +package chipyard.clocking + +import chisel3._ +import chisel3.util._ + +class ClockDividerN(div: Int) extends BlackBox(Map("DIV" -> div)) with HasBlackBoxResource { + require(div > 0); + val io = IO(new Bundle { + val clk_out = Output(Clock()) + val clk_in = Input(Clock()) + }) + addResource("/vsrc/ClockDividerN.sv") +} + +object ClockDivideByN { + def apply(clockIn: Clock, div: Int): Clock = { + val clockDivider = Module(new ClockDividerN(div)) + clockDivider.io.clk_in := clockIn + clockDivider.io.clk_out + } +} diff --git a/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala b/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala new file mode 100644 index 00000000..3ffea3c0 --- /dev/null +++ b/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala @@ -0,0 +1,51 @@ +package chipyard.clocking + +import chisel3._ + +import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.prci._ + +/** + * Somewhat hacky. Since not all clocks in a clock group specify a taken frequency + * current, this LazyModule attempts to dealias them, by finding a specified + * clock whose name has the longest matching prefix. + * + * Perhaps another, simpler solution would be to pass a default. + * + */ + +case class ClockGroupDealiaserNode()(implicit valName: ValName) + extends NexusNode(ClockGroupImp)( + dFn = { _ => ClockGroupSourceParameters() }, + uFn = { u => + require(u.size == 1) + val takenClocks = u.head.members.filter(_.take.nonEmpty) + require(takenClocks.nonEmpty, + "At least one sink clock in clock group must specify its take parameter") + u.head.copy(members = takenClocks) + }) + +class ClockGroupDealiaser(name: String)(implicit p: Parameters) extends LazyModule { + val node = ClockGroupDealiaserNode() + + lazy val module = new LazyRawModuleImp(this) { + require(node.out.size == 1, "Must use a ClockGroupAggregator") + val (outClocks, e @ ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head + val (inClocks, ClockGroupEdgeParameters(_, inSinkParams, _, _)) = node.in.head + val inMap = inClocks.member.data.zip(inSinkParams.members).map({ case (b, p) => p.name -> b}).toMap + + for (((outBName, outB), outName) <- outClocks.member.elements.zip(outSinkParams.members.map(_.name))) { + val inClock = inMap.getOrElse(outName, throw new Exception(""" + | No clock in input group with name: Option matching ${outName}. At least one clock + | with the same must specify a frequency in its take parameter.""".stripMargin)) + // This will be removed. + dontTouch(outB) + outB := inClock + } + } +} + +object ClockGroupDealiaser { + def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new ClockGroupDealiaser(valName.name)).node +} diff --git a/generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala b/generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala new file mode 100644 index 00000000..981ed327 --- /dev/null +++ b/generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala @@ -0,0 +1,29 @@ + +package chipyard.clocking + +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.prci.{ClockNode, ClockTempNode, ClockAdapterNode, ClockParameters} +/** + * An adapter node hack c that just throws out the existing sink node + * clock parameters in favor of the provided ones. + */ +class ForceTakeClock(clockParams: Option[ClockParameters])(implicit p: Parameters, v: ValName) extends LazyModule { + val node = ClockAdapterNode(sinkFn = { s => s.copy(take = clockParams) }) + lazy val module = new LazyRawModuleImp(this) { + (node.out zip node.in) map { case ((o, _), (i, _)) => o := i } + } +} + +object ForceTakeClock { + def apply(clockParams: Option[ClockParameters])(implicit p: Parameters, v: ValName): ClockAdapterNode = + LazyModule(new ForceTakeClock(clockParams)).node +} + +object ClockNodeInjectionUtils { + type InjectClockNodeFunc = (Attachable, Parameters) => ClockNode + val injectIdentityClockNode: InjectClockNodeFunc = (a: Attachable, p: Parameters) => ClockTempNode() + def forceTakeFrequency(freqMHz: Double): InjectClockNodeFunc = + (a: Attachable, p: Parameters) => ForceTakeClock(Some(ClockParameters(freqMHz)))(p, ValName("ForcedTakeClock")) +} diff --git a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala new file mode 100644 index 00000000..3de99e8e --- /dev/null +++ b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala @@ -0,0 +1,68 @@ +package chipyard.clocking + +import chisel3._ + +import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.prci._ + +import scala.collection.mutable + +object FrequencyUtils { + def computeReferenceFrequencyMHz( + requestedOutputs: Seq[ClockParameters], + maximumAllowableDivisor: Int = 0xFFFF): ClockParameters = { + require(requestedOutputs.nonEmpty) + require(!requestedOutputs.contains(0.0)) + val freqs = requestedOutputs.map(f => BigInt(Math.round(f.freqMHz * 1000 * 1000))) + val refFreq = freqs.reduce((a, b) => a * b / a.gcd(b)).toDouble / (1000 * 1000) + assert((refFreq / freqs.min.toDouble) < maximumAllowableDivisor.toDouble) + ClockParameters(refFreq) + } +} + +case class IdealizedPLLNode(pllName: String)(implicit valName: ValName) + extends MixedNexusNode(ClockImp, ClockGroupImp)( + dFn = { _ => ClockGroupSourceParameters() }, + uFn = { u => + require(u.size == 1) + require(!u.head.members.contains(None), + "All output clocks in group must set their take parameters. Use a ClockGroupDealiaser") + ClockSinkParameters( + name = Some(s"${pllName}_reference_input"), + take = Some(FrequencyUtils.computeReferenceFrequencyMHz(u.head.members.flatMap(_.take)))) } + ) + +class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) extends LazyModule { + val node = IdealizedPLLNode(pllName) + + lazy val module = new LazyRawModuleImp(this) { + require(node.out.size == 1, "Must use a ClockGroupAggregator") + val (refClock, ClockEdgeParameters(_, refSinkParam, _, _)) = node.in.head + val (outClocks, ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head + + val referenceFreq = refSinkParam.take.get.freqMHz + val requestedFreqs = outSinkParams.members.map(m => m.name -> m.take) + + val dividedClocks = mutable.HashMap[Int, Clock]() + def instantiateDivider(div: Int): Clock = { + val divider = Module(new ClockDividerN(div)) + divider.suggestName(s"ClockDivideBy${div}") + divider.io.clk_in := refClock.clock + dividedClocks(div) = divider.io.clk_out + divider.io.clk_out + } + + for (((sinkBName, sinkB), sinkP) <- outClocks.member.elements.zip(outSinkParams.members)) { + val requested = sinkP.take.get.freqMHz + val div = Math.round(referenceFreq / requested).toInt + val actual = referenceFreq / div.toDouble + println(s"Clock ${sinkBName}, requested freq: ${requested} MHz. Actual freq: ${actual} MHz via division of ${div}") + sinkB.clock := dividedClocks.getOrElse(div, instantiateDivider(div)) + } + } +} + +object IdealizedPLL { + def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new IdealizedPLL(valName.name)).node +} diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 16d298fb..a4e1af72 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -182,4 +182,11 @@ class DividedClockRocketConfig extends Config( new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) - +// Multiclock Sketch +class ForcedClockRocketConfig extends Config( + new chipyard.config.WithForcedTileFrequency(200) ++ + new chipyard.config.WithIdealizedPLL ++ // Put the Tile on its own clock domain + //new chipyard.config.WithTileDividedClock ++ // Put the Tile on its own clock domain + new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new chipyard.config.AbstractConfig) From 8e4dedcecfe7c0f7a4e1a5a0e3cfdc867479cfcd Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 16 Sep 2020 16:30:00 -0700 Subject: [PATCH 53/93] Remove require guard on divided configs --- generators/chipyard/src/main/scala/Clocks.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 01d6c828..afe04eaf 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -134,8 +134,6 @@ object ClockingSchemeGenerators { val harnessDividedClock: ChipTop => Unit = { chiptop => implicit val p = chiptop.p - require(false, "Divided clock is broken until we fix passing onchip clocks to TestHarness objects") - val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters())) chiptop.implicitClockSinkNode := implicitClockSourceNode From b8d3e4a66d6e8a984bc49cc0ca1d11f0d49a87ed Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 16 Sep 2020 16:30:25 -0700 Subject: [PATCH 54/93] Update Idealized PLL config --- generators/chipyard/src/main/scala/Clocks.scala | 4 ++-- generators/chipyard/src/main/scala/ConfigFragments.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index afe04eaf..7c9ade21 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -179,7 +179,7 @@ object ClockingSchemeGenerators { implicit val p = chiptop.p // Requires existence of undriven asyncClockGroups in subsystem - val systemAsyncClockGroup = chiptop.lSystem match { + val systemAsyncClockGroup = chiptop.lazySystem match { case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => l.asyncClockGroupsNode } @@ -204,7 +204,7 @@ object ClockingSchemeGenerators { o.reset := reset_wire } - chiptop.harnessFunctions += ((th: HasHarnessUtils) => { + chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { clock_io := th.harnessClock Nil }) } diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 9fb3adb2..03ccdbca 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -193,5 +193,5 @@ class WithForcedTileFrequency(fMHz: Double) extends Config((site, here, up) => { }) class WithIdealizedPLL extends Config((site, here, up) => { - case ChipyardClockKey => ClockDrivers.idealizedPLL + case ClockingSchemeKey => ClockingSchemeGenerators.idealizedPLL }) From cfa7e30d95f82acc69811753183ca6b681f8954a Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 17 Sep 2020 11:32:51 -0700 Subject: [PATCH 55/93] [clocks] Fix comment in ClockDividerN --- generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv b/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv index 33f7a05b..868b0eee 100644 --- a/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv +++ b/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv @@ -2,7 +2,7 @@ /** * An unsynthesizable divide-by-N clock divider. - * Duty cycle is 100 * (ceil(DIV / 2)) / 2. + * Duty cycle is 100 * (ceil(DIV / 2)) / DIV. */ module ClockDividerN #(parameter DIV)(output logic clk_out = 1'b0, input clk_in); From 6a26a350eee9d67032e6710d20ad59822bd51390 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 17 Sep 2020 11:33:26 -0700 Subject: [PATCH 56/93] [clocks] Update dealiaser based on feedback --- .../src/main/scala/clocking/ClockGroupDealiaser.scala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala b/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala index 3ffea3c0..54b384e9 100644 --- a/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala +++ b/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.prci._ /** * Somewhat hacky. Since not all clocks in a clock group specify a taken frequency * current, this LazyModule attempts to dealias them, by finding a specified - * clock whose name has the longest matching prefix. + * clock with a matching name. * * Perhaps another, simpler solution would be to pass a default. * @@ -30,17 +30,16 @@ class ClockGroupDealiaser(name: String)(implicit p: Parameters) extends LazyModu val node = ClockGroupDealiaserNode() lazy val module = new LazyRawModuleImp(this) { - require(node.out.size == 1, "Must use a ClockGroupAggregator") + require(node.out.size == 1 && node.in.size == 1, + "ClockGroupDealiaser requires a single ClockGroup, please use a ClockGroupAggregator") val (outClocks, e @ ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head val (inClocks, ClockGroupEdgeParameters(_, inSinkParams, _, _)) = node.in.head val inMap = inClocks.member.data.zip(inSinkParams.members).map({ case (b, p) => p.name -> b}).toMap for (((outBName, outB), outName) <- outClocks.member.elements.zip(outSinkParams.members.map(_.name))) { val inClock = inMap.getOrElse(outName, throw new Exception(""" - | No clock in input group with name: Option matching ${outName}. At least one clock + | No clock in input group with name option matching ${outName}. At least one clock | with the same must specify a frequency in its take parameter.""".stripMargin)) - // This will be removed. - dontTouch(outB) outB := inClock } } From 0f33ea3999f0c7cf5610e4099178c683ada680f8 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 17 Sep 2020 11:37:56 -0700 Subject: [PATCH 57/93] [clocks] Stringly specified clock frequencies; DRY out schemes --- .../chipyard/src/main/scala/ChipTop.scala | 2 +- .../chipyard/src/main/scala/Clocks.scala | 122 ++++-------------- .../src/main/scala/ConfigFragments.scala | 39 +++--- .../clocking/ClockGroupNamePrefixer.scala | 65 ++++++++++ .../main/scala/clocking/IdealizedPLL.scala | 20 ++- .../src/main/scala/config/RocketConfigs.scala | 13 +- 6 files changed, 125 insertions(+), 136 deletions(-) create mode 100644 generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala diff --git a/generators/chipyard/src/main/scala/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index dfe08780..1cef2180 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -31,7 +31,7 @@ class ChipTop(implicit p: Parameters) extends LazyModule with HasTestHarnessFunc val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system") // The implicitClockSinkNode provides the implicit clock and reset for the System - val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters())) + val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock")))) // Generate Clocks and Reset p(ClockingSchemeKey)(this) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 7c9ade21..609bf8a0 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -6,13 +6,13 @@ import scala.collection.mutable.{ArrayBuffer} import freechips.rocketchip.prci._ import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey} -import freechips.rocketchip.config.{Parameters, Field} +import freechips.rocketchip.config.{Parameters, Field, Config} import freechips.rocketchip.diplomacy.{OutwardNodeHandle, InModuleBody, LazyModule} import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider} import barstools.iocell.chisel._ -import chipyard.clocking.{IdealizedPLL, ClockGroupDealiaser} +import chipyard.clocking.{IdealizedPLL, ClockGroupDealiaser, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} /** * Chipyard provides three baseline, top-level reset schemes, set using the @@ -80,101 +80,26 @@ object GenerateReset { } -case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGenerators.harnessClock) +case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGenerators.idealizedPLL) +/** + * This is a dictionary of clock name to clock frequency in MHz. Names + * correspond to the IO coming off digital top. If the map is undefined for the given name, + * it will return a default value -- DFU. + */ +case object ClockFrequencyAssignment extends Field[Seq[(String) => Option[Double]]](Seq.empty) +case object DefaultClockFrequencyKey extends Field[Double](100.0) +class ClockNameMatchesAssignment(name: String, fMHz: Double) extends Config((site, here, up) => { + case ClockFrequencyAssignment => up(ClockFrequencyAssignment, site) ++ + Seq((cName: String) => if (cName == name) Some(fMHz) else None) +}) +class ClockNameContainsAssignment(name: String, fMHz: Double) extends Config((site, here, up) => { + case ClockFrequencyAssignment => up(ClockFrequencyAssignment, site) ++ + Seq((cName: String) => if (cName.contains(name)) Some(fMHz) else None) +}) object ClockingSchemeGenerators { - // A simple clock provider, for testing - val harnessClock: ChipTop => Unit = { chiptop => - implicit val p = chiptop.p - - val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters())) - chiptop.implicitClockSinkNode := implicitClockSourceNode - - // Drive the diplomaticclock graph of the DigitalTop (if present) - val simpleClockGroupSourceNode = chiptop.lazySystem match { - case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { - val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) - l.asyncClockGroupsNode := n - Some(n) - } - case _ => None - } - - InModuleBody { - //this needs directionality so generateIOFromSignal works - val clock_wire = Wire(Input(Clock())) - val reset_wire = GenerateReset(chiptop, clock_wire) - val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, Some("iocell_clock")) - chiptop.iocells ++= clockIOCell - clock_io.suggestName("clock") - - implicitClockSourceNode.out.unzip._1.map { o => - o.clock := clock_wire - o.reset := reset_wire - } - - simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle => - out.member.data.foreach { o => - o.clock := clock_wire - o.reset := reset_wire - } - }} - - chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { - clock_io := th.harnessClock - Nil - }) - } - - } - - - val harnessDividedClock: ChipTop => Unit = { chiptop => - implicit val p = chiptop.p - - val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters())) - chiptop.implicitClockSinkNode := implicitClockSourceNode - - val simpleClockGroupSourceNode = chiptop.lazySystem match { - case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { - val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) - l.asyncClockGroupsNode := n - Some(n) - } - case _ => throw new Exception("Harness multiclock assumes BaseSubsystem") - } - - InModuleBody { - // this needs directionality so generateIOFromSignal works - val clock_wire = Wire(Input(Clock())) - val reset_wire = GenerateReset(chiptop, clock_wire) - val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, Some("iocell_clock")) - chiptop.iocells ++= clockIOCell - clock_io.suggestName("clock") - val div_clock = Pow2ClockDivider(clock_wire, 2) - - implicitClockSourceNode.out.unzip._1.map { o => - o.clock := div_clock - o.reset := reset_wire - } - - simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle => - out.member.elements.map { case (name, data) => - // This is mega hacks, how are you actually supposed to do this? - data.clock := (if (name.contains("core")) clock_wire else div_clock) - data.reset := reset_wire - } - }} - - chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { - clock_io := th.harnessClock - Nil - }) - } - } - val idealizedPLL: ChipTop => Unit = { chiptop => implicit val p = chiptop.p @@ -184,15 +109,18 @@ object ClockingSchemeGenerators { l.asyncClockGroupsNode } - val aggregator = ClockGroupAggregator() + val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node chiptop.implicitClockSinkNode := ClockGroup() := aggregator - systemAsyncClockGroup := aggregator + systemAsyncClockGroup := ClockGroupNamePrefixer() := aggregator val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) - aggregator := ClockGroupDealiaser() := IdealizedPLL() := referenceClockSource + (aggregator + := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignment), p(DefaultClockFrequencyKey)) + := IdealizedPLL() + := referenceClockSource) + InModuleBody { - val clock_wire = Wire(Input(Clock())) val reset_wire = GenerateReset(chiptop, clock_wire) val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, Some("iocell_clock")) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 03ccdbca..94b6477b 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -26,7 +26,7 @@ import sifive.blocks.devices.gpio._ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ -import chipyard.{BuildTop, BuildSystem, ClockingSchemeGenerators, ClockingSchemeKey, TestSuitesKey, TestSuiteHelper} +import chipyard.{BuildTop, BuildSystem, ClockingSchemeGenerators, ClockingSchemeKey, TestSuitesKey, TestSuiteHelper, ClockNameContainsAssignment} // Imports for multiclock sketch import boom.common.{BoomTile, BoomTileParams} @@ -163,10 +163,6 @@ class WithNoSubsystemDrivenClocks extends Config((site, here, up) => { case SubsystemDriveAsyncClockGroupsKey => None }) -class WithTileDividedClock extends Config((site, here, up) => { - case ClockingSchemeKey => ClockingSchemeGenerators.harnessDividedClock -}) - class WithDMIDTM extends Config((site, here, up) => { case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI)) }) @@ -175,23 +171,20 @@ class WithNoDebug extends Config((site, here, up) => { case DebugModuleKey => None }) - // Multiclock sketch -class WithForcedTileFrequency(fMHz: Double) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => - val genericAttachParams = up(TilesLocated(InSubsystem), site) map { - case b: BoomTileAttachParams => GenericallyAttachableTile[BoomTile]( - b.tileParams, GenericCrossingParams(b.crossingParams), b.lookup) - case r: RocketTileAttachParams => GenericallyAttachableTile[RocketTile]( - r.tileParams, GenericCrossingParams(r.crossingParams), r.lookup) - case a: ArianeTileAttachParams => GenericallyAttachableTile[ArianeTile]( - a.tileParams, GenericCrossingParams(a.crossingParams), a.lookup) - case g: GenericallyAttachableTile[_] => g - } - genericAttachParams.map(p => p.copy(crossingParams = p.crossingParams.copy( - injectClockNodeFunc = ClockNodeInjectionUtils.forceTakeFrequency(fMHz)))) -}) +//class WithForcedTileFrequency(fMHz: Double) extends Config((site, here, up) => { +// case TilesLocated(InSubsystem) => +// val genericAttachParams = up(TilesLocated(InSubsystem), site) map { +// case b: BoomTileAttachParams => GenericallyAttachableTile[BoomTile]( +// b.tileParams, GenericCrossingParams(b.crossingParams), b.lookup) +// case r: RocketTileAttachParams => GenericallyAttachableTile[RocketTile]( +// r.tileParams, GenericCrossingParams(r.crossingParams), r.lookup) +// case a: ArianeTileAttachParams => GenericallyAttachableTile[ArianeTile]( +// a.tileParams, GenericCrossingParams(a.crossingParams), a.lookup) +// case g: GenericallyAttachableTile[_] => g +// } +// genericAttachParams.map(p => p.copy(crossingParams = p.crossingParams.copy( +// injectClockNodeFunc = ClockNodeInjectionUtils.forceTakeFrequency(fMHz)))) +//}) -class WithIdealizedPLL extends Config((site, here, up) => { - case ClockingSchemeKey => ClockingSchemeGenerators.idealizedPLL -}) +class WithTileFrequency(fMHz: Double) extends ClockNameContainsAssignment("core", fMHz) diff --git a/generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala b/generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala new file mode 100644 index 00000000..bf756003 --- /dev/null +++ b/generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala @@ -0,0 +1,65 @@ +package chipyard.clocking + +import chisel3._ + +import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.prci._ + +/** + * This sort of node can be used when it is a connectivity passthrough, but modifies + * the flow of parameters (which may result in changing the names of the underlying signals). + */ +class ClockGroupParameterModifier( + sourceFn: ClockGroupSourceParameters => ClockGroupSourceParameters = { m => m }, + sinkFn: ClockGroupSinkParameters => ClockGroupSinkParameters = { s => s })( + implicit p: Parameters, v: ValName) extends LazyModule { + val node = ClockGroupAdapterNode(sourceFn, sinkFn) + lazy val module = new LazyRawModuleImp(this) { + (node.out zip node.in).map { case ((o, _), (i, _)) => + (o.member.data zip i.member.data).foreach { case (oD, iD) => oD := iD } + } + } +} + +/** + * Pushes the ClockGroup's name into each member's name field as a prefix. This is + * intended to be used before a ClockGroupAggregator so that sources from + * different aggregated ClockGroups can be disambiguated by their names. + */ +object ClockGroupNamePrefixer { + def apply()(implicit p: Parameters, valName: ValName): ClockGroupAdapterNode = + LazyModule(new ClockGroupParameterModifier(sinkFn = { s => s.copy(members = s.members.zipWithIndex.map { case (m, idx) => + m.copy(name = m.name match { + // This matches what the chisel would do if the names were not modified + case Some(clockName) => Some(s"${s.name}_${clockName}") + case None => Some(s"${s.name}_${idx}") + }) + })})).node +} + +/** + * [Word from on high is that Strings are in...] + * Overrides the take field of all clocks in a group, by attempting to apply a + * series of assignment functions: + * (name: String) => freq-in-MHz: Option[Double] + * to each sink. Later functions that return non-empty values take priority. + * The default if all functions return None. + */ +object ClockGroupFrequencySpecifier { + def apply( + assigners: Seq[(String) => Option[Double]], + defaultFreq: Double)( + implicit p: Parameters, valName: ValName): ClockGroupAdapterNode = { + + def lookupFrequencyForName(clock: ClockSinkParameters): ClockSinkParameters = { + require(clock.name.nonEmpty, "All clocks in clock group must have an assigned name") + val clockFreq = assigners.foldLeft(defaultFreq)( + (currentFreq, candidateFunc) => candidateFunc(clock.name.get).getOrElse(currentFreq)) + + clock.copy(take = clock.take.map(_.copy(freqMHz = clockFreq)).orElse(Some(ClockParameters(clockFreq)))) + } + + LazyModule(new ClockGroupParameterModifier(sinkFn = { s => s.copy(members = s.members.map(lookupFrequencyForName)) })).node + } +} diff --git a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala index 3de99e8e..6cf03e27 100644 --- a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala +++ b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala @@ -8,6 +8,9 @@ import freechips.rocketchip.prci._ import scala.collection.mutable +/** + * TODO: figure out how much division is acceptable in our simulators and redefine this. + */ object FrequencyUtils { def computeReferenceFrequencyMHz( requestedOutputs: Seq[ClockParameters], @@ -33,16 +36,26 @@ case class IdealizedPLLNode(pllName: String)(implicit valName: ValName) take = Some(FrequencyUtils.computeReferenceFrequencyMHz(u.head.members.flatMap(_.take)))) } ) +/** + * Generates a digttal-divider-only PLL model that verilator can simulate. + * Inspects all take-specified frequencies in the output ClockGroup, calculates a + * fast reference clock (roughly LCM(requested frequencies)) which is passed up the + * diplomatic graph, and then generates dividers for each unique requested + * frequency. + */ + class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) extends LazyModule { val node = IdealizedPLLNode(pllName) lazy val module = new LazyRawModuleImp(this) { - require(node.out.size == 1, "Must use a ClockGroupAggregator") + require(node.out.size == 1, "Idealized PLL expects to generate a single output clock group. Use a ClockGroupAggregator") val (refClock, ClockEdgeParameters(_, refSinkParam, _, _)) = node.in.head val (outClocks, ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head val referenceFreq = refSinkParam.take.get.freqMHz - val requestedFreqs = outSinkParams.members.map(m => m.name -> m.take) + println(s"Idealized PLL Frequency Summary") + println(s"-------------------------------") + println(s" Requested Reference Frequency: ${referenceFreq} MHz") val dividedClocks = mutable.HashMap[Int, Clock]() def instantiateDivider(div: Int): Clock = { @@ -57,8 +70,9 @@ class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) ex val requested = sinkP.take.get.freqMHz val div = Math.round(referenceFreq / requested).toInt val actual = referenceFreq / div.toDouble - println(s"Clock ${sinkBName}, requested freq: ${requested} MHz. Actual freq: ${actual} MHz via division of ${div}") + println(s" Output Clock ${sinkBName}: Requested: ${requested} MHz, Actual: ${actual} MHz (division of ${div})") sinkB.clock := dividedClocks.getOrElse(div, instantiateDivider(div)) + sinkB.reset := refClock.reset } } } diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index a4e1af72..dd186828 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -174,19 +174,8 @@ class MMIORocketConfig extends Config( new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) -// NOTE: This config doesn't work yet because SimWidgets in the TestHarness -// always get the TestHarness clock. The Tiles and Uncore receive the correct clocks class DividedClockRocketConfig extends Config( - new chipyard.config.WithTileDividedClock ++ // Put the Tile on its own clock domain - new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore - new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new chipyard.config.AbstractConfig) - -// Multiclock Sketch -class ForcedClockRocketConfig extends Config( - new chipyard.config.WithForcedTileFrequency(200) ++ - new chipyard.config.WithIdealizedPLL ++ // Put the Tile on its own clock domain - //new chipyard.config.WithTileDividedClock ++ // Put the Tile on its own clock domain + new chipyard.config.WithTileFrequency(200.0) ++ new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) From ad147ec7f227abd1c02935e8c429280f00e45990 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 17 Sep 2020 11:39:01 -0700 Subject: [PATCH 58/93] [clocks] Remove dealiaser and node injector until they are needed --- .../chipyard/src/main/scala/Clocks.scala | 2 +- .../src/main/scala/ConfigFragments.scala | 20 +------- .../src/main/scala/GenericAttachParams.scala | 38 -------------- .../scala/clocking/ClockGroupDealiaser.scala | 50 ------------------- .../scala/clocking/ClockNodeInjectors.scala | 29 ----------- 5 files changed, 2 insertions(+), 137 deletions(-) delete mode 100644 generators/chipyard/src/main/scala/GenericAttachParams.scala delete mode 100644 generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala delete mode 100644 generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 609bf8a0..1d3a981e 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -12,7 +12,7 @@ import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider} import barstools.iocell.chisel._ -import chipyard.clocking.{IdealizedPLL, ClockGroupDealiaser, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} +import chipyard.clocking.{IdealizedPLL, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} /** * Chipyard provides three baseline, top-level reset schemes, set using the diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 94b6477b..19fe0630 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -31,8 +31,6 @@ import chipyard.{BuildTop, BuildSystem, ClockingSchemeGenerators, ClockingScheme // Imports for multiclock sketch import boom.common.{BoomTile, BoomTileParams} import ariane.{ArianeTile, ArianeTileParams} -import chipyard.{GenericallyAttachableTile, GenericCrossingParams} -import chipyard.clocking.{ClockNodeInjectionUtils } // ----------------------- // Common Config Fragments // ----------------------- @@ -169,22 +167,6 @@ class WithDMIDTM extends Config((site, here, up) => { class WithNoDebug extends Config((site, here, up) => { case DebugModuleKey => None + }) - -// Multiclock sketch -//class WithForcedTileFrequency(fMHz: Double) extends Config((site, here, up) => { -// case TilesLocated(InSubsystem) => -// val genericAttachParams = up(TilesLocated(InSubsystem), site) map { -// case b: BoomTileAttachParams => GenericallyAttachableTile[BoomTile]( -// b.tileParams, GenericCrossingParams(b.crossingParams), b.lookup) -// case r: RocketTileAttachParams => GenericallyAttachableTile[RocketTile]( -// r.tileParams, GenericCrossingParams(r.crossingParams), r.lookup) -// case a: ArianeTileAttachParams => GenericallyAttachableTile[ArianeTile]( -// a.tileParams, GenericCrossingParams(a.crossingParams), a.lookup) -// case g: GenericallyAttachableTile[_] => g -// } -// genericAttachParams.map(p => p.copy(crossingParams = p.crossingParams.copy( -// injectClockNodeFunc = ClockNodeInjectionUtils.forceTakeFrequency(fMHz)))) -//}) - class WithTileFrequency(fMHz: Double) extends ClockNameContainsAssignment("core", fMHz) diff --git a/generators/chipyard/src/main/scala/GenericAttachParams.scala b/generators/chipyard/src/main/scala/GenericAttachParams.scala deleted file mode 100644 index f90598af..00000000 --- a/generators/chipyard/src/main/scala/GenericAttachParams.scala +++ /dev/null @@ -1,38 +0,0 @@ - -package chipyard - -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.config.{Field, Parameters} -import freechips.rocketchip.subsystem._ -import freechips.rocketchip.tile.{LookupByHartIdImpl, TileParams, InstantiableTileParams, BaseTile} - -import chipyard.clocking.ClockNodeInjectionUtils._ - -case class GenericCrossingParams( - crossingType: ClockCrossingType = SynchronousCrossing(), - master: TilePortParamsLike = TileMasterPortParams(), - slave: TilePortParamsLike = TileSlavePortParams(), - mmioBaseAddressPrefixWhere: TLBusWrapperLocation = CBUS, - injectClockNodeFunc: InjectClockNodeFunc = injectIdentityClockNode, - forceSeparateClockReset: Boolean = false) extends TileCrossingParamsLike { - - def injectClockNode(a: Attachable)(implicit p: Parameters) = injectClockNodeFunc(a, p) -} - -object GenericCrossingParams { - def apply(params: TileCrossingParamsLike): GenericCrossingParams = GenericCrossingParams( - params.crossingType, - params.master, - params.slave, - params.mmioBaseAddressPrefixWhere, - (a: Attachable, p: Parameters) => params.injectClockNode(a)(p), - params.forceSeparateClockReset) -} - -case class GenericallyAttachableTile[TT <: BaseTile]( - tileParams: InstantiableTileParams[TT], - crossingParams: GenericCrossingParams, - lookup: LookupByHartIdImpl) extends CanAttachTile { - type TileType = TT -} - diff --git a/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala b/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala deleted file mode 100644 index 54b384e9..00000000 --- a/generators/chipyard/src/main/scala/clocking/ClockGroupDealiaser.scala +++ /dev/null @@ -1,50 +0,0 @@ -package chipyard.clocking - -import chisel3._ - -import freechips.rocketchip.config.{Parameters} -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.prci._ - -/** - * Somewhat hacky. Since not all clocks in a clock group specify a taken frequency - * current, this LazyModule attempts to dealias them, by finding a specified - * clock with a matching name. - * - * Perhaps another, simpler solution would be to pass a default. - * - */ - -case class ClockGroupDealiaserNode()(implicit valName: ValName) - extends NexusNode(ClockGroupImp)( - dFn = { _ => ClockGroupSourceParameters() }, - uFn = { u => - require(u.size == 1) - val takenClocks = u.head.members.filter(_.take.nonEmpty) - require(takenClocks.nonEmpty, - "At least one sink clock in clock group must specify its take parameter") - u.head.copy(members = takenClocks) - }) - -class ClockGroupDealiaser(name: String)(implicit p: Parameters) extends LazyModule { - val node = ClockGroupDealiaserNode() - - lazy val module = new LazyRawModuleImp(this) { - require(node.out.size == 1 && node.in.size == 1, - "ClockGroupDealiaser requires a single ClockGroup, please use a ClockGroupAggregator") - val (outClocks, e @ ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head - val (inClocks, ClockGroupEdgeParameters(_, inSinkParams, _, _)) = node.in.head - val inMap = inClocks.member.data.zip(inSinkParams.members).map({ case (b, p) => p.name -> b}).toMap - - for (((outBName, outB), outName) <- outClocks.member.elements.zip(outSinkParams.members.map(_.name))) { - val inClock = inMap.getOrElse(outName, throw new Exception(""" - | No clock in input group with name option matching ${outName}. At least one clock - | with the same must specify a frequency in its take parameter.""".stripMargin)) - outB := inClock - } - } -} - -object ClockGroupDealiaser { - def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new ClockGroupDealiaser(valName.name)).node -} diff --git a/generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala b/generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala deleted file mode 100644 index 981ed327..00000000 --- a/generators/chipyard/src/main/scala/clocking/ClockNodeInjectors.scala +++ /dev/null @@ -1,29 +0,0 @@ - -package chipyard.clocking - -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.config.{Parameters} -import freechips.rocketchip.subsystem._ -import freechips.rocketchip.prci.{ClockNode, ClockTempNode, ClockAdapterNode, ClockParameters} -/** - * An adapter node hack c that just throws out the existing sink node - * clock parameters in favor of the provided ones. - */ -class ForceTakeClock(clockParams: Option[ClockParameters])(implicit p: Parameters, v: ValName) extends LazyModule { - val node = ClockAdapterNode(sinkFn = { s => s.copy(take = clockParams) }) - lazy val module = new LazyRawModuleImp(this) { - (node.out zip node.in) map { case ((o, _), (i, _)) => o := i } - } -} - -object ForceTakeClock { - def apply(clockParams: Option[ClockParameters])(implicit p: Parameters, v: ValName): ClockAdapterNode = - LazyModule(new ForceTakeClock(clockParams)).node -} - -object ClockNodeInjectionUtils { - type InjectClockNodeFunc = (Attachable, Parameters) => ClockNode - val injectIdentityClockNode: InjectClockNodeFunc = (a: Attachable, p: Parameters) => ClockTempNode() - def forceTakeFrequency(freqMHz: Double): InjectClockNodeFunc = - (a: Attachable, p: Parameters) => ForceTakeClock(Some(ClockParameters(freqMHz)))(p, ValName("ForcedTakeClock")) -} From aa355c7c1abb3980f28ba167b8ebac89b9255fb2 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 18 Sep 2020 10:41:59 -0700 Subject: [PATCH 59/93] Bump firesim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 2b52057e..7b2691c9 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 2b52057e158fd91d44c6259aa08869622a88040a +Subproject commit 7b2691c935aef13fd9de0e8d95d99ad9bceaab2e From bbf941c865f660fbf15ddac2c4f579a55628191f Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 18 Sep 2020 10:43:58 -0700 Subject: [PATCH 60/93] Bump Firesim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 7b2691c9..3dbe8aee 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 7b2691c935aef13fd9de0e8d95d99ad9bceaab2e +Subproject commit 3dbe8aee3f917079e7319391bac5d23d2ba5e6de From f36183d236ea6a7ea48041f5da084665c443d2fd Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 17 Sep 2020 12:17:02 -0700 Subject: [PATCH 61/93] [clocks] Update AssignerKey name and comment --- generators/chipyard/src/main/scala/Clocks.scala | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 1d3a981e..499d4844 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -82,20 +82,21 @@ object GenerateReset { case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGenerators.idealizedPLL) /** - * This is a dictionary of clock name to clock frequency in MHz. Names - * correspond to the IO coming off digital top. If the map is undefined for the given name, - * it will return a default value -- DFU. + * This is a Seq of assignment functions, that accept a clock name and return an optional frequency. + * Functions that appear later in this seq have higher precedence that earlier ones. + * If no function returns a non-empty value, the value specified in + * [[DefaultClockFrequencyKey]] will be used -- DFU. */ -case object ClockFrequencyAssignment extends Field[Seq[(String) => Option[Double]]](Seq.empty) +case object ClockFrequencyAssignersKey extends Field[Seq[(String) => Option[Double]]](Seq.empty) case object DefaultClockFrequencyKey extends Field[Double](100.0) class ClockNameMatchesAssignment(name: String, fMHz: Double) extends Config((site, here, up) => { - case ClockFrequencyAssignment => up(ClockFrequencyAssignment, site) ++ + case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++ Seq((cName: String) => if (cName == name) Some(fMHz) else None) }) class ClockNameContainsAssignment(name: String, fMHz: Double) extends Config((site, here, up) => { - case ClockFrequencyAssignment => up(ClockFrequencyAssignment, site) ++ + case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++ Seq((cName: String) => if (cName.contains(name)) Some(fMHz) else None) }) @@ -115,7 +116,7 @@ object ClockingSchemeGenerators { val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) (aggregator - := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignment), p(DefaultClockFrequencyKey)) + := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) := IdealizedPLL() := referenceClockSource) From a43400acb9f0397c18c510d72827933fb1e65991 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 18 Sep 2020 15:36:14 -0700 Subject: [PATCH 62/93] Update CI --- .circleci/config.yml | 94 +++++++++++++++++-- .circleci/defaults.sh | 6 +- .circleci/run-tests.sh | 14 ++- .../src/main/scala/config/SodorConfigs.scala | 30 +++--- generators/riscv-sodor | 2 +- 5 files changed, 124 insertions(+), 22 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b09791c..a695cf28 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -262,11 +262,31 @@ jobs: steps: - prepare-rtl: project-key: "chipyard-ariane" - prepare-chipyard-sodor: + prepare-chipyard-sodor-stage1: executor: main-env steps: - prepare-rtl: - project-key: "chipyard-sodor" + project-key: "chipyard-sodor-stage1" + prepare-chipyard-sodor-stage2: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-sodor-stage2" + prepare-chipyard-sodor-stage3: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-sodor-stage3" + prepare-chipyard-sodor-stage5: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-sodor-stage5" + prepare-chipyard-sodor-ucode: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-sodor-ucode" prepare-icenet: executor: main-env steps: @@ -395,11 +415,35 @@ jobs: - run-tests: project-key: "chipyard-ariane" timeout: "30m" - chipyard-sodor-run-tests: + chipyard-sodor-stage1-run-tests: executor: main-env steps: - run-tests: - project-key: "chipyard-sodor" + project-key: "chipyard-sodor-stage1" + timeout: "20m" + chipyard-sodor-stage2-run-tests: + executor: main-env + steps: + - run-tests: + project-key: "chipyard-sodor-stage2" + timeout: "20m" + chipyard-sodor-stage3-run-tests: + executor: main-env + steps: + - run-tests: + project-key: "chipyard-sodor-stage3" + timeout: "20m" + chipyard-sodor-stage5-run-tests: + executor: main-env + steps: + - run-tests: + project-key: "chipyard-sodor-stage5" + timeout: "20m" + chipyard-sodor-ucode-run-tests: + executor: main-env + steps: + - run-tests: + project-key: "chipyard-sodor-ucode" timeout: "20m" chipyard-nvdla-run-tests: executor: main-env @@ -522,7 +566,27 @@ workflows: - install-riscv-toolchain - install-verilator - - prepare-chipyard-sodor: + - prepare-chipyard-sodor-stage1: + requires: + - install-riscv-toolchain + - install-verilator + + - prepare-chipyard-sodor-stage2: + requires: + - install-riscv-toolchain + - install-verilator + + - prepare-chipyard-sodor-stage3: + requires: + - install-riscv-toolchain + - install-verilator + + - prepare-chipyard-sodor-stage5: + requires: + - install-riscv-toolchain + - install-verilator + + - prepare-chipyard-sodor-ucode: requires: - install-riscv-toolchain - install-verilator @@ -632,9 +696,25 @@ workflows: requires: - prepare-chipyard-ariane - - chipyard-sodor-run-tests: + - chipyard-sodor-stage1-run-tests: requires: - - prepare-chipyard-sodor + - prepare-chipyard-sodor-stage1 + + - chipyard-sodor-stage2-run-tests: + requires: + - prepare-chipyard-sodor-stage2 + + - chipyard-sodor-stage3-run-tests: + requires: + - prepare-chipyard-sodor-stage3 + + - chipyard-sodor-stage5-run-tests: + requires: + - prepare-chipyard-sodor-stage5 + + - chipyard-sodor-ucode-run-tests: + requires: + - prepare-chipyard-sodor-ucode - chipyard-nvdla-run-tests: requires: diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 703737cd..62b9ceb4 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -69,4 +69,8 @@ mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Test mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests" mapping["icenet"]="SUB_PROJECT=icenet" mapping["testchipip"]="SUB_PROJECT=testchipip" - +mapping["chipyard-sodor-stage1"]="SUB_PROJEET=Sodor1StageConfig" +mapping["chipyard-sodor-stage2"]="SUB_PROJEET=Sodor2StageConfig" +mapping["chipyard-sodor-stage3"]="SUB_PROJEET=Sodor3StageSinglePortConfig" +mapping["chipyard-sodor-stage5"]="SUB_PROJEET=Sodor5StageConfig" +mapping["chipyard-sodor-ucode"]="SUB_PROJEET=SodorUCodeConfig" diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index c0b932b6..cd4afd23 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -91,7 +91,19 @@ case $1 in chipyard-ariane) make run-binary-fast -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv ;; - chipyard-sodor) + chipyard-sodor-stage1) + run_asm ${mapping[$1]} + ;; + chipyard-sodor-stage2) + run_asm ${mapping[$1]} + ;; + chipyard-sodor-stage3) + run_asm ${mapping[$1]} + ;; + chipyard-sodor-stage5) + run_asm ${mapping[$1]} + ;; + chipyard-sodor-ucode) run_asm ${mapping[$1]} ;; chipyard-nvdla) diff --git a/generators/chipyard/src/main/scala/config/SodorConfigs.scala b/generators/chipyard/src/main/scala/config/SodorConfigs.scala index df386dd9..eb7b4086 100644 --- a/generators/chipyard/src/main/scala/config/SodorConfigs.scala +++ b/generators/chipyard/src/main/scala/config/SodorConfigs.scala @@ -5,43 +5,49 @@ import chisel3._ import freechips.rocketchip.config.{Config} class Sodor1StageConfig extends Config( + // Create a Sodor 1-stage core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage1Factory) ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ new chipyard.config.AbstractConfig) class Sodor2StageConfig extends Config( + // Create a Sodor 2-stage core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage2Factory) ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ new chipyard.config.AbstractConfig) class Sodor3StageConfig extends Config( + // Create a Sodor 1-stage core with two ports new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 2)) ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ new chipyard.config.AbstractConfig) class Sodor3StageSinglePortConfig extends Config( + // Create a Sodor 3-stage core with one ports (instruction and data memory access controlled by arbiter) new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 1)) ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ new chipyard.config.AbstractConfig) class Sodor5StageConfig extends Config( + // Create a Sodor 5-stage core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage5Factory) ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ new chipyard.config.AbstractConfig) class SodorUCodeConfig extends Config( + // Construct a Sodor microcode-based single-bus core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.UCodeFactory) ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad + new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ new chipyard.config.AbstractConfig) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 43985218..69df2b01 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 43985218b8c91c9206018177d81e37e27267dbf6 +Subproject commit 69df2b013f162cf4c450cdc3e7bbd6e7b9f2de16 From 56d1d5b500178af08f7233cfdb463ce8fd0e0e08 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 18 Sep 2020 22:42:19 -0700 Subject: [PATCH 63/93] Fix CI errors --- .circleci/config.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7e8219a3..be39e21a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -462,7 +462,19 @@ workflows: - chipyard-ariane-run-tests: requires: - prepare-chipyard-cores - - chipyard-sodor-run-tests: + - chipyard-sodor-stage1-run-tests: + requires: + - prepare-chipyard-cores + - chipyard-sodor-stage2-run-tests: + requires: + - prepare-chipyard-cores + - chipyard-sodor-stage3-run-tests: + requires: + - prepare-chipyard-cores + - chipyard-sodor-stage5-run-tests: + requires: + - prepare-chipyard-cores + - chipyard-sodor-ucode-run-tests: requires: - prepare-chipyard-cores From a02700a1d4a39d433b2e3a2b0bdfad176d9375ed Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 18 Sep 2020 23:14:47 -0700 Subject: [PATCH 64/93] Add documentation for sodor --- docs/Generators/Sodor.rst | 17 +++++++++++++++++ docs/Generators/index.rst | 1 + generators/riscv-sodor | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 docs/Generators/Sodor.rst diff --git a/docs/Generators/Sodor.rst b/docs/Generators/Sodor.rst new file mode 100644 index 00000000..7f4282eb --- /dev/null +++ b/docs/Generators/Sodor.rst @@ -0,0 +1,17 @@ +Sodor Core +==================================== + +`Sodor `__ is a collection of 5 simple RV32MI cores designed for educational purpose. +The `Sodor core` is wrapped in an tile during generation so it can be used as a component within the `Rocket Chip SoC generator`. +The cores contain a small scratchpad memory to which the program are loaded through a TileLink slave port, and the cores **DO NOT** +support external memory. + +The five available cores and their corresponding generator configuration are: + +* 1-stage (essentially an ISA simulator) - ``Sodor1StageConfig`` +* 2-stage (demonstrates pipelining in Chisel) - ``Sodor2StageConfig`` +* 3-stage (uses sequential memory; supports both Harvard (``Sodor3StageConfig``) and Princeton (``Sodor3StageSinglePortConfig``) versions) +* 5-stage (can toggle between fully bypassed or fully interlocked) - ``Sodor5StageConfig`` +* "bus"-based micro-coded implementation - ``SodorUCodeConfig`` + +For more information, please refer to the `GitHub repository `__. diff --git a/docs/Generators/index.rst b/docs/Generators/index.rst index be9c5e55..cebb17e5 100644 --- a/docs/Generators/index.rst +++ b/docs/Generators/index.rst @@ -29,4 +29,5 @@ so changes to the generators themselves will automatically be used when building SHA3 Ariane NVDLA + Sodor diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 69df2b01..12fa11e4 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 69df2b013f162cf4c450cdc3e7bbd6e7b9f2de16 +Subproject commit 12fa11e485c4854a48eec0561698dd0b32230243 From ae5fb8470bcfbd06772df0044a6a1a097648e749 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sat, 19 Sep 2020 10:27:20 -0700 Subject: [PATCH 65/93] Remove unnecessary CI tests --- .circleci/config.yml | 47 +++--------------------------------------- .circleci/defaults.sh | 6 +----- .circleci/run-tests.sh | 14 +------------ 3 files changed, 5 insertions(+), 62 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index be39e21a..4ee84ced 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -241,40 +241,12 @@ jobs: group-key: "group-cores" project-key: "chipyard-ariane" timeout: "30m" - chipyard-sodor-stage1-run-tests: + chipyard-sodor-run-tests: executor: main-env steps: - run-tests: group-key: "group-cores" - project-key: "chipyard-sodor-stage1" - timeout: "30m" - chipyard-sodor-stage2-run-tests: - executor: main-env - steps: - - run-tests: - group-key: "group-cores" - project-key: "chipyard-sodor-stage2" - timeout: "30m" - chipyard-sodor-stage3-run-tests: - executor: main-env - steps: - - run-tests: - group-key: "group-cores" - project-key: "chipyard-sodor-stage3" - timeout: "30m" - chipyard-sodor-stage5-run-tests: - executor: main-env - steps: - - run-tests: - group-key: "group-cores" - project-key: "chipyard-sodor-stage5" - timeout: "30m" - chipyard-sodor-ucode-run-tests: - executor: main-env - steps: - - run-tests: - group-key: "group-cores" - project-key: "chipyard-sodor-ucode" + project-key: "chipyard-sodor" timeout: "30m" chipyard-dmirocket-run-tests: executor: main-env @@ -462,22 +434,9 @@ workflows: - chipyard-ariane-run-tests: requires: - prepare-chipyard-cores - - chipyard-sodor-stage1-run-tests: + - chipyard-sodor-run-tests: requires: - prepare-chipyard-cores - - chipyard-sodor-stage2-run-tests: - requires: - - prepare-chipyard-cores - - chipyard-sodor-stage3-run-tests: - requires: - - prepare-chipyard-cores - - chipyard-sodor-stage5-run-tests: - requires: - - prepare-chipyard-cores - - chipyard-sodor-ucode-run-tests: - requires: - - prepare-chipyard-cores - - chipyard-dmirocket-run-tests: requires: - prepare-chipyard-peripherals diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 75101884..e3318d87 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -79,8 +79,4 @@ mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Test mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests" mapping["icenet"]="SUB_PROJECT=icenet" mapping["testchipip"]="SUB_PROJECT=testchipip" -mapping["chipyard-sodor-stage1"]="SUB_PROJEET=Sodor1StageConfig" -mapping["chipyard-sodor-stage2"]="SUB_PROJEET=Sodor2StageConfig" -mapping["chipyard-sodor-stage3"]="SUB_PROJEET=Sodor3StageSinglePortConfig" -mapping["chipyard-sodor-stage5"]="SUB_PROJEET=Sodor5StageConfig" -mapping["chipyard-sodor-ucode"]="SUB_PROJEET=SodorUCodeConfig" +mapping["chipyard-sodor"]="CONFIG=Sodor5StageConfig" diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index 37b22b70..da5029b5 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -94,19 +94,7 @@ case $1 in chipyard-ariane) make run-binary-fast -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/multiply.riscv ;; - chipyard-sodor-stage1) - run_asm ${mapping[$1]} - ;; - chipyard-sodor-stage2) - run_asm ${mapping[$1]} - ;; - chipyard-sodor-stage3) - run_asm ${mapping[$1]} - ;; - chipyard-sodor-stage5) - run_asm ${mapping[$1]} - ;; - chipyard-sodor-ucode) + chipyard-sodor) run_asm ${mapping[$1]} ;; chipyard-nvdla) From 6c297e3179a7e32c00dd4a0edb8ed7729b6f2c05 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 22 Sep 2020 11:08:52 -0700 Subject: [PATCH 66/93] Fix smartelf2hex.sh creating files 64x the minimum size --- scripts/smartelf2hex.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/smartelf2hex.sh b/scripts/smartelf2hex.sh index 782977ff..e6fd1f7a 100755 --- a/scripts/smartelf2hex.sh +++ b/scripts/smartelf2hex.sh @@ -11,4 +11,6 @@ entry_dec=`bc <<< "ibase=16;$entry_hex"` length_hex=`echo "$segments" | grep LOAD | tail -n 1 | tr -s [:space:] | cut -f4,6 -d' '` length_dec=`echo $length_hex | tr -d x | tr [:lower:] [:upper:] | tr ' ' + | sed 's/^/ibase=16;/' | sed "s/$/-$entry_hex/" | bc` power_2_length=`echo "x=l($length_dec)/l(2); scale=0; 2^((x+1)/1)" | bc -l` -elf2hex 64 $power_2_length $binary $entry_dec +width=64 +depth=$((power_2_length / width)) +elf2hex $width $depth $binary $entry_dec From d5660c01f3ada775c671409e593826b56cd9f7bf Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 22 Sep 2020 12:58:34 -0700 Subject: [PATCH 67/93] Bump esp-isa-sim for loadmem-fix add TLS segments to smartelf2hex --- scripts/smartelf2hex.sh | 2 +- toolchains/esp-tools/riscv-isa-sim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/smartelf2hex.sh b/scripts/smartelf2hex.sh index e6fd1f7a..dd035690 100755 --- a/scripts/smartelf2hex.sh +++ b/scripts/smartelf2hex.sh @@ -8,7 +8,7 @@ binary=$1 segments=`readelf --segments --wide $binary` entry_hex=`echo -e "$segments" | grep "Entry point" | cut -f3 -d' ' | sed 's/0x//' | tr [:lower:] [:upper:]` entry_dec=`bc <<< "ibase=16;$entry_hex"` -length_hex=`echo "$segments" | grep LOAD | tail -n 1 | tr -s [:space:] | cut -f4,6 -d' '` +length_hex=`echo "$segments" | grep "LOAD\|TLS" | tail -n 1 | tr -s [:space:] | cut -f4,6 -d' '` length_dec=`echo $length_hex | tr -d x | tr [:lower:] [:upper:] | tr ' ' + | sed 's/^/ibase=16;/' | sed "s/$/-$entry_hex/" | bc` power_2_length=`echo "x=l($length_dec)/l(2); scale=0; 2^((x+1)/1)" | bc -l` width=64 diff --git a/toolchains/esp-tools/riscv-isa-sim b/toolchains/esp-tools/riscv-isa-sim index aa332c6a..fa94e84d 160000 --- a/toolchains/esp-tools/riscv-isa-sim +++ b/toolchains/esp-tools/riscv-isa-sim @@ -1 +1 @@ -Subproject commit aa332c6a9a5ec77a9b97cdb4a1978ad394b17f1e +Subproject commit fa94e84d4ff3e23ba909a63376b294e444234752 From 84195d28bb9894a039dda01d506a5a3a952084e1 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 23 Sep 2020 15:29:52 -0700 Subject: [PATCH 68/93] [clocks] Don't override existing take frequency if present. --- .../src/main/scala/clocking/ClockGroupNamePrefixer.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala b/generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala index bf756003..a5618c2d 100644 --- a/generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala +++ b/generators/chipyard/src/main/scala/clocking/ClockGroupNamePrefixer.scala @@ -57,7 +57,12 @@ object ClockGroupFrequencySpecifier { val clockFreq = assigners.foldLeft(defaultFreq)( (currentFreq, candidateFunc) => candidateFunc(clock.name.get).getOrElse(currentFreq)) - clock.copy(take = clock.take.map(_.copy(freqMHz = clockFreq)).orElse(Some(ClockParameters(clockFreq)))) + clock.copy(take = clock.take match { + case Some(cp) => + println(s"Clock ${clock.name.get}: using diplomatically specified frequency of ${cp.freqMHz}.") + Some(cp) + case None => Some(ClockParameters(clockFreq)) + }) } LazyModule(new ClockGroupParameterModifier(sinkFn = { s => s.copy(members = s.members.map(lookupFrequencyForName)) })).node From 6641c1f983464b133114be6ead681f95559865c5 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 24 Sep 2020 22:42:49 -0700 Subject: [PATCH 69/93] Attempt to fix CI --- .circleci/check-commit.sh | 2 +- .circleci/defaults.sh | 4 ++-- generators/riscv-sodor | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/check-commit.sh b/.circleci/check-commit.sh index 7824b943..2d393aae 100755 --- a/.circleci/check-commit.sh +++ b/.circleci/check-commit.sh @@ -48,7 +48,7 @@ search () { done } -submodules=("ariane" "boom" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip") +submodules=("ariane" "boom" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip" "sodor") dir="generators" if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ] then diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index e3318d87..1b41e395 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -47,7 +47,7 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim # key value store to get the build groups declare -A grouping -grouping["group-cores"]="chipyard-ariane chipyard-rocket chipyard-hetero chipyard-boom" +grouping["group-cores"]="chipyard-ariane chipyard-rocket chipyard-hetero chipyard-boom chipyard-sodor" grouping["group-peripherals"]="chipyard-dmirocket chipyard-blkdev chipyard-spiflashread chipyard-spiflashwrite chipyard-mmios chipyard-lbwif" grouping["group-accels"]="chipyard-nvdla chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-streaming-fir chipyard-streaming-passthrough" grouping["group-tracegen"]="tracegen tracegen-boom" @@ -73,10 +73,10 @@ mapping["chipyard-mmios"]=" CONFIG=MMIORocketConfig verilog" mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config" mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig" mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig" +mapping["chipyard-sodor"]=" CONFIG=Sodor5StageConfig" mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests" mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests" mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests" mapping["icenet"]="SUB_PROJECT=icenet" mapping["testchipip"]="SUB_PROJECT=testchipip" -mapping["chipyard-sodor"]="CONFIG=Sodor5StageConfig" diff --git a/generators/riscv-sodor b/generators/riscv-sodor index 12fa11e4..b36ce1a7 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit 12fa11e485c4854a48eec0561698dd0b32230243 +Subproject commit b36ce1a7958a748c90508be6822a05c8208cd184 From 96bf702c3b12cd1c6ed73090904a3609fe85ee95 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 24 Sep 2020 23:23:11 -0700 Subject: [PATCH 70/93] [clocks] Factor out the PLL calculations into their own class --- .../src/main/scala/ConfigFragments.scala | 2 +- .../main/scala/clocking/IdealizedPLL.scala | 28 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 19fe0630..38dea871 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -26,7 +26,7 @@ import sifive.blocks.devices.gpio._ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ -import chipyard.{BuildTop, BuildSystem, ClockingSchemeGenerators, ClockingSchemeKey, TestSuitesKey, TestSuiteHelper, ClockNameContainsAssignment} +import chipyard._ // Imports for multiclock sketch import boom.common.{BoomTile, BoomTileParams} diff --git a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala index 6cf03e27..44e58053 100644 --- a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala +++ b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala @@ -7,6 +7,7 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.prci._ import scala.collection.mutable +import scala.collection.immutable.ListMap /** * TODO: figure out how much division is acceptable in our simulators and redefine this. @@ -24,6 +25,23 @@ object FrequencyUtils { } } +class SimplePllConfiguration(val sinks: Seq[ClockSinkParameters]) { + val referenceFreqMHz = FrequencyUtils.computeReferenceFrequencyMHz(sinks.flatMap(_.take)).freqMHz + val sinkDividerMap = ListMap((sinks.map({s => (s, Math.round(referenceFreqMHz / s.take.get.freqMHz).toInt) })):_*) + + def prettyPrint(pllName: String) { + val preamble = s""" + |${pllName} Frequency Summary + | Input Reference Frequency: ${referenceFreqMHz} MHz\n""".stripMargin + val outputSummaries = sinkDividerMap.map { case (sink, division) => + val requested = sink.take.get.freqMHz + val actual = referenceFreqMHz / division.toDouble + s" Output clock ${sink.name.get}, requested: ${requested} MHz, actual: ${actual} MHz (division of ${division})" + } + println(preamble + outputSummaries.mkString("\n")) + } +} + case class IdealizedPLLNode(pllName: String)(implicit valName: ValName) extends MixedNexusNode(ClockImp, ClockGroupImp)( dFn = { _ => ClockGroupSourceParameters() }, @@ -53,9 +71,8 @@ class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) ex val (outClocks, ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head val referenceFreq = refSinkParam.take.get.freqMHz - println(s"Idealized PLL Frequency Summary") - println(s"-------------------------------") - println(s" Requested Reference Frequency: ${referenceFreq} MHz") + val pllConfig = new SimplePllConfiguration(outSinkParams.members) + pllConfig.prettyPrint(pllName) val dividedClocks = mutable.HashMap[Int, Clock]() def instantiateDivider(div: Int): Clock = { @@ -67,10 +84,7 @@ class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) ex } for (((sinkBName, sinkB), sinkP) <- outClocks.member.elements.zip(outSinkParams.members)) { - val requested = sinkP.take.get.freqMHz - val div = Math.round(referenceFreq / requested).toInt - val actual = referenceFreq / div.toDouble - println(s" Output Clock ${sinkBName}: Requested: ${requested} MHz, Actual: ${actual} MHz (division of ${div})") + val div = pllConfig.sinkDividerMap(sinkP) sinkB.clock := dividedClocks.getOrElse(div, instantiateDivider(div)) sinkB.reset := refClock.reset } From f6989a1968817daec39fd26f37001b93bbe6f853 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 24 Sep 2020 23:24:08 -0700 Subject: [PATCH 71/93] [clocks] Use the periphery frequency as the default --- generators/chipyard/src/main/scala/Clocks.scala | 2 +- generators/chipyard/src/main/scala/ConfigFragments.scala | 6 ++++++ .../chipyard/src/main/scala/config/AbstractConfig.scala | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 499d4844..531f6add 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -88,7 +88,7 @@ case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGener * [[DefaultClockFrequencyKey]] will be used -- DFU. */ case object ClockFrequencyAssignersKey extends Field[Seq[(String) => Option[Double]]](Seq.empty) -case object DefaultClockFrequencyKey extends Field[Double](100.0) +case object DefaultClockFrequencyKey extends Field[Double]() class ClockNameMatchesAssignment(name: String, fMHz: Double) extends Config((site, here, up) => { case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++ diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 38dea871..df20af68 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -169,4 +169,10 @@ class WithNoDebug extends Config((site, here, up) => { case DebugModuleKey => None }) + class WithTileFrequency(fMHz: Double) extends ClockNameContainsAssignment("core", fMHz) + +class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => { + case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble +}) + diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 950cb4b4..85d3961b 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -44,6 +44,7 @@ class AbstractConfig extends Config( new chipyard.config.WithUART ++ // add a UART new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs new chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks + new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // Unspecified clocks will match the frequency specified by the pbus dtsFrequency parameter new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) From cc949aadab96c6bd2ba9281fa8cad93a8b5e5d76 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 24 Sep 2020 23:28:47 -0700 Subject: [PATCH 72/93] [clocking] Address some of Colin's PR comments --- generators/chipyard/src/main/scala/ConfigFragments.scala | 4 ---- .../chipyard/src/main/scala/clocking/IdealizedPLL.scala | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index df20af68..d7becac6 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -28,9 +28,6 @@ import sifive.blocks.devices.spi._ import chipyard._ -// Imports for multiclock sketch -import boom.common.{BoomTile, BoomTileParams} -import ariane.{ArianeTile, ArianeTileParams} // ----------------------- // Common Config Fragments // ----------------------- @@ -167,7 +164,6 @@ class WithDMIDTM extends Config((site, here, up) => { class WithNoDebug extends Config((site, here, up) => { case DebugModuleKey => None - }) class WithTileFrequency(fMHz: Double) extends ClockNameContainsAssignment("core", fMHz) diff --git a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala index 44e58053..5b99a17b 100644 --- a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala +++ b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala @@ -55,7 +55,7 @@ case class IdealizedPLLNode(pllName: String)(implicit valName: ValName) ) /** - * Generates a digttal-divider-only PLL model that verilator can simulate. + * Generates a digital-divider-only PLL model that verilator can simulate. * Inspects all take-specified frequencies in the output ClockGroup, calculates a * fast reference clock (roughly LCM(requested frequencies)) which is passed up the * diplomatic graph, and then generates dividers for each unique requested From 7b8a954d04ce8346b73786f2f892c4995d95462f Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Thu, 24 Sep 2020 23:32:07 -0700 Subject: [PATCH 73/93] [firechip] Rework FireSim clocking to be more similar to default CY targets --- .../src/main/scala/BridgeBinders.scala | 12 +- .../firechip/src/main/scala/FireSim.scala | 185 +++++++++--------- .../src/main/scala/TargetConfigs.scala | 2 +- sims/firesim | 2 +- 4 files changed, 96 insertions(+), 105 deletions(-) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 8a4d0a69..9197215c 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -68,9 +68,7 @@ class WithFireSimIOCellModels extends Config((site, here, up) => { class WithSerialBridge extends OverrideHarnessBinder({ (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { ports.map { p => - withClockAndReset(p.clock, th.harnessReset) { - SerialBridge(p.clock, p.bits, MainMemoryConsts.globalName)(GetSystemParameters(system)) - } + SerialBridge(p.clock, p.bits, MainMemoryConsts.globalName)(GetSystemParameters(system)) } Nil } @@ -79,7 +77,7 @@ class WithSerialBridge extends OverrideHarnessBinder({ class WithNICBridge extends OverrideHarnessBinder({ (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { val p: Parameters = GetSystemParameters(system) - ports.map { n => withClockAndReset(n.clock, th.harnessReset) { NICBridge(n.clock, n.bits)(p) } } + ports.map { n => NICBridge(n.clock, n.bits)(p) } Nil } }) @@ -119,11 +117,7 @@ class WithFASEDBridge extends OverrideHarnessBinder({ class WithTracerVBridge extends ComposeHarnessBinder({ (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => { - ports.map { p => - p.traces.map( - tileTrace => withClockAndReset(tileTrace.clock, tileTrace.reset) { TracerVBridge(tileTrace)(system.p) } - ) - } + ports.map { p => p.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p)) } Nil } }) diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index d2ef4e60..d72ec467 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -8,14 +8,15 @@ import chisel3.experimental.{IO} import freechips.rocketchip.prci._ import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey} import freechips.rocketchip.config.{Field, Config, Parameters} -import freechips.rocketchip.diplomacy.{LazyModule, InModuleBody} -import freechips.rocketchip.util.{ResetCatchAndSync} +import freechips.rocketchip.diplomacy.{LazyModule, InModuleBody, ValName} +import freechips.rocketchip.util.{ResetCatchAndSync, RecordMap} import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock} import chipyard._ import chipyard.harness._ import chipyard.iobinders._ +import chipyard.clocking.{FrequencyUtils, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier, SimplePllConfiguration} // Determines the number of times to instantiate the DUT in the harness. // Subsumes legacy supernode support @@ -25,16 +26,6 @@ class WithNumNodes(n: Int) extends Config((pname, site, here) => { case NumNodes => n }) -// Note, the main prerequisite for supporting an additional clock domain in a -// FireSim simulation is to supply an additional clock parameter -// (RationalClock) to the clock bridge (RationalClockBridge). The bridge -// produces a vector of clocks, based on the provided parameter list, which you -// may use freely without further modifications to your target design. -case class FireSimClockParameters(additionalClocks: Seq[RationalClock]) { - def numClocks(): Int = additionalClocks.size + 1 -} -case object FireSimClockKey extends Field[FireSimClockParameters](FireSimClockParameters(Seq())) - // Hacky: Set before each node is generated. Ideally we'd give IO binders // accesses to the the Harness's parameters instance. We could then alter that. object NodeIdx { @@ -43,107 +34,114 @@ object NodeIdx { def apply(): Int = idx } + +/** + * Under FireSim's current multiclock implementation there can be only a + * single clock bridge. This requires, therefore, that it be instantiated in + * the harness and reused across all supernode instances. This class attempts to + * memoize its instantiation such that it can be referenced from within a ClockScheme function. + */ +class ClockBridgeInstantiator { + private var _clockRecord: Option[RecordMap[Clock]] = None + + def getClockRecord: RecordMap[Clock] = _clockRecord.get + + def getClockRecordOrInstantiate(allClocks: Seq[RationalClock], baseClockName: String): RecordMap[Clock] = { + if (_clockRecord.isEmpty) { + require(allClocks.exists(_.name == baseClockName), + s"Provided base-clock name, ${baseClockName}, does not match a defined clock. Available clocks:\n " + + allClocks.map(_.name).mkString("\n ")) + + val baseClock = allClocks.find(_.name == baseClockName).get + val simplified = allClocks.map { c => + c.copy(multiplier = c.multiplier * baseClock.divisor, divisor = c.divisor * baseClock.multiplier) + .simplify + } + + /** + * Removes clocks that have the same frequency before instantiating the + * clock bridge to avoid unnecessary BUFGCE use. + */ + val distinct = simplified.foldLeft(Seq(RationalClock(baseClockName, 1, 1))) { case (list, candidate) => + if (list.exists { clock => clock.equalFrequency(candidate) }) list else list :+ candidate + } + + val clockBridge = Module(new RationalClockBridge(distinct)) + val cbVecTuples = distinct.zip(clockBridge.io.clocks) + val outputWire = Wire(RecordMap(allClocks.map { c => (c.name, Clock()) }:_*)) + for (parameter <- allClocks) { + val (_, cbClockField) = cbVecTuples.find(_._1.equalFrequency(parameter)).get + outputWire(parameter.name).get := cbClockField + } + _clockRecord = Some(outputWire) + } + getClockRecord + } +} + +case object ClockBridgeInstantiatorKey extends Field[ClockBridgeInstantiator](new ClockBridgeInstantiator) +case object FireSimBaseClockNameKey extends Field[String]("implicit_clock") + class WithFireSimSimpleClocks extends Config((site, here, up) => { case ClockingSchemeKey => { chiptop: ChipTop => implicit val p = chiptop.p + // Figure out what provides this in the chipyard scheme + implicit val valName = ValName("FireSimClocking") - val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters())) - chiptop.implicitClockSinkNode := implicitClockSourceNode - - // Drive the diplomaticclock graph of the DigitalTop (if present) - val simpleClockGroupSourceNode = chiptop.lazySystem match { - case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { - val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) - l.asyncClockGroupsNode := n - Some(n) - } - case _ => None + // Requires existence of undriven asyncClockGroups in subsystem + val systemAsyncClockGroup = chiptop.lazySystem match { + case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => + l.asyncClockGroupsNode } + val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node + (chiptop.implicitClockSinkNode := ClockGroup() := aggregator) + (systemAsyncClockGroup := ClockGroupNamePrefixer() := aggregator) + + val inputClockSource = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) + + (aggregator + := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) + := inputClockSource) + + InModuleBody { - val clock = IO(Input(Clock())).suggestName("clock") + val (clockGroupBundle, clockGroupEdge) = inputClockSource.out.head + val input_clocks = IO(Input(RecordMap((clockGroupEdge.sink.members.map { m => (m.name.get, Clock()) }):_* ))) + .suggestName("clocks") val reset = IO(Input(Reset())).suggestName("reset") - implicitClockSourceNode.out.unzip._1.map { o => - o.clock := clock - o.reset := reset + (clockGroupBundle.member.data zip input_clocks.data).foreach { case (clockBundle, inputClock) => + clockBundle.clock := inputClock } - simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle => - out.member.data.foreach { o => - o.clock := clock - o.reset := reset + // Assign resets. The synchronization scheme is still WIP. + for ((name, clockBundle) <- clockGroupBundle.member.elements) { + if (name.contains("core")) { + clockBundle.reset := ResetCatchAndSync(clockBundle.clock, reset.asBool) + } else { + clockBundle.reset := reset } - }} + } + + val pllConfig = new SimplePllConfiguration(clockGroupEdge.sink.members) + pllConfig.prettyPrint("FireSim RationalClockBridge") + val rationalClockSpecs = for ((sinkP, division) <- pllConfig.sinkDividerMap) yield { + RationalClock(sinkP.name.get, 1, division) + } chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { - clock := th.harnessClock reset := th.harnessReset - Nil - }) - } - } -}) - -class WithFireSimRationalTileDomain(multiplier: Int, divisor: Int) extends Config((site, here, up) => { - case FireSimClockKey => FireSimClockParameters(Seq(RationalClock("TileDomain", multiplier, divisor))) - case ClockingSchemeKey => { chiptop: ChipTop => - implicit val p = chiptop.p - - val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters())) - chiptop.implicitClockSinkNode := implicitClockSourceNode - - // Drive the diplomaticclock graph of the DigitalTop (if present) - val simpleClockGroupSourceNode = chiptop.lazySystem match { - case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => { - val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) - l.asyncClockGroupsNode := n - Some(n) - } - case _ => None - } - - InModuleBody { - val uncore_clock = IO(Input(Clock())).suggestName("uncore_clock") - val tile_clock = IO(Input(Clock())).suggestName("tile_clock") - val reset = IO(Input(Reset())).suggestName("reset") - - implicitClockSourceNode.out.unzip._1.map { o => - o.clock := uncore_clock - o.reset := reset - } - - simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle => - out.member.elements.map { case (name, data) => - // This is mega hacks, how are you actually supposed to do this? - if (name.contains("core")) { - data.clock := tile_clock - data.reset := ResetCatchAndSync(tile_clock, reset.asBool) - } else { - data.clock := uncore_clock - data.reset := reset - } - } - }} - - chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { - uncore_clock := th.harnessClock - reset := th.harnessReset - th match { - case f: FireSim => tile_clock := f.additionalClocks(0) - case _ => throw new Exception("FireSimMultiClock must be used with FireSim") - } - Nil - }) + input_clocks := p(ClockBridgeInstantiatorKey) + .getClockRecordOrInstantiate(rationalClockSpecs.toSeq, p(FireSimBaseClockNameKey)) + Nil }) } } }) class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSignalReferences { freechips.rocketchip.util.property.cover.setPropLib(new midas.passes.FireSimPropertyLibrary()) - val clockBridge = Module(new RationalClockBridge(p(FireSimClockKey).additionalClocks:_*)) - val harnessClock = clockBridge.io.clocks.head // This is the reference clock - val additionalClocks = clockBridge.io.clocks.tail + val harnessClock = Wire(Clock()) val harnessReset = WireInit(false.B) val peekPokeBridge = PeekPokeBridge(harnessClock, harnessReset) def dutReset = { require(false, "dutReset should not be used in Firesim"); false.B } @@ -165,8 +163,7 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSigna d.harnessFunctions.foreach(_(this)) ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap) } - - NodeIdx.increment() } + harnessClock := p(ClockBridgeInstantiatorKey).getClockRecord("implicit_clock").get } diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 2dede960..fcacde8b 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -194,7 +194,7 @@ class FireSimArianeConfig extends Config( //* Multiclock Configurations //*********************************************************************************/ class FireSimMulticlockRocketConfig extends Config( - new WithFireSimRationalTileDomain(2, 1) ++ + new chipyard.config.WithTileFrequency(6400.0) ++ //lol new WithDefaultFireSimBridges ++ new WithDefaultMemModel ++ new WithFireSimConfigTweaks ++ diff --git a/sims/firesim b/sims/firesim index c1cd3e5e..4342b333 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit c1cd3e5e7013b30f30508c7f47ff13180949eafe +Subproject commit 4342b33301ae9b3f53b98ca3b1d1afff73d64997 From 1b3514f95f4eb58dc13b41093a3948f1ea0a27a0 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Fri, 25 Sep 2020 10:03:46 -0700 Subject: [PATCH 74/93] [clocks] Specify a default frequency for TraceGen --- generators/chipyard/src/main/scala/config/TracegenConfigs.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala index 78cb6851..f9980bf6 100644 --- a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala @@ -10,6 +10,7 @@ class AbstractTraceGenConfig extends Config( new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ + new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ new freechips.rocketchip.groundtest.GroundTestBaseConfig) From 67145c6ccd9edf7cf42592d6f50f7f115213e205 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Fri, 25 Sep 2020 10:05:28 -0700 Subject: [PATCH 75/93] [clocking] Fix FireSim clock look up --- generators/firechip/src/main/scala/FireSim.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index d72ec467..28daec52 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -68,8 +68,8 @@ class ClockBridgeInstantiator { val clockBridge = Module(new RationalClockBridge(distinct)) val cbVecTuples = distinct.zip(clockBridge.io.clocks) - val outputWire = Wire(RecordMap(allClocks.map { c => (c.name, Clock()) }:_*)) - for (parameter <- allClocks) { + val outputWire = Wire(RecordMap(simplified.map { c => (c.name, Clock()) }:_*)) + for (parameter <- simplified) { val (_, cbClockField) = cbVecTuples.find(_._1.equalFrequency(parameter)).get outputWire(parameter.name).get := cbClockField } From f7407709d2a51c5946e1b84e6420651de5cc5802 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 25 Sep 2020 21:31:12 -0700 Subject: [PATCH 76/93] Attempt to fix CI (2) --- .../chipyard/src/main/scala/config/SodorConfigs.scala | 6 ++++++ generators/testchipip | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/generators/chipyard/src/main/scala/config/SodorConfigs.scala b/generators/chipyard/src/main/scala/config/SodorConfigs.scala index eb7b4086..ea245fbc 100644 --- a/generators/chipyard/src/main/scala/config/SodorConfigs.scala +++ b/generators/chipyard/src/main/scala/config/SodorConfigs.scala @@ -7,6 +7,7 @@ import freechips.rocketchip.config.{Config} class Sodor1StageConfig extends Config( // Create a Sodor 1-stage core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage1Factory) ++ + new testchipip.WithSerialPBusMem ++ new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ @@ -15,6 +16,7 @@ class Sodor1StageConfig extends Config( class Sodor2StageConfig extends Config( // Create a Sodor 2-stage core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage2Factory) ++ + new testchipip.WithSerialPBusMem ++ new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ @@ -23,6 +25,7 @@ class Sodor2StageConfig extends Config( class Sodor3StageConfig extends Config( // Create a Sodor 1-stage core with two ports new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 2)) ++ + new testchipip.WithSerialPBusMem ++ new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ @@ -31,6 +34,7 @@ class Sodor3StageConfig extends Config( class Sodor3StageSinglePortConfig extends Config( // Create a Sodor 3-stage core with one ports (instruction and data memory access controlled by arbiter) new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 1)) ++ + new testchipip.WithSerialPBusMem ++ new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ @@ -39,6 +43,7 @@ class Sodor3StageSinglePortConfig extends Config( class Sodor5StageConfig extends Config( // Create a Sodor 5-stage core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage5Factory) ++ + new testchipip.WithSerialPBusMem ++ new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ @@ -47,6 +52,7 @@ class Sodor5StageConfig extends Config( class SodorUCodeConfig extends Config( // Construct a Sodor microcode-based single-bus core new sodor.common.WithNSodorCores(1, internalTile = sodor.common.UCodeFactory) ++ + new testchipip.WithSerialPBusMem ++ new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory new freechips.rocketchip.subsystem.WithNBanks(0) ++ diff --git a/generators/testchipip b/generators/testchipip index bdca33ec..bd0ff2d0 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit bdca33ec1684e6e00df2f5c9aebc0b41fb593585 +Subproject commit bd0ff2d0c61023549304709ce0d377a837564295 From a6ce85039142c9c1e6c14b4e4cabf10674b579d2 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Tue, 29 Sep 2020 16:06:48 -0700 Subject: [PATCH 77/93] [clocks] ClockDividerN: make first output edge occur on first input edge --- .../chipyard/src/main/resources/vsrc/ClockDividerN.sv | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv b/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv index 868b0eee..4d940d06 100644 --- a/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv +++ b/generators/chipyard/src/main/resources/vsrc/ClockDividerN.sv @@ -7,8 +7,10 @@ module ClockDividerN #(parameter DIV)(output logic clk_out = 1'b0, input clk_in); - localparam DIV_COUNTER_WIDTH = $clog2(DIV); + localparam CWIDTH = $clog2(DIV); localparam LOW_CYCLES = DIV / 2; + localparam HIGH_TRANSITION = LOW_CYCLES - 1; + localparam LOW_TRANSITION = DIV - 1; generate if (DIV == 1) begin @@ -17,19 +19,19 @@ module ClockDividerN #(parameter DIV)(output logic clk_out = 1'b0, input clk_in) clk_out = clk_in; end end else begin - reg [DIV_COUNTER_WIDTH - 1: 0] count = '0; + reg [CWIDTH - 1: 0] count = HIGH_TRANSITION[CWIDTH-1:0]; // The blocking assignment to clock out is used to conform what was done // in RC's clock dividers. // It should have the effect of preventing registers in the divided clock // domain latching register updates launched by the fast clock-domain edge // that occurs at the same simulated time (as the divided clock edge). always @(posedge clk_in) begin - if (count == (DIV - 1)) begin + if (count == LOW_TRANSITION[CWIDTH-1:0]) begin clk_out = 1'b0; count <= '0; end else begin - if (count == (LOW_CYCLES - 1)) begin + if (count == HIGH_TRANSITION[CWIDTH-1:0]) begin clk_out = 1'b1; end count <= count + 1'b1; From 5b414f58299b9f600e1220d77e2b0b92a7a47921 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Tue, 29 Sep 2020 16:59:37 -0700 Subject: [PATCH 78/93] [clocks] Emit frequency summary for divider-only PLL model --- .../src/main/scala/clocking/IdealizedPLL.scala | 17 +++++++++-------- .../firechip/src/main/scala/FireSim.scala | 3 +-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala index 5b99a17b..8dfc7908 100644 --- a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala +++ b/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala @@ -5,6 +5,7 @@ import chisel3._ import freechips.rocketchip.config.{Parameters} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.prci._ +import freechips.rocketchip.util.ElaborationArtefacts import scala.collection.mutable import scala.collection.immutable.ListMap @@ -25,21 +26,22 @@ object FrequencyUtils { } } -class SimplePllConfiguration(val sinks: Seq[ClockSinkParameters]) { +class SimplePllConfiguration(pllName: String, val sinks: Seq[ClockSinkParameters]) { val referenceFreqMHz = FrequencyUtils.computeReferenceFrequencyMHz(sinks.flatMap(_.take)).freqMHz val sinkDividerMap = ListMap((sinks.map({s => (s, Math.round(referenceFreqMHz / s.take.get.freqMHz).toInt) })):_*) - def prettyPrint(pllName: String) { - val preamble = s""" + private val preamble = s""" |${pllName} Frequency Summary | Input Reference Frequency: ${referenceFreqMHz} MHz\n""".stripMargin - val outputSummaries = sinkDividerMap.map { case (sink, division) => + private val outputSummaries = sinkDividerMap.map { case (sink, division) => val requested = sink.take.get.freqMHz val actual = referenceFreqMHz / division.toDouble s" Output clock ${sink.name.get}, requested: ${requested} MHz, actual: ${actual} MHz (division of ${division})" } - println(preamble + outputSummaries.mkString("\n")) - } + + val summaryString = preamble + outputSummaries.mkString("\n") + ElaborationArtefacts.add(s"${pllName}.freq-summary", summaryString) + println(summaryString) } case class IdealizedPLLNode(pllName: String)(implicit valName: ValName) @@ -71,8 +73,7 @@ class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) ex val (outClocks, ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head val referenceFreq = refSinkParam.take.get.freqMHz - val pllConfig = new SimplePllConfiguration(outSinkParams.members) - pllConfig.prettyPrint(pllName) + val pllConfig = new SimplePllConfiguration(pllName, outSinkParams.members) val dividedClocks = mutable.HashMap[Int, Clock]() def instantiateDivider(div: Int): Clock = { diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index 28daec52..90fd473a 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -124,8 +124,7 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => { } } - val pllConfig = new SimplePllConfiguration(clockGroupEdge.sink.members) - pllConfig.prettyPrint("FireSim RationalClockBridge") + val pllConfig = new SimplePllConfiguration("FireSim RationalClockBridge", clockGroupEdge.sink.members) val rationalClockSpecs = for ((sinkP, division) <- pllConfig.sinkDividerMap) yield { RationalClock(sinkP.name.get, 1, division) } From ebfe3103a45d2b7b4e62609baa083fb4a20647a7 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Tue, 29 Sep 2020 17:33:49 -0700 Subject: [PATCH 79/93] [clocks] IdealizedPll -> DividerOnlyClockGenerator --- generators/chipyard/src/main/scala/Clocks.scala | 12 ++++++------ ...PLL.scala => DividerOnlyClockGenerator.scala} | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) rename generators/chipyard/src/main/scala/clocking/{IdealizedPLL.scala => DividerOnlyClockGenerator.scala} (87%) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index b54d5c42..554e9905 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -12,7 +12,7 @@ import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider} import barstools.iocell.chisel._ -import chipyard.clocking.{IdealizedPLL, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} +import chipyard.clocking.{DividerOnlyClockGenerator, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} /** * Chipyard provides three baseline, top-level reset schemes, set using the @@ -79,12 +79,12 @@ object GenerateReset { } -case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGenerators.idealizedPLL) -/** +case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGenerators.dividerOnlyClockGenerator) +/* * This is a Seq of assignment functions, that accept a clock name and return an optional frequency. * Functions that appear later in this seq have higher precedence that earlier ones. * If no function returns a non-empty value, the value specified in - * [[DefaultClockFrequencyKey]] will be used -- DFU. + * [[DefaultClockFrequencyKey]] will be used. */ case object ClockFrequencyAssignersKey extends Field[Seq[(String) => Option[Double]]](Seq.empty) case object DefaultClockFrequencyKey extends Field[Double]() @@ -100,7 +100,7 @@ class ClockNameContainsAssignment(name: String, fMHz: Double) extends Config((si }) object ClockingSchemeGenerators { - val idealizedPLL: ChipTop => Unit = { chiptop => + val dividerOnlyClockGenerator: ChipTop => Unit = { chiptop => implicit val p = chiptop.p // Requires existence of undriven asyncClockGroups in subsystem @@ -116,7 +116,7 @@ object ClockingSchemeGenerators { val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) (aggregator := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) - := IdealizedPLL() + := DividerOnlyClockGenerator() := referenceClockSource) diff --git a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala b/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala similarity index 87% rename from generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala rename to generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala index 8dfc7908..4355fc71 100644 --- a/generators/chipyard/src/main/scala/clocking/IdealizedPLL.scala +++ b/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala @@ -26,12 +26,12 @@ object FrequencyUtils { } } -class SimplePllConfiguration(pllName: String, val sinks: Seq[ClockSinkParameters]) { +class SimplePllConfiguration(name: String, val sinks: Seq[ClockSinkParameters]) { val referenceFreqMHz = FrequencyUtils.computeReferenceFrequencyMHz(sinks.flatMap(_.take)).freqMHz val sinkDividerMap = ListMap((sinks.map({s => (s, Math.round(referenceFreqMHz / s.take.get.freqMHz).toInt) })):_*) private val preamble = s""" - |${pllName} Frequency Summary + |${name} Frequency Summary | Input Reference Frequency: ${referenceFreqMHz} MHz\n""".stripMargin private val outputSummaries = sinkDividerMap.map { case (sink, division) => val requested = sink.take.get.freqMHz @@ -40,11 +40,11 @@ class SimplePllConfiguration(pllName: String, val sinks: Seq[ClockSinkParameters } val summaryString = preamble + outputSummaries.mkString("\n") - ElaborationArtefacts.add(s"${pllName}.freq-summary", summaryString) + ElaborationArtefacts.add(s"${name}.freq-summary", summaryString) println(summaryString) } -case class IdealizedPLLNode(pllName: String)(implicit valName: ValName) +case class DividerOnlyClockGeneratorNode(pllName: String)(implicit valName: ValName) extends MixedNexusNode(ClockImp, ClockGroupImp)( dFn = { _ => ClockGroupSourceParameters() }, uFn = { u => @@ -64,8 +64,8 @@ case class IdealizedPLLNode(pllName: String)(implicit valName: ValName) * frequency. */ -class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) extends LazyModule { - val node = IdealizedPLLNode(pllName) +class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName: ValName) extends LazyModule { + val node = DividerOnlyClockGeneratorNode(pllName) lazy val module = new LazyRawModuleImp(this) { require(node.out.size == 1, "Idealized PLL expects to generate a single output clock group. Use a ClockGroupAggregator") @@ -92,6 +92,6 @@ class IdealizedPLL(pllName: String)(implicit p: Parameters, valName: ValName) ex } } -object IdealizedPLL { - def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new IdealizedPLL(valName.name)).node +object DividerOnlyClockGenerator { + def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new DividerOnlyClockGenerator(valName.name)).node } From ef03a5efe0a652ff7fd19ff8b18e9661a12b8fcc Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 30 Sep 2020 14:36:45 -0700 Subject: [PATCH 80/93] Bump testchipip --- generators/testchipip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/testchipip b/generators/testchipip index bd0ff2d0..10351d36 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit bd0ff2d0c61023549304709ce0d377a837564295 +Subproject commit 10351d36a961d89e6f5ac1177dff0e9f3efb8c0f From 7d7f7ae4a83f0177a16d8dd0e6aba42d91b3cebd Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Wed, 30 Sep 2020 14:43:29 -0700 Subject: [PATCH 81/93] Bump FireSim --- sims/firesim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sims/firesim b/sims/firesim index 54ffa13d..801baeb9 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 54ffa13d980609549be47222a284521b73e56188 +Subproject commit 801baeb901c207beb0511311e09ae10e0dbb8b5f From 2f5790d6111913462006fa7b06e9c42f4663c972 Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Wed, 30 Sep 2020 12:04:22 -0700 Subject: [PATCH 82/93] Add model multi-threading annotations (ignored by default) to FireChip --- .../firechip/src/main/scala/BridgeBinders.scala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 653f8026..5a0b4837 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -18,7 +18,7 @@ import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvon import junctions.{NastiKey, NastiParameters} import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig} -import midas.targetutils.{MemModelAnnotation} +import midas.targetutils.{FAMEModelAnnotation, MemModelAnnotation, EnableModelMultiThreadingAnnotation} import firesim.bridges._ import firesim.configs.MemModelKey import tracegen.{TraceGenSystemModuleImp} @@ -156,6 +156,20 @@ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ } }) +class WithFireSimFAME5 extends ComposeIOBinder({ + (system: HasTilesModuleImp) => { + system.outer.tiles.map { + case b: BoomTile => + annotate(FAMEModelAnnotation(b.module)) + annotate(EnableModelMultiThreadingAnnotation(b.module)) + case r: RocketTile => + annotate(FAMEModelAnnotation(r.module)) + annotate(EnableModelMultiThreadingAnnotation(r.module)) + } + (Nil, Nil) + } +}) + // Shorthand to register all of the provided bridges above class WithDefaultFireSimBridges extends Config( new WithSerialBridge ++ @@ -164,6 +178,7 @@ class WithDefaultFireSimBridges extends Config( new WithBlockDeviceBridge ++ new WithFASEDBridge ++ new WithFireSimMultiCycleRegfile ++ + new WithFireSimFAME5 ++ new WithTracerVBridge ++ new WithFireSimIOCellModels ) From 6c33672c664b7990cd443f27d93c977c55817c01 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 1 Oct 2020 10:08:39 -0700 Subject: [PATCH 83/93] Bump Sodor submodule after merge --- generators/riscv-sodor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/riscv-sodor b/generators/riscv-sodor index b36ce1a7..d92a8476 160000 --- a/generators/riscv-sodor +++ b/generators/riscv-sodor @@ -1 +1 @@ -Subproject commit b36ce1a7958a748c90508be6822a05c8208cd184 +Subproject commit d92a8476e4afbae189381d708136aef7d3970952 From 93a06cc5e7ceeb888cb32f6e3efd0418083f6d38 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 1 Oct 2020 10:11:04 -0700 Subject: [PATCH 84/93] Fix CI master check --- .circleci/check-commit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/check-commit.sh b/.circleci/check-commit.sh index 2d393aae..68cc975c 100755 --- a/.circleci/check-commit.sh +++ b/.circleci/check-commit.sh @@ -48,7 +48,7 @@ search () { done } -submodules=("ariane" "boom" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip" "sodor") +submodules=("ariane" "boom" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip" "riscv-sodor") dir="generators" if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ] then From 489ae695fc8427b7dca264916ce6844f81d59e11 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 1 Oct 2020 10:19:43 -0700 Subject: [PATCH 85/93] Add tile-resetter to all designs --- .../chipyard/src/main/scala/Clocks.scala | 18 +++++++++++++++--- generators/testchipip | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 554e9905..8dfb9ac6 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -5,12 +5,13 @@ import chisel3._ import scala.collection.mutable.{ArrayBuffer} import freechips.rocketchip.prci._ -import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey} +import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey, InstantiatesTiles} import freechips.rocketchip.config.{Parameters, Field, Config} import freechips.rocketchip.diplomacy.{OutwardNodeHandle, InModuleBody, LazyModule} import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider} import barstools.iocell.chisel._ +import testchipip.{TLTileResetCtrl} import chipyard.clocking.{DividerOnlyClockGenerator, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier} @@ -109,9 +110,20 @@ object ClockingSchemeGenerators { l.asyncClockGroupsNode } + // Add a control register for each tile's reset + val resetSetter = chiptop.lazySystem match { + case sys: BaseSubsystem with InstantiatesTiles => TLTileResetCtrl(sys) + case _ => ClockGroupEphemeralNode() + } + val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node - chiptop.implicitClockSinkNode := ClockGroup() := aggregator - systemAsyncClockGroup := ClockGroupNamePrefixer() := aggregator + (chiptop.implicitClockSinkNode + := ClockGroup() + := aggregator) + (systemAsyncClockGroup + := resetSetter + := ClockGroupNamePrefixer() + := aggregator) val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) (aggregator diff --git a/generators/testchipip b/generators/testchipip index bdca33ec..89b528de 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit bdca33ec1684e6e00df2f5c9aebc0b41fb593585 +Subproject commit 89b528decffa8fd33f21dd7a6feabb639274f99a From 164617e2d64c716643dfff5925c450c502e9609f Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 1 Oct 2020 10:20:10 -0700 Subject: [PATCH 86/93] Fix no-mbus example design --- generators/chipyard/src/main/scala/config/RocketConfigs.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 11399a62..ab0e16ec 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -117,6 +117,7 @@ class LoopbackNICRocketConfig extends Config( // DOC include start: l1scratchpadrocket class ScratchpadOnlyRocketConfig extends Config( + new testchipip.WithSerialPBusMem ++ new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNoMemPort ++ From 79042e4ce86302a7335ab49e9c703a181a237bef Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 1 Oct 2020 10:21:43 -0700 Subject: [PATCH 87/93] Bump to support firesim simulation of no-AXI4DRAM designs --- generators/firechip/src/main/scala/BridgeBinders.scala | 9 +++++---- sims/firesim | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 653f8026..1f8bb418 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebugModuleImp} import freechips.rocketchip.amba.axi4.{AXI4Bundle} -import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPort, HasExtInterruptsModuleImp, BaseSubsystem, HasTilesModuleImp} +import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPort, HasExtInterruptsModuleImp, BaseSubsystem, HasTilesModuleImp, ExtMem} import freechips.rocketchip.tile.{RocketTile} import sifive.blocks.devices.uart._ @@ -67,9 +67,10 @@ class WithFireSimIOCellModels extends Config((site, here, up) => { class WithSerialBridge extends OverrideHarnessBinder({ (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { - ports.map { p => - val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, p, th.harnessReset) - SerialBridge(p.clock, ram.module.io.tsi_ser, MainMemoryConsts.globalName)(GetSystemParameters(system)) + ports.map { port => + implicit val p = GetSystemParameters(system) + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) + SerialBridge(port.clock, ram.module.io.tsi_ser, p(ExtMem).map(_ => MainMemoryConsts.globalName)) } Nil } diff --git a/sims/firesim b/sims/firesim index 801baeb9..ef615d35 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 801baeb901c207beb0511311e09ae10e0dbb8b5f +Subproject commit ef615d35da118e73f5128d373f17b80884100773 From 3d0022667a905321e4d0af8dc0f1b5672d330e10 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 1 Oct 2020 22:43:43 -0700 Subject: [PATCH 88/93] Bump testchipip --- generators/testchipip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/testchipip b/generators/testchipip index 89b528de..b3aa1bea 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 89b528decffa8fd33f21dd7a6feabb639274f99a +Subproject commit b3aa1bea536ee96a1e69796d35f7651a314c2f6a From 399b909dec01e32d6c122a626bebabf8c775bf54 Mon Sep 17 00:00:00 2001 From: Nathan Pemberton Date: Wed, 7 Oct 2020 20:50:26 -0400 Subject: [PATCH 89/93] Bump firemarshal to v1.10.0 --- software/firemarshal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/software/firemarshal b/software/firemarshal index 83b86610..45aebace 160000 --- a/software/firemarshal +++ b/software/firemarshal @@ -1 +1 @@ -Subproject commit 83b866104c6860b5d03989a6cf8439aa6934b398 +Subproject commit 45aebace86d3a46c357337a19d4c8e894a5d0ed4 From d71c3b6357597da5aca589ee0dda1b7e5f4fe79a Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 2 Oct 2020 11:22:55 -0700 Subject: [PATCH 90/93] Unify htif implementation with firesim --- generators/testchipip | 2 +- sims/firesim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generators/testchipip b/generators/testchipip index b3aa1bea..9cf31ace 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit b3aa1bea536ee96a1e69796d35f7651a314c2f6a +Subproject commit 9cf31acea528543896f04457573454a3e51f1e6a diff --git a/sims/firesim b/sims/firesim index ef615d35..dd20a99f 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit ef615d35da118e73f5128d373f17b80884100773 +Subproject commit dd20a99f33eba31ffa2d6c7e9fc914445224d4e9 From 25129c27ca20870518161228723e6d55fb31f9de Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 2 Oct 2020 13:07:42 -0700 Subject: [PATCH 91/93] Add testchip_fesvr to uncondtionally used resources --- generators/utilities/src/main/scala/Simulator.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generators/utilities/src/main/scala/Simulator.scala b/generators/utilities/src/main/scala/Simulator.scala index b2982db7..02224fdb 100644 --- a/generators/utilities/src/main/scala/Simulator.scala +++ b/generators/utilities/src/main/scala/Simulator.scala @@ -83,6 +83,8 @@ object GenerateSimFiles extends App with HasGenerateSimConfig { } def resources(sim: Simulator): Seq[String] = Seq( "/testchipip/csrc/SimSerial.cc", + "/testchipip/csrc/testchip_fesvr.cc", + "/testchipip/csrc/testchip_fesvr.h", "/testchipip/csrc/SimDRAM.cc", "/testchipip/csrc/mm.h", "/testchipip/csrc/mm.cc", From 0c46ed167633ebe948ac746f9e0eccd9ab69b361 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 9 Oct 2020 09:34:20 -0700 Subject: [PATCH 92/93] Rename testchip_fesvr to testchip_tsi --- generators/testchipip | 2 +- generators/utilities/src/main/scala/Simulator.scala | 4 ++-- sims/firesim | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generators/testchipip b/generators/testchipip index 9cf31ace..56bfaa3f 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 9cf31acea528543896f04457573454a3e51f1e6a +Subproject commit 56bfaa3f9bcd11206d93fdfa3c8e7656665e462a diff --git a/generators/utilities/src/main/scala/Simulator.scala b/generators/utilities/src/main/scala/Simulator.scala index 02224fdb..f40ad032 100644 --- a/generators/utilities/src/main/scala/Simulator.scala +++ b/generators/utilities/src/main/scala/Simulator.scala @@ -83,8 +83,8 @@ object GenerateSimFiles extends App with HasGenerateSimConfig { } def resources(sim: Simulator): Seq[String] = Seq( "/testchipip/csrc/SimSerial.cc", - "/testchipip/csrc/testchip_fesvr.cc", - "/testchipip/csrc/testchip_fesvr.h", + "/testchipip/csrc/testchip_tsi.cc", + "/testchipip/csrc/testchip_tsi.h", "/testchipip/csrc/SimDRAM.cc", "/testchipip/csrc/mm.h", "/testchipip/csrc/mm.cc", diff --git a/sims/firesim b/sims/firesim index dd20a99f..6318184f 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit dd20a99f33eba31ffa2d6c7e9fc914445224d4e9 +Subproject commit 6318184f304315a94b5eb5c670f0eec1a3205f59 From 9c298eedfe539e05aa409d4b60595f5a0ab2ada1 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 13 Oct 2020 15:10:41 -0700 Subject: [PATCH 93/93] Support evaluation of HarnessBinders in LazyModule context --- .../src/main/scala/HarnessBinders.scala | 75 ++++++++++--------- .../chipyard/src/main/scala/IOBinders.scala | 46 +++++------- .../chipyard/src/main/scala/TestHarness.scala | 2 +- .../src/main/scala/BridgeBinders.scala | 16 ++-- 4 files changed, 66 insertions(+), 73 deletions(-) diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index e5cfacfb..6f7d2dd8 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -1,7 +1,7 @@ package chipyard.harness import chisel3._ -import chisel3.experimental.{Analog} +import chisel3.experimental.{Analog, BaseModule} import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} @@ -33,40 +33,41 @@ case object HarnessBinders extends Field[Map[String, (Any, HasHarnessSignalRefer object ApplyHarnessBinders { - def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = { + def apply(th: HasHarnessSignalReferences, sys: LazyModule, portMap: Map[String, Seq[Data]])(implicit p: Parameters) = { val pm = portMap.withDefaultValue(Nil) - map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) } + p(HarnessBinders).map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) } } } -class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => { +class HarnessBinder[T, S <: HasHarnessSignalReferences, U <: Data](composer: ((T, S, Seq[U]) => Seq[Any]) => (T, S, Seq[U]) => Seq[Any])(implicit tag: ClassTag[T], thtag: ClassTag[S], ptag: ClassTag[U]) extends Config((site, here, up) => { case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val pts = ports.collect({case p: S => p}) + val pts = ports.collect({case p: U => p}) require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}") - t match { - case system: T => fn(system, th, pts) + val upfn = up(HarnessBinders, site)(tag.runtimeClass.toString) + th match { + case th: S => + t match { + case system: T => composer(upfn)(system, th, pts) + case _ => Nil + } case _ => Nil } }) ) }) -class ComposeHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => { - case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> - ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { - val pts = ports.collect({case p: S => p}) - require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}") - t match { - case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, pts) ++ fn(system, th, pts) - case _ => Nil - } - }) - ) -}) +class OverrideHarnessBinder[T, S <: HasHarnessSignalReferences, U <: Data](fn: => (T, S, Seq[U]) => Seq[Any]) + (implicit tag: ClassTag[T], thtag: ClassTag[S], ptag: ClassTag[U]) + extends HarnessBinder[T, S, U]((upfn: (T, S, Seq[U]) => Seq[Any]) => fn) + +class ComposeHarnessBinder[T, S <: HasHarnessSignalReferences, U <: Data](fn: => (T, S, Seq[U]) => Seq[Any]) + (implicit tag: ClassTag[T], thtag: ClassTag[S], ptag: ClassTag[U]) + extends HarnessBinder[T, S, U]((upfn: (T, S, Seq[U]) => Seq[Any]) => (t, th, p) => upfn(t, th, p) ++ fn(t, th, p)) + class WithGPIOTiedOff extends OverrideHarnessBinder({ - (system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Analog]) => { + (system: HasPeripheryGPIOModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Analog]) => { ports.foreach { _ <> AnalogConst(0) } Nil } @@ -74,7 +75,7 @@ class WithGPIOTiedOff extends OverrideHarnessBinder({ // DOC include start: WithUARTAdapter class WithUARTAdapter extends OverrideHarnessBinder({ - (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => { + (system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => { UARTAdapter.connect(ports)(system.p) Nil } @@ -82,14 +83,14 @@ class WithUARTAdapter extends OverrideHarnessBinder({ // DOC include end: WithUARTAdapter class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({ - (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => { + (system: HasPeripherySPIFlashModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => { SimSPIFlashModel.connect(ports, th.harnessReset, rdOnly)(system.p) Nil } }) class WithSimBlockDevice extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + (system: CanHavePeripheryBlockDevice, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { implicit val p: Parameters = GetSystemParameters(system) ports.map { b => SimBlockDevice.connect(b.clock, th.harnessReset.asBool, Some(b.bits)) } Nil @@ -97,7 +98,7 @@ class WithSimBlockDevice extends OverrideHarnessBinder({ }) class WithBlockDeviceModel extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + (system: CanHavePeripheryBlockDevice, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { implicit val p: Parameters = GetSystemParameters(system) ports.map { b => withClockAndReset(b.clock, th.harnessReset) { BlockDeviceModel.connect(Some(b.bits)) } } Nil @@ -105,7 +106,7 @@ class WithBlockDeviceModel extends OverrideHarnessBinder({ }) class WithLoopbackNIC extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + (system: CanHavePeripheryIceNIC, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { implicit val p: Parameters = GetSystemParameters(system) ports.map { n => withClockAndReset(n.clock, th.harnessReset) { @@ -117,7 +118,7 @@ class WithLoopbackNIC extends OverrideHarnessBinder({ }) class WithSimNetwork extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + (system: CanHavePeripheryIceNIC, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { implicit val p: Parameters = GetSystemParameters(system) ports.map { n => SimNetwork.connect(Some(n.bits), n.clock, th.harnessReset.asBool) } Nil @@ -125,7 +126,7 @@ class WithSimNetwork extends OverrideHarnessBinder({ }) class WithSimAXIMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MemPort, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) (ports zip system.memAXI4Node.edges.in).map { case (port, edge) => val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p)) @@ -139,7 +140,7 @@ class WithSimAXIMem extends OverrideHarnessBinder({ }) class WithBlackBoxSimMem extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MemPort, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) (ports zip system.memAXI4Node.edges.in).map { case (port, edge) => val memSize = p(ExtMem).get.master.size @@ -154,7 +155,7 @@ class WithBlackBoxSimMem extends OverrideHarnessBinder({ }) class WithSimAXIMMIO extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MMIOPort, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) (ports zip system.mmioAXI4Node.edges.in).map { case (port, edge) => val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p)) @@ -168,21 +169,21 @@ class WithSimAXIMMIO extends OverrideHarnessBinder({ }) class WithTieOffInterrupts extends OverrideHarnessBinder({ - (system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[UInt]) => { + (system: HasExtInterruptsModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[UInt]) => { ports.foreach { _ := 0.U } Nil } }) class WithTieOffL2FBusAXI extends OverrideHarnessBinder({ - (system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveSlaveAXI4Port, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { ports.foreach({ p => p := DontCare; p.bits.tieoff() }) Nil } }) class WithSimDebug extends OverrideHarnessBinder({ - (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + (system: HasPeripheryDebugModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Data]) => { ports.map { case d: ClockedDMIIO => val dtm_success = WireInit(false.B) @@ -198,7 +199,7 @@ class WithSimDebug extends OverrideHarnessBinder({ }) class WithTiedOffDebug extends OverrideHarnessBinder({ - (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { + (system: HasPeripheryDebugModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Data]) => { ports.map { case j: JTAGIO => j.TCK := true.B.asClock @@ -224,7 +225,7 @@ class WithTiedOffDebug extends OverrideHarnessBinder({ class WithSerialAdapterTiedOff extends OverrideHarnessBinder({ - (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + (system: CanHavePeripheryTLSerial, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { implicit val p = chipyard.iobinders.GetSystemParameters(system) ports.map({ port => val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) @@ -234,7 +235,7 @@ class WithSerialAdapterTiedOff extends OverrideHarnessBinder({ }) class WithSimSerial extends OverrideHarnessBinder({ - (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + (system: CanHavePeripheryTLSerial, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { implicit val p = chipyard.iobinders.GetSystemParameters(system) ports.map({ port => val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) @@ -245,14 +246,14 @@ class WithSimSerial extends OverrideHarnessBinder({ }) class WithTraceGenSuccess extends OverrideHarnessBinder({ - (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => { + (system: TraceGenSystemModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Bool]) => { ports.map { p => when (p) { th.success := true.B } } Nil } }) class WithSimDromajoBridge extends ComposeHarnessBinder({ - (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => { + (system: CanHaveTraceIOModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => { ports.map { p => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } Nil } diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 4a31e2c0..5259cbb1 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -72,41 +72,33 @@ object GetSystemParameters { } } -class IOBinder(f: (View, View, View) => PartialFunction[Any, Any]) extends Config(f) +class IOBinder[T, S <: Data](composer: (Any => (Seq[Data], Seq[IOCell])) => T => (Seq[Data], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { + case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> + ((t: Any) => { + val upfn = up(IOBinders, site)(tag.runtimeClass.toString) + t match { + case system: T => composer(upfn)(system) + case _ => (Nil, Nil) + } + }) + ) +}) + // This macro overrides previous matches on some Top mixin. This is useful for // binders which drive IO, since those typically cannot be composed -class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => { - case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> - ((t: Any) => { - t match { - case system: T => - val (ports, cells) = fn(system) - (ports, cells) - case _ => (Nil, Nil) - } - }) - ) -}) +class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder[T, S](upfn => fn) + // This macro composes with previous matches on some Top mixin. This is useful for // annotation-like binders, since those can typically be composed -class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => { - case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> - ((t: Any) => { - t match { - case system: T => - val r = up(IOBinders, site)(tag.runtimeClass.toString)(system) - val h = fn(system) - val ports = r._1 ++ h._1 - val cells = r._2 ++ h._2 - (ports, cells) - case _ => (Nil, Nil) - } - }) - ) +class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder[T, S](upfn => t => { + val r = upfn(t) + val h = fn(t) + (r._1 ++ h._1, r._2 ++ h._2) }) + object BoreHelper { def apply(name: String, source: Clock): Clock = { val clock_io = IO(Output(Clock())).suggestName(name) diff --git a/generators/chipyard/src/main/scala/TestHarness.scala b/generators/chipyard/src/main/scala/TestHarness.scala index 2faff565..64b889e3 100644 --- a/generators/chipyard/src/main/scala/TestHarness.scala +++ b/generators/chipyard/src/main/scala/TestHarness.scala @@ -44,7 +44,7 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign lazyDut match { case d: HasTestHarnessFunctions => d.harnessFunctions.foreach(_(this)) - ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap) + ApplyHarnessBinders(this, d.lazySystem, d.portMap.toMap) } } diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 444c7b33..2fa49fc3 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -66,7 +66,7 @@ class WithFireSimIOCellModels extends Config((site, here, up) => { }) class WithSerialBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + (system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedIO[SerialIO]]) => { ports.map { port => implicit val p = GetSystemParameters(system) val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) @@ -77,7 +77,7 @@ class WithSerialBridge extends OverrideHarnessBinder({ }) class WithNICBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { + (system: CanHavePeripheryIceNIC, th: FireSim, ports: Seq[ClockedIO[NICIOvonly]]) => { val p: Parameters = GetSystemParameters(system) ports.map { n => NICBridge(n.clock, n.bits)(p) } Nil @@ -85,12 +85,12 @@ class WithNICBridge extends OverrideHarnessBinder({ }) class WithUARTBridge extends OverrideHarnessBinder({ - (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => + (system: HasPeripheryUARTModuleImp, th: FireSim, ports: Seq[UARTPortIO]) => ports.map { p => UARTBridge(th.harnessClock, p)(system.p) }; Nil }) class WithBlockDeviceBridge extends OverrideHarnessBinder({ - (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { + (system: CanHavePeripheryBlockDevice, th: FireSim, ports: Seq[ClockedIO[BlockDeviceIO]]) => { implicit val p: Parameters = GetSystemParameters(system) ports.map { b => BlockDevBridge(b.clock, b.bits, th.harnessReset.toBool) } Nil @@ -98,7 +98,7 @@ class WithBlockDeviceBridge extends OverrideHarnessBinder({ }) class WithFASEDBridge extends OverrideHarnessBinder({ - (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => { + (system: CanHaveMasterAXI4MemPort, th: FireSim, ports: Seq[ClockedIO[AXI4Bundle]]) => { implicit val p: Parameters = GetSystemParameters(system) (ports zip system.memAXI4Node.edges.in).map { case (axi4, edge) => val nastiKey = NastiParameters(axi4.bits.r.bits.data.getWidth, @@ -118,20 +118,20 @@ class WithFASEDBridge extends OverrideHarnessBinder({ }) class WithTracerVBridge extends ComposeHarnessBinder({ - (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => { + (system: CanHaveTraceIOModuleImp, th: FireSim, ports: Seq[TraceOutputTop]) => { ports.map { p => p.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p)) } Nil } }) class WithDromajoBridge extends ComposeHarnessBinder({ - (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => + (system: CanHaveTraceIOModuleImp, th: FireSim, ports: Seq[TraceOutputTop]) => ports.map { p => p.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p)) }; Nil }) class WithTraceGenBridge extends OverrideHarnessBinder({ - (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => + (system: TraceGenSystemModuleImp, th: FireSim, ports: Seq[Bool]) => ports.map { p => GroundTestBridge(th.harnessClock, p)(system.p) }; Nil })