Merge remote-tracking branch 'origin/main' into port_api

This commit is contained in:
Jerry Zhao
2023-10-09 11:18:00 -07:00
17 changed files with 351 additions and 32 deletions

View File

@@ -57,6 +57,21 @@ ifeq ($(SUB_PROJECT),bringup)
BOARD ?= vcu118
FPGA_BRAND ?= xilinx
endif
ifeq ($(SUB_PROJECT),nexysvideo)
SBT_PROJECT ?= fpga_platforms
MODEL ?= NexysVideoHarness
VLOG_MODEL ?= NexysVideoHarness
MODEL_PACKAGE ?= chipyard.fpga.nexysvideo
CONFIG ?= RocketNexysVideoConfig
CONFIG_PACKAGE ?= chipyard.fpga.nexysvideo
GENERATOR_PACKAGE ?= chipyard
TB ?= none # unused
TOP ?= ChipTop
BOARD ?= nexys_video
FPGA_BRAND ?= xilinx
endif
ifeq ($(SUB_PROJECT),arty)
# TODO: Fix with Arty
SBT_PROJECT ?= fpga_platforms

View File

@@ -54,6 +54,7 @@ class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell
override lazy val module = new HarnessLikeImpl
class HarnessLikeImpl extends Impl with HasHarnessInstantiators {
all_leds.foreach(_ := DontCare)
clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin
val clk_100mhz = clockOverlay.overlayOutput.node.out.head._1.clock

View File

@@ -0,0 +1,72 @@
// See LICENSE for license details.
package chipyard.fpga.nexysvideo
import org.chipsalliance.cde.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.debug._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.system._
import freechips.rocketchip.tile._
import sifive.blocks.devices.uart._
import sifive.fpgashells.shell.{DesignKey}
import testchipip.{SerialTLKey}
import chipyard.{BuildSystem}
// don't use FPGAShell's DesignKey
class WithNoDesignKey extends Config((site, here, up) => {
case DesignKey => (p: Parameters) => new SimpleLazyModule()(p)
})
// DOC include start: WithNexysVideoTweaks and Rocket
class WithNexysVideoTweaks extends Config(
new WithNexysVideoUARTTSI ++
new WithNexysVideoDDRTL ++
new WithNoDesignKey ++
new testchipip.WithUARTTSIClient ++
new chipyard.harness.WithSerialTLTiedOff ++
new chipyard.harness.WithHarnessBinderClockFreqMHz(50) ++
new chipyard.config.WithMemoryBusFrequency(50.0) ++
new chipyard.config.WithFrontBusFrequency(50.0) ++
new chipyard.config.WithSystemBusFrequency(50.0) ++
new chipyard.config.WithPeripheryBusFrequency(50.0) ++
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
new chipyard.clocking.WithPassthroughClockGenerator ++
new chipyard.config.WithNoDebug ++ // no jtag
new chipyard.config.WithNoUART ++ // use UART for the UART-TSI thing instad
new chipyard.config.WithTLBackingMemory ++ // FPGA-shells converts the AXI to TL for us
new freechips.rocketchip.subsystem.WithExtMemSize(BigInt(512) << 20) ++ // 512mb on Nexys Video
new freechips.rocketchip.subsystem.WithoutTLMonitors)
class RocketNexysVideoConfig extends Config(
new WithNexysVideoTweaks ++
new chipyard.config.WithBroadcastManager ++ // no l2
new chipyard.RocketConfig)
// DOC include end: WithNexysVideoTweaks and Rocket
// DOC include start: WithTinyNexysVideoTweaks and Rocket
class WithTinyNexysVideoTweaks extends Config(
new WithNexysVideoUARTTSI ++
new WithNoDesignKey ++
new sifive.fpgashells.shell.xilinx.WithNoNexysVideoShellDDR ++ // no DDR
new testchipip.WithUARTTSIClient ++
new chipyard.harness.WithSerialTLTiedOff ++
new chipyard.harness.WithHarnessBinderClockFreqMHz(50) ++
new chipyard.config.WithMemoryBusFrequency(50.0) ++
new chipyard.config.WithFrontBusFrequency(50.0) ++
new chipyard.config.WithSystemBusFrequency(50.0) ++
new chipyard.config.WithPeripheryBusFrequency(50.0) ++
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
new chipyard.clocking.WithPassthroughClockGenerator ++
new chipyard.config.WithNoDebug ++ // no jtag
new chipyard.config.WithNoUART ++ // use UART for the UART-TSI thing instad
new freechips.rocketchip.subsystem.WithoutTLMonitors)
class TinyRocketNexysVideoConfig extends Config(
new WithTinyNexysVideoTweaks ++
new chipyard.config.WithBroadcastManager ++ // no l2
new chipyard.TinyRocketConfig)
// DOC include end: WithTinyNexysVideoTweaks and Rocket

View File

@@ -0,0 +1,92 @@
// See LICENSE for license details.
package chipyard.fpga.nexysvideo
import chisel3._
import chisel3.util._
import freechips.rocketchip.diplomacy._
import org.chipsalliance.cde.config.{Parameters}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.subsystem.{SystemBusKey}
import sifive.fpgashells.shell.xilinx._
import sifive.fpgashells.shell._
import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler}
import sifive.blocks.devices.uart._
import chipyard._
import chipyard.harness._
import chipyard.iobinders.{HasIOBinders}
class NexysVideoHarness(override implicit val p: Parameters) extends NexysVideoShell {
def dp = designParameters
val clockOverlay = dp(ClockInputOverlayKey).map(_.place(ClockInputDesignInput())).head
val harnessSysPLL = dp(PLLFactoryKey)
val harnessSysPLLNode = harnessSysPLL()
val dutFreqMHz = (dp(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toInt
val dutClock = ClockSinkNode(freqMHz = dutFreqMHz)
println(s"NexysVideo FPGA Base Clock Freq: ${dutFreqMHz} MHz")
val dutWrangler = LazyModule(new ResetWrangler())
val dutGroup = ClockGroup()
dutClock := dutWrangler.node := dutGroup := harnessSysPLLNode
harnessSysPLLNode := clockOverlay.overlayOutput.node
val io_uart_bb = BundleBridgeSource(() => new UARTPortIO(dp(PeripheryUARTKey).headOption.getOrElse(UARTParams(0))))
val uartOverlay = dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
// Optional DDR
val ddrOverlay = if (p(NexysVideoShellDDR)) Some(dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRNexysVideoPlacedOverlay]) else None
val ddrClient = if (p(NexysVideoShellDDR)) Some(TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
name = "chip_ddr",
sourceId = IdRange(0, 1 << dp(ExtTLMem).get.master.idBits)
)))))) else None
val ddrBlockDuringReset = if (p(NexysVideoShellDDR)) Some(LazyModule(new TLBlockDuringReset(4))) else None
if (p(NexysVideoShellDDR)) { ddrOverlay.get.overlayOutput.ddr := ddrBlockDuringReset.get.node := ddrClient.get }
val ledOverlays = dp(LEDOverlayKey).map(_.place(LEDDesignInput()))
val all_leds = ledOverlays.map(_.overlayOutput.led)
val status_leds = all_leds.take(2)
val other_leds = all_leds.drop(2)
override lazy val module = new HarnessLikeImpl
class HarnessLikeImpl extends Impl with HasHarnessInstantiators {
all_leds.foreach(_ := DontCare)
clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin
val clk_100mhz = clockOverlay.overlayOutput.node.out.head._1.clock
// Blink the status LEDs for sanity
withClockAndReset(clk_100mhz, dutClock.in.head._1.reset) {
val period = (BigInt(100) << 20) / status_leds.size
val counter = RegInit(0.U(log2Ceil(period).W))
val on = RegInit(0.U(log2Ceil(status_leds.size).W))
status_leds.zipWithIndex.map { case (o,s) => o := on === s.U }
counter := Mux(counter === (period-1).U, 0.U, counter + 1.U)
when (counter === 0.U) {
on := Mux(on === (status_leds.size-1).U, 0.U, on + 1.U)
}
}
other_leds(0) := resetPin
harnessSysPLL.plls.foreach(_._1.getReset.get := pllReset)
def referenceClockFreqMHz = dutFreqMHz
def referenceClock = dutClock.in.head._1.clock
def referenceReset = dutClock.in.head._1.reset
def success = { require(false, "Unused"); false.B }
if (p(NexysVideoShellDDR)) {
ddrOverlay.get.mig.module.clock := harnessBinderClock
ddrOverlay.get.mig.module.reset := harnessBinderReset
ddrBlockDuringReset.get.module.clock := harnessBinderClock
ddrBlockDuringReset.get.module.reset := harnessBinderReset.asBool || !ddrOverlay.get.mig.module.io.port.init_calib_complete
}
instantiateChipTops()
}
}

