Merge pull request #1278 from Lorilandly/vc707fpga

Add support for VC707 FPGA board changelog:added
This commit is contained in:
Abraham Gonzalez
2022-12-14 19:16:49 -08:00
committed by GitHub
13 changed files with 378 additions and 51 deletions

View File

@@ -31,7 +31,7 @@ grouping["group-accels"]="chipyard-fftgenerator chipyard-nvdla chipyard-mempress
grouping["group-constellation"]="chipyard-constellation"
grouping["group-tracegen"]="tracegen tracegen-boom"
grouping["group-other"]="icenet testchipip constellation"
grouping["group-fpga"]="arty vcu118"
grouping["group-fpga"]="arty vcu118 vc707"
# key value store to get the build strings
declare -A mapping
@@ -71,3 +71,4 @@ mapping["testchipip"]="SUB_PROJECT=testchipip"
mapping["arty"]="SUB_PROJECT=arty verilog"
mapping["vcu118"]="SUB_PROJECT=vcu118 verilog"
mapping["vc707"]="SUB_PROJECT=vc707 verilog"

View File

@@ -16,6 +16,20 @@ sim_name := none
#########################################################################################
SUB_PROJECT ?= vcu118
ifeq ($(SUB_PROJECT),vc707)
SBT_PROJECT ?= fpga_platforms
MODEL ?= VC707FPGATestHarness
VLOG_MODEL ?= VC707FPGATestHarness
MODEL_PACKAGE ?= chipyard.fpga.vc707
CONFIG ?= RocketVC707Config
CONFIG_PACKAGE ?= chipyard.fpga.vc707
GENERATOR_PACKAGE ?= chipyard
TB ?= none # unused
TOP ?= ChipTop
BOARD ?= vc707
FPGA_BRAND ?= xilinx
endif
ifeq ($(SUB_PROJECT),vcu118)
SBT_PROJECT ?= fpga_platforms
MODEL ?= VCU118FPGATestHarness
@@ -98,8 +112,7 @@ include $(base_dir)/common.mk
#########################################################################################
all_vsrcs := \
$(sim_vsrcs) \
$(base_dir)/generators/sifive-blocks/vsrc/SRLatch.v \
$(fpga_dir)/common/vsrc/PowerOnResetFPGAOnly.v
$(base_dir)/generators/sifive-blocks/vsrc/SRLatch.v
#########################################################################################
# vivado rules

View File

@@ -0,0 +1 @@
vcu118

View File

@@ -26,6 +26,7 @@ class WithDefaultPeripherals extends Config((site, here, up) => {
debugIdleCycles = 5)
case SerialTLKey => None // remove serialized tl port
})
// DOC include start: AbstractArty and Rocket
class WithArtyTweaks extends Config(
new WithArtyJTAGHarnessBinder ++
@@ -33,9 +34,11 @@ class WithArtyTweaks extends Config(
new WithArtyResetHarnessBinder ++
new WithDebugResetPassthrough ++
new WithDefaultPeripherals ++
new freechips.rocketchip.subsystem.WithNBreakpoints(2))
new freechips.rocketchip.subsystem.WithNBreakpoints(2)
)
class TinyRocketArtyConfig extends Config(
new WithArtyTweaks ++
new chipyard.TinyRocketConfig)
new chipyard.TinyRocketConfig
)
// DOC include end: AbstractArty and Rocket

View File

