Skip to content

Commit

Permalink
Merge pull request #1445 from ucb-bar/flip_serial_tl
Browse files Browse the repository at this point in the history
Flip serial_tl_clock to be generated off-chip
  • Loading branch information
jerryz123 committed May 8, 2023
2 parents c4bc627 + 3196d44 commit 352cc77
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 28 deletions.
10 changes: 7 additions & 3 deletions docs/Advanced-Concepts/Chip-Communication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,12 @@ This type of simulation setup is done in the following multi-clock configuration
:start-after: DOC include start: MulticlockAXIOverSerialConfig
:end-before: DOC include end: MulticlockAXIOverSerialConfig

Bringup Setup of the Example Test Chip after Tapeout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Softcore-driven Bringup Setup of the Example Test Chip after Tapeout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. warning::
Bringing up test chips with a FPGA softcore as described here is discouraged.
An alternative approach using the FPGA to "bridge" between a host computer and the test chip is the preferred approach.

Assuming this example test chip is taped out and now ready to be tested, we can communicate with the chip using this serial-link.
For example, a common test setup used at Berkeley to evaluate Chipyard-based test-chips includes an FPGA running a RISC-V soft-core that is able to speak to the DUT (over an FMC).
Expand All @@ -222,4 +226,4 @@ The following image shows this flow:
.. image:: ../_static/images/chip-bringup.png

In fact, this exact type of bringup setup is what the following section discusses:
:ref:`Prototyping/VCU118:Introduction to the Bringup Design`.
:ref:_legacy-vcu118-bringup.
10 changes: 8 additions & 2 deletions docs/Prototyping/VCU118.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,14 @@ After the harness is created, the ``BundleBridgeSource``'s must be connected to
This is done with harness binders and io binders (see ``fpga/src/main/scala/vcu118/HarnessBinders.scala`` and ``fpga/src/main/scala/vcu118/IOBinders.scala``).
For more information on harness binders and io binders, refer to :ref:`Customization/IOBinders:IOBinders and HarnessBinders`.

Introduction to the Bringup Design
----------------------------------
(Legacy) Introduction to the Legacy Bringup Design
--------------------------------------------------

.. warning::
The bringup VCU118 design described here is designed for old versions of Chipyard SoCs, pre-1.9.1.
The key difference is that these designs rely on a clock generated on-chip to synchronize the slow serialized-TileLink interface.
After Chipyard 1.9.1, the FPGA host is expected to pass the clock to the chip, instead of the other way around.
A new bringup solution will be developed for post-1.9.1 Chipyard designs.

