Use 2nd system clock for TSI DDR | Small cleanups
This commit is contained in:
@@ -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 sys_clk_placed = dp(ClockInputOverlayKey)(0).place(ClockInputDesignInput())
|
||||
|
||||
/*** 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 := sys_clk_placed.overlayOutput.node
|
||||
|
||||
// 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
|
||||
@@ -110,9 +99,7 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod
|
||||
val reset_ibuf = Module(new IBUF)
|
||||
reset_ibuf.io.I := reset
|
||||
|
||||
val sysclk: Clock = _outer.sys_clock.get() match {
|
||||
case Some(x: SysClockVCU118PlacedOverlay) => x.clock
|
||||
}
|
||||
val sysclk: Clock = _outer.sys_clk_placed.overlayOutput.node.out.head._1.clock
|
||||
|
||||
val powerOnReset: Bool = PowerOnResetFPGAOnly(sysclk)
|
||||
_outer.sdc.addAsyncPath(Seq(powerOnReset))
|
||||
|
||||
@@ -5,7 +5,7 @@ import chisel3.experimental.{attach}
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import freechips.rocketchip.tilelink.{TLInwardNode}
|
||||
import freechips.rocketchip.tilelink.{TLInwardNode, TLAsyncCrossingSink}
|
||||
|
||||
import sifive.fpgashells.shell._
|
||||
import sifive.fpgashells.ip.xilinx._
|
||||
@@ -176,7 +176,7 @@ abstract class TSIHostPlacedOverlay[IO <: Data](val name: String, val di: TSIHos
|
||||
}
|
||||
|
||||
case object TSIHostVCU118DDRSize extends Field[BigInt](0x40000000L * 2) // 2GB
|
||||
class TSIHostVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: TSIHostDesignInput, val shellInput: TSIHostShellInput)
|
||||
class TSIHostVCU118PlacedOverlay(val shell: BringupVCU118FPGATestHarness, name: String, val designInput: TSIHostDesignInput, val shellInput: TSIHostShellInput)
|
||||
extends TSIHostPlacedOverlay[TSIHostWithDDRIO](name, designInput, shellInput)
|
||||
{
|
||||
val size = p(TSIHostVCU118DDRSize)
|
||||
@@ -190,6 +190,14 @@ class TSIHostVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: Stri
|
||||
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))
|
||||
@@ -202,6 +210,10 @@ class TSIHostVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: Stri
|
||||
// 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
|
||||
@@ -216,10 +228,15 @@ class TSIHostVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: Stri
|
||||
|
||||
// connect the DDR port
|
||||
shell { InModuleBody {
|
||||
require (shell.sys_clock.get.isDefined, "Use of DDRVCU118Overlay depends on SysClockVCU118Overlay")
|
||||
val (sys, _) = shell.sys_clock.get.get.overlayOutput.node.out(0)
|
||||
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
|
||||
@@ -250,7 +267,7 @@ class TSIHostVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: Stri
|
||||
shell.sdc.addGroup(pins = Seq(mig.island.module.blackbox.io.c0_ddr4_ui_clk))
|
||||
}
|
||||
|
||||
class BringupTSIHostVCU118PlacedOverlay(override val shell: VCU118ShellBasicOverlays, override val name: String, override val designInput: TSIHostDesignInput, override val shellInput: TSIHostShellInput)
|
||||
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
|
||||
@@ -293,7 +310,25 @@ class BringupTSIHostVCU118PlacedOverlay(override val shell: VCU118ShellBasicOver
|
||||
} }
|
||||
}
|
||||
|
||||
class BringupTSIHostVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: TSIHostShellInput)(implicit val valName: ValName)
|
||||
extends TSIHostShellPlacer[VCU118ShellBasicOverlays] {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -70,10 +70,22 @@ class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends
|
||||
/*** 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 sys_clk2_placed = dp(ClockInputOverlayKey).last.place(ClockInputDesignInput())
|
||||
|
||||
val ddr2PLL = dp(PLLFactoryKey)()
|
||||
ddr2PLL := sys_clk2_placed.overlayOutput.node
|
||||
|
||||
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 tsiDdrPlaced = dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(dutWrangler.node, harnessSysPLL, dp(PeripheryTSIHostKey).head, io_tsi_serial_bb))
|
||||
val tsiDdrPlaced = dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(ddrWrangler.node, ddr2PLL, dp(PeripheryTSIHostKey).head, io_tsi_serial_bb))
|
||||
|
||||
// connect 1 mem. channel to the FPGA DDR
|
||||
val inTsiParams = topDesign match { case td: ChipTop =>
|
||||
|
||||
Reference in New Issue
Block a user