@@ -2,13 +2,12 @@ package chipyard.fpga.arty
import chisel3._
import freechips.rocketchip.devices.debug._
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
import freechips.rocketchip.jtag.{JTAGIO}
import freechips.rocketchip.subsystem._
import sifive.blocks.devices.uart._
import sifive.blocks.devices.jtag._
import sifive.blocks.devices.pinctrl._
import sifive.blocks.devices.uart.{UARTPortIO, HasPeripheryUARTModuleImp}
import sifive.blocks.devices.jtag.{JTAGPins, JTAGPinsFromPort}
import sifive.blocks.devices.pinctrl.{BasePin}
import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}
@@ -32,39 +31,38 @@ class WithArtyResetHarnessBinder extends ComposeHarnessBinder({
class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => {
ports.map {
case j: JTAGChipIO =>
withClockAndReset(th.buildtopClock, th.hReset) {
val jtag_wire = Wire(new JTAGIO)
jtag_wire.TDO.data := j.TDO
jtag_wire.TDO.driven := true.B
j.TCK := jtag_wire.TCK
j.TMS := jtag_wire.TMS
j.TDI := jtag_wire.TDI
case j: JTAGChipIO => withClockAndReset(th.buildtopClock, th.hReset) {
val jtag_wire = Wire(new JTAGIO)
jtag_wire.TDO.data := j.TDO
jtag_wire.TDO.driven := true.B
j.TCK := jtag_wire.TCK
j.TMS := jtag_wire.TMS
j.TDI := jtag_wire.TDI
val io_jtag = Wire(new JTAGPins(() => new BasePin(), false)).suggestName("jtag")
val io_jtag = Wire(new JTAGPins(() => new BasePin(), false)).suggestName("jtag")
JTAGPinsFromPort(io_jtag, jtag_wire)
JTAGPinsFromPort(io_jtag, jtag_wire)
io_jtag.TCK.i.ival := IBUFG(IOBUF(th.jd_2).asClock).asBool
io_jtag.TCK.i.ival := IBUFG(IOBUF(th.jd_2).asClock).asBool
IOBUF(th.jd_5, io_jtag.TMS)
PULLUP(th.jd_5)
IOBUF(th.jd_5, io_jtag.TMS)
PULLUP(th.jd_5)
IOBUF(th.jd_4, io_jtag.TDI)
PULLUP(th.jd_4)
IOBUF(th.jd_4, io_jtag.TDI)
PULLUP(th.jd_4)
IOBUF(th.jd_0, io_jtag.TDO)
IOBUF(th.jd_0, io_jtag.TDO)
// mimic putting a pullup on this line (part of reset vote)
th.SRST_n := IOBUF(th.jd_6)
PULLUP(th.jd_6)
// mimic putting a pullup on this line (part of reset vote)
th.SRST_n := IOBUF(th.jd_6)
PULLUP(th.jd_6)
// ignore the po input
io_jtag.TCK.i.po.map(_ := DontCare)
io_jtag.TDI.i.po.map(_ := DontCare)
io_jtag.TMS.i.po.map(_ := DontCare)
io_jtag.TDO.i.po.map(_ := DontCare)
}
// ignore the po input
io_jtag.TCK.i.po.map(_ := DontCare)
io_jtag.TDI.i.po.map(_ := DontCare)
io_jtag.TMS.i.po.map(_ := DontCare)
io_jtag.TDO.i.po.map(_ := DontCare)
}
}
}
})

View File

@@ -3,8 +3,7 @@ package chipyard.fpga.arty
import chisel3._
import chisel3.experimental.{IO}
import freechips.rocketchip.util._
import freechips.rocketchip.devices.debug._
import freechips.rocketchip.devices.debug.{HasPeripheryDebugModuleImp}
import chipyard.iobinders.{ComposeIOBinder}

View File