An example of a more complicated design used for Chipyard test chips can be viewed in ``fpga/src/main/scala/vcu118/bringup/``.
This example extends the default test harness and creates new ``Overlays`` to connect to a DUT (connected to the FMC port).
Expand Down
3 changes: 2 additions & 1 deletion fpga/src/main/scala/arty100t/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarness
ports.map({ port =>
val ath = th.asInstanceOf[Arty100THarness]
val freq = p(PeripheryBusKey).dtsFrequency.get
val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)
val bits = port.bits
port.clock := th.buildtopClock
withClockAndReset(th.buildtopClock, th.buildtopReset) {
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset)
val uart_to_serial = Module(new UARTToSerial(
Expand Down
19 changes: 11 additions & 8 deletions generators/chipyard/src/main/scala/HarnessBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ class WithSimAXIMemOverSerialTL extends OverrideHarnessBinder({
// DOC include start: HarnessClockInstantiatorEx
withClockAndReset(th.buildtopClock, th.buildtopReset) {
val memOverSerialTLClockBundle = th.harnessClockInstantiator.requestClockBundle("mem_over_serial_tl_clock", memFreq)
val serial_bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)
val serial_bits = port.bits
port.clock := th.buildtopClock
val harnessMultiClockAXIRAM = SerialAdapter.connectHarnessMultiClockAXIRAM(
system.serdesser.get,
serial_bits,
Expand Down Expand Up @@ -302,11 +303,11 @@ class WithSerialAdapterTiedOff extends OverrideHarnessBinder({
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
implicit val p = chipyard.iobinders.GetSystemParameters(system)
ports.map({ port =>
val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)
withClockAndReset(th.buildtopClock, th.buildtopReset) {
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset)
SerialAdapter.tieoff(ram.module.io.tsi_ser)
}
val bits = port.bits
port.clock := false.B.asClock
port.bits.out.ready := false.B
port.bits.in.valid := false.B
port.bits.in.bits := DontCare
})
}
})
Expand All @@ -315,7 +316,8 @@ class WithSimSerial extends OverrideHarnessBinder({
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
implicit val p = chipyard.iobinders.GetSystemParameters(system)
ports.map({ port =>
val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)
val bits = port.bits
port.clock := th.buildtopClock
withClockAndReset(th.buildtopClock, th.buildtopReset) {
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset)
val success = SerialAdapter.connectSimSerial(ram.module.io.tsi_ser, th.buildtopClock, th.buildtopReset.asBool)
Expand All @@ -330,7 +332,8 @@ class WithUARTSerial extends OverrideHarnessBinder({
implicit val p = chipyard.iobinders.GetSystemParameters(system)
ports.map({ port =>
val freq = p(PeripheryBusKey).dtsFrequency.get
val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)
val bits = port.bits
port.clock := th.buildtopClock
withClockAndReset(th.buildtopClock, th.buildtopReset) {
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset)
val uart_to_serial = Module(new UARTToSerial(freq, UARTParams(0)))
Expand Down
11 changes: 2 additions & 9 deletions generators/chipyard/src/main/scala/config/ChipConfigs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,8 @@ class ChipLikeQuadRocketConfig extends Config(
//==================================
new chipyard.clocking.WithPLLSelectorDividerClockGenerator ++ // Use a PLL-based clock selector/divider generator structure

// Create two clock groups, uncore and fbus, in addition to the tile clock groups
new chipyard.clocking.WithClockGroupsCombinedByName("uncore", "implicit", "sbus", "mbus", "cbus", "system_bus") ++
new chipyard.clocking.WithClockGroupsCombinedByName("fbus", "fbus", "pbus") ++

// Set up the crossings
new chipyard.config.WithFbusToSbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between SBUS and FBUS
new chipyard.config.WithCbusToPbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between PBUS and CBUS
new chipyard.config.WithSbusToMbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossings between backside of L2 and MBUS
new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS
// Create the uncore clock group
new chipyard.clocking.WithClockGroupsCombinedByName("uncore", "implicit", "sbus", "mbus", "cbus", "system_bus", "fbus", "pbus") ++

new chipyard.config.AbstractConfig)

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class FlatTestHarness(implicit val p: Parameters) extends Module {
val memOverSerialTLClockBundle = Wire(new ClockBundle(ClockBundleParameters()))
memOverSerialTLClockBundle.clock := clock
memOverSerialTLClockBundle.reset := reset
val serial_bits = SerialAdapter.asyncQueue(dut.serial_tl_pad, clock, reset)
val serial_bits = dut.serial_tl_pad.bits
dut.serial_tl_pad.clock := clock
val harnessMultiClockAXIRAM = SerialAdapter.connectHarnessMultiClockAXIRAM(
lazyDut.system.serdesser.get,
serial_bits,
Expand Down
7 changes: 4 additions & 3 deletions generators/firechip/src/main/scala/BridgeBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class WithSerialBridge extends OverrideHarnessBinder({
(system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedIO[SerialIO]]) => {
ports.map { port =>
implicit val p = GetSystemParameters(system)
val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)
val bits = port.bits
port.clock := th.buildtopClock
val ram = withClockAndReset(th.buildtopClock, th.buildtopReset) {
SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset)
}
Expand Down Expand Up @@ -125,8 +126,8 @@ class WithAXIOverSerialTLCombinedBridges extends OverrideHarnessBinder({
axiClockBundle.clock := axiClock
axiClockBundle.reset := ResetCatchAndSync(axiClock, th.buildtopReset.asBool)

val serial_bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)

val serial_bits = port.bits
port.clock := th.buildtopClock
val harnessMultiClockAXIRAM = withClockAndReset(th.buildtopClock, th.buildtopReset) {
SerialAdapter.connectHarnessMultiClockAXIRAM(
system.serdesser.get,
Expand Down
2 changes: 1 addition & 1 deletion generators/testchipip

0 comments on commit 352cc77

Please sign in to comment.