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 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>``, memory is backed by a file which is provided using ``+spiflash#=<NAME_OF_FILE>``,
where ``#`` is the SPI flash ID (usually ``0``). 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.soc.CanHaveBankedScratchpad // Enables optionally adding a banked scratchpad
with testchipip.iceblk.CanHavePeripheryBlockDevice // Enables optionally adding the block device 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.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.i2c.HasPeripheryI2C // Enables optionally adding the sifive I2C
with sifive.blocks.devices.pwm.HasPeripheryPWM // Enables optionally adding the sifive PWM with sifive.blocks.devices.pwm.HasPeripheryPWM // Enables optionally adding the sifive PWM
with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART 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.WithTieOffInterrupts ++ // tie-off interrupt ports, if present
new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, 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.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.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.WithClockFromHarness ++ // all Clock I/O in ChipTop should be driven by harnessClockInstantiator
new chipyard.harness.WithResetFromHarness ++ // reset controlled by harness new chipyard.harness.WithResetFromHarness ++ // reset controlled by harness
@@ -36,6 +37,7 @@ class AbstractConfig extends Config(
new chipyard.iobinders.WithGPIOCells ++ new chipyard.iobinders.WithGPIOCells ++
new chipyard.iobinders.WithSPIFlashIOCells ++ new chipyard.iobinders.WithSPIFlashIOCells ++
new chipyard.iobinders.WithExtInterruptIOCells ++ new chipyard.iobinders.WithExtInterruptIOCells ++
new chipyard.iobinders.WithChipIdIOCells ++
new chipyard.iobinders.WithCustomBootPin ++ new chipyard.iobinders.WithCustomBootPin ++
// The "punchthrough" IOBInders below don't generate IOCells, as these interfaces shouldn't really be mapped to ASIC IO // 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 // 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 // Simple design which exposes a second serial-tl port that can connect to another instance of itself
class SymmetricChipletRocketConfig extends Config( 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 chipyard.harness.WithSerialTLTiedOff(tieoffs=Some(Seq(1))) ++ // Tie-off the chip-to-chip link in single-chip sims
new testchipip.serdes.WithSerialTL(Seq( new testchipip.serdes.WithSerialTL(Seq(
testchipip.serdes.SerialTLParams( // 0th serial-tl is chip-to-bringup-fpga 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({ class WithSimUARTToUARTTSI extends HarnessBinder({
case (th: HasHarnessInstantiators, port: UARTPort, chipId: Int) => { case (th: HasHarnessInstantiators, port: UARTPort, chipId: Int) => {
UARTAdapter.connect(Seq(port.io), UARTAdapter.connect(Seq(port.io),

View File

@@ -27,6 +27,7 @@ import barstools.iocell.chisel._
import testchipip.serdes.{CanHavePeripheryTLSerial, SerialTLKey} import testchipip.serdes.{CanHavePeripheryTLSerial, SerialTLKey}
import testchipip.spi.{SPIChipIO} import testchipip.spi.{SPIChipIO}
import testchipip.boot.{CanHavePeripheryCustomBootPin} import testchipip.boot.{CanHavePeripheryCustomBootPin}
import testchipip.soc.{CanHavePeripheryChipIdPin}
import testchipip.util.{ClockedIO} import testchipip.util.{ClockedIO}
import testchipip.iceblk.{CanHavePeripheryBlockDevice, BlockDeviceKey, BlockDeviceIO} import testchipip.iceblk.{CanHavePeripheryBlockDevice, BlockDeviceKey, BlockDeviceIO}
import testchipip.cosim.{CanHaveTraceIO, TraceOutputTop, SpikeCosimConfig} 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({ class WithSerialTLPunchthrough extends OverrideIOBinder({
(system: CanHavePeripheryTLSerial) => { (system: CanHavePeripheryTLSerial) => {
val (ports, cells) = system.serial_tls.zipWithIndex.map({ case (s, id) => 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) case class SerialTLPort (val getIO: () => Data, val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int)
extends Port[Data] extends Port[Data]
case class ChipIdPort (val getIO: () => UInt)
extends Port[UInt]
case class UARTTSIPort (val getIO: () => UARTTSIIO) case class UARTTSIPort (val getIO: () => UARTTSIIO)
extends Port[UARTTSIIO] extends Port[UARTTSIIO]