Basic working with UART
This commit is contained in:
@@ -26,7 +26,7 @@ CONFIG := FakeBringupConfig
|
|||||||
CONFIG_PACKAGE := chipyard.fpga.vcu118
|
CONFIG_PACKAGE := chipyard.fpga.vcu118
|
||||||
GENERATOR_PACKAGE := chipyard
|
GENERATOR_PACKAGE := chipyard
|
||||||
TB := none # unused
|
TB := none # unused
|
||||||
TOP := VCU118Platform
|
TOP := ChipTop
|
||||||
|
|
||||||
# setup the board to use
|
# setup the board to use
|
||||||
BOARD ?= arty
|
BOARD ?= arty
|
||||||
|
|||||||
@@ -73,11 +73,11 @@ class FakeBringupConfig extends Config(
|
|||||||
new WithBringupUART ++
|
new WithBringupUART ++
|
||||||
//new WithBringupSPI ++
|
//new WithBringupSPI ++
|
||||||
//new WithBringupI2C ++
|
//new WithBringupI2C ++
|
||||||
new WithBringupGPIO ++
|
//new WithBringupGPIO ++
|
||||||
new chipyard.iobinders.WithUARTIOCells ++
|
new WithUARTIOPassthrough ++
|
||||||
//new WithSPICells ++
|
//new WithSPICells ++
|
||||||
//new WithI2CCells ++
|
//new WithI2CCells ++
|
||||||
new chipyard.iobinders.WithGPIOCells ++
|
//new chipyard.iobinders.WithGPIOCells ++
|
||||||
//new WithBringupDDR ++
|
//new WithBringupDDR ++
|
||||||
new WithBringupPeripherals ++
|
new WithBringupPeripherals ++
|
||||||
new chipyard.config.WithNoSubsystemDrivenClocks ++
|
new chipyard.config.WithNoSubsystemDrivenClocks ++
|
||||||
|
|||||||
@@ -20,14 +20,31 @@ import sifive.blocks.devices.gpio._
|
|||||||
|
|
||||||
import chipyard.fpga.vcu118.bringup.{BringupGPIOs, BringupUARTVCU118ShellPlacer, BringupSPIVCU118ShellPlacer, BringupI2CVCU118ShellPlacer, BringupGPIOVCU118ShellPlacer}
|
import chipyard.fpga.vcu118.bringup.{BringupGPIOs, BringupUARTVCU118ShellPlacer, BringupSPIVCU118ShellPlacer, BringupI2CVCU118ShellPlacer, BringupGPIOVCU118ShellPlacer}
|
||||||
import chipyard.harness._
|
import chipyard.harness._
|
||||||
import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions}
|
import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop}
|
||||||
|
|
||||||
case object DUTFrequencyKey extends Field[Double](100.0)
|
case object DUTFrequencyKey extends Field[Double](100.0)
|
||||||
|
|
||||||
class VCU118FPGATestHarness(override implicit val p: Parameters) extends ChipyardVCU118Shell with HasHarnessSignalReferences {
|
class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays {
|
||||||
|
|
||||||
def dp = designParameters
|
def dp = designParameters
|
||||||
|
|
||||||
|
val pmod_is_sdio = p(VCU118ShellPMOD) == "SDIO"
|
||||||
|
val jtag_location = Some(if (pmod_is_sdio) "FMC_J2" else "PMOD_J52")
|
||||||
|
|
||||||
|
// Order matters; ddr depends on sys_clock
|
||||||
|
val uart = Overlay(UARTOverlayKey, new UARTVCU118ShellPlacer(this, UARTShellInput()))
|
||||||
|
val sdio = if (pmod_is_sdio) Some(Overlay(SPIOverlayKey, new SDIOVCU118ShellPlacer(this, SPIShellInput()))) else None
|
||||||
|
val jtag = Overlay(JTAGDebugOverlayKey, new JTAGDebugVCU118ShellPlacer(this, JTAGDebugShellInput(location = jtag_location)))
|
||||||
|
val cjtag = Overlay(cJTAGDebugOverlayKey, new cJTAGDebugVCU118ShellPlacer(this, cJTAGDebugShellInput()))
|
||||||
|
val jtagBScan = Overlay(JTAGDebugBScanOverlayKey, new JTAGDebugBScanVCU118ShellPlacer(this, JTAGDebugBScanShellInput()))
|
||||||
|
val fmc = Overlay(PCIeOverlayKey, new PCIeVCU118FMCShellPlacer(this, PCIeShellInput()))
|
||||||
|
val edge = Overlay(PCIeOverlayKey, new PCIeVCU118EdgeShellPlacer(this, PCIeShellInput()))
|
||||||
|
|
||||||
|
val topDesign = LazyModule(p(BuildTop)(dp))
|
||||||
|
|
||||||
|
// place all clocks in the shell
|
||||||
|
dp(ClockInputOverlayKey).foreach { _.place(ClockInputDesignInput()) }
|
||||||
|
|
||||||
/*** Connect/Generate clocks ***/
|
/*** Connect/Generate clocks ***/
|
||||||
|
|
||||||
// connect to the PLL that will generate multiple clocks
|
// connect to the PLL that will generate multiple clocks
|
||||||
@@ -44,13 +61,13 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends Chipyar
|
|||||||
val dutGroup = ClockGroup()
|
val dutGroup = ClockGroup()
|
||||||
dutClock := dutWrangler.node := dutGroup := harnessSysPLL
|
dutClock := dutWrangler.node := dutGroup := harnessSysPLL
|
||||||
|
|
||||||
InModuleBody {
|
//InModuleBody {
|
||||||
topDesign.module match { case td: LazyModuleImp => {
|
// topDesign.module match { case td: LazyModuleImp => {
|
||||||
td.clock := dutClock.in.head._1.clock
|
// td.clock := dutClock.in.head._1.clock
|
||||||
td.reset := dutClock.in.head._1.reset
|
// td.reset := dutClock.in.head._1.reset
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
// connect ref clock to dummy sink node
|
// connect ref clock to dummy sink node
|
||||||
ref_clock.get() match {
|
ref_clock.get() match {
|
||||||
@@ -60,20 +77,75 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends Chipyar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val harnessClock = InModuleBody {
|
// extra overlays
|
||||||
dutClock.in.head._1.clock
|
|
||||||
}.getWrappedValue
|
|
||||||
lazy val harnessReset = InModuleBody {
|
|
||||||
WireInit(dutClock.in.head._1.reset)
|
|
||||||
}.getWrappedValue
|
|
||||||
lazy val dutReset = harnessReset
|
|
||||||
lazy val success = InModuleBody { false.B }.getWrappedValue
|
|
||||||
|
|
||||||
topDesign match { case d: HasTestHarnessFunctions =>
|
/*** UART ***/
|
||||||
InModuleBody {
|
|
||||||
d.harnessFunctions.foreach(_(this))
|
// 1st UART goes to the VCU118 dedicated UART
|
||||||
}
|
|
||||||
ApplyHarnessBinders(this, d.lazySystem, d.portMap.toMap)
|
// BundleBridgeSource is a was for Diplomacy to connect something from very deep in the design
|
||||||
|
// to somewhere much, much higher. For ex. tunneling trace from the tile to the very top level.
|
||||||
|
val io_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).head)))
|
||||||
|
dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
|
||||||
|
|
||||||
|
// 2nd UART goes to the FMC UART
|
||||||
|
|
||||||
|
val uart_fmc = Overlay(UARTOverlayKey, new BringupUARTVCU118ShellPlacer(this, UARTShellInput()))
|
||||||
|
|
||||||
|
val io_uart_bb_2 = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).last)))
|
||||||
|
dp(UARTOverlayKey).last.place(UARTDesignInput(io_uart_bb_2))
|
||||||
|
|
||||||
|
/*** GPIO ***/
|
||||||
|
|
||||||
|
val gpio = Seq.tabulate(dp(PeripheryGPIOKey).size)(i => {
|
||||||
|
val maxGPIOSupport = 32
|
||||||
|
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)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// module implementation
|
||||||
|
override lazy val module = new VCU118FPGATestHarnessImp(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences {
|
||||||
|
|
||||||
|
val outer = _outer
|
||||||
|
|
||||||
|
val reset = IO(Input(Bool()))
|
||||||
|
_outer.xdc.addPackagePin(reset, "L19")
|
||||||
|
_outer.xdc.addIOStandard(reset, "LVCMOS12")
|
||||||
|
|
||||||
|
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 powerOnReset: Bool = PowerOnResetFPGAOnly(sysclk)
|
||||||
|
_outer.sdc.addAsyncPath(Seq(powerOnReset))
|
||||||
|
|
||||||
|
val ereset: Bool = _outer.chiplink.get() match {
|
||||||
|
case Some(x: ChipLinkVCU118PlacedOverlay) => !x.ereset_n
|
||||||
|
case _ => false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
_outer.pllReset := (reset_ibuf.io.O || powerOnReset || ereset)
|
||||||
|
|
||||||
|
// cy stuff
|
||||||
|
val harnessClock = _outer.dutClock.in.head._1.clock
|
||||||
|
val harnessReset = WireInit(_outer.dutClock.in.head._1.reset)
|
||||||
|
val dutReset = harnessReset
|
||||||
|
val success = false.B
|
||||||
|
|
||||||
|
// harness binders are non-lazy
|
||||||
|
_outer.topDesign match { case d: HasTestHarnessFunctions =>
|
||||||
|
d.harnessFunctions.foreach(_(this))
|
||||||
|
ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user