diff --git a/docs/Generators/TestChipIP.rst b/docs/Generators/TestChipIP.rst index 2c382d4f12..32e76f5b51 100644 --- a/docs/Generators/TestChipIP.rst +++ b/docs/Generators/TestChipIP.rst @@ -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#=``, 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. diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index 879ede5708..3a0e2fa901 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -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 diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 7077049101..8a328dafae 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -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 diff --git a/generators/chipyard/src/main/scala/config/ChipletConfigs.scala b/generators/chipyard/src/main/scala/config/ChipletConfigs.scala index e07aa73daa..a7d2113f81 100644 --- a/generators/chipyard/src/main/scala/config/ChipletConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ChipletConfigs.scala @@ -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 diff --git a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala index d70519b3ed..59d4110d45 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala @@ -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), diff --git a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala index 309ec0043b..64b1296e6a 100644 --- a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala +++ b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala @@ -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) => diff --git a/generators/chipyard/src/main/scala/iobinders/Ports.scala b/generators/chipyard/src/main/scala/iobinders/Ports.scala index 627693aa8d..6b327a183d 100644 --- a/generators/chipyard/src/main/scala/iobinders/Ports.scala +++ b/generators/chipyard/src/main/scala/iobinders/Ports.scala @@ -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] diff --git a/generators/testchipip b/generators/testchipip index e844c51a08..28a4d01b11 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit e844c51a084aebd89968166bab421dda87a1e693 +Subproject commit 28a4d01b1130b76ea725850fe8b600f9847b6cb8