Merge pull request #1721 from ucb-bar/chip-id-pin

Add Chip ID Pin and Port
This commit is contained in:
Jerry Zhao
2024-01-16 10:16:15 -08:00
committed by GitHub
8 changed files with 36 additions and 1 deletions

View File

@@ -92,3 +92,15 @@ The SPI flash model is a device that models a simple SPI flash device. It curren
only supports single read, quad read, single write, and quad write instructions. The
memory is backed by a file which is provided using ``+spiflash#=<NAME_OF_FILE>``,
where ``#`` is the SPI flash ID (usually ``0``).
Chip ID Pin
---------------
The chip ID pin sets the chip ID for the chip it is added to. This is most useful in
multi-chip configs. The pin value is driven by the chip ID value set in the harness
binder and the chip ID value can be read through MMIO at the address ``0x2000`` by default.
The pin can be added to a system with the ``testchipip.soc.WithChipIdPin`` config. The pin
width and MMIO address are parameterizable and can be set by passing ``ChipIdPinParams`` as an
argument to the config. The width can additionally be set using the ``testchipip.soc.WithChipIdPinWidth``
config.

View File

@@ -20,6 +20,7 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
with testchipip.soc.CanHaveBankedScratchpad // Enables optionally adding a banked scratchpad
with testchipip.iceblk.CanHavePeripheryBlockDevice // Enables optionally adding the block device
with testchipip.serdes.CanHavePeripheryTLSerial // Enables optionally adding the backing memory and serial adapter
with testchipip.soc.CanHavePeripheryChipIdPin // Enables optional pin to set chip id for multi-chip configs
with sifive.blocks.devices.i2c.HasPeripheryI2C // Enables optionally adding the sifive I2C
with sifive.blocks.devices.pwm.HasPeripheryPWM // Enables optionally adding the sifive PWM
with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART

View File

@@ -23,6 +23,7 @@ class AbstractConfig extends Config(
new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present
new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present
new chipyard.harness.WithCustomBootPinPlusArg ++ // drive custom-boot pin with a plusarg, if custom-boot-pin is present
new chipyard.harness.WithDriveChipIdPin ++ // drive chip id pin from harness binder, if chip id pin is present
new chipyard.harness.WithSimUARTToUARTTSI ++ // connect a SimUART to the UART-TSI port
new chipyard.harness.WithClockFromHarness ++ // all Clock I/O in ChipTop should be driven by harnessClockInstantiator
new chipyard.harness.WithResetFromHarness ++ // reset controlled by harness
@@ -36,6 +37,7 @@ class AbstractConfig extends Config(
new chipyard.iobinders.WithGPIOCells ++
new chipyard.iobinders.WithSPIFlashIOCells ++
new chipyard.iobinders.WithExtInterruptIOCells ++
new chipyard.iobinders.WithChipIdIOCells ++
new chipyard.iobinders.WithCustomBootPin ++
// The "punchthrough" IOBInders below don't generate IOCells, as these interfaces shouldn't really be mapped to ASIC IO
// Instead, they directly pass through the DigitalTop ports to ports in the ChipTop

View File

@@ -11,6 +11,7 @@ import testchipip.soc.{OBUS}
// Simple design which exposes a second serial-tl port that can connect to another instance of itself
class SymmetricChipletRocketConfig extends Config(
new testchipip.soc.WithChipIdPin ++ // Add pin to identify chips
new chipyard.harness.WithSerialTLTiedOff(tieoffs=Some(Seq(1))) ++ // Tie-off the chip-to-chip link in single-chip sims
new testchipip.serdes.WithSerialTL(Seq(
testchipip.serdes.SerialTLParams( // 0th serial-tl is chip-to-bringup-fpga

View File

@@ -252,6 +252,13 @@ class WithSimTSIOverSerialTL extends HarnessBinder({
}
})
class WithDriveChipIdPin extends HarnessBinder({
case (th: HasHarnessInstantiators, port: ChipIdPort, chipId: Int) => {
require(chipId < math.pow(2, port.io.getWidth), "ID Pin is not wide enough")
port.io := chipId.U
}
})
class WithSimUARTToUARTTSI extends HarnessBinder({
case (th: HasHarnessInstantiators, port: UARTPort, chipId: Int) => {
UARTAdapter.connect(Seq(port.io),

View File

@@ -27,6 +27,7 @@ import barstools.iocell.chisel._
import testchipip.serdes.{CanHavePeripheryTLSerial, SerialTLKey}
import testchipip.spi.{SPIChipIO}
import testchipip.boot.{CanHavePeripheryCustomBootPin}
import testchipip.soc.{CanHavePeripheryChipIdPin}
import testchipip.util.{ClockedIO}
import testchipip.iceblk.{CanHavePeripheryBlockDevice, BlockDeviceKey, BlockDeviceIO}
import testchipip.cosim.{CanHaveTraceIO, TraceOutputTop, SpikeCosimConfig}
@@ -355,6 +356,14 @@ class WithSerialTLIOCells extends OverrideIOBinder({
}
})
class WithChipIdIOCells extends OverrideIOBinder({
(system: CanHavePeripheryChipIdPin) => system.chip_id_pin.map({ p =>
val sys = system.asInstanceOf[BaseSubsystem]
val (port, cells) = IOCell.generateIOFromSignal(p.getWrappedValue, s"chip_id", sys.p(IOCellKey), abstractResetAsAsync = true)
(Seq(ChipIdPort(() => port)), cells)
}).getOrElse(Nil, Nil)
})
class WithSerialTLPunchthrough extends OverrideIOBinder({
(system: CanHavePeripheryTLSerial) => {
val (ports, cells) = system.serial_tls.zipWithIndex.map({ case (s, id) =>

View File

@@ -76,6 +76,9 @@ case class JTAGPort (val getIO: () => JTAGChipIO)
case class SerialTLPort (val getIO: () => Data, val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int)
extends Port[Data]
case class ChipIdPort (val getIO: () => UInt)
extends Port[UInt]
case class UARTTSIPort (val getIO: () => UARTTSIIO)
extends Port[UARTTSIIO]