From 27b78f4de21d390cbe6deb24cc2743a63b4a10ca Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 27 Aug 2020 23:48:01 -0700 Subject: [PATCH 1/7] Only punch realistic subset of DebugIO through chiptop --- .../chipyard/src/main/scala/IOBinders.scala | 135 ++++++++++++------ 1 file changed, 92 insertions(+), 43 deletions(-) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 6438801ac4..1c81f53527 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")) - - 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")) - - psdPort.suggestName("psd") - (psdPort, resetctrlPortOpt, debugPortOpt, psdIOs ++ debugIOs ++ resetctrlIOs) + def debug(system: HasPeripheryDebugModuleImp)(implicit p: Parameters): (Seq[Bundle], Seq[IOCell]) = { + system.debug.map { debug => + + // 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.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 2/7] 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 a1ff6b03f7..aa332c6a9a 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 f1370d0543..e116930c7d 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 8d860c1906..acd953afd2 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 7c82a7b9d5..cbb15587dc 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 249796cec9..19bfdab48c 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 3/7] 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 88a20f248d..eac8504a36 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 7cb8c1e272..7ffb1d3c31 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 08b95e682c..3e7b0285de 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 4/7] 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 1c81f53527..7f4daea374 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 c8448cc3e105c38eac54d1fc78545b8897cbad44 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sun, 30 Aug 2020 18:10:52 -0700 Subject: [PATCH 5/7] 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 7f4daea374..f13a6882cb 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 4b304623208b4c0b55f4c2f0f280f2c30011acf4 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 2 Sep 2020 20:19:27 -0700 Subject: [PATCH 6/7] 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 e36805ecd1..84bfc5fb44 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 6336c05aae..cfa465e72f 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 f13a6882cb..54a0d1dc72 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 2b9473ed6a..a925ec56c9 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 7bc985aacd..6bc7cf6952 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 070336093f..420ba192d7 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 8872ed5e8b..d501b6c0a8 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 3258fd8db8021407d24abb37f303e1d2a3dd34d6 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 3 Sep 2020 23:53:51 -0700 Subject: [PATCH 7/7] 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 84bfc5fb44..8d63992a83 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 66a20bce3a..0d8cd367a1 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 ) /*******************************************************************************