Remove references to legacy softcore-based bringup

This commit is contained in:
Jerry Zhao
2024-01-29 07:57:36 -08:00
parent d8e44d2b5e
commit 0ccd032a73
10 changed files with 0 additions and 585 deletions

View File

@@ -198,25 +198,3 @@ bringup design).
:language: scala
:start-after: DOC include start: TetheredChipLikeRocketConfig
:end-before: DOC include end: TetheredChipLikeRocketConfig
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).
This RISC-V soft-core would serve as the host of the test that will run on the DUT.
This is done by the RISC-V soft-core running FESVR, sending TSI commands to a ``TSIToTileLink`` / ``TLSerdesser`` programmed on the FPGA.
Once the commands are converted to serialized TileLink, then they can be sent over some medium to the DUT
(like an FMC cable or a set of wires connecting FPGA outputs to the DUT board).
Similar to simulation, if the chip requests offchip memory, it can then send the transaction back over the serial-link.
Then the request can be serviced by the FPGA DRAM.
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:_legacy-vcu118-bringup.

View File

@@ -47,20 +47,6 @@ 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`.
(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).
Extensions include another UART (connected over FMC), I2C (connected over FMC), miscellaneous GPIOS (can be connected to anything), and a TSI Host Widget.
The TSI Host Widget is used to interact with the DUT from the prototype over a SerDes link (sometimes called the Low BandWidth InterFace - LBWIF) and provide access to a channel of the FPGA's DRAM.
.. Note:: Remember that since whenever a new test harness is created (or the config changes, or the config packages changes, or...), you need to modify the make invocation.
For example, ``make SUB_PROJECT=vcu118 CONFIG=MyNewVCU118Config CONFIG_PACKAGE=this.is.my.scala.package bitstream``.
See :ref:`Prototyping/General:Generating a Bitstream` for information on the various make variables.

View File

@@ -44,20 +44,6 @@ ifeq ($(SUB_PROJECT),vcu118)
FPGA_BRAND ?= xilinx
endif
ifeq ($(SUB_PROJECT),bringup)
SBT_PROJECT ?= fpga_platforms
MODEL ?= BringupVCU118FPGATestHarness
VLOG_MODEL ?= BringupVCU118FPGATestHarness
MODEL_PACKAGE ?= chipyard.fpga.vcu118.bringup
CONFIG ?= RocketBringupConfig
CONFIG_PACKAGE ?= chipyard.fpga.vcu118.bringup
GENERATOR_PACKAGE ?= chipyard
TB ?= none # unused
TOP ?= ChipTop
BOARD ?= vcu118
FPGA_BRAND ?= xilinx
endif
ifeq ($(SUB_PROJECT),nexysvideo)
SBT_PROJECT ?= fpga_platforms
MODEL ?= NexysVideoHarness

View File

@@ -1,28 +0,0 @@
package chipyard.fpga.vcu118.bringup
import scala.collection.mutable.{LinkedHashMap}
object BringupGPIOs {
// map of the pin name (akin to die pin name) to (fpga package pin, IOSTANDARD, add pullup resistor?)
val pinMapping = LinkedHashMap(
// these connect to LEDs and switches on the VCU118 (and use 1.2V)
"led0" -> ("AT32", "LVCMOS12", false), // 0
"led1" -> ("AV34", "LVCMOS12", false), // 1
"led2" -> ("AY30", "LVCMOS12", false), // 2
"led3" -> ("BB32", "LVCMOS12", false), // 3
"led4" -> ("BF32", "LVCMOS12", false), // 4
"led5" -> ("AU37", "LVCMOS12", false), // 5
"led6" -> ("AV36", "LVCMOS12", false), // 6
"led7" -> ("BA37", "LVCMOS12", false), // 7
"sw0" -> ("B17", "LVCMOS12", false), // 8
"sw1" -> ("G16", "LVCMOS12", false), // 9
"sw2" -> ("J16", "LVCMOS12", false), // 10
"sw3" -> ("D21", "LVCMOS12", false) // 11
)
// return list of names (ordered)
def names: Seq[String] = pinMapping.keys.toSeq
// return number of GPIOs
def width: Int = pinMapping.size
}

View File

@@ -1,97 +0,0 @@
package chipyard.fpga.vcu118.bringup
import math.min
import org.chipsalliance.cde.config.{Config, Parameters}
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet, ResourceBinding, Resource, ResourceAddress}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.{MasterPortParams}
import sifive.blocks.devices.gpio.{PeripheryGPIOKey, GPIOParams}
import sifive.blocks.devices.i2c.{PeripheryI2CKey, I2CParams}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
import sifive.fpgashells.shell.{DesignKey}
import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize}
import testchipip.tsi.{PeripheryTSIHostKey, TSIHostParams, TSIHostSerdesParams}
import chipyard.{BuildSystem}
import chipyard.fpga.vcu118.{WithVCU118Tweaks, WithFPGAFrequency, VCU118DDR2Size}
import chipyard.iobinders.{WithGPIOPunchthrough}
class WithBringupPeripherals extends Config((site, here, up) => {
case PeripheryUARTKey => up(PeripheryUARTKey, site) ++ List(UARTParams(address = BigInt(0x64003000L)))
case PeripheryI2CKey => List(I2CParams(address = BigInt(0x64005000L)))
case PeripheryGPIOKey => {
if (BringupGPIOs.width > 0) {
require(BringupGPIOs.width <= 64) // currently only support 64 GPIOs (change addrs to get more)
val gpioAddrs = Seq(BigInt(0x64002000), BigInt(0x64007000))
val maxGPIOSupport = 32 // max gpios supported by SiFive driver (split by 32)
List.tabulate(((BringupGPIOs.width - 1)/maxGPIOSupport) + 1)(n => {
GPIOParams(address = gpioAddrs(n), width = min(BringupGPIOs.width - maxGPIOSupport*n, maxGPIOSupport))
})
}
else {
List.empty[GPIOParams]
}
}
case TSIClockMaxFrequencyKey => 100
case PeripheryTSIHostKey => List(
TSIHostParams(
offchipSerialIfWidth = 4,
mmioBaseAddress = BigInt(0x64006000),
mmioSourceId = 1 << 13, // manager source
serdesParams = TSIHostSerdesParams(
clientPortParams = TLMasterPortParameters.v1(
clients = Seq(TLMasterParameters.v1(
name = "tl-tsi-host-serdes",
sourceId = IdRange(0, (1 << 13))))),
managerPortParams = TLSlavePortParameters.v1(
managers = Seq(TLSlaveParameters.v1(
address = Seq(AddressSet(0, BigInt("FFFFFFFF", 16))), // access everything on chip
regionType = RegionType.UNCACHED,
executable = true,
supportsGet = TransferSizes(1, 64),
supportsPutFull = TransferSizes(1, 64),
supportsPutPartial = TransferSizes(1, 64),
supportsAcquireT = TransferSizes(1, 64),
supportsAcquireB = TransferSizes(1, 64),
supportsArithmetic = TransferSizes(1, 64),
supportsLogical = TransferSizes(1, 64))),
endSinkId = 1 << 6, // manager sink
beatBytes = 8)),
targetMasterPortParams = MasterPortParams(
base = BigInt("80000000", 16),
size = site(VCU118DDR2Size),
beatBytes = 8, // comes from test chip
idBits = 4) // comes from VCU118 idBits in XilinxVCU118MIG
))
})
class WithBringupVCU118System extends Config((site, here, up) => {
case BuildSystem => (p: Parameters) => new BringupVCU118DigitalTop()(p) // use the VCU118-extended bringup digital top
})
class WithBringupAdditions extends Config(
new WithBringupUART ++
new WithBringupI2C ++
new WithBringupGPIO ++
new WithBringupTSIHost ++
new WithTSITLIOPassthrough ++
new WithGPIOPunchthrough ++
new WithBringupPeripherals ++
new WithBringupVCU118System)
class RocketBringupConfig extends Config(
new WithBringupAdditions ++
new WithVCU118Tweaks ++
new chipyard.RocketConfig)
class BoomBringupConfig extends Config(
new WithFPGAFrequency(50) ++
new WithBringupAdditions ++
new WithVCU118Tweaks ++
new chipyard.MegaBoomConfig)

View File

@@ -1,204 +0,0 @@
package chipyard.fpga.vcu118.bringup
import chisel3._
import chisel3.experimental.{attach}
import freechips.rocketchip.diplomacy._
import org.chipsalliance.cde.config.{Parameters, Field}
import freechips.rocketchip.tilelink.{TLInwardNode, TLAsyncCrossingSink}
import sifive.fpgashells.shell._
import sifive.fpgashells.ip.xilinx._
import sifive.fpgashells.shell.xilinx._
import sifive.fpgashells.clocks._
import sifive.fpgashells.devices.xilinx.xilinxvcu118mig.{XilinxVCU118MIGPads, XilinxVCU118MIGParams, XilinxVCU118MIG}
import testchipip.tsi.{TSIHostWidgetIO}
import chipyard.fpga.vcu118.{FMCPMap}
/* Connect the I2C to certain FMC pins */
class BringupI2CVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: I2CDesignInput, val shellInput: I2CShellInput)
extends I2CXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
require(shellInput.index == 0) // only support 1 I2C <-> FMC connection
val i2cLocations = List(List(FMCPMap("K11"), FMCPMap("E2")))
val packagePinsWithPackageIOs = Seq((i2cLocations(shellInput.index)(0), IOPin(io.scl)),
(i2cLocations(shellInput.index)(1), IOPin(io.sda)))
packagePinsWithPackageIOs foreach { case (pin, io) => {
shell.xdc.addPackagePin(io, pin)
shell.xdc.addIOStandard(io, "LVCMOS18")
shell.xdc.addIOB(io)
} }
} }
}
class BringupI2CVCU118ShellPlacer(val shell: VCU118ShellBasicOverlays, val shellInput: I2CShellInput)(implicit val valName: ValName)
extends I2CShellPlacer[VCU118ShellBasicOverlays]
{
def place(designInput: I2CDesignInput) = new BringupI2CVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
/* Connect the UART to certain FMC pins */
class BringupUARTVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
{
shell { InModuleBody {
val packagePinsWithPackageIOs = Seq((FMCPMap("E9"), IOPin(io.ctsn.get)), // unused
(FMCPMap("E10"), IOPin(io.rtsn.get)), // unused
(FMCPMap("C15"), IOPin(io.rxd)),
(FMCPMap("C14"), IOPin(io.txd)))
packagePinsWithPackageIOs foreach { case (pin, io) => {
shell.xdc.addPackagePin(io, pin)
shell.xdc.addIOStandard(io, "LVCMOS18")
shell.xdc.addIOB(io)
} }
// add pullup on ctsn (ctsn is an input that is not used or driven)
packagePinsWithPackageIOs take 1 foreach { case (pin, io) => {
shell.xdc.addPullup(io)
} }
} }
}
class BringupUARTVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: UARTShellInput)(implicit val valName: ValName)
extends UARTShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: UARTDesignInput) = new BringupUARTVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
/* Connect GPIOs to FPGA I/Os */
abstract class GPIOXilinxPlacedOverlay(name: String, di: GPIODesignInput, si: GPIOShellInput)
extends GPIOPlacedOverlay(name, di, si)
{
def shell: XilinxShell
shell { InModuleBody {
(io.gpio zip tlgpioSink.bundle.pins).map { case (ioPin, sinkPin) =>
val iobuf = Module(new IOBUF)
iobuf.suggestName(s"gpio_iobuf")
attach(ioPin, iobuf.io.IO)
sinkPin.i.ival := iobuf.io.O
iobuf.io.T := !sinkPin.o.oe
iobuf.io.I := sinkPin.o.oval
}
} }
}
class BringupGPIOVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: GPIODesignInput, val shellInput: GPIOShellInput, gpioNames: Seq[String])
extends GPIOXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
require(gpioNames.length == io.gpio.length)
val packagePinsWithIOStdWithPackageIOs = (gpioNames zip io.gpio).map { case (name, io) =>
val (pin, iostd, pullupEnable) = BringupGPIOs.pinMapping(name)
(pin, iostd, pullupEnable, IOPin(io))
}
packagePinsWithIOStdWithPackageIOs foreach { case (pin, iostd, pullupEnable, io) => {
shell.xdc.addPackagePin(io, pin)
shell.xdc.addIOStandard(io, iostd)
if (iostd == "LVCMOS12") { shell.xdc.addDriveStrength(io, "8") }
if (pullupEnable) { shell.xdc.addPullup(io) }
} }
} }
}
class BringupGPIOVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: GPIOShellInput, gpioNames: Seq[String])(implicit val valName: ValName)
extends GPIOShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: GPIODesignInput) = new BringupGPIOVCU118PlacedOverlay(shell, valName.name, designInput, shellInput, gpioNames)
}
case class TSIHostShellInput()
case class TSIHostDesignInput(
serialIfWidth: Int,
node: BundleBridgeSource[TSIHostWidgetIO]
)(
implicit val p: Parameters)
case class TSIHostOverlayOutput()
trait TSIHostShellPlacer[Shell] extends ShellPlacer[TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]
case object TSIHostOverlayKey extends Field[Seq[DesignPlacer[TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]]](Nil)
abstract class TSIHostPlacedOverlay[IO <: Data](val name: String, val di: TSIHostDesignInput, val si: TSIHostShellInput)
extends IOPlacedOverlay[IO, TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]
{
implicit val p = di.p
}
case object TSIHostVCU118DDRSize extends Field[BigInt](0x40000000L * 2) // 2GB
class TSIHostVCU118PlacedOverlay(val shell: BringupVCU118FPGATestHarness, name: String, val designInput: TSIHostDesignInput, val shellInput: TSIHostShellInput)
extends TSIHostPlacedOverlay[TSIHostWidgetIO](name, designInput, shellInput)
{
val tlTsiSerialSink = di.node.makeSink()
val tsiIoNode = BundleBridgeSource(() => new TSIHostWidgetIO(di.serialIfWidth))
val topTSIIONode = shell { tsiIoNode.makeSink() }
def overlayOutput = TSIHostOverlayOutput()
def ioFactory = new TSIHostWidgetIO(di.serialIfWidth)
InModuleBody {
// connect TSI serial
val tsiSourcePort = tsiIoNode.bundle
val tsiSinkPort = tlTsiSerialSink.bundle
tsiSinkPort.serial_clock := tsiSourcePort.serial_clock
tsiSourcePort.serial.out.bits := tsiSinkPort.serial.out.bits
tsiSourcePort.serial.out.valid := tsiSinkPort.serial.out.valid
tsiSinkPort.serial.out.ready := tsiSourcePort.serial.out.ready
tsiSinkPort.serial.in.bits := tsiSourcePort.serial.in.bits
tsiSinkPort.serial.in.valid := tsiSourcePort.serial.in.valid
tsiSourcePort.serial.in.ready := tsiSinkPort.serial.in.ready
}
}
case object TSIClockMaxFrequencyKey extends Field[Int](50) // in MHz
class BringupTSIHostVCU118PlacedOverlay(override val shell: BringupVCU118FPGATestHarness, override val name: String, override val designInput: TSIHostDesignInput, override val shellInput: TSIHostShellInput)
extends TSIHostVCU118PlacedOverlay(shell, name, designInput, shellInput)
{
// connect the TSI port
shell { InModuleBody {
// connect TSI signals
val tsiPort = topTSIIONode.bundle
io <> tsiPort
require(di.serialIfWidth == 4)
val clkIo = IOPin(io.serial_clock)
val packagePinsWithPackageIOs = Seq(
(FMCPMap("D8"), clkIo),
(FMCPMap("D17"), IOPin(io.serial.out.ready)),
(FMCPMap("D18"), IOPin(io.serial.out.valid)),
(FMCPMap("D11"), IOPin(io.serial.out.bits, 0)),
(FMCPMap("D12"), IOPin(io.serial.out.bits, 1)),
(FMCPMap("D14"), IOPin(io.serial.out.bits, 2)),
(FMCPMap("D15"), IOPin(io.serial.out.bits, 3)),
(FMCPMap("D26"), IOPin(io.serial.in.ready)),
(FMCPMap("D27"), IOPin(io.serial.in.valid)),
(FMCPMap("D20"), IOPin(io.serial.in.bits, 0)),
(FMCPMap("D21"), IOPin(io.serial.in.bits, 1)),
(FMCPMap("D23"), IOPin(io.serial.in.bits, 2)),
(FMCPMap("D24"), IOPin(io.serial.in.bits, 3)))
packagePinsWithPackageIOs foreach { case (pin, io) => {
shell.xdc.addPackagePin(io, pin)
shell.xdc.addIOStandard(io, "LVCMOS18")
} }
// Don't add an IOB to the clock
(packagePinsWithPackageIOs take 1) foreach { case (pin, io) => {
shell.xdc.addIOB(io)
} }
shell.sdc.addClock("TSI_CLK", clkIo, p(TSIClockMaxFrequencyKey))
shell.sdc.addGroup(pins = Seq(clkIo))
shell.xdc.clockDedicatedRouteFalse(clkIo)
} }
}
class BringupTSIHostVCU118ShellPlacer(shell: BringupVCU118FPGATestHarness, val shellInput: TSIHostShellInput)(implicit val valName: ValName)
extends TSIHostShellPlacer[BringupVCU118FPGATestHarness] {
def place(designInput: TSIHostDesignInput) = new BringupTSIHostVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}

View File

@@ -1,26 +0,0 @@
package chipyard.fpga.vcu118.bringup
import chisel3._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.system._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import chipyard.{DigitalTop, DigitalTopModule}
// ------------------------------------
// Bringup VCU118 DigitalTop
// ------------------------------------
class BringupVCU118DigitalTop(implicit p: Parameters) extends DigitalTop
with sifive.blocks.devices.i2c.HasPeripheryI2C
with testchipip.tsi.HasPeripheryTSIHostWidget
{
override lazy val module = new BringupVCU118DigitalTopModule(this)
}
class BringupVCU118DigitalTopModule[+L <: BringupVCU118DigitalTop](l: L) extends DigitalTopModule(l)
with sifive.blocks.devices.i2c.HasPeripheryI2CModuleImp

View File

@@ -1,51 +0,0 @@
package chipyard.fpga.vcu118.bringup
import chisel3._
import chisel3.experimental.{Analog, IO, BaseModule}
import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.tilelink.{TLBundle}
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp, UARTPortIO}
import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
import sifive.blocks.devices.i2c.{HasPeripheryI2CModuleImp, I2CPort}
import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp, GPIOPortIO}
import testchipip.tsi.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
import chipyard.harness._
import chipyard.iobinders._
/*** UART ***/
class WithBringupUART extends HarnessBinder({
case (th: BringupVCU118FPGATestHarnessImp, port: UARTPort, chipId: Int) => {
th.bringupOuter.io_fmc_uart_bb.bundle <> port.io
}
})
/*** I2C ***/
class WithBringupI2C extends HarnessBinder({
case (th: BringupVCU118FPGATestHarnessImp, port: chipyard.iobinders.I2CPort, chipId: Int) => {
th.bringupOuter.io_i2c_bb.bundle <> port.io
}
})
/*** GPIO ***/
class WithBringupGPIO extends HarnessBinder({
case (th: BringupVCU118FPGATestHarnessImp, port: GPIOPort, chipId: Int) => {
th.bringupOuter.io_gpio_bb(port.pinId).bundle <> port.io
}
})
/*** TSI Host Widget ***/
class WithBringupTSIHost extends HarnessBinder({
case (th: BringupVCU118FPGATestHarnessImp, port: TLMemPort, chipId: Int) => {
val tsiBundles = th.bringupOuter.tsiDdrClient.out.map(_._1)
val tsiDdrClientBundle = Wire(new HeterogeneousBag(tsiBundles.map(_.cloneType)))
tsiBundles.zip(tsiDdrClientBundle).foreach { case (bundle, io) => bundle <> io }
tsiDdrClientBundle <> port.io
}
case (th: BringupVCU118FPGATestHarnessImp, port: TSIHostWidgetPort, chipId: Int) => {
th.bringupOuter.io_tsi_serial_bb.bundle <> port.io
}
})

View File

@@ -1,30 +0,0 @@
package chipyard.fpga.vcu118.bringup
import chisel3._
import chisel3.reflect.DataMirror
import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.tilelink.{TLBundle}
import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp}
import sifive.blocks.devices.i2c.{HasPeripheryI2CModuleImp}
import testchipip.tsi.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
import chipyard.iobinders.{OverrideIOBinder, Port, TLMemPort}
case class TSIHostWidgetPort(val getIO: () => TSIHostWidgetIO)
extends Port[TSIHostWidgetIO]
class WithTSITLIOPassthrough extends OverrideIOBinder({
(system: HasPeripheryTSIHostWidget) => {
require(system.tsiTLMem.size == 1)
val io_tsi_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.tsiTLMem.head)).suggestName("tsi_tl_slave")
io_tsi_tl_mem_pins_temp <> system.tsiTLMem.head
require(system.tsiSerial.size == 1)
val io_tsi_serial_pins_temp = IO(DataMirror.internal.chiselTypeClone[TSIHostWidgetIO](system.tsiSerial.head)).suggestName("tsi_serial")
io_tsi_serial_pins_temp <> system.tsiSerial.head
(Seq(TLMemPort(() => io_tsi_tl_mem_pins_temp), TSIHostWidgetPort(() => io_tsi_serial_pins_temp)), Nil)
}
})

View File

@@ -1,99 +0,0 @@
package chipyard.fpga.vcu118.bringup
import chisel3._
import freechips.rocketchip.diplomacy._
import org.chipsalliance.cde.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.prci._
import sifive.fpgashells.shell.xilinx._
import sifive.fpgashells.ip.xilinx._
import sifive.fpgashells.shell._
import sifive.fpgashells.clocks._
import sifive.blocks.devices.uart._
import sifive.blocks.devices.spi._
import sifive.blocks.devices.i2c._
import sifive.blocks.devices.gpio._
import testchipip.tsi.{HasPeripheryTSIHostWidget, PeripheryTSIHostKey, TSIHostWidgetIO}
import testchipip.util.{TLSinkSetter}
import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp, DDR2VCU118ShellPlacer, SysClock2VCU118ShellPlacer}
import chipyard.{ChipTop}
import chipyard.harness._
class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118FPGATestHarness {
/*** UART ***/
require(dp(PeripheryUARTKey).size == 2)
// 2nd UART goes to the FMC UART
val uart_fmc = Overlay(UARTOverlayKey, new BringupUARTVCU118ShellPlacer(this, UARTShellInput()))
val io_fmc_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).last)))
dp(UARTOverlayKey).last.place(UARTDesignInput(io_fmc_uart_bb))
/*** I2C ***/
val i2c = Overlay(I2COverlayKey, new BringupI2CVCU118ShellPlacer(this, I2CShellInput()))
val io_i2c_bb = BundleBridgeSource(() => (new I2CPort))
dp(I2COverlayKey).head.place(I2CDesignInput(io_i2c_bb))
/*** GPIO ***/
val gpio = Seq.tabulate(dp(PeripheryGPIOKey).size)(i => {
val maxGPIOSupport = 32 // max gpio per gpio chip
val names = BringupGPIOs.names.slice(maxGPIOSupport*i, maxGPIOSupport*(i+1))
Overlay(GPIOOverlayKey, new BringupGPIOVCU118ShellPlacer(this, GPIOShellInput(), names))
})
val io_gpio_bb = dp(PeripheryGPIOKey).map { p => BundleBridgeSource(() => (new GPIOPortIO(p))) }
(dp(GPIOOverlayKey) zip dp(PeripheryGPIOKey)).zipWithIndex.map { case ((placer, params), i) =>
placer.place(GPIODesignInput(params, io_gpio_bb(i)))
}
/*** TSI Host Widget ***/
require(dp(PeripheryTSIHostKey).size == 1)
// use the 2nd system clock for the 2nd DDR
val sysClk2Node = dp(ClockInputOverlayKey).last.place(ClockInputDesignInput()).overlayOutput.node
val ddr2PLL = dp(PLLFactoryKey)()
ddr2PLL := sysClk2Node
val ddr2Clock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey))
val ddr2Wrangler = LazyModule(new ResetWrangler)
val ddr2Group = ClockGroup()
ddr2Clock := ddr2Wrangler.node := ddr2Group := ddr2PLL
val tsi_host = Overlay(TSIHostOverlayKey, new BringupTSIHostVCU118ShellPlacer(this, TSIHostShellInput()))
val ddr2Node = dp(DDROverlayKey).last.place(DDRDesignInput(dp(PeripheryTSIHostKey).head.targetMasterPortParams.base, ddr2Wrangler.node, ddr2PLL)).overlayOutput.ddr
val io_tsi_serial_bb = BundleBridgeSource(() => (new TSIHostWidgetIO(dp(PeripheryTSIHostKey).head.offchipSerialIfWidth)))
dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(dp(PeripheryTSIHostKey).head.offchipSerialIfWidth, io_tsi_serial_bb))
// connect 1 mem. channel to the FPGA DDR
val tsiDdrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
name = "chip_ddr",
sourceId = IdRange(0, 64)
)))))
(ddr2Node
:= TLFragmenter(8,64,holdFirstDeny=true)
:= TLCacheCork()
:= TLAtomicAutomata(passthrough=false)
:= TLSinkSetter(64)
:= tsiDdrClient)
// module implementation
override lazy val module = new BringupVCU118FPGATestHarnessImp(this)
}
class BringupVCU118FPGATestHarnessImp(_outer: BringupVCU118FPGATestHarness) extends VCU118FPGATestHarnessImp(_outer) {
lazy val bringupOuter = _outer
}