View File

@@ -0,0 +1,43 @@
// See LICENSE for license details.
package chipyard.fpga.nexysvideo
import chisel3._
import freechips.rocketchip.subsystem.{PeripheryBusKey}
import freechips.rocketchip.tilelink.{TLBundle}
import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.diplomacy.{LazyRawModuleImp}
import sifive.blocks.devices.uart.{UARTParams}
import chipyard._
import chipyard.harness._
import testchipip._
class WithNexysVideoUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarnessBinder({
(system: CanHavePeripheryUARTTSI, th: HasHarnessInstantiators, ports: Seq[UARTTSIIO]) => {
implicit val p = chipyard.iobinders.GetSystemParameters(system)
require(ports.size <= 1)
val nexysvideoth = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[NexysVideoHarness]
ports.map({ port =>
nexysvideoth.io_uart_bb.bundle <> port.uart
nexysvideoth.other_leds(1) := port.dropped
nexysvideoth.other_leds(2) := port.tsi2tl_state(0)
nexysvideoth.other_leds(3) := port.tsi2tl_state(1)
nexysvideoth.other_leds(4) := port.tsi2tl_state(2)
nexysvideoth.other_leds(5) := port.tsi2tl_state(3)
})
}
})
class WithNexysVideoDDRTL extends OverrideHarnessBinder({
(system: CanHaveMasterTLMemPort, th: HasHarnessInstantiators, ports: Seq[HeterogeneousBag[TLBundle]]) => {
require(ports.size == 1)
val nexysTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[NexysVideoHarness]
val bundles = nexysTh.ddrClient.get.out.map(_._1)
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
ddrClientBundle <> ports.head
}
})