Connected clocks | Exposed Master TL port

This commit is contained in:
abejgonzalez
2020-09-15 12:58:58 -07:00
parent 72c0f4b3d3
commit f1b40d51af
6 changed files with 159 additions and 46 deletions

View File

@@ -7,7 +7,7 @@ import freechips.rocketchip.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.debug._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase}
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet}
import freechips.rocketchip.system._
import freechips.rocketchip.tile._
@@ -52,20 +52,35 @@ class WithBringupPeripherals extends Config((site, here, up) => {
}
})
class SmallModifications extends Config((site, here, up) => {
case SystemBusKey => up(SystemBusKey).copy(
errorDevice = Some(DevNullParams(
Seq(AddressSet(0x3000, 0xfff)),
maxAtomic=site(XLen)/8,
maxTransfer=128,
region = RegionType.TRACKED)))
case PeripheryBusKey => up(PeripheryBusKey, site).copy(dtsFrequency =
Some(BigDecimal(site(DUTFrequencyKey)*1000000).setScale(0, BigDecimal.RoundingMode.HALF_UP).toBigInt),
errorDevice = None)
case DTSTimebase => BigInt(1000000)
case JtagDTMKey => new JtagDTMConfig(
idcodeVersion = 2, // 1 was legacy (FE310-G000, Acai).
idcodePartNum = 0x000, // Decided to simplify.
idcodeManufId = 0x489, // As Assigned by JEDEC to SiFive. Only used in wrappers / test harnesses.
debugIdleCycles = 5) // Reasonable guess for synchronization
})
class FakeBringupConfig extends Config(
new WithBringupPeripherals ++
new WithChipyardBuildTop ++
new chipyard.config.WithBootROM ++
new chipyard.config.WithL2TLBs(1024) ++
new freechips.rocketchip.subsystem.With1TinyCore ++
new freechips.rocketchip.subsystem.WithNBanks(0) ++
new freechips.rocketchip.subsystem.WithNoMemPort ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++
new freechips.rocketchip.subsystem.WithNBreakpoints(2) ++
new freechips.rocketchip.subsystem.WithJtagDTM ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)

View File

@@ -12,10 +12,11 @@ import sifive.fpgashells.shell.xilinx._
import sifive.blocks.devices.gpio._
import chipyard.fpga.vcu118.{FMCPMap}
/* Connect the I2C to certain FMC pins */
class BringupI2CVCU118PlacedOverlay(val shell: VCU118Shell, name: String, val designInput: I2CDesignInput, val shellInput: I2CShellInput)
class BringupI2CVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: I2CDesignInput, val shellInput: I2CShellInput)
extends I2CXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
@@ -32,14 +33,14 @@ class BringupI2CVCU118PlacedOverlay(val shell: VCU118Shell, name: String, val de
} }
}
class BringupI2CVCU118ShellPlacer(val shell: VCU118Shell, val shellInput: I2CShellInput)(implicit val valName: ValName)
extends I2CShellPlacer[VCU118Shell]
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: VCU118Shell, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
class BringupUARTVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
{
shell { InModuleBody {
@@ -61,13 +62,13 @@ class BringupUARTVCU118PlacedOverlay(val shell: VCU118Shell, name: String, val d
} }
}
class BringupUARTVCU118ShellPlacer(shell: VCU118Shell, val shellInput: UARTShellInput)(implicit val valName: ValName)
extends UARTShellPlacer[VCU118Shell] {
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 SPI to ADI device */
class BringupSPIVCU118PlacedOverlay(val shell: VCU118Shell, name: String, val designInput: SPIDesignInput, val shellInput: SPIShellInput)
class BringupSPIVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: SPIDesignInput, val shellInput: SPIShellInput)
extends SDIOXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
@@ -89,8 +90,8 @@ class BringupSPIVCU118PlacedOverlay(val shell: VCU118Shell, name: String, val de
} }
}
class BringupSPIVCU118ShellPlacer(shell: VCU118Shell, val shellInput: SPIShellInput)(implicit val valName: ValName)
extends SPIShellPlacer[VCU118Shell] {
class BringupSPIVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: SPIShellInput)(implicit val valName: ValName)
extends SPIShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: SPIDesignInput) = new BringupSPIVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
@@ -123,7 +124,7 @@ abstract class GPIOXilinxPlacedOverlay(name: String, di: GPIODesignInput, si: GP
} }
}
class BringupGPIOVCU118PlacedOverlay(val shell: VCU118Shell, name: String, val designInput: GPIODesignInput, val shellInput: GPIOShellInput, gpioNames: Seq[String])
class BringupGPIOVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: GPIODesignInput, val shellInput: GPIOShellInput, gpioNames: Seq[String])
extends GPIOXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
@@ -143,8 +144,8 @@ class BringupGPIOVCU118PlacedOverlay(val shell: VCU118Shell, name: String, val d
} }
}
class BringupGPIOVCU118ShellPlacer(shell: VCU118Shell, val shellInput: GPIOShellInput, gpioNames: Seq[String])(implicit val valName: ValName)
extends GPIOShellPlacer[VCU118Shell] {
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)
}

View File

@@ -1,11 +1,12 @@
package chipyard.fpga.vcu118
import chisel3._
import chisel3.experimental.{Analog, IO}
import chisel3.experimental.{Analog, IO, DataMirror}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
import freechips.rocketchip.diplomacy.{InModuleBody, BundleBridgeSource}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, LazyScope, InModuleBody, BundleBridgeSource, ValName}
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.tilelink.{TLBundle}
import chipyard.{BuildSystem}
@@ -19,9 +20,10 @@ trait HasVCU118PlatformIO {
val io_spi: Seq[SPIPortIO]
val io_i2c: Seq[I2CPort]
val io_gpio: Seq[GPIOPortIO]
val io_tl_mem: HeterogeneousBag[TLBundle]
}
class VCU118Platform(override implicit val p: Parameters) extends LazyModule {
class VCU118Platform(override implicit val p: Parameters) extends LazyModule with LazyScope {
val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system")
@@ -62,4 +64,10 @@ class VCU118PlatformModule[+L <: VCU118Platform](_outer: L) extends LazyModuleIm
}
io_gpio_pins_temp
}
val io_tl_mem = _outer.lazySystem match { case sys: chipyard.CanHaveMasterTLMemPort =>
val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](sys.mem_tl)).suggestName("tl_slave")
io_tl_mem_pins_temp <> sys.mem_tl
io_tl_mem_pins_temp
}
}

View File

@@ -4,7 +4,8 @@ import chisel3._
import chisel3.experimental.{Analog, IO}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.subsystem.{ExtMem, BaseSubsystem}
import sifive.fpgashells.shell.xilinx._
import sifive.fpgashells.ip.xilinx._
@@ -16,20 +17,55 @@ import sifive.blocks.devices.spi._
import sifive.blocks.devices.i2c._
import sifive.blocks.devices.gpio._
import chipyard.fpga.vcu118.bringup._
import chipyard.fpga.vcu118.bringup.{BringupGPIOs, BringupUARTVCU118ShellPlacer, BringupSPIVCU118ShellPlacer, BringupI2CVCU118ShellPlacer, BringupGPIOVCU118ShellPlacer}
class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118Shell {
case object DUTFrequencyKey extends Field[Double](100.0)
class VCU118FPGATestHarness(override implicit val p: Parameters) extends ChipyardVCU118Shell {
def dp = designParameters
/*** 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
}
}
// create and connect to the dutClock
val dutClock = ClockSinkNode(freqMHz = dp(DUTFrequencyKey))
val dutWrangler = LazyModule(new ResetWrangler)
val dutGroup = ClockGroup()
dutClock := dutWrangler.node := dutGroup := harnessSysPLL
InModuleBody {
topDesign.module match { case td: LazyModuleImp => {
td.clock := dutClock.in.head._1.clock
td.reset := dutClock.in.head._1.reset
}
}
}
// connect ref clock to dummy sink node
ref_clock.get() match {
case Some(x : RefClockVCU118PlacedOverlay) => {
val sink = ClockSinkNode(Seq(ClockSinkParameters()))
sink := x.node
}
}
/*** UART ***/
require(p(PeripheryUARTKey).size == 2)
require(dp(PeripheryUARTKey).size == 2)
// 1st UART goes to the VCU118 dedicated UART
// 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(p(PeripheryUARTKey).head)))
designParameters(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
val io_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).head)))
dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
InModuleBody {
topDesign.module match { case dutMod: HasVCU118PlatformIO =>
io_uart_bb.bundle <> dutMod.io_uart.head
@@ -38,10 +74,10 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
// 2nd UART goes to the FMC UART
val uart_fmc = Overlay(UARTOverlayKey, new chipyard.fpga.vcu118.bringup.BringupUARTVCU118ShellPlacer(this, UARTShellInput()))
val uart_fmc = Overlay(UARTOverlayKey, new BringupUARTVCU118ShellPlacer(this, UARTShellInput()))
val io_uart_bb_2 = BundleBridgeSource(() => (new UARTPortIO(p(PeripheryUARTKey).last)))
designParameters(UARTOverlayKey).last.place(UARTDesignInput(io_uart_bb_2))
val io_uart_bb_2 = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).last)))
dp(UARTOverlayKey).last.place(UARTDesignInput(io_uart_bb_2))
InModuleBody {
topDesign.module match { case dutMod: HasVCU118PlatformIO =>
io_uart_bb_2.bundle <> dutMod.io_uart.last
@@ -49,12 +85,12 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
}
/*** SPI ***/
require(p(PeripherySPIKey).size == 2)
require(dp(PeripherySPIKey).size == 2)
// 1st SPI goes to the VCU118 SDIO port
val io_spi_bb = BundleBridgeSource(() => (new SPIPortIO(p(PeripherySPIKey).head)))
val sdio_placed = designParameters(SPIOverlayKey).head.place(SPIDesignInput(p(PeripherySPIKey).head, io_spi_bb))
val io_spi_bb = BundleBridgeSource(() => (new SPIPortIO(dp(PeripherySPIKey).head)))
val sdio_placed = dp(SPIOverlayKey).head.place(SPIDesignInput(dp(PeripherySPIKey).head, io_spi_bb))
InModuleBody {
topDesign.module match { case dutMod: HasVCU118PlatformIO =>
io_spi_bb.bundle <> dutMod.io_spi.head
@@ -69,10 +105,10 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
// 2nd SPI goes to the ADI port
val adi = Overlay(SPIOverlayKey, new chipyard.fpga.vcu118.bringup.BringupSPIVCU118ShellPlacer(this, SPIShellInput()))
val adi = Overlay(SPIOverlayKey, new BringupSPIVCU118ShellPlacer(this, SPIShellInput()))
val io_spi_bb_2 = BundleBridgeSource(() => (new SPIPortIO(p(PeripherySPIKey).last)))
val adi_placed = designParameters(SPIOverlayKey).last.place(SPIDesignInput(p(PeripherySPIKey).last, io_spi_bb_2))
val io_spi_bb_2 = BundleBridgeSource(() => (new SPIPortIO(dp(PeripherySPIKey).last)))
val adi_placed = dp(SPIOverlayKey).last.place(SPIDesignInput(dp(PeripherySPIKey).last, io_spi_bb_2))
InModuleBody {
topDesign.module match { case dutMod: HasVCU118PlatformIO =>
io_spi_bb_2.bundle <> dutMod.io_spi.last
@@ -86,12 +122,12 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
//}
/*** I2C ***/
require(p(PeripheryI2CKey).size == 1)
require(dp(PeripheryI2CKey).size == 1)
val i2c = Overlay(I2COverlayKey, new chipyard.fpga.vcu118.bringup.BringupI2CVCU118ShellPlacer(this, I2CShellInput()))
val i2c = Overlay(I2COverlayKey, new BringupI2CVCU118ShellPlacer(this, I2CShellInput()))
val io_i2c_bb = BundleBridgeSource(() => (new I2CPort))
designParameters(I2COverlayKey).head.place(I2CDesignInput(io_i2c_bb))
dp(I2COverlayKey).head.place(I2CDesignInput(io_i2c_bb))
InModuleBody {
topDesign.module match { case dutMod: HasVCU118PlatformIO =>
io_i2c_bb.bundle <> dutMod.io_i2c.head
@@ -99,14 +135,14 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
}
/*** GPIO ***/
val gpio = Seq.tabulate(p(PeripheryGPIOKey).size)(i => {
val gpio = Seq.tabulate(dp(PeripheryGPIOKey).size)(i => {
val maxGPIOSupport = 32
val names = BringupGPIOs.names.slice(maxGPIOSupport*i, maxGPIOSupport*(i+1))
Overlay(GPIOOverlayKey, new chipyard.fpga.vcu118.bringup.BringupGPIOVCU118ShellPlacer(this, GPIOShellInput(), names))
Overlay(GPIOOverlayKey, new BringupGPIOVCU118ShellPlacer(this, GPIOShellInput(), names))
})
val io_gpio_bb = p(PeripheryGPIOKey).map { p => BundleBridgeSource(() => (new GPIOPortIO(p))) }
(designParameters(GPIOOverlayKey) zip p(PeripheryGPIOKey)).zipWithIndex.map { case ((placer, params), i) =>
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)))
}
InModuleBody {
@@ -116,5 +152,19 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
}
}
}
/*** Experimental DDR ***/
//val ddrPlaced = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtMem).get.master.base, dutWrangler.node, harnessSysPLL))
//topDesign match { case lazyDut: VCU118Platform =>
// lazyDut.lazySystem match { case lazyDutWBus: BaseSubsystem =>
// lazyDutWBus {
// InModuleBody {
// ddrPlaced.overlayOutput.ddr := lazyDutWBus.mbus.toDRAMController(Some("xilinxvcu118mig"))()
// }
// }
// }
//}
}

View File

@@ -29,6 +29,7 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
with chipyard.example.CanHavePeripheryStreamingFIR // Enables optionally adding the DSPTools FIR example widget
with chipyard.example.CanHavePeripheryStreamingPassthrough // Enables optionally adding the DSPTools streaming-passthrough example widget
with nvidia.blocks.dla.CanHavePeripheryNVDLA // Enables optionally having an NVDLA
with CanHaveMasterTLMemPort
{
override lazy val module = new DigitalTopModule(this)
}
@@ -47,3 +48,42 @@ class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l)
with chipyard.example.CanHavePeripheryGCDModuleImp
with freechips.rocketchip.util.DontTouch
// DOC include end: DigitalTop
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
/** Adds a TileLink port to the system intended to master an MMIO device bus */
trait CanHaveMasterTLMemPort { this: BaseSubsystem =>
private val memPortParamsOpt = p(ExtMem)
private val portName = "tl_mem"
private val device = new MemoryDevice
private val idBits = memPortParamsOpt.map(_.master.idBits).getOrElse(1)
val memTLNode = TLManagerNode(memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels) =>
Seq.tabulate(nMemoryChannels) { channel =>
val base = AddressSet.misaligned(memPortParams.base, memPortParams.size)
val filter = AddressSet(channel * mbus.blockBytes, ~((nMemoryChannels-1) * mbus.blockBytes))
TLSlavePortParameters.v1(
managers = Seq(TLSlaveParameters.v1(
address = base.flatMap(_.intersect(filter)),
resources = device.reg,
regionType = RegionType.UNCACHED, // cacheable
executable = true,
supportsGet = TransferSizes(1, mbus.blockBytes),
supportsPutFull = TransferSizes(1, mbus.blockBytes),
supportsPutPartial = TransferSizes(1, mbus.blockBytes))),
beatBytes = memPortParams.beatBytes)
}
}).toList.flatten)
mbus.coupleTo(s"memory_controller_port_named_$portName") {
(memTLNode
:*= TLBuffer()
:*= TLSourceShrinker(1 << idBits)
:*= TLWidthWidget(mbus.beatBytes)
:*= _)
}
val mem_tl = InModuleBody { memTLNode.makeIOs() }
}

View File

@@ -23,7 +23,6 @@ import freechips.rocketchip.util.{DontTouch}
*/
class ChipyardSystem(implicit p: Parameters) extends ChipyardSubsystem
with HasAsyncExtInterrupts
with CanHaveMasterAXI4MemPort
with CanHaveMasterAXI4MMIOPort
with CanHaveSlaveAXI4Port
{