From a5597fd32f57553f7a87710433c319e3ebcb77fe Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 25 Oct 2023 11:49:16 -0700 Subject: [PATCH] Support using HarnessBinders without IOBinders --- fpga/src/main/scala/arty/TestHarness.scala | 1 - fpga/src/main/scala/arty100t/Harness.scala | 1 - fpga/src/main/scala/nexysvideo/Harness.scala | 1 - fpga/src/main/scala/vc707/TestHarness.scala | 1 - fpga/src/main/scala/vcu118/TestHarness.scala | 1 - .../src/main/scala/config/ChipConfigs.scala | 4 +++ .../src/main/scala/example/FlatChipTop.scala | 26 ++++++++++++++++--- .../main/scala/harness/HarnessClocks.scala | 1 - .../harness/HasHarnessInstantiators.scala | 4 +-- .../scala/harness/MultiHarnessBinders.scala | 6 ++--- .../src/main/scala/harness/TestHarness.scala | 1 - .../src/main/scala/iobinders/IOBinders.scala | 4 ++- .../src/main/scala/iobinders/Ports.scala | 4 +++ 13 files changed, 38 insertions(+), 17 deletions(-) diff --git a/fpga/src/main/scala/arty/TestHarness.scala b/fpga/src/main/scala/arty/TestHarness.scala index 2d524fe3..0a81740a 100644 --- a/fpga/src/main/scala/arty/TestHarness.scala +++ b/fpga/src/main/scala/arty/TestHarness.scala @@ -9,7 +9,6 @@ import org.chipsalliance.cde.config.{Parameters} import sifive.fpgashells.shell.xilinx.artyshell.{ArtyShell} import chipyard.harness.{HasHarnessInstantiators} -import chipyard.iobinders.{HasIOBinders} class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell with HasHarnessInstantiators { // Convert harness resets from Bool to Reset type. diff --git a/fpga/src/main/scala/arty100t/Harness.scala b/fpga/src/main/scala/arty100t/Harness.scala index 47ffe7e0..a535e65f 100644 --- a/fpga/src/main/scala/arty100t/Harness.scala +++ b/fpga/src/main/scala/arty100t/Harness.scala @@ -17,7 +17,6 @@ import sifive.blocks.devices.uart._ import chipyard._ import chipyard.harness._ -import chipyard.iobinders.{HasIOBinders} class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell { def dp = designParameters diff --git a/fpga/src/main/scala/nexysvideo/Harness.scala b/fpga/src/main/scala/nexysvideo/Harness.scala index 0cfb7110..a68cf24e 100644 --- a/fpga/src/main/scala/nexysvideo/Harness.scala +++ b/fpga/src/main/scala/nexysvideo/Harness.scala @@ -16,7 +16,6 @@ import sifive.blocks.devices.uart._ import chipyard._ import chipyard.harness._ -import chipyard.iobinders.{HasIOBinders} class NexysVideoHarness(override implicit val p: Parameters) extends NexysVideoShell { def dp = designParameters diff --git a/fpga/src/main/scala/vc707/TestHarness.scala b/fpga/src/main/scala/vc707/TestHarness.scala index 008e2399..1ed7ab33 100644 --- a/fpga/src/main/scala/vc707/TestHarness.scala +++ b/fpga/src/main/scala/vc707/TestHarness.scala @@ -18,7 +18,6 @@ import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO} import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO} import chipyard._ -import chipyard.iobinders.{HasIOBinders} import chipyard.harness._ class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707Shell { outer => diff --git a/fpga/src/main/scala/vcu118/TestHarness.scala b/fpga/src/main/scala/vcu118/TestHarness.scala index 6bffc9a7..733c5167 100644 --- a/fpga/src/main/scala/vcu118/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/TestHarness.scala @@ -18,7 +18,6 @@ import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO} import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO} import chipyard._ -import chipyard.iobinders.{HasIOBinders} import chipyard.harness._ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays { diff --git a/generators/chipyard/src/main/scala/config/ChipConfigs.scala b/generators/chipyard/src/main/scala/config/ChipConfigs.scala index cc61794c..c9ff068d 100644 --- a/generators/chipyard/src/main/scala/config/ChipConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ChipConfigs.scala @@ -43,6 +43,10 @@ class ChipLikeRocketConfig extends Config( new chipyard.config.AbstractConfig) +class FlatChipTopChipLikeRocketConfig extends Config( + new chipyard.example.WithFlatChipTop ++ + new chipyard.ChipLikeRocketConfig) + // A simple config demonstrating a "bringup prototype" to bringup the ChipLikeRocketconfig class ChipBringupHostConfig extends Config( //============================= diff --git a/generators/chipyard/src/main/scala/example/FlatChipTop.scala b/generators/chipyard/src/main/scala/example/FlatChipTop.scala index a1a1aeaa..165f9186 100644 --- a/generators/chipyard/src/main/scala/example/FlatChipTop.scala +++ b/generators/chipyard/src/main/scala/example/FlatChipTop.scala @@ -2,22 +2,28 @@ package chipyard.example import chisel3._ -import org.chipsalliance.cde.config.{Field, Parameters} +import org.chipsalliance.cde.config.{Config, Field, Parameters} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.prci._ import freechips.rocketchip.util._ +import freechips.rocketchip.subsystem.{PBUS, HasTileLinkLocations} import freechips.rocketchip.devices.debug.{ExportDebug, JtagDTMKey, Debug} import freechips.rocketchip.tilelink.{TLBuffer, TLFragmenter} import chipyard.{BuildSystem, DigitalTop} +import chipyard.harness.{BuildTop} import chipyard.clocking._ -import chipyard.iobinders.{IOCellKey, JTAGChipIO} +import chipyard.iobinders._ import barstools.iocell.chisel._ +import testchipip.{SerialTLKey} +class WithFlatChipTop extends Config((site, here, up) => { + case BuildTop => (p: Parameters) => new FlatChipTop()(p) +}) // This "FlatChipTop" uses no IOBinders, so all the IO have // to be explicitly constructed. // This only supports the base "DigitalTop" -class FlatChipTop(implicit p: Parameters) extends LazyModule { +class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPorts { override lazy val desiredName = "ChipTop" val system = LazyModule(p(BuildSystem)(p)).suggestName("system").asInstanceOf[DigitalTop] @@ -56,6 +62,8 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule { debugClockSinkNode := system.locateTLBusWrapper(p(ExportDebug).slaveWhere).fixedClockNode def debugClockBundle = debugClockSinkNode.in.head._1 + var ports: Seq[Port[_]] = Nil + override lazy val module = new FlatChipTopImpl class FlatChipTopImpl extends LazyRawModuleImp(this) { //========================= @@ -78,6 +86,9 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule { o.reset := reset_wire } + ports = ports :+ ClockPort(clock_pad, 100.0) + ports = ports :+ ResetPort(reset_pad) + // For a real chip you should replace this ClockSourceAtFreqFromPlusArg // with a blackbox of whatever PLL is being integrated val fake_pll = Module(new ClockSourceAtFreqFromPlusArg("pll_freq_mhz")) @@ -93,11 +104,13 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule { // Custom Boot //========================= val (custom_boot_pad, customBootIOCell) = IOCell.generateIOFromSignal(system.custom_boot_pin.get.getWrappedValue, "custom_boot", p(IOCellKey)) + ports = ports :+ CustomBootPort(custom_boot_pad) //========================= // Serialized TileLink //========================= val (serial_tl_pad, serialTLIOCells) = IOCell.generateIOFromSignal(system.serial_tl.get.getWrappedValue, "serial_tl", p(IOCellKey)) + ports = ports :+ SerialTLPort(serial_tl_pad, p(SerialTLKey).get, system.serdesser.get, 0) //========================= // JTAG/Debug @@ -136,12 +149,17 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule { IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true) }.get + ports = ports :+ JTAGPort(jtag_pad) + //========================== // UART //========================== require(system.uarts.size == 1) val (uart_pad, uartIOCells) = IOCell.generateIOFromSignal(system.module.uart.head, "uart_0", p(IOCellKey)) - + val where = PBUS // TODO fix + val bus = system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where) + val freqMHz = bus.dtsFrequency.get / 1000000 + ports = ports :+ UARTPort(uart_pad, 0, freqMHz.toInt) //========================== // External interrupts (tie off) diff --git a/generators/chipyard/src/main/scala/harness/HarnessClocks.scala b/generators/chipyard/src/main/scala/harness/HarnessClocks.scala index 0f58f33b..cfc1cad4 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessClocks.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessClocks.scala @@ -10,7 +10,6 @@ import freechips.rocketchip.util.{ResetCatchAndSync} import freechips.rocketchip.prci._ import chipyard.harness.{ApplyHarnessBinders, HarnessBinders, HarnessClockInstantiatorKey} -import chipyard.iobinders.HasIOBinders import chipyard.clocking.{SimplePllConfiguration, ClockDividerN} diff --git a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala index 48f63e04..9052bc77 100644 --- a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala +++ b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala @@ -10,7 +10,7 @@ import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters, ClockSinkP import chipyard.stage.phases.TargetDirKey import chipyard.harness.{ApplyHarnessBinders, HarnessBinders} -import chipyard.iobinders.HasIOBinders +import chipyard.iobinders.HasChipyardPorts import chipyard.clocking.{SimplePllConfiguration, ClockDividerN} import chipyard.{ChipTop} @@ -83,7 +83,7 @@ trait HasHarnessInstantiators { withClockAndReset (harnessBinderClock, harnessBinderReset) { lazyDuts.zipWithIndex.foreach { - case (d: HasIOBinders, i: Int) => ApplyHarnessBinders(this, d.portMap.values.flatten.toSeq)(chipParameters(i)) + case (d: HasChipyardPorts, i: Int) => ApplyHarnessBinders(this, d.ports)(chipParameters(i)) case _ => } ApplyMultiHarnessBinders(this, lazyDuts) diff --git a/generators/chipyard/src/main/scala/harness/MultiHarnessBinders.scala b/generators/chipyard/src/main/scala/harness/MultiHarnessBinders.scala index 399e64be..1200208c 100644 --- a/generators/chipyard/src/main/scala/harness/MultiHarnessBinders.scala +++ b/generators/chipyard/src/main/scala/harness/MultiHarnessBinders.scala @@ -13,7 +13,7 @@ import freechips.rocketchip.util._ import testchipip._ import chipyard._ -import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasIOBinders, Port, SerialTLPort} +import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasChipyardPorts, Port, SerialTLPort} import scala.reflect.{ClassTag} @@ -23,8 +23,8 @@ object ApplyMultiHarnessBinders { def apply(th: HasHarnessInstantiators, chips: Seq[LazyModule])(implicit p: Parameters): Unit = { Seq.tabulate(chips.size, chips.size) { case (i, j) => if (i != j) { (chips(i), chips(j)) match { - case (l0: HasIOBinders, l1: HasIOBinders) => p(MultiHarnessBinders(i, j)).foreach { f => - f(l0.portMap.values.flatten.toSeq, l1.portMap.values.flatten.toSeq) + case (l0: HasChipyardPorts, l1: HasChipyardPorts) => p(MultiHarnessBinders(i, j)).foreach { f => + f(l0.ports, l1.ports) } } }} diff --git a/generators/chipyard/src/main/scala/harness/TestHarness.scala b/generators/chipyard/src/main/scala/harness/TestHarness.scala index 459c6511..43bf2dd0 100644 --- a/generators/chipyard/src/main/scala/harness/TestHarness.scala +++ b/generators/chipyard/src/main/scala/harness/TestHarness.scala @@ -9,7 +9,6 @@ import freechips.rocketchip.util.{ResetCatchAndSync} import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters, ClockSinkParameters, ClockParameters} import chipyard.harness.{ApplyHarnessBinders, HarnessBinders} -import chipyard.iobinders.HasIOBinders import chipyard.clocking.{SimplePllConfiguration, ClockDividerN} import chipyard.{ChipTop} diff --git a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala index 773f3d39..4b5ac1c6 100644 --- a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala +++ b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala @@ -57,7 +57,7 @@ class WithDontTouchIOBinders(b: Boolean = true) extends Config((site, here, up) case DontTouchIOBindersPorts => b }) -abstract trait HasIOBinders { this: LazyModule => +abstract trait HasIOBinders extends HasChipyardPorts { this: LazyModule => val lazySystem: LazyModule private val iobinders = p(IOBinders) // Note: IOBinders cannot rely on the implicit clock/reset, as they may be called from the @@ -81,6 +81,8 @@ abstract trait HasIOBinders { this: LazyModule => // A mapping between stringified DigitalSystem traits and their corresponding ChipTop iocells val iocellMap = InModuleBody { iobinders.keys.map(k => k -> (lzyFlattened(k)._2 ++ impFlattened(k)._2)).toMap } + def ports = portMap.getWrappedValue.values.flatten.toSeq + InModuleBody { if (p(DontTouchIOBindersPorts)) { portMap.values.flatten.foreach { case (port: Port[Data]) => dontTouch(port.io) } diff --git a/generators/chipyard/src/main/scala/iobinders/Ports.scala b/generators/chipyard/src/main/scala/iobinders/Ports.scala index 61c25a36..391d3baf 100644 --- a/generators/chipyard/src/main/scala/iobinders/Ports.scala +++ b/generators/chipyard/src/main/scala/iobinders/Ports.scala @@ -19,6 +19,10 @@ trait Port[T <: Data] { val io: T } +trait HasChipyardPorts { + def ports: Seq[Port[_]] +} + // These case classes are generated by IOBinders, and interpreted by HarnessBinders case class GPIOPort (val io: Analog, val gpioId: Int, val pinId: Int) extends Port[Analog]