@@ -42,17 +42,14 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
|
||||
val topDesign = LazyModule(p(BuildTop)(dp))
|
||||
|
||||
// place all clocks in the shell
|
||||
dp(ClockInputOverlayKey).foreach { _.place(ClockInputDesignInput()) }
|
||||
require(dp(ClockInputOverlayKey).size >= 1)
|
||||
val sysClkNode = dp(ClockInputOverlayKey)(0).place(ClockInputDesignInput()).overlayOutput.node
|
||||
|
||||
/*** Connect/Generate clocks ***/
|
||||
|
||||
// connect to the PLL that will generate multiple clocks
|
||||
val harnessSysPLL = dp(PLLFactoryKey)()
|
||||
sys_clock.get() match {
|
||||
case Some(x : SysClockVCU118PlacedOverlay) => {
|
||||
harnessSysPLL := x.node
|
||||
}
|
||||
}
|
||||
harnessSysPLL := sysClkNode
|
||||
|
||||
// create and connect to the dutClock
|
||||
val dutClock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey))
|
||||
@@ -60,14 +57,6 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
|
||||
val dutGroup = ClockGroup()
|
||||
dutClock := dutWrangler.node := dutGroup := harnessSysPLL
|
||||
|
||||
// connect ref clock to dummy sink node
|
||||
ref_clock.get() match {
|
||||
case Some(x : RefClockVCU118PlacedOverlay) => {
|
||||
val sink = ClockSinkNode(Seq(ClockSinkParameters()))
|
||||
sink := x.node
|
||||
}
|
||||
}
|
||||
|
||||
/*** UART ***/
|
||||
|
||||
// 1st UART goes to the VCU118 dedicated UART
|
||||
@@ -84,7 +73,7 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
|
||||
|
||||
/*** DDR ***/
|
||||
|
||||
val ddrPlaced = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtMem).get.master.base, dutWrangler.node, harnessSysPLL))
|
||||
val ddrNode = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtMem).get.master.base, dutWrangler.node, harnessSysPLL)).overlayOutput.ddr
|
||||
|
||||
// connect 1 mem. channel to the FPGA DDR
|
||||
val inParams = topDesign match { case td: ChipTop =>
|
||||
@@ -93,7 +82,7 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
|
||||
}
|
||||
}
|
||||
val ddrClient = TLClientNode(Seq(inParams.master))
|
||||
ddrPlaced.overlayOutput.ddr := ddrClient
|
||||
ddrNode := ddrClient
|
||||
|
||||
// module implementation
|
||||
override lazy val module = new VCU118FPGATestHarnessImp(this)
|
||||
@@ -107,12 +96,10 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod
|
||||
_outer.xdc.addPackagePin(reset, "L19")
|
||||
_outer.xdc.addIOStandard(reset, "LVCMOS12")
|
||||
|
||||
val reset_ibuf = Module(new IBUF)
|
||||
reset_ibuf.io.I := reset
|
||||
val resetIBUF = Module(new IBUF)
|
||||
resetIBUF.io.I := reset
|
||||
|
||||
val sysclk: Clock = _outer.sys_clock.get() match {
|
||||
case Some(x: SysClockVCU118PlacedOverlay) => x.clock
|
||||
}
|
||||
val sysclk: Clock = _outer.sysClkNode.out.head._1.clock
|
||||
|
||||
val powerOnReset: Bool = PowerOnResetFPGAOnly(sysclk)
|
||||
_outer.sdc.addAsyncPath(Seq(powerOnReset))
|
||||
@@ -122,7 +109,7 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod
|
||||
case _ => false.B
|
||||
}
|
||||
|
||||
_outer.pllReset := (reset_ibuf.io.O || powerOnReset || ereset)
|
||||
_outer.pllReset := (resetIBUF.io.O || powerOnReset || ereset)
|
||||
|
||||
// reset setup
|
||||
val hReset = Wire(Reset())
|
||||
|
||||
@@ -4,6 +4,8 @@ import math.min
|
||||
|
||||
import freechips.rocketchip.config.{Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet, ResourceBinding, Resource, ResourceAddress}
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
import sifive.blocks.devices.gpio.{PeripheryGPIOKey, GPIOParams}
|
||||
import sifive.blocks.devices.i2c.{PeripheryI2CKey, I2CParams}
|
||||
@@ -13,6 +15,8 @@ import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
||||
import sifive.fpgashells.shell.{DesignKey}
|
||||
import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize}
|
||||
|
||||
import testchipip.{PeripheryTSIHostKey, TSIHostParams, TSIHostSerdesParams}
|
||||
|
||||
import chipyard.{BuildSystem}
|
||||
|
||||
import chipyard.fpga.vcu118.{WithVCU118Tweaks, WithFPGAFrequency}
|
||||
@@ -34,6 +38,30 @@ class WithBringupPeripherals extends Config((site, here, up) => {
|
||||
List.empty[GPIOParams]
|
||||
}
|
||||
}
|
||||
case PeripheryTSIHostKey => List(
|
||||
TSIHostParams(
|
||||
serialIfWidth = 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))),
|
||||
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))))
|
||||
})
|
||||
|
||||
class WithBringupVCU118System extends Config((site, here, up) => {
|
||||
@@ -45,6 +73,8 @@ class WithBringupAdditions extends Config(
|
||||
new WithBringupSPI ++
|
||||
new WithBringupI2C ++
|
||||
new WithBringupGPIO ++
|
||||
new WithBringupTSIHost ++
|
||||
new WithTSITLIOPassthrough ++
|
||||
new WithI2CIOPassthrough ++
|
||||
new WithGPIOIOPassthrough ++
|
||||
new WithBringupPeripherals ++
|
||||
|
||||
@@ -4,10 +4,16 @@ import chisel3._
|
||||
import chisel3.experimental.{attach}
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.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.{TSIHostParams, TSIHostWidgetIO}
|
||||
|
||||
import chipyard.fpga.vcu118.{FMCPMap}
|
||||
|
||||
@@ -144,4 +150,185 @@ class BringupGPIOVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInp
|
||||
def place(designInput: GPIODesignInput) = new BringupGPIOVCU118PlacedOverlay(shell, valName.name, designInput, shellInput, gpioNames)
|
||||
}
|
||||
|
||||
case class TSIHostShellInput()
|
||||
case class TSIHostDesignInput(
|
||||
wrangler: ClockAdapterNode,
|
||||
corePLL: PLLNode,
|
||||
tsiHostParams: TSIHostParams,
|
||||
node: BundleBridgeSource[TSIHostWidgetIO],
|
||||
vc7074gbdimm: Boolean = false
|
||||
)(
|
||||
implicit val p: Parameters)
|
||||
case class TSIHostOverlayOutput(ddr: TLInwardNode)
|
||||
trait TSIHostShellPlacer[Shell] extends ShellPlacer[TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]
|
||||
|
||||
class TSIHostWithDDRIO(val w: Int, val size: BigInt) extends Bundle {
|
||||
val tsi = new TSIHostWidgetIO(w)
|
||||
val ddr = new XilinxVCU118MIGPads(size)
|
||||
}
|
||||
|
||||
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[TSIHostWithDDRIO](name, designInput, shellInput)
|
||||
{
|
||||
val size = p(TSIHostVCU118DDRSize)
|
||||
|
||||
// connect the DDR
|
||||
val migParams = XilinxVCU118MIGParams(address = AddressSet.misaligned(di.tsiHostParams.targetBaseAddress, size))
|
||||
val mig = LazyModule(new XilinxVCU118MIG(migParams))
|
||||
val ioNode = BundleBridgeSource(() => mig.module.io.cloneType)
|
||||
val topIONode = shell { ioNode.makeSink() }
|
||||
val ddrUI = shell { ClockSourceNode(freqMHz = 200) }
|
||||
val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
|
||||
areset := designInput.wrangler := ddrUI
|
||||
|
||||
// since this uses a separate clk/rst need to put an async crossing
|
||||
val asyncSink = LazyModule(new TLAsyncCrossingSink())
|
||||
val migClkRstNode = BundleBridgeSource(() => new Bundle {
|
||||
val clock = Output(Clock())
|
||||
val reset = Output(Bool())
|
||||
})
|
||||
val topMigClkRstIONode = shell { migClkRstNode.makeSink() }
|
||||
|
||||
// connect the TSI serial
|
||||
val tlTsiSerialSink = di.node.makeSink()
|
||||
val tsiIoNode = BundleBridgeSource(() => new TSIHostWidgetIO(di.tsiHostParams.serialIfWidth))
|
||||
val topTSIIONode = shell { tsiIoNode.makeSink() }
|
||||
|
||||
def overlayOutput = TSIHostOverlayOutput(ddr = mig.node)
|
||||
def ioFactory = new TSIHostWithDDRIO(di.tsiHostParams.serialIfWidth, size)
|
||||
|
||||
InModuleBody {
|
||||
// connect MIG
|
||||
ioNode.bundle <> mig.module.io
|
||||
|
||||
// setup async crossing
|
||||
asyncSink.module.clock := migClkRstNode.bundle.clock
|
||||
asyncSink.module.reset := migClkRstNode.bundle.reset
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// connect the DDR port
|
||||
shell { InModuleBody {
|
||||
require (shell.sys_clock2.get.isDefined, "Use of TSIHostVCU118Overlay depends on SysClock2VCU118Overlay")
|
||||
val (sys, _) = shell.sys_clock2.get.get.overlayOutput.node.out(0)
|
||||
val (ui, _) = ddrUI.out(0)
|
||||
val (ar, _) = areset.in(0)
|
||||
|
||||
// connect the async fifo sink to sys_clock2
|
||||
topMigClkRstIONode.bundle.clock := sys.clock
|
||||
topMigClkRstIONode.bundle.reset := sys.reset
|
||||
|
||||
val ddrPort = topIONode.bundle.port
|
||||
io.ddr <> ddrPort
|
||||
ui.clock := ddrPort.c0_ddr4_ui_clk
|
||||
ui.reset := /*!ddrPort.mmcm_locked ||*/ ddrPort.c0_ddr4_ui_clk_sync_rst
|
||||
ddrPort.c0_sys_clk_i := sys.clock.asUInt
|
||||
ddrPort.sys_rst := sys.reset // pllReset
|
||||
ddrPort.c0_ddr4_aresetn := !ar.reset
|
||||
|
||||
// This was just copied from the SiFive example, but it's hard to follow.
|
||||
// The pins are emitted in the following order:
|
||||
// adr[0->13], we_n, cas_n, ras_n, bg, ba[0->1], reset_n, act_n, ck_c, ck_t, cke, cs_n, odt, dq[0->63], dqs_c[0->7], dqs_t[0->7], dm_dbi_n[0->7]
|
||||
val allddrpins = Seq(
|
||||
"AM27", "AL27", "AP26", "AP25", "AN28", "AM28", "AP28", "AP27", "AN26", "AM26", "AR28", "AR27", "AV25", "AT25", // adr[0->13]
|
||||
"AV28", "AU26", "AV26", "AU27", // we_n, cas_n, ras_n, bg
|
||||
"AR25", "AU28", // ba[0->1]
|
||||
"BD35", "AN25", "AT27", "AT26", "AW28", "AY29", "BB29", // reset_n, act_n, ck_c, ck_t, cke, cs_n, odt
|
||||
"BD30", "BE30", "BD32", "BE33", "BC33", "BD33", "BC31", "BD31", "BA32", "BB33", "BA30", "BA31", "AW31", "AW32", "AY32", "AY33", // dq[0->15]
|
||||
"AV30", "AW30", "AU33", "AU34", "AT31", "AU32", "AU31", "AV31", "AR33", "AT34", "AT29", "AT30", "AP30", "AR30", "AN30", "AN31", // dq[16->31]
|
||||
"BE34", "BF34", "BC35", "BC36", "BD36", "BE37", "BF36", "BF37", "BD37", "BE38", "BC39", "BD40", "BB38", "BB39", "BC38", "BD38", // dq[32->47]
|
||||
"BB36", "BB37", "BA39", "BA40", "AW40", "AY40", "AY38", "AY39", "AW35", "AW36", "AU40", "AV40", "AU38", "AU39", "AV38", "AV39", // dq[48->63]
|
||||
"BF31", "BA34", "AV29", "AP32", "BF35", "BF39", "BA36", "AW38", // dqs_c[0->7]
|
||||
"BF30", "AY34", "AU29", "AP31", "BE35", "BE39", "BA35", "AW37", // dqs_t[0->7]
|
||||
"BE32", "BB31", "AV33", "AR32", "BC34", "BE40", "AY37", "AV35") // dm_dbi_n[0->7]
|
||||
|
||||
(IOPin.of(io.ddr) zip allddrpins) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
|
||||
} }
|
||||
|
||||
shell.sdc.addGroup(pins = Seq(mig.island.module.blackbox.io.c0_ddr4_ui_clk))
|
||||
}
|
||||
|
||||
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.tsi <> tsiPort
|
||||
|
||||
require(di.tsiHostParams.serialIfWidth == 4)
|
||||
|
||||
val clkIo = IOPin(io.tsi.serial_clock)
|
||||
val packagePinsWithPackageIOs = Seq(
|
||||
(FMCPMap("D8"), clkIo),
|
||||
(FMCPMap("D17"), IOPin(io.tsi.serial.out.ready)),
|
||||
(FMCPMap("D18"), IOPin(io.tsi.serial.out.valid)),
|
||||
(FMCPMap("D11"), IOPin(io.tsi.serial.out.bits, 0)),
|
||||
(FMCPMap("D12"), IOPin(io.tsi.serial.out.bits, 1)),
|
||||
(FMCPMap("D14"), IOPin(io.tsi.serial.out.bits, 2)),
|
||||
(FMCPMap("D15"), IOPin(io.tsi.serial.out.bits, 3)),
|
||||
(FMCPMap("D26"), IOPin(io.tsi.serial.in.ready)),
|
||||
(FMCPMap("D27"), IOPin(io.tsi.serial.in.valid)),
|
||||
(FMCPMap("D20"), IOPin(io.tsi.serial.in.bits, 0)),
|
||||
(FMCPMap("D21"), IOPin(io.tsi.serial.in.bits, 1)),
|
||||
(FMCPMap("D23"), IOPin(io.tsi.serial.in.bits, 2)),
|
||||
(FMCPMap("D24"), IOPin(io.tsi.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, 50)
|
||||
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)
|
||||
}
|
||||
|
||||
class SysClock2VCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
|
||||
extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput)
|
||||
{
|
||||
val node = shell { ClockSourceNode(freqMHz = 250, jitterPS = 50)(ValName(name)) }
|
||||
|
||||
shell { InModuleBody {
|
||||
shell.xdc.addPackagePin(io.p, "AW26")
|
||||
shell.xdc.addPackagePin(io.n, "AW27")
|
||||
shell.xdc.addIOStandard(io.p, "DIFF_SSTL12")
|
||||
shell.xdc.addIOStandard(io.n, "DIFF_SSTL12")
|
||||
} }
|
||||
}
|
||||
class SysClock2VCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
|
||||
extends ClockInputShellPlacer[VCU118ShellBasicOverlays]
|
||||
{
|
||||
def place(designInput: ClockInputDesignInput) = new SysClock2VCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
import chipyard.fpga.vcu118.{VCU118DigitalTop, VCU118DigitalTopModule}
|
||||
|
||||
// ------------------------------------
|
||||
// BringupVCU118 DigitalTop
|
||||
// ------------------------------------
|
||||
|
||||
class BringupVCU118DigitalTop(implicit p: Parameters) extends VCU118DigitalTop
|
||||
with sifive.blocks.devices.i2c.HasPeripheryI2C
|
||||
with testchipip.HasPeripheryTSIHostWidget
|
||||
{
|
||||
override lazy val module = new BringupVCU118DigitalTopModule(this)
|
||||
}
|
||||
|
||||
@@ -3,11 +3,16 @@ 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.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
||||
|
||||
import chipyard.{HasHarnessSignalReferences}
|
||||
import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder}
|
||||
|
||||
@@ -54,3 +59,25 @@ class WithBringupGPIO extends OverrideHarnessBinder({
|
||||
} }
|
||||
}
|
||||
})
|
||||
|
||||
/*** TSI Host Widget ***/
|
||||
class WithBringupTSIHost extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryTSIHostWidget, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
|
||||
require(ports.size == 2) // 1st goes to the TL mem, 2nd goes to the serial link
|
||||
|
||||
ports.head match { case tlPort: HeterogeneousBag[TLBundle] =>
|
||||
val tsiBundles = vcu118th.bringupOuter.tsiDdrClient.out.map(_._1)
|
||||
val tsiDdrClientBundle = Wire(new HeterogeneousBag(tsiBundles.map(_.cloneType)))
|
||||
tsiBundles.zip(tsiDdrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
||||
tsiDdrClientBundle <> tlPort
|
||||
}
|
||||
|
||||
ports.last match { case serialPort: TSIHostWidgetIO =>
|
||||
vcu118th.bringupOuter.io_tsi_serial_bb.bundle <> serialPort
|
||||
}
|
||||
} }
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@ package chipyard.fpga.vcu118.bringup
|
||||
import chisel3._
|
||||
import chisel3.experimental.{IO, 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.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
||||
|
||||
import chipyard.iobinders.{OverrideIOBinder}
|
||||
|
||||
class WithGPIOIOPassthrough extends OverrideIOBinder({
|
||||
@@ -27,3 +32,16 @@ class WithI2CIOPassthrough extends OverrideIOBinder({
|
||||
(io_i2c_pins_temp, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
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(io_tsi_tl_mem_pins_temp, io_tsi_serial_pins_temp), Nil)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -17,8 +17,12 @@ import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.i2c._
|
||||
import sifive.blocks.devices.gpio._
|
||||
|
||||
import testchipip.{HasPeripheryTSIHostWidget, PeripheryTSIHostKey, TSIHostWidgetIO, TLSinkSetter}
|
||||
|
||||
import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp}
|
||||
|
||||
import chipyard.{ChipTop}
|
||||
|
||||
class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118FPGATestHarness {
|
||||
|
||||
/*** UART ***/
|
||||
@@ -63,6 +67,40 @@ class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends
|
||||
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 sys_clock2 = Overlay(ClockInputOverlayKey, new SysClock2VCU118ShellPlacer(this, ClockInputShellInput()))
|
||||
val sysClk2Node = dp(ClockInputOverlayKey).last.place(ClockInputDesignInput()).overlayOutput.node
|
||||
|
||||
val ddr2PLL = dp(PLLFactoryKey)()
|
||||
ddr2PLL := sysClk2Node
|
||||
|
||||
val ddrClock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey))
|
||||
val ddrWrangler = LazyModule(new ResetWrangler)
|
||||
val ddrGroup = ClockGroup()
|
||||
ddrClock := ddrWrangler.node := ddrGroup := ddr2PLL
|
||||
|
||||
val tsi_host = Overlay(TSIHostOverlayKey, new BringupTSIHostVCU118ShellPlacer(this, TSIHostShellInput()))
|
||||
|
||||
val io_tsi_serial_bb = BundleBridgeSource(() => (new TSIHostWidgetIO(dp(PeripheryTSIHostKey).head.serialIfWidth)))
|
||||
val tsiDdrNode = dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(ddrWrangler.node, ddr2PLL, dp(PeripheryTSIHostKey).head, io_tsi_serial_bb)).overlayOutput.ddr
|
||||
|
||||
// connect 1 mem. channel to the FPGA DDR
|
||||
val inTsiParams = topDesign match { case td: ChipTop =>
|
||||
td.lazySystem match { case lsys: HasPeripheryTSIHostWidget =>
|
||||
lsys.tsiMemTLNodes.head.edges.in(0)
|
||||
}
|
||||
}
|
||||
val tsiDdrClient = TLClientNode(Seq(inTsiParams.master))
|
||||
(tsiDdrNode
|
||||
:= TLFragmenter(8,64,holdFirstDeny=true)
|
||||
:= TLCacheCork()
|
||||
:= TLAtomicAutomata(passthrough=false)
|
||||
:= TLSinkSetter(64)
|
||||
:= tsiDdrClient)
|
||||
|
||||
// module implementation
|
||||
override lazy val module = new BringupVCU118FPGATestHarnessImp(this)
|
||||
}
|
||||
|
||||
Submodule generators/testchipip updated: 03af7aa539...e956a60cbf
Reference in New Issue
Block a user