@@ -0,0 +1,78 @@
package chipyard.fpga.vc707
import sys.process._
import freechips.rocketchip.config.{Config, Parameters}
import freechips.rocketchip.subsystem.{SystemBusKey, PeripheryBusKey, ControlBusKey, ExtMem}
import freechips.rocketchip.devices.debug.{DebugModuleKey, ExportDebug, JTAG}
import freechips.rocketchip.devices.tilelink.{DevNullParams, BootROMLocated}
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet}
import freechips.rocketchip.tile.{XLen}
import sifive.blocks.devices.spi.{PeripherySPIKey, SPIParams}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
import sifive.fpgashells.shell.{DesignKey}
import sifive.fpgashells.shell.xilinx.{VC7074GDDRSize}
import testchipip.{SerialTLKey}
import chipyard.{BuildSystem, ExtTLMem, DefaultClockFrequencyKey}
class WithDefaultPeripherals extends Config((site, here, up) => {
case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L)))
case PeripherySPIKey => List(SPIParams(rAddress = BigInt(0x64001000L)))
})
class WithSystemModifications extends Config((site, here, up) => {
case DTSTimebase => BigInt{(1e6).toLong}
case BootROMLocated(x) => up(BootROMLocated(x), site).map { p =>
// invoke makefile for sdboot
val freqMHz = (site(DefaultClockFrequencyKey) * 1e6).toLong
val make = s"make -C fpga/src/main/resources/vc707/sdboot PBUS_CLK=${freqMHz} bin"
require (make.! == 0, "Failed to build bootrom")
p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vc707/sdboot/build/sdboot.bin")
}
case ExtMem => up(ExtMem, site).map(x => x.copy(master = x.master.copy(size = site(VC7074GDDRSize)))) // set extmem to DDR size (note the size)
case SerialTLKey => None // remove serialized tl port
})
class WithVC707Tweaks extends Config (
// harness binders
new WithVC707UARTHarnessBinder ++
new WithVC707SPISDCardHarnessBinder ++
new WithVC707DDRMemHarnessBinder ++
// io binders
new WithUARTIOPassthrough ++
new WithSPIIOPassthrough ++
new WithTLIOPassthrough ++
// other configuration
new WithDefaultPeripherals ++
new chipyard.config.WithTLBackingMemory ++ // use TL backing memory
new WithSystemModifications ++ // setup busses, use sdboot bootrom, setup ext. mem. size
new chipyard.config.WithNoDebug ++ // remove debug module
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++
new WithFPGAFrequency(50) // default 50MHz freq
)
class RocketVC707Config extends Config (
new WithVC707Tweaks ++
new chipyard.RocketConfig
)
class BoomVC707Config extends Config (
new WithFPGAFrequency(50) ++
new WithVC707Tweaks ++
new chipyard.MegaBoomConfig
)
class WithFPGAFrequency(fMHz: Double) extends Config (
new chipyard.config.WithPeripheryBusFrequency(fMHz) ++ // assumes using PBUS as default freq.
new chipyard.config.WithMemoryBusFrequency(fMHz)
)
class WithFPGAFreq25MHz extends WithFPGAFrequency(25)
class WithFPGAFreq50MHz extends WithFPGAFrequency(50)
class WithFPGAFreq75MHz extends WithFPGAFrequency(75)
class WithFPGAFreq100MHz extends WithFPGAFrequency(100)

View File

@@ -0,0 +1,46 @@
package chipyard.fpga.vc707
import chisel3._
import chisel3.experimental.{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.fpgashells.devices.xilinx.xilinxvc707pciex1.{HasSystemXilinxVC707PCIeX1ModuleImp, XilinxVC707PCIeX1IO}
import chipyard.{CanHaveMasterTLMemPort}
import chipyard.harness.{OverrideHarnessBinder}
/*** UART ***/
class WithVC707UARTHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripheryUARTModuleImp, th: BaseModule, ports: Seq[UARTPortIO]) => {
th match { case vc707th: VC707FPGATestHarnessImp => {
vc707th.vc707Outer.io_uart_bb.bundle <> ports.head
}}
}
})
/*** SPI ***/
class WithVC707SPISDCardHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripherySPI, th: BaseModule, ports: Seq[SPIPortIO]) => {
th match { case vc707th: VC707FPGATestHarnessImp => {
vc707th.vc707Outer.io_spi_bb.bundle <> ports.head
}}
}
})
/*** Experimental DDR ***/
class WithVC707DDRMemHarnessBinder extends OverrideHarnessBinder({
(system: CanHaveMasterTLMemPort, th: BaseModule, ports: Seq[HeterogeneousBag[TLBundle]]) => {
th match { case vc707th: VC707FPGATestHarnessImp => {
require(ports.size == 1)
val bundles = vc707th.vc707Outer.ddrClient.out.map(_._1)
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
ddrClientBundle <> ports.head
}}
}
})

View File

@@ -0,0 +1,53 @@
package chipyard.fpga.vc707
import chisel3._
import chisel3.experimental.{IO, DataMirror}
import freechips.rocketchip.diplomacy.{ResourceBinding, Resource, ResourceAddress, InModuleBody}
import freechips.rocketchip.subsystem.{BaseSubsystem}
import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.tilelink.{TLBundle}
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp}
import sifive.blocks.devices.spi.{HasPeripherySPI, HasPeripherySPIModuleImp, MMCDevice}
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{HasSystemXilinxVC707PCIeX1ModuleImp}
import chipyard.{CanHaveMasterTLMemPort}
import chipyard.iobinders.{OverrideIOBinder, OverrideLazyIOBinder}
class WithUARTIOPassthrough extends OverrideIOBinder({
(system: HasPeripheryUARTModuleImp) => {
val io_uart_pins_temp = system.uart.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"uart_$i") }
(io_uart_pins_temp zip system.uart).map { case (io, sysio) =>
io <> sysio
}
(io_uart_pins_temp, Nil)
}
})
class WithSPIIOPassthrough extends OverrideLazyIOBinder({
(system: HasPeripherySPI) => {
// attach resource to 1st SPI
ResourceBinding {
Resource(new MMCDevice(system.tlSpiNodes.head.device, 1), "reg").bind(ResourceAddress(0))
}
InModuleBody {
system.asInstanceOf[BaseSubsystem].module match { case system: HasPeripherySPIModuleImp => {
val io_spi_pins_temp = system.spi.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"spi_$i") }
(io_spi_pins_temp zip system.spi).map { case (io, sysio) =>
io <> sysio
}
(io_spi_pins_temp, Nil)
} }
}
}
})
class WithTLIOPassthrough extends OverrideIOBinder({
(system: CanHaveMasterTLMemPort) => {
val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave")
io_tl_mem_pins_temp <> system.mem_tl
(Seq(io_tl_mem_pins_temp), Nil)
}
})

View File

@@ -0,0 +1,135 @@
package chipyard.fpga.vc707
import chisel3._
import chisel3.experimental.{IO}
import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource}
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.tilelink.{TLClientNode}
import sifive.fpgashells.shell.xilinx.{VC707Shell, UARTVC707ShellPlacer, PCIeVC707ShellPlacer, ChipLinkVC707PlacedOverlay}
import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly}
import sifive.fpgashells.shell.{ClockInputOverlayKey, ClockInputDesignInput, UARTOverlayKey, UARTDesignInput, UARTShellInput, LEDOverlayKey, LEDDesignInput, SwitchOverlayKey, SwitchDesignInput, ButtonOverlayKey, ButtonDesignInput, SPIOverlayKey, SPIDesignInput, ChipLinkOverlayKey, ChipLinkDesignInput, PCIeOverlayKey, PCIeDesignInput, PCIeShellInput, DDROverlayKey, DDRDesignInput, JTAGDebugOverlayKey, JTAGDebugDesignInput}
import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler}
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{XilinxVC707PCIeX1IO}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO}
import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO}
import chipyard.{HasHarnessSignalReferences, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey}
import chipyard.iobinders.{HasIOBinders}
import chipyard.harness.{ApplyHarnessBinders}
class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707Shell { outer =>
def dp = designParameters
// Order matters; ddr depends on sys_clock
val uart = Overlay(UARTOverlayKey, new UARTVC707ShellPlacer(this, UARTShellInput()))
val topDesign = LazyModule(p(BuildTop)(dp)).suggestName("chiptop")
// place all clocks in the shell
require(dp(ClockInputOverlayKey).size >= 1)
val sysClkNode = dp(ClockInputOverlayKey).head.place(ClockInputDesignInput()).overlayOutput.node
/*** Connect/Generate clocks ***/
// connect to the PLL that will generate multiple clocks
val harnessSysPLL = dp(PLLFactoryKey)()
harnessSysPLL := sysClkNode
// create and connect to the dutClock
println(s"VC707 FPGA Base Clock Freq: ${dp(DefaultClockFrequencyKey)} MHz")
val dutClock = ClockSinkNode(freqMHz = dp(DefaultClockFrequencyKey))
val dutWrangler = LazyModule(new ResetWrangler)
val dutGroup = ClockGroup()
dutClock := dutWrangler.node := dutGroup := harnessSysPLL
/*** LED ***/
val ledModule = dp(LEDOverlayKey).map(_.place(LEDDesignInput()).overlayOutput.led)
/*** Switch ***/
val switchModule = dp(SwitchOverlayKey).map(_.place(SwitchDesignInput()).overlayOutput.sw)
/*** Button ***/
val buttonModule = dp(ButtonOverlayKey).map(_.place(ButtonDesignInput()).overlayOutput.but)
/*** JTAG ***/
val jtagModule = dp(JTAGDebugOverlayKey).head.place(JTAGDebugDesignInput()).overlayOutput.jtag
/*** UART ***/
// 1st UART goes to the VC707 dedicated UART
val io_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).head)))
dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
/*** SPI ***/
// 1st SPI goes to the VC707 SDIO port
val io_spi_bb = BundleBridgeSource(() => (new SPIPortIO(dp(PeripherySPIKey).head)))
dp(SPIOverlayKey).head.place(SPIDesignInput(dp(PeripherySPIKey).head, io_spi_bb))
/*** DDR ***/
// Modify the last field of `DDRDesignInput` for 1GB RAM size
val ddrNode = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLL, true)).overlayOutput.ddr
// connect 1 mem. channel to the FPGA DDR
val inParams = topDesign match { case td: ChipTop =>
td.lazySystem match { case lsys: CanHaveMasterTLMemPort =>
lsys.memTLNode.edges.in(0)
}
}
val ddrClient = TLClientNode(Seq(inParams.master))
ddrNode := ddrClient
// module implementation
override lazy val module = new VC707FPGATestHarnessImp(this)
}
class VC707FPGATestHarnessImp(_outer: VC707FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences {
val vc707Outer = _outer
val reset = IO(Input(Bool()))
_outer.xdc.addBoardPin(reset, "reset")
val resetIBUF = Module(new IBUF)
resetIBUF.io.I := reset
val sysclk: Clock = _outer.sysClkNode.out.head._1.clock
val powerOnReset: Bool = PowerOnResetFPGAOnly(sysclk)
_outer.sdc.addAsyncPath(Seq(powerOnReset))
val ereset: Bool = _outer.chiplink.get() match {
case Some(x: ChipLinkVC707PlacedOverlay) => !x.ereset_n
case _ => false.B
}
_outer.pllReset := (resetIBUF.io.O || powerOnReset || ereset)
// reset setup
val hReset = Wire(Reset())
hReset := _outer.dutClock.in.head._1.reset
val buildtopClock = _outer.dutClock.in.head._1.clock
val buildtopReset = WireInit(hReset)
val dutReset = hReset.asAsyncReset
val success = false.B
childClock := buildtopClock
childReset := buildtopReset
// harness binders are non-lazy
_outer.topDesign match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
// check the top-level reference clock is equal to the default
// non-exhaustive since you need all ChipTop clocks to equal the default
require(getRefClockFreq == p(DefaultClockFrequencyKey))
}

View File

@@ -60,13 +60,15 @@ class WithVCU118Tweaks extends Config(
class RocketVCU118Config extends Config(
new WithVCU118Tweaks ++
new chipyard.RocketConfig)
new chipyard.RocketConfig
)
// DOC include end: AbstractVCU118 and Rocket
class BoomVCU118Config extends Config(
new WithFPGAFrequency(50) ++
new WithVCU118Tweaks ++
new chipyard.MegaBoomConfig)
new chipyard.MegaBoomConfig
)
class WithFPGAFrequency(fMHz: Double) extends Config(
new chipyard.config.WithPeripheryBusFrequency(fMHz) ++ // assumes using PBUS as default freq.

View File

@@ -3,19 +3,17 @@ package chipyard.fpga.vcu118
import chisel3._
import chisel3.experimental.{IO}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource}
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.tilelink.{TLClientNode}
import sifive.fpgashells.shell.xilinx._
import sifive.fpgashells.ip.xilinx._
import sifive.fpgashells.shell._
import sifive.fpgashells.clocks._
import sifive.fpgashells.shell.xilinx.{VCU118ShellBasicOverlays, UARTVCU118ShellPlacer, SDIOVCU118ShellPlacer, JTAGDebugBScanVCU118ShellPlacer, JTAGDebugVCU118ShellPlacer, cJTAGDebugVCU118ShellPlacer, PCIeVCU118FMCShellPlacer, PCIeVCU118EdgeShellPlacer, VCU118ShellPMOD, ChipLinkVCU118PlacedOverlay}
import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly}
import sifive.fpgashells.shell.{ClockInputOverlayKey, ClockInputDesignInput, ClockInputShellInput, UARTOverlayKey, UARTDesignInput, UARTShellInput, SPIOverlayKey, SPIDesignInput, SPIShellInput, JTAGDebugOverlayKey, JTAGDebugShellInput, JTAGDebugBScanOverlayKey, JTAGDebugBScanShellInput, cJTAGDebugOverlayKey, cJTAGDebugShellInput, PCIeOverlayKey, PCIeDesignInput, PCIeShellInput, DDROverlayKey, DDRDesignInput, DDRShellInput}
import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler}
import sifive.blocks.devices.uart._
import sifive.blocks.devices.spi._
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO}
import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO}
import chipyard.{HasHarnessSignalReferences, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey}
import chipyard.iobinders.{HasIOBinders}