Update testchipip with source-synchronous serdes

This commit is contained in:
Jerry Zhao
2023-12-21 20:33:24 -08:00
parent cfd555ee94
commit 194d4462f9
10 changed files with 60 additions and 41 deletions

View File

@@ -56,5 +56,5 @@ class NoCoresArty100TConfig extends Config(
class BringupArty100TConfig extends Config( class BringupArty100TConfig extends Config(
new WithArty100TSerialTLToGPIO ++ new WithArty100TSerialTLToGPIO ++
new WithArty100TTweaks(freqMHz = 50) ++ new WithArty100TTweaks(freqMHz = 50) ++
new testchipip.serdes.WithSerialTLClockDirection(provideClockFreqMHz = Some(50)) ++ new testchipip.serdes.WithSerialTLPHYParams(testchipip.serdes.InternalSyncSerialParams(freqMHz=50)) ++
new chipyard.ChipBringupHostConfig) new chipyard.ChipBringupHostConfig)

View File

@@ -53,8 +53,8 @@ class WithArty100TSerialTLToGPIO extends HarnessBinder({
harnessIO match { harnessIO match {
case io: DecoupledSerialIO => { case io: DecoupledSerialIO => {
val clkIO = io match { val clkIO = io match {
case io: LocallySyncSerialIO => IOPin(io.clock_out) case io: InternalSyncSerialIO => IOPin(io.clock_out)
case io: ExternallySyncSerialIO => IOPin(io.clock_in) case io: ExternalSyncSerialIO => IOPin(io.clock_in)
} }
val packagePinsWithPackageIOs = Seq( val packagePinsWithPackageIOs = Seq(
("G13", clkIO), ("G13", clkIO),
@@ -78,10 +78,10 @@ class WithArty100TSerialTLToGPIO extends HarnessBinder({
// Don't add IOB to the clock, if its an input // Don't add IOB to the clock, if its an input
io match { io match {
case io: LocallySyncSerialIO => packagePinsWithPackageIOs foreach { case (pin, io) => { case io: InternalSyncSerialIO => packagePinsWithPackageIOs foreach { case (pin, io) => {
artyTh.xdc.addIOB(io) artyTh.xdc.addIOB(io)
}} }}
case io: ExternallySyncSerialIO => packagePinsWithPackageIOs.drop(1).foreach { case (pin, io) => { case io: ExternalSyncSerialIO => packagePinsWithPackageIOs.drop(1).foreach { case (pin, io) => {
artyTh.xdc.addIOB(io) artyTh.xdc.addIOB(io)
}} }}
} }

View File

@@ -65,8 +65,8 @@ class AbstractConfig extends Config(
new testchipip.boot.WithBootAddrReg ++ // add a boot-addr-reg for configurable boot address new testchipip.boot.WithBootAddrReg ++ // add a boot-addr-reg for configurable boot address
new testchipip.serdes.WithSerialTL(Seq( // add a serial-tilelink interface new testchipip.serdes.WithSerialTL(Seq( // add a serial-tilelink interface
testchipip.serdes.SerialTLParams( testchipip.serdes.SerialTLParams(
client = Some(testchipip.serdes.SerialTLClientParams(idBits=4)), // serial-tilelink interface will master the FBUS, and support 4 idBits client = Some(testchipip.serdes.SerialTLClientParams()), // serial-tilelink interface will master the FBUS, and support 4 idBits
width = 32 // serial-tilelink interface with 32 lanes phyParams = testchipip.serdes.ExternalSyncSerialParams(width=32) // serial-tilelink interface with 32 lanes
) )
)) ++ )) ++
new chipyard.config.WithDebugModuleAbstractDataWords(8) ++ // increase debug module data capacity new chipyard.config.WithDebugModuleAbstractDataWords(8) ++ // increase debug module data capacity

View File

@@ -22,8 +22,18 @@ class ChipLikeRocketConfig extends Config(
//================================== //==================================
// Set up I/O // Set up I/O
//================================== //==================================
new testchipip.serdes.WithSerialTLWidth(4) ++ // 4bit wide Serialized TL interface to minimize IO new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams( // 1 serial tilelink port
new testchipip.serdes.WithSerialTLMem(size = (1 << 30) * 4L) ++ // Configure the off-chip memory accessible over serial-tl as backing memory manager = Some(testchipip.serdes.SerialTLManagerParams( // port acts as a manager of offchip memory
memParams = Seq(testchipip.serdes.ManagerRAMParams( // 4 GB of off-chip memory
address = BigInt("80000000", 16),
size = BigInt("100000000", 16)
)),
isMemoryDevice = true
)),
client = Some(testchipip.serdes.SerialTLClientParams()), // Allow an external manager to probe this chip
phyParams = testchipip.serdes.ExternalSyncSerialParams(width=4) // 4-bit bidir interface, sync'd to an external clock
))) ++
new freechips.rocketchip.subsystem.WithNoMemPort ++ // Remove axi4 mem port new freechips.rocketchip.subsystem.WithNoMemPort ++ // Remove axi4 mem port
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // 1 memory channel new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // 1 memory channel
@@ -60,10 +70,16 @@ class ChipBringupHostConfig extends Config(
//============================= //=============================
// Setup the SerialTL side on the bringup device // Setup the SerialTL side on the bringup device
//============================= //=============================
new testchipip.serdes.WithSerialTLWidth(4) ++ // match width with the chip new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams(
new testchipip.serdes.WithSerialTLMem(base = 0x0, size = 0x80000000L, // accessible memory of the chip that doesn't come from the tethered host manager = Some(testchipip.serdes.SerialTLManagerParams(
idBits = 4, isMainMemory = false) ++ // This assumes off-chip mem starts at 0x8000_0000 memParams = Seq(testchipip.serdes.ManagerRAMParams( // Bringup platform can access all memory from 0 to DRAM_BASE
new testchipip.serdes.WithSerialTLClockDirection(provideClockFreqMHz = Some(75)) ++ // bringup board drives the clock for the serial-tl receiver on the chip, use 75MHz clock address = BigInt("00000000", 16),
size = BigInt("80000000", 16)
))
)),
client = Some(testchipip.serdes.SerialTLClientParams()), // Allow chip to access this device's memory (DRAM)
phyParams = testchipip.serdes.InternalSyncSerialParams(width=4, freqMHz = 75) // bringup platform provides the clock
))) ++
//============================ //============================
// Setup bus topology on the bringup system // Setup bus topology on the bringup system

View File

@@ -11,7 +11,7 @@ import freechips.rocketchip.util.{PlusArg}
import freechips.rocketchip.subsystem.{CacheBlockBytes} import freechips.rocketchip.subsystem.{CacheBlockBytes}
import freechips.rocketchip.devices.debug.{SimJTAG} import freechips.rocketchip.devices.debug.{SimJTAG}
import freechips.rocketchip.jtag.{JTAGIO} import freechips.rocketchip.jtag.{JTAGIO}
import testchipip.serdes.{SerialTLKey, LocallySyncSerialIO, ExternallySyncSerialIO} import testchipip.serdes._
import testchipip.uart.{UARTAdapter} import testchipip.uart.{UARTAdapter}
import testchipip.dram.{SimDRAM} import testchipip.dram.{SimDRAM}
import testchipip.tsi.{TSIHarness, SimTSI, SerialRAM} import testchipip.tsi.{TSIHarness, SimTSI, SerialRAM}
@@ -48,23 +48,26 @@ class FlatTestHarness(implicit val p: Parameters) extends Module {
// Figure out which clock drives the harness TLSerdes, based on the port type // Figure out which clock drives the harness TLSerdes, based on the port type
val serial_ram_clock = dut.serial_tl_pad match { val serial_ram_clock = dut.serial_tl_pad match {
case io: LocallySyncSerialIO => io.clock_out case io: InternalSyncSerialIO => io.clock_out
case io: ExternallySyncSerialIO => clock case io: ExternalSyncSerialIO => clock
}
dut.serial_tl_pad match {
case io: ExternalSyncSerialIO => io.clock_in := clock
case io: InternalSyncSerialIO =>
} }
withClockAndReset(serial_ram_clock, reset) { dut.serial_tl_pad match {
dut.serial_tl_pad match { case pad: DecoupledSerialIO => {
case io: ExternallySyncSerialIO => io.clock_in := clock withClockAndReset(serial_ram_clock, reset) {
case io: LocallySyncSerialIO => // SerialRAM implements the memory regions the chip expects
val ram = Module(LazyModule(new SerialRAM(lazyDut.system.serdessers(0), p(SerialTLKey)(0))).module)
ram.io.ser.in <> pad.out
pad.in <> ram.io.ser.out
// Allow TSI to master the chip
io.success := SimTSI.connect(ram.io.tsi, serial_ram_clock, reset)
}
} }
// SerialRAM implements the memory regions the chip expects
val ram = Module(LazyModule(new SerialRAM(lazyDut.system.serdessers(0), p(SerialTLKey)(0))).module)
ram.io.ser.in <> dut.serial_tl_pad.out
dut.serial_tl_pad.in <> ram.io.ser.out
// Allow TSI to master the chip
io.success := SimTSI.connect(ram.io.tsi, serial_ram_clock, reset)
} }
// JTAG // JTAG

View File

@@ -211,8 +211,8 @@ class WithSerialTLTiedOff extends HarnessBinder({
case io: DecoupledSerialIO => io.out.ready := false.B; io.in.valid := false.B; io.in.bits := DontCare; case io: DecoupledSerialIO => io.out.ready := false.B; io.in.valid := false.B; io.in.bits := DontCare;
} }
port.io match { port.io match {
case io: LocallySyncSerialIO => case io: InternalSyncSerialIO =>
case io: ExternallySyncSerialIO => io.clock_in := false.B.asClock case io: ExternalSyncSerialIO => io.clock_in := false.B.asClock
} }
} }
}) })
@@ -220,8 +220,8 @@ class WithSerialTLTiedOff extends HarnessBinder({
class WithSimTSIOverSerialTL extends HarnessBinder({ class WithSimTSIOverSerialTL extends HarnessBinder({
case (th: HasHarnessInstantiators, port: SerialTLPort) => { case (th: HasHarnessInstantiators, port: SerialTLPort) => {
port.io match { port.io match {
case io: LocallySyncSerialIO => case io: InternalSyncSerialIO =>
case io: ExternallySyncSerialIO => io.clock_in := false.B.asClock case io: ExternalSyncSerialIO => io.clock_in := false.B.asClock
} }
port.io match { port.io match {
@@ -229,8 +229,8 @@ class WithSimTSIOverSerialTL extends HarnessBinder({
// If the port is locally synchronous (provides a clock), drive everything with that clock // If the port is locally synchronous (provides a clock), drive everything with that clock
// Else, drive everything with the harnes clock // Else, drive everything with the harnes clock
val clock = port.io match { val clock = port.io match {
case io: LocallySyncSerialIO => io.clock_out case io: InternalSyncSerialIO => io.clock_out
case io: ExternallySyncSerialIO => th.harnessBinderClock case io: ExternalSyncSerialIO => th.harnessBinderClock
} }
withClock(clock) { withClock(clock) {
val ram = Module(LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p)).module) val ram = Module(LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p)).module)

View File

@@ -60,14 +60,14 @@ class WithMultiChipSerialTL(chip0: Int, chip1: Int, chip0portId: Int = 0, chip1p
(p0: SerialTLPort) => p0.portId == chip0portId, (p0: SerialTLPort) => p0.portId == chip0portId,
(p1: SerialTLPort) => p1.portId == chip1portId, (p1: SerialTLPort) => p1.portId == chip1portId,
(th: HasHarnessInstantiators, p0: SerialTLPort, p1: SerialTLPort) => { (th: HasHarnessInstantiators, p0: SerialTLPort, p1: SerialTLPort) => {
def connectDecoupledSyncSerialIO(clkSource: LocallySyncSerialIO, clkSink: ExternallySyncSerialIO) = { def connectDecoupledSyncSerialIO(clkSource: InternalSyncSerialIO, clkSink: ExternalSyncSerialIO) = {
clkSink.clock_in := clkSource.clock_out clkSink.clock_in := clkSource.clock_out
clkSink.in <> clkSource.out clkSink.in <> clkSource.out
clkSource.in <> clkSink.out clkSource.in <> clkSink.out
} }
(p0.io, p1.io) match { (p0.io, p1.io) match {
case (io0: LocallySyncSerialIO , io1: ExternallySyncSerialIO) => connectDecoupledSyncSerialIO(io0, io1) case (io0: InternalSyncSerialIO, io1: ExternalSyncSerialIO) => connectDecoupledSyncSerialIO(io0, io1)
case (io0: ExternallySyncSerialIO, io1: LocallySyncSerialIO) => connectDecoupledSyncSerialIO(io1, io0) case (io0: ExternalSyncSerialIO, io1: InternalSyncSerialIO) => connectDecoupledSyncSerialIO(io1, io0)
} }
} }
) )

View File

@@ -15,7 +15,7 @@ import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters}
import freechips.rocketchip.util.{ResetCatchAndSync} import freechips.rocketchip.util.{ResetCatchAndSync}
import sifive.blocks.devices.uart._ import sifive.blocks.devices.uart._
import testchipip.serdes.{ExternallySyncSerialIO} import testchipip.serdes.{ExternalSyncSerialIO}
import testchipip.tsi.{SerialRAM} import testchipip.tsi.{SerialRAM}
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
@@ -69,7 +69,7 @@ class WithFireSimIOCellModels extends Config((site, here, up) => {
class WithTSIBridgeAndHarnessRAMOverSerialTL extends HarnessBinder({ class WithTSIBridgeAndHarnessRAMOverSerialTL extends HarnessBinder({
case (th: FireSim, port: SerialTLPort) => { case (th: FireSim, port: SerialTLPort) => {
port.io match { port.io match {
case io: ExternallySyncSerialIO => { case io: ExternalSyncSerialIO => {
io.clock_in := th.harnessBinderClock io.clock_in := th.harnessBinderClock
val ram = Module(LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p)).module) val ram = Module(LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p)).module)
ram.io.ser.in <> io.out ram.io.ser.in <> io.out

View File

@@ -260,7 +260,7 @@ class FireSimSmallSystemConfig extends Config(
new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++ new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++
new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams( new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams(
client = Some(testchipip.serdes.SerialTLClientParams(idBits = 4)), client = Some(testchipip.serdes.SerialTLClientParams(idBits = 4)),
width = 32 phyParams = testchipip.serdes.ExternalSyncSerialParams(width=32)
))) ++ ))) ++
new testchipip.iceblk.WithBlockDevice ++ new testchipip.iceblk.WithBlockDevice ++
new chipyard.config.WithUARTInitBaudRate(BigInt(3686400L)) ++ new chipyard.config.WithUARTInitBaudRate(BigInt(3686400L)) ++