diff --git a/src/main/scala/devices/xilinx/xilinxvc709mig/XilinxVC709MIG.scala b/src/main/scala/devices/xilinx/xilinxvc709mig/XilinxVC709MIG.scala
new file mode 100644
index 00000000..bac63af0
--- /dev/null
+++ b/src/main/scala/devices/xilinx/xilinxvc709mig/XilinxVC709MIG.scala
@@ -0,0 +1,179 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc709mig
+
+import Chisel._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.subsystem._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import sifive.fpgashells.ip.xilinx.vc709mig.{VC709MIGIOClocksReset, VC709MIGIODDR, vc709mig}
+
+case class XilinxVC709MIGParams(
+ address : Seq[AddressSet]
+)
+
+class XilinxVC709MIGPads(depth : BigInt) extends VC709MIGIODDR(depth) {
+ def this(c : XilinxVC709MIGParams) {
+ this(AddressRange.fromSets(c.address).head.size)
+ }
+}
+
+class XilinxVC709MIGIO(depth : BigInt) extends VC709MIGIODDR(depth) with VC709MIGIOClocksReset
+
+class XilinxVC709MIGIsland(c : XilinxVC709MIGParams)(implicit p: Parameters) extends LazyModule with CrossesToOnlyOneClockDomain {
+ val ranges = AddressRange.fromSets(c.address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val offset = ranges.head.base
+ val depth = ranges.head.size
+ val crossing = AsynchronousCrossing(8)
+ require((depth<=0x100000000L),"vc709mig supports upto 4GB depth configuraton")
+
+ val device = new MemoryDevice
+ val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = c.address,
+ resources = device.reg,
+ regionType = RegionType.UNCACHED,
+ executable = true,
+ supportsWrite = TransferSizes(1, 128),
+ supportsRead = TransferSizes(1, 128))),
+ beatBytes = 8)))
+
+ lazy val module = new LazyRawModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVC709MIGIO(depth)
+ })
+
+ childClock := io.port.ui_clk
+ childReset := io.port.ui_clk_sync_rst
+
+ //MIG black box instantiation
+ val blackbox = Module(new vc709mig(depth))
+ val (axi_async, _) = node.in(0)
+
+ //pins to top level
+
+ //inouts
+ //#[DDR3 SODIMM 0]
+ attach(io.port.ddr3_dq,blackbox.io.ddr3_dq)
+ attach(io.port.ddr3_dqs_n,blackbox.io.ddr3_dqs_n)
+ attach(io.port.ddr3_dqs_p,blackbox.io.ddr3_dqs_p)
+
+ //outputs
+ //#[DDR3 SODIMM 0]
+ io.port.ddr3_addr := blackbox.io.ddr3_addr
+ io.port.ddr3_ba := blackbox.io.ddr3_ba
+ io.port.ddr3_ras_n := blackbox.io.ddr3_ras_n
+ io.port.ddr3_cas_n := blackbox.io.ddr3_cas_n
+ io.port.ddr3_we_n := blackbox.io.ddr3_we_n
+ io.port.ddr3_reset_n := blackbox.io.ddr3_reset_n
+ io.port.ddr3_ck_p := blackbox.io.ddr3_ck_p
+ io.port.ddr3_ck_n := blackbox.io.ddr3_ck_n
+ io.port.ddr3_cke := blackbox.io.ddr3_cke
+ io.port.ddr3_cs_n := blackbox.io.ddr3_cs_n
+ io.port.ddr3_dm := blackbox.io.ddr3_dm
+ io.port.ddr3_odt := blackbox.io.ddr3_odt
+
+ //inputs
+ //NO_BUFFER clock
+ blackbox.io.sys_clk_i := io.port.sys_clk_i
+
+ //#[DDR3 SODIMM 0]
+ io.port.ui_clk := blackbox.io.ui_clk
+ io.port.ui_clk_sync_rst := blackbox.io.ui_clk_sync_rst
+ io.port.mmcm_locked := blackbox.io.mmcm_locked
+ blackbox.io.aresetn := io.port.aresetn
+ blackbox.io.app_sr_req := Bool(false)
+ blackbox.io.app_ref_req := Bool(false)
+ blackbox.io.app_zq_req := Bool(false)
+ //app_sr_active := unconnected
+ //app_ref_ack := unconnected
+ //app_zq_ack := unconnected
+
+ val awaddr = axi_async.aw.bits.addr - UInt(offset)
+ val araddr = axi_async.ar.bits.addr - UInt(offset)
+
+ // [DDR3 SODIMM 0]
+ //slave AXI interface write address ports
+ blackbox.io.s_axi_awid := axi_async.aw.bits.id
+ blackbox.io.s_axi_awaddr := awaddr //truncated
+ blackbox.io.s_axi_awlen := axi_async.aw.bits.len
+ blackbox.io.s_axi_awsize := axi_async.aw.bits.size
+ blackbox.io.s_axi_awburst := axi_async.aw.bits.burst
+ blackbox.io.s_axi_awlock := axi_async.aw.bits.lock
+ blackbox.io.s_axi_awcache := UInt("b0011")
+ blackbox.io.s_axi_awprot := axi_async.aw.bits.prot
+ blackbox.io.s_axi_awqos := axi_async.aw.bits.qos
+ blackbox.io.s_axi_awvalid := axi_async.aw.valid
+ axi_async.aw.ready := blackbox.io.s_axi_awready
+
+ //slave interface write data ports
+ blackbox.io.s_axi_wdata := axi_async.w.bits.data
+ blackbox.io.s_axi_wstrb := axi_async.w.bits.strb
+ blackbox.io.s_axi_wlast := axi_async.w.bits.last
+ blackbox.io.s_axi_wvalid := axi_async.w.valid
+ axi_async.w.ready := blackbox.io.s_axi_wready
+
+ //slave interface write response
+ blackbox.io.s_axi_bready := axi_async.b.ready
+ axi_async.b.bits.id := blackbox.io.s_axi_bid
+ axi_async.b.bits.resp := blackbox.io.s_axi_bresp
+ axi_async.b.valid := blackbox.io.s_axi_bvalid
+
+ //slave AXI interface read address ports
+ blackbox.io.s_axi_arid := axi_async.ar.bits.id
+ blackbox.io.s_axi_araddr := araddr // truncated
+ blackbox.io.s_axi_arlen := axi_async.ar.bits.len
+ blackbox.io.s_axi_arsize := axi_async.ar.bits.size
+ blackbox.io.s_axi_arburst := axi_async.ar.bits.burst
+ blackbox.io.s_axi_arlock := axi_async.ar.bits.lock
+ blackbox.io.s_axi_arcache := UInt("b0011")
+ blackbox.io.s_axi_arprot := axi_async.ar.bits.prot
+ blackbox.io.s_axi_arqos := axi_async.ar.bits.qos
+ blackbox.io.s_axi_arvalid := axi_async.ar.valid
+
+ axi_async.ar.ready := blackbox.io.s_axi_arready
+
+ //slace AXI interface read data ports
+ blackbox.io.s_axi_rready := axi_async.r.ready
+ axi_async.r.bits.id := blackbox.io.s_axi_rid
+ axi_async.r.bits.data := blackbox.io.s_axi_rdata
+ axi_async.r.bits.resp := blackbox.io.s_axi_rresp
+ axi_async.r.bits.last := blackbox.io.s_axi_rlast
+ axi_async.r.valid := blackbox.io.s_axi_rvalid
+
+ //misc
+ io.port.init_calib_complete := blackbox.io.init_calib_complete
+
+ blackbox.io.sys_rst :=io.port.sys_rst
+ //mig.device_temp_i :- unconnected
+ //mig.device_temp :- unconnceted
+ }
+}
+
+class XilinxVC709MIG(c : XilinxVC709MIGParams)(implicit p: Parameters) extends LazyModule {
+ val ranges = AddressRange.fromSets(c.address)
+ val depth = ranges.head.size
+
+ // The data follows from top to down
+ val buffer = LazyModule(new TLBuffer)
+ val toaxi4 = LazyModule(new TLToAXI4(adapterName = Some("mem")))
+ val indexer = LazyModule(new AXI4IdIndexer(idBits = 4))
+ val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes)))
+ val yank = LazyModule(new AXI4UserYanker)
+ val island = LazyModule(new XilinxVC709MIGIsland(c))
+
+ val node: TLInwardNode =
+ island.crossAXI4In(island.node) := yank.node := deint.node := indexer.node := toaxi4.node := buffer.node
+
+ lazy val module = new LazyModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVC709MIGIO(depth)
+ })
+
+ io.port <> island.module.io.port
+ }
+}
diff --git a/src/main/scala/devices/xilinx/xilinxvc709mig/XilinxVC709MIGPeriphery.scala b/src/main/scala/devices/xilinx/xilinxvc709mig/XilinxVC709MIGPeriphery.scala
new file mode 100644
index 00000000..93f23ccd
--- /dev/null
+++ b/src/main/scala/devices/xilinx/xilinxvc709mig/XilinxVC709MIGPeriphery.scala
@@ -0,0 +1,35 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc709mig
+
+import Chisel._
+import freechips.rocketchip.config._
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange}
+
+case object MemoryXilinxDDRKey extends Field[XilinxVC709MIGParams]
+
+trait HasMemoryXilinxVC709MIG { this: BaseSubsystem =>
+ val module: HasMemoryXilinxVC709MIGModuleImp
+
+ val xilinxvc709mig = LazyModule(new XilinxVC709MIG(p(MemoryXilinxDDRKey)))
+
+ xilinxvc709mig.node := mbus.toDRAMController(Some("xilinxvc709mig"))()
+}
+
+trait HasMemoryXilinxVC709MIGBundle {
+ val xilinxvc709mig: XilinxVC709MIGIO
+ def connectXilinxVC709MIGToPads(pads: XilinxVC709MIGPads) {
+ pads <> xilinxvc709mig
+ }
+}
+
+trait HasMemoryXilinxVC709MIGModuleImp extends LazyModuleImp
+ with HasMemoryXilinxVC709MIGBundle {
+ val outer: HasMemoryXilinxVC709MIG
+ val ranges = AddressRange.fromSets(p(MemoryXilinxDDRKey).address)
+ require (ranges.size == 1, "DDR range must be contiguous")
+ val depth = ranges.head.size
+ val xilinxvc709mig = IO(new XilinxVC709MIGIO(depth))
+
+ xilinxvc709mig <> outer.xilinxvc709mig.module.io.port
+}
diff --git a/src/main/scala/devices/xilinx/xilinxvc709pcie/XilinxVC709PCIe.scala b/src/main/scala/devices/xilinx/xilinxvc709pcie/XilinxVC709PCIe.scala
new file mode 100644
index 00000000..d39d350f
--- /dev/null
+++ b/src/main/scala/devices/xilinx/xilinxvc709pcie/XilinxVC709PCIe.scala
@@ -0,0 +1,76 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc709pcie
+
+import Chisel._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.config.Parameters
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.subsystem.{CrossesToOnlyOneClockDomain, CacheBlockBytes}
+import sifive.fpgashells.ip.xilinx.vc709axi_to_pcie.{VC709AXIToPCIe, VC709AXIToPCIeIOClocksReset, VC709AXIToPCIeIOSerial}
+import sifive.fpgashells.ip.xilinx.ibufds_gte2.IBUFDS_GTE2
+
+trait VC709AXIToPCIeRefClk extends Bundle{
+ val REFCLK_rxp = Bool(INPUT)
+ val REFCLK_rxn = Bool(INPUT)
+}
+
+class XilinxVC709PCIePads extends Bundle
+ with VC709AXIToPCIeIOSerial
+ with VC709AXIToPCIeRefClk
+
+class XilinxVC709PCIeIO extends Bundle
+ with VC709AXIToPCIeRefClk
+ with VC709AXIToPCIeIOSerial
+ with VC709AXIToPCIeIOClocksReset {
+ val axi_ctl_aresetn = Bool(INPUT)
+}
+
+class XilinxVC709PCIe(implicit p: Parameters, val crossing: ClockCrossingType = AsynchronousCrossing(8))
+ extends LazyModule with CrossesToOnlyOneClockDomain
+{
+ val axi_to_pcie = LazyModule(new VC709AXIToPCIe)
+
+ val slave: TLInwardNode =
+ (axi_to_pcie.slave
+ := AXI4Buffer()
+ := AXI4UserYanker()
+ := AXI4Deinterleaver(p(CacheBlockBytes))
+ := AXI4IdIndexer(idBits=4)
+ := TLToAXI4(adapterName = Some("pcie-slave")))
+
+ val control: TLInwardNode =
+ (axi_to_pcie.control
+ := AXI4Buffer()
+ := AXI4UserYanker(capMaxFlight = Some(2))
+ := TLToAXI4()
+ := TLFragmenter(4, p(CacheBlockBytes), holdFirstDeny = true))
+
+ val master: TLOutwardNode =
+ (TLWidthWidget(8)
+ := AXI4ToTL()
+ := AXI4UserYanker(capMaxFlight=Some(8))
+ := AXI4Fragmenter()
+ := axi_to_pcie.master)
+
+ val intnode: IntOutwardNode = axi_to_pcie.intnode
+
+ lazy val module = new LazyRawModuleImp(this) {
+ val io = IO(new Bundle {
+ val port = new XilinxVC709PCIeIO
+ })
+
+ childClock := io.port.axi_aclk // axi_aclk_out is changed to axi_aclk
+ childReset := ~io.port.axi_aresetn //
+
+ io.port <> axi_to_pcie.module.io.port
+
+ //PCIe Reference Clock
+ val ibufds_gte2 = Module(new IBUFDS_GTE2)
+ axi_to_pcie.module.io.refclk := ibufds_gte2.io.O // REFCLK is changed to refclk
+ ibufds_gte2.io.CEB := UInt(0)
+ ibufds_gte2.io.I := io.port.REFCLK_rxp
+ ibufds_gte2.io.IB := io.port.REFCLK_rxn
+ }
+}
diff --git a/src/main/scala/devices/xilinx/xilinxvc709pcie/XilinxVC709PCIePeriphery.scala b/src/main/scala/devices/xilinx/xilinxvc709pcie/XilinxVC709PCIePeriphery.scala
new file mode 100644
index 00000000..a0b7aafd
--- /dev/null
+++ b/src/main/scala/devices/xilinx/xilinxvc709pcie/XilinxVC709PCIePeriphery.scala
@@ -0,0 +1,32 @@
+// See LICENSE for license details.
+package sifive.fpgashells.devices.xilinx.xilinxvc709pcie
+
+import Chisel._
+import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams}
+import freechips.rocketchip.subsystem.BaseSubsystem
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.interrupts.IntSyncCrossingSink
+
+trait HasSystemXilinxVC709PCIe { this: BaseSubsystem =>
+ val xilinxvc709pcie = LazyModule(new XilinxVC709PCIe)
+ private val cname = "xilinxvc709pcie"
+ sbus.coupleFrom(s"master_named_$cname") { _ :=* TLFIFOFixer(TLFIFOFixer.all) :=* xilinxvc709pcie.crossTLOut(xilinxvc709pcie.master) }
+ sbus.coupleTo(s"slave_named_$cname") { xilinxvc709pcie.crossTLIn(xilinxvc709pcie.slave) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
+ sbus.coupleTo(s"controller_named_$cname") { xilinxvc709pcie.crossTLIn(xilinxvc709pcie.control) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
+ ibus.fromSync := xilinxvc709pcie.crossIntOut(xilinxvc709pcie.intnode)
+}
+
+trait HasSystemXilinxVC709PCIeBundle {
+ val xilinxvc709pcie: XilinxVC709PCIeIO
+ def connectXilinxVC709PCIeToPads(pads: XilinxVC709PCIePads) {
+ pads <> xilinxvc709pcie
+ }
+}
+
+trait HasSystemXilinxVC709PCIeModuleImp extends LazyModuleImp
+ with HasSystemXilinxVC709PCIeBundle {
+ val outer: HasSystemXilinxVC709PCIe
+ val xilinxvc709pcie = IO(new XilinxVC709PCIeIO)
+
+ xilinxvc709pcie <> outer.xilinxvc709pcie.module.io.port
+}
\ No newline at end of file
diff --git a/src/main/scala/ip/xilinx/vc709axi_to_pcie/vc709axi_to_pcie.scala b/src/main/scala/ip/xilinx/vc709axi_to_pcie/vc709axi_to_pcie.scala
new file mode 100644
index 00000000..760bbd9f
--- /dev/null
+++ b/src/main/scala/ip/xilinx/vc709axi_to_pcie/vc709axi_to_pcie.scala
@@ -0,0 +1,378 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.vc709axi_to_pcie
+
+import Chisel._
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.amba.axi4._
+import freechips.rocketchip.interrupts._
+import freechips.rocketchip.util.{ElaborationArtefacts}
+
+// AXI Bridge for PCI Express Gen3 Subsystem v3.0
+// Product Guide Vivado Design Suite PG194 (v3.0) July 22, 2020
+// IP VLNV: xilinx.com:customize_ip:vc709pcietoaxi:3.0
+// Black Box Signals named _exactly_ as per Vivado generated verilog
+trait VC709AXIToPCIeIOSerial extends Bundle {
+ def NUM_LANES = 8
+ // PCIe Interface
+ val pci_exp_txp = Bits(OUTPUT,NUM_LANES)
+ val pci_exp_txn = Bits(OUTPUT,NUM_LANES)
+ val pci_exp_rxp = Bits(INPUT,NUM_LANES)
+ val pci_exp_rxn = Bits(INPUT,NUM_LANES)
+}
+
+trait VC709AXIToPCIeIOClocksReset extends Bundle {
+ // Global Signals
+ val axi_aresetn = Bool(INPUT)
+ val axi_aclk = Clock(OUTPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class vc709axi_to_pcie() extends BlackBox
+{
+ def AXI_ADDR_WIDTH = 32
+ def AXI_DATA_WIDTH = 128
+ val io = new Bundle with VC709AXIToPCIeIOSerial
+ with VC709AXIToPCIeIOClocksReset {
+ // Global Signals
+ val refclk = Bool(INPUT)
+ val interrupt_out = Bool(OUTPUT)
+
+ // AXI Bridge for PCIe Gen3 MSI Signals
+ val intx_msi_request = Bool(INPUT)
+ val intx_msi_grant = Bool(OUTPUT)
+ val msi_enable = Bool(OUTPUT)
+ val msi_vector_width = Bits(OUTPUT,3)
+ val msi_vector_num = Bits(INPUT,5)
+
+ // AXI Slave Interface
+ // write address
+ val s_axi_awid = Bits(INPUT,4)
+ val s_axi_awaddr = Bits(INPUT,AXI_ADDR_WIDTH)
+ val s_axi_awregion = Bits(INPUT,4)
+ val s_axi_awlen = Bits(INPUT,8)
+ val s_axi_awsize = Bits(INPUT,3)
+ val s_axi_awburst = Bits(INPUT,2)
+ val s_axi_awvalid = Bool(INPUT)
+ val s_axi_awready = Bool(OUTPUT)
+ // write data
+ val s_axi_wdata = Bits(INPUT,AXI_DATA_WIDTH)
+ val s_axi_wstrb = Bits(INPUT,16)
+ val s_axi_wlast = Bool(INPUT)
+ val s_axi_wvalid = Bool(INPUT)
+ val s_axi_wready = Bool(OUTPUT)
+ // write response
+ val s_axi_bready = Bool(INPUT)
+ val s_axi_bid = Bits(OUTPUT,4)
+ val s_axi_bresp = Bits(OUTPUT,2)
+ val s_axi_bvalid = Bool(OUTPUT)
+ // read address
+ val s_axi_arid = Bits(INPUT,4)
+ val s_axi_araddr = Bits(INPUT,AXI_ADDR_WIDTH)
+ val s_axi_arregion = Bits(INPUT,4)
+ val s_axi_arlen = Bits(INPUT,8)
+ val s_axi_arsize = Bits(INPUT,3)
+ val s_axi_arburst = Bits(INPUT,2)
+ val s_axi_arvalid = Bool(INPUT)
+ val s_axi_arready = Bool(OUTPUT)
+ //slave interface read data
+ val s_axi_rready = Bool(INPUT)
+ val s_axi_rid = Bits(OUTPUT,4)
+ val s_axi_rdata = Bits(OUTPUT,AXI_DATA_WIDTH)
+ val s_axi_rresp = Bits(OUTPUT,2)
+ val s_axi_rlast = Bool(OUTPUT)
+ val s_axi_rvalid = Bool(OUTPUT)
+
+ // AXI Master Interface
+ // write address
+ val m_axi_awaddr = Bits(OUTPUT,AXI_ADDR_WIDTH)
+ val m_axi_awlen = Bits(OUTPUT,8)
+ val m_axi_awsize = Bits(OUTPUT,3)
+ val m_axi_awburst = Bits(OUTPUT,2)
+ val m_axi_awprot = Bits(OUTPUT,3)
+ val m_axi_awvalid = Bool(OUTPUT)
+ val m_axi_awlock = Bits(OUTPUT,1)
+ val m_axi_awcache = Bits(OUTPUT,4)
+ val m_axi_awready = Bool(INPUT)
+ // write data
+ val m_axi_wdata = Bits(OUTPUT,AXI_DATA_WIDTH)
+ val m_axi_wstrb = Bits(OUTPUT,16)
+ val m_axi_wlast = Bool(OUTPUT)
+ val m_axi_wvalid = Bool(OUTPUT)
+ val m_axi_wready = Bool(INPUT)
+ // write response
+ val m_axi_bready = Bool(OUTPUT)
+ val m_axi_bresp = Bits(INPUT,2)
+ val m_axi_bvalid = Bool(INPUT)
+ // read address
+ val m_axi_araddr = Bits(OUTPUT,AXI_ADDR_WIDTH)
+ val m_axi_arlen = Bits(OUTPUT,8)
+ val m_axi_arsize = Bits(OUTPUT,3)
+ val m_axi_arburst = Bits(OUTPUT,2)
+ val m_axi_arprot = Bits(OUTPUT,3)
+ val m_axi_arvalid = Bool(OUTPUT)
+ val m_axi_arlock = Bits(OUTPUT,1)
+ val m_axi_arcache = Bits(OUTPUT,4)
+ val m_axi_arready = Bool(INPUT)
+ // read data
+ val m_axi_rready = Bool(OUTPUT)
+ val m_axi_rdata = Bits(INPUT,AXI_DATA_WIDTH)
+ val m_axi_rresp = Bits(INPUT,2)
+ val m_axi_rlast = Bool(INPUT)
+ val m_axi_rvalid = Bool(INPUT)
+
+ // AXI4-Lite Control Interface
+ val s_axi_ctl_awaddr = Bits(INPUT,28)
+ val s_axi_ctl_awvalid = Bool(INPUT)
+ val s_axi_ctl_awready = Bool(OUTPUT)
+ val s_axi_ctl_wdata = Bits(INPUT,32)
+ val s_axi_ctl_wstrb = Bits(INPUT,4)
+ val s_axi_ctl_wvalid = Bool(INPUT)
+ val s_axi_ctl_wready = Bool(OUTPUT)
+ val s_axi_ctl_bresp = Bits(OUTPUT,2)
+ val s_axi_ctl_bvalid = Bool(OUTPUT)
+ val s_axi_ctl_bready = Bool(INPUT)
+ val s_axi_ctl_araddr = Bits(INPUT,28)
+ val s_axi_ctl_arvalid = Bool(INPUT)
+ val s_axi_ctl_arready = Bool(OUTPUT)
+ val s_axi_ctl_rdata = Bits(OUTPUT,32)
+ val s_axi_ctl_rresp = Bits(OUTPUT,2)
+ val s_axi_ctl_rvalid = Bool(OUTPUT)
+ val s_axi_ctl_rready = Bool(INPUT)
+ }
+}
+//scalastyle:off
+
+//wrap vc709_axi_to_pcie black box in Nasti Bundles
+// see Chipyard doc: 9.1.2 Manager Node
+class VC709AXIToPCIe(implicit p:Parameters) extends LazyModule
+{
+ // device-tree node
+ val device = new SimpleDevice("pci", Seq("xlnx,axi-pcie-host-1.00.a")) {
+ override def describe(resources: ResourceBindings): Description = {
+ val Description(name, mapping) = super.describe(resources)
+ val intc = "pcie_intc"
+ def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
+ def ofMap(x: Int) = Seq(0, 0, 0, x).flatMap(ofInt) ++ Seq(ResourceReference(intc)) ++ ofInt(x)
+ val extra = Map(
+ "#address-cells" -> ofInt(3),
+ "#size-cells" -> ofInt(2),
+ "#interrupt-cells" -> ofInt(1),
+ "device_type" -> Seq(ResourceString("pci")),
+ "interrupt-map-mask" -> Seq(0, 0, 0, 7).flatMap(ofInt),
+ "interrupt-map" -> Seq(1, 2, 3, 4).flatMap(ofMap),
+ "ranges" -> resources("ranges").map(x =>
+ (x: @unchecked) match { case Binding(_, ResourceAddress(address, perms)) =>
+ ResourceMapping(address, BigInt(0x02000000) << 64, perms) }),
+ "interrupt-controller" -> Seq(ResourceMap(labels = Seq(intc), value = Map(
+ "interrupt-controller" -> Nil,
+ "#address-cells" -> ofInt(0),
+ "#interrupt-cells" -> ofInt(1)))))
+ Description(name, mapping ++ extra)
+ }
+ }
+
+ val slave = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = List(AddressSet(0x40000000L, 0x1fffffffL)),
+ resources = Seq(Resource(device, "ranges")),
+ executable = true,
+ supportsWrite = TransferSizes(1, 128),
+ supportsRead = TransferSizes(1, 128))),
+ beatBytes = 8)))
+
+ val control = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
+ slaves = Seq(AXI4SlaveParameters(
+ address = List(AddressSet(0x2000000000L, 0x3ffffffL)), // when truncated to 32-bits, is 0
+ resources = device.reg("control"),
+ supportsWrite = TransferSizes(1, 4),
+ supportsRead = TransferSizes(1, 4),
+ interleavedId = Some(0))), // AXI4-Lite never interleaves responses
+ beatBytes = 4)))
+
+ val master = AXI4MasterNode(Seq(AXI4MasterPortParameters(
+ masters = Seq(AXI4MasterParameters(
+ name = "VC709 PCIe",
+ id = IdRange(0, 1),
+ aligned = false)))))
+
+ val intnode = IntSourceNode(IntSourcePortSimple(resources = device.int))
+
+ lazy val module = new LazyModuleImp(this) {
+ // The master on the control port must be AXI-lite
+ require (control.edges.in(0).master.endId == 1)
+ // Must have exactly the right number of idBits
+ require (slave.edges.in(0).bundle.idBits == 4)
+
+ class VC709AXIToPCIeIOBundle extends Bundle with VC709AXIToPCIeIOSerial
+ with VC709AXIToPCIeIOClocksReset;
+
+ val io = IO(new Bundle {
+ val port = new VC709AXIToPCIeIOBundle
+ val refclk = Bool(INPUT) // REFCLK is changed to refclk in 3.0
+ })
+
+ val blackbox = Module(new vc709axi_to_pcie)
+
+ val (s, _) = slave.in(0)
+ val (c, _) = control.in(0)
+ val (m, _) = master.out(0)
+ val (i, _) = intnode.out(0)
+
+ //to top level
+ blackbox.io.axi_aresetn := io.port.axi_aresetn
+ io.port.axi_aclk := blackbox.io.axi_aclk
+ io.port.pci_exp_txp := blackbox.io.pci_exp_txp
+ io.port.pci_exp_txn := blackbox.io.pci_exp_txn
+ blackbox.io.pci_exp_rxp := io.port.pci_exp_rxp
+ blackbox.io.pci_exp_rxn := io.port.pci_exp_rxn
+ i(0) := blackbox.io.interrupt_out
+ blackbox.io.refclk := io.refclk
+
+ // AXI Slave Interface
+ // write address
+ blackbox.io.s_axi_awid := s.aw.bits.id
+ blackbox.io.s_axi_awaddr := s.aw.bits.addr
+ blackbox.io.s_axi_awlen := s.aw.bits.len
+ blackbox.io.s_axi_awsize := s.aw.bits.size
+ blackbox.io.s_axi_awburst := s.aw.bits.burst
+ blackbox.io.s_axi_awregion := UInt(0)
+ blackbox.io.s_axi_awvalid := s.aw.valid
+ s.aw.ready := blackbox.io.s_axi_awready
+ // write data
+ blackbox.io.s_axi_wdata := s.w.bits.data
+ blackbox.io.s_axi_wstrb := s.w.bits.strb
+ blackbox.io.s_axi_wlast := s.w.bits.last
+ blackbox.io.s_axi_wvalid := s.w.valid
+ s.w.ready := blackbox.io.s_axi_wready
+ // write response
+ s.b.bits.id := blackbox.io.s_axi_bid
+ s.b.bits.resp := blackbox.io.s_axi_bresp
+ s.b.valid := blackbox.io.s_axi_bvalid
+ blackbox.io.s_axi_bready := s.b.ready
+ // read address
+ blackbox.io.s_axi_arid := s.ar.bits.id
+ blackbox.io.s_axi_araddr := s.ar.bits.addr
+ blackbox.io.s_axi_arlen := s.ar.bits.len
+ blackbox.io.s_axi_arsize := s.ar.bits.size
+ blackbox.io.s_axi_arburst := s.ar.bits.burst
+ blackbox.io.s_axi_arregion := UInt(0)
+ blackbox.io.s_axi_arvalid := s.ar.valid
+ s.ar.ready := blackbox.io.s_axi_arready
+ // read data
+ s.r.bits.id := blackbox.io.s_axi_rid
+ s.r.bits.data := blackbox.io.s_axi_rdata
+ s.r.bits.resp := blackbox.io.s_axi_rresp
+ s.r.bits.last := blackbox.io.s_axi_rlast
+ s.r.valid := blackbox.io.s_axi_rvalid
+ blackbox.io.s_axi_rready := s.r.ready
+
+ // AXI4-Lite Control Interface
+ // write address
+ blackbox.io.s_axi_ctl_awaddr := c.aw.bits.addr
+ blackbox.io.s_axi_ctl_awvalid := c.aw.valid
+ c.aw.ready := blackbox.io.s_axi_ctl_awready
+ // write data
+ blackbox.io.s_axi_ctl_wdata := c.w.bits.data
+ blackbox.io.s_axi_ctl_wstrb := c.w.bits.strb
+ blackbox.io.s_axi_ctl_wvalid := c.w.valid
+ c.w.ready := blackbox.io.s_axi_ctl_wready
+ // write response
+ blackbox.io.s_axi_ctl_bready := c.b.ready
+ c.b.bits.id := UInt(0)
+ c.b.bits.resp := blackbox.io.s_axi_ctl_bresp
+ c.b.valid := blackbox.io.s_axi_ctl_bvalid
+ // read address
+ blackbox.io.s_axi_ctl_araddr := c.ar.bits.addr
+ blackbox.io.s_axi_ctl_arvalid := c.ar.valid
+ c.ar.ready := blackbox.io.s_axi_ctl_arready
+ // read data
+ blackbox.io.s_axi_ctl_rready := c.r.ready
+ c.r.bits.id := UInt(0)
+ c.r.bits.data := blackbox.io.s_axi_ctl_rdata
+ c.r.bits.resp := blackbox.io.s_axi_ctl_rresp
+ c.r.bits.last := Bool(true)
+ c.r.valid := blackbox.io.s_axi_ctl_rvalid
+
+ // AXI Master Interface
+ // write address
+ m.aw.bits.id := UInt(0)
+ m.aw.bits.addr := blackbox.io.m_axi_awaddr
+ m.aw.bits.len := blackbox.io.m_axi_awlen
+ m.aw.bits.size := blackbox.io.m_axi_awsize
+ m.aw.bits.burst := blackbox.io.m_axi_awburst
+ m.aw.bits.prot := blackbox.io.m_axi_awprot
+ m.aw.bits.lock := blackbox.io.m_axi_awlock
+ m.aw.bits.cache := blackbox.io.m_axi_awcache
+ m.aw.bits.qos := UInt(0)
+ m.aw.valid := blackbox.io.m_axi_awvalid
+ blackbox.io.m_axi_awready := m.aw.ready
+ // write data
+ m.w.bits.data := blackbox.io.m_axi_wdata
+ m.w.bits.strb := blackbox.io.m_axi_wstrb
+ m.w.bits.last := blackbox.io.m_axi_wlast
+ m.w.valid := blackbox.io.m_axi_wvalid
+ blackbox.io.m_axi_wready := m.w.ready
+ // write response
+ blackbox.io.m_axi_bresp := m.b.bits.resp
+ blackbox.io.m_axi_bvalid := m.b.valid
+ m.b.ready := blackbox.io.m_axi_bready
+ // read address
+ m.ar.bits.id := UInt(0)
+ m.ar.bits.addr := blackbox.io.m_axi_araddr
+ m.ar.bits.len := blackbox.io.m_axi_arlen
+ m.ar.bits.size := blackbox.io.m_axi_arsize
+ m.ar.bits.burst := blackbox.io.m_axi_arburst
+ m.ar.bits.lock := blackbox.io.m_axi_arlock
+ m.ar.bits.cache := blackbox.io.m_axi_arcache
+ m.ar.bits.prot := blackbox.io.m_axi_arprot
+ m.ar.bits.qos := UInt(0)
+ m.ar.valid := blackbox.io.m_axi_arvalid
+ blackbox.io.m_axi_arready := m.ar.ready
+ // read data
+ blackbox.io.m_axi_rdata := m.r.bits.data
+ blackbox.io.m_axi_rresp := m.r.bits.resp
+ blackbox.io.m_axi_rlast := m.r.bits.last
+ blackbox.io.m_axi_rvalid := m.r.valid
+ m.r.ready := blackbox.io.m_axi_rready
+ }
+
+ ElaborationArtefacts.add(
+ "vc709axi_to_pcie.vivado.tcl",
+ """
+ create_ip -vendor xilinx.com -library ip -version 3.0 -name axi_pcie3 -module_name vc709axi_to_pcie -dir $ipdir -force
+ set_property -dict [list \
+ CONFIG.AXIBAR2PCIEBAR_0 {0x40000000} \
+ CONFIG.AXIBAR_0 {0x40000000} \
+ CONFIG.AXIBAR_HIGHADDR_0 {0x5FFFFFFF} \
+ CONFIG.AXIBAR_NUM {1} \
+ CONFIG.BASEADDR {0x00000000} \
+ CONFIG.HIGHADDR {0x03FFFFFF} \
+ CONFIG.DEVICE_PORT_TYPE {Root_Port_of_PCI_Express_Root_Complex} \
+ CONFIG.INCLUDE_BAROFFSET_REG {true} \
+ CONFIG.PCIEBAR2AXIBAR_0 {0x00000000} \
+ CONFIG.PCIE_BLK_LOCN {X0Y0} \
+ CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} \
+ CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {2.5_GT/s} \
+ CONFIG.PF0_DEVICE_ID {7118} \
+ CONFIG.PF0_REVISION_ID {0} \
+ CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10EE} \
+ CONFIG.PF0_SUBSYSTEM_ID {0007} \
+ CONFIG.PF0_BAR0_64BIT {true} \
+ CONFIG.PF0_BAR0_ENABLED {true} \
+ CONFIG.PF0_BAR0_PREFETCHABLE {false} \
+ CONFIG.PF0_BAR0_SCALE {Gigabytes} \
+ CONFIG.PF0_BAR0_SIZE {4} \
+ CONFIG.PF0_BAR0_TYPE {Memory} \
+ CONFIG.PF0_BASE_CLASS_MENU {Bridge_device} \
+ CONFIG.PF0_SUB_CLASS_interface_menu {Host_bridge} \
+ CONFIG.PF0_CLASS_CODE {0x060000} \
+ CONFIG.COMP_TIMEOUT {50ms} \
+ CONFIG.REF_CLK_FREQ {100_MHz} \
+ CONFIG.AXI_ADDR_WIDTH {32} \
+ CONFIG.AXI_DATA_WIDTH {128_bit} \
+ CONFIG.C_S_AXI_SUPPORTS_NARROW_BURST {false} \
+ CONFIG.XLNX_REF_BOARD {VC709} ] [get_ips vc709axi_to_pcie]"""
+ )
+}
diff --git a/src/main/scala/ip/xilinx/vc709mig/vc709mig.scala b/src/main/scala/ip/xilinx/vc709mig/vc709mig.scala
new file mode 100644
index 00000000..c13fe735
--- /dev/null
+++ b/src/main/scala/ip/xilinx/vc709mig/vc709mig.scala
@@ -0,0 +1,542 @@
+// See LICENSE for license details.
+package sifive.fpgashells.ip.xilinx.vc709mig
+
+import Chisel._
+import chisel3.util._
+import chisel3.experimental.{Analog,attach}
+import freechips.rocketchip.util.{ElaborationArtefacts}
+import freechips.rocketchip.util.GenericParameterizedBundle
+import freechips.rocketchip.config._
+
+// IP VLNV: xilinx.com:customize_ip:vc709mig:4.1
+// Black Box
+
+class VC709MIGIODDR(depth : BigInt) extends GenericParameterizedBundle(depth) {
+ require((depth<=0x200000000L),"VC709MIGIODDR supports upto 4GB depth configuraton")
+ val ddr3_addr = Bits(OUTPUT,16)
+ val ddr3_ba = Bits(OUTPUT,3)
+ val ddr3_ras_n = Bool(OUTPUT)
+ val ddr3_cas_n = Bool(OUTPUT)
+ val ddr3_we_n = Bool(OUTPUT)
+ val ddr3_reset_n = Bool(OUTPUT)
+ val ddr3_ck_p = Bits(OUTPUT,1)
+ val ddr3_ck_n = Bits(OUTPUT,1)
+ val ddr3_cke = Bits(OUTPUT,1)
+ val ddr3_cs_n = Bits(OUTPUT,1)
+ val ddr3_odt = Bits(OUTPUT,1)
+ val ddr3_dm = Bits(OUTPUT,8)
+
+ val ddr3_dq = Analog(64.W)
+ val ddr3_dqs_n = Analog(8.W)
+ val ddr3_dqs_p = Analog(8.W)
+}
+
+//reused directly in io bundle for sifive.blocks.devices.xilinxvc709mig
+trait VC709MIGIOClocksReset extends Bundle {
+ //inputs
+ //"NO_BUFFER" clock source (must be connected to IBUF outside of IP)
+ val sys_clk_i = Bool(INPUT)
+ //user interface signals
+ val ui_clk = Clock(OUTPUT)
+ val ui_clk_sync_rst = Bool(OUTPUT)
+ val mmcm_locked = Bool(OUTPUT)
+ val aresetn = Bool(INPUT)
+ //misc
+ val init_calib_complete = Bool(OUTPUT)
+ val sys_rst = Bool(INPUT)
+}
+
+//scalastyle:off
+//turn off linter: blackbox name must match verilog module
+class vc709mig(depth : BigInt)(implicit val p:Parameters) extends BlackBox
+{
+ require((depth<=0x200000000L), "vc709mig supports upto 8GB depth configuraton")
+
+ override def desiredName = "vc709mig_a"
+
+ def DDR3_ADDR_WIDTH = 32
+ def DDR3_DATA_WIDTH = 64
+
+ val io = new VC709MIGIODDR(depth) with VC709MIGIOClocksReset {
+ // User interface signals
+ val app_sr_req = Bool(INPUT)
+ val app_ref_req = Bool(INPUT)
+ val app_zq_req = Bool(INPUT)
+ val app_sr_active = Bool(OUTPUT)
+ val app_ref_ack = Bool(OUTPUT)
+ val app_zq_ack = Bool(OUTPUT)
+ //axi_s
+ //slave interface write address ports
+ val s_axi_awid = Bits(INPUT,4)
+ val s_axi_awaddr = Bits(INPUT,DDR3_ADDR_WIDTH)
+ val s_axi_awlen = Bits(INPUT,8)
+ val s_axi_awsize = Bits(INPUT,3)
+ val s_axi_awburst = Bits(INPUT,2)
+ val s_axi_awlock = Bits(INPUT,1)
+ val s_axi_awcache = Bits(INPUT,4)
+ val s_axi_awprot = Bits(INPUT,3)
+ val s_axi_awqos = Bits(INPUT,4)
+ val s_axi_awvalid = Bool(INPUT)
+ val s_axi_awready = Bool(OUTPUT)
+ //slave interface write data ports
+ val s_axi_wdata = Bits(INPUT,DDR3_DATA_WIDTH)
+ val s_axi_wstrb = Bits(INPUT,8)
+ val s_axi_wlast = Bool(INPUT)
+ val s_axi_wvalid = Bool(INPUT)
+ val s_axi_wready = Bool(OUTPUT)
+ //slave interface write response ports
+ val s_axi_bready = Bool(INPUT)
+ val s_axi_bid = Bits(OUTPUT,4)
+ val s_axi_bresp = Bits(OUTPUT,2)
+ val s_axi_bvalid = Bool(OUTPUT)
+ //slave interface read address ports
+ val s_axi_arid = Bits(INPUT,4)
+ val s_axi_araddr = Bits(INPUT,DDR3_ADDR_WIDTH)
+ val s_axi_arlen = Bits(INPUT,8)
+ val s_axi_arsize = Bits(INPUT,3)
+ val s_axi_arburst = Bits(INPUT,2)
+ val s_axi_arlock = Bits(INPUT,1)
+ val s_axi_arcache = Bits(INPUT,4)
+ val s_axi_arprot = Bits(INPUT,3)
+ val s_axi_arqos = Bits(INPUT,4)
+ val s_axi_arvalid = Bool(INPUT)
+ val s_axi_arready = Bool(OUTPUT)
+ //slave interface read data ports
+ val s_axi_rready = Bool(INPUT)
+ val s_axi_rid = Bits(OUTPUT,4)
+ val s_axi_rdata = Bits(OUTPUT,DDR3_DATA_WIDTH)
+ val s_axi_rresp = Bits(OUTPUT,2)
+ val s_axi_rlast = Bool(OUTPUT)
+ val s_axi_rvalid = Bool(OUTPUT)
+ //misc
+ val device_temp_i = Bits(INPUT,12)
+ // val device_temp = Bits(OUTPUT,12)
+ }
+
+ val vc709mig_a = """ {
+
+
+ vc709mig_a
+ 1
+ 1
+ OFF
+ 1024
+ ON
+ Disabled
+ xc7vx690t-ffg1761/-2
+ 4.1
+ No Buffer
+ Use System Clock
+ ACTIVE HIGH
+ FALSE
+ 0
+ 50 Ohms
+ 0
+
+ DDR3_SDRAM/SODIMMs/MT8KTF51264HZ-1G9
+ 1250
+ 2.0V
+ 4:1
+ 200
+ 0
+ 800
+ 1.000
+ 1
+ 1
+ 1
+ 1
+ 64
+ 1
+ 1
+ Disabled
+ Normal
+ 4
+ FALSE
+
+ 16
+ 10
+ 3
+ 1.5V
+ BANK_ROW_COLUMN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 8 - Fixed
+ Sequential
+ 11
+ Normal
+ No
+ Slow Exit
+ Enable
+ RZQ/7
+ Disable
+ Enable
+ RZQ/6
+ 0
+ Disabled
+ Enabled
+ Output Buffer Enabled
+ Full Array
+ 8
+ Enabled
+ Normal
+ Dynamic ODT off
+ AXI
+
+ RD_PRI_REG
+ 32
+ 64
+ 4
+ 0
+
+
+
+
+}"""
+
+ val vc709mig_b = """ {
+
+
+ vc709mig_b
+ 1
+ 1
+ OFF
+ 1024
+ ON
+ Disabled
+ xc7vx690t-ffg1761/-2
+ 4.1
+ No Buffer
+ Use System Clock
+ ACTIVE HIGH
+ FALSE
+ 0
+ 50 Ohms
+ 0
+
+ DDR3_SDRAM/SODIMMs/MT8KTF51264HZ-1G9
+ 1250
+ 2.0V
+ 4:1
+ 200
+ 0
+ 800
+ 1.000
+ 1
+ 1
+ 1
+ 1
+ 64
+ 1
+ 1
+ Disabled
+ Normal
+ 4
+ FALSE
+
+ 16
+ 10
+ 3
+ 1.5V
+ BANK_ROW_COLUMN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 8 - Fixed
+ Sequential
+ 11
+ Normal
+ No
+ Slow Exit
+ Enable
+ RZQ/7
+ Disable
+ Enable
+ RZQ/6
+ 0
+ Disabled
+ Enabled
+ Output Buffer Enabled
+ Full Array
+ 8
+ Enabled
+ Normal
+ Dynamic ODT off
+ AXI
+
+ RD_PRI_REG
+ 32
+ 64
+ 4
+ 0
+
+
+
+
+}"""
+
+ def add_vc709mig(migprj : String, modulename : String) =
+ ElaborationArtefacts.add(
+ "%1$s.vivado.tcl".format(modulename),
+ """set migprj %1$s
+ set migprjfile {/%2$s.prj}
+ set migprjfilepath $ipdir$migprjfile
+ set fp [open $migprjfilepath w+]
+ puts $fp $migprj
+ close $fp
+ create_ip -vendor xilinx.com -library ip -name mig_7series -module_name %2$s -dir $ipdir -force
+ set_property CONFIG.XML_INPUT_FILE $migprjfilepath [get_ips %2$s] """.format(migprj, modulename)
+ )
+
+ add_vc709mig(vc709mig_a, "vc709mig_a")
+ add_vc709mig(vc709mig_b, "vc709mig_b")
+
+ // addResource("/vsrc/vc709mig8gb.v")
+}
+//scalastyle:on
diff --git a/src/main/scala/shell/DDROverlay.scala b/src/main/scala/shell/DDROverlay.scala
index be0ed9e0..45019bbd 100644
--- a/src/main/scala/shell/DDROverlay.scala
+++ b/src/main/scala/shell/DDROverlay.scala
@@ -24,4 +24,4 @@ abstract class DDRPlacedOverlay[IO <: Data](val name: String, val di: DDRDesignI
extends IOPlacedOverlay[IO, DDRDesignInput, DDRShellInput, DDROverlayOutput]
{
implicit val p = di.p
-}
+}
\ No newline at end of file
diff --git a/src/main/scala/shell/PCIeOverlay.scala b/src/main/scala/shell/PCIeOverlay.scala
index 072104dd..d6ed571d 100644
--- a/src/main/scala/shell/PCIeOverlay.scala
+++ b/src/main/scala/shell/PCIeOverlay.scala
@@ -29,4 +29,4 @@ abstract class PCIePlacedOverlay[IO <: Data](
extends IOPlacedOverlay[IO, PCIeDesignInput, PCIeShellInput, PCIeOverlayOutput]
{
implicit val p = di.p
-}
+}
\ No newline at end of file
diff --git a/src/main/scala/shell/SPIOverlay.scala b/src/main/scala/shell/SPIOverlay.scala
index 996d9e7b..e939cb42 100644
--- a/src/main/scala/shell/SPIOverlay.scala
+++ b/src/main/scala/shell/SPIOverlay.scala
@@ -11,7 +11,7 @@ import freechips.rocketchip.tilelink.TLBusWrapper
import freechips.rocketchip.interrupts.IntInwardNode
//This should not do the controller placement either
-case class SPIShellInput()
+case class SPIShellInput(index: Int = 0)
case class SPIDesignInput(spiParam: SPIParams, node: BundleBridgeSource[SPIPortIO])(implicit val p: Parameters)
case class SPIOverlayOutput()
case object SPIOverlayKey extends Field[Seq[DesignPlacer[SPIDesignInput, SPIShellInput, SPIOverlayOutput]]](Nil)
diff --git a/src/main/scala/shell/xilinx/DDR3Overlay.scala b/src/main/scala/shell/xilinx/DDR3Overlay.scala
new file mode 100644
index 00000000..4203e52e
--- /dev/null
+++ b/src/main/scala/shell/xilinx/DDR3Overlay.scala
@@ -0,0 +1,34 @@
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import chisel3.experimental.{attach, IO, withClockAndReset}
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+import sifive.blocks.devices.chiplink._
+import sifive.fpgashells.devices.xilinx.xilinxvc709mig._
+
+case object VC709DDR3Size extends Field[BigInt](0x100000000L) // 4GB
+case object DualVC709DDR3Size extends Field[BigInt](0x200000000L) // 8GB
+abstract class DDR3XilinxPlacedOverlay(shell: VC709ShellBasicOverlays, name: String, designInput: DDRDesignInput, shellInput: DDRShellInput)
+ extends DDRPlacedOverlay[XilinxVC709MIGPads](name, designInput, shellInput)
+{
+ val size = p(VC709DDR3Size)
+
+ val migParams = XilinxVC709MIGParams(address = AddressSet.misaligned(di.baseAddress, size))
+ val mig = LazyModule(new XilinxVC709MIG(migParams))
+ val ioNode = BundleBridgeSource(() => mig.module.io.cloneType)
+ val topIONode = shell { ioNode.makeSink() }
+ val ddrUI = shell { ClockSourceNode(freqMHz = 200) }
+ val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
+ areset := designInput.wrangler := ddrUI
+
+ def overlayOutput = DDROverlayOutput(ddr = mig.node)
+ def ioFactory = new XilinxVC709MIGPads(size)
+
+ InModuleBody { ioNode.bundle <> mig.module.io }
+}
\ No newline at end of file
diff --git a/src/main/scala/shell/xilinx/VC707NewShell.scala b/src/main/scala/shell/xilinx/VC707NewShell.scala
index dbe811af..64ef8310 100644
--- a/src/main/scala/shell/xilinx/VC707NewShell.scala
+++ b/src/main/scala/shell/xilinx/VC707NewShell.scala
@@ -217,15 +217,15 @@ class DDRVC707ShellPlacer(val shell: VC707Shell, val shellInput: DDRShellInput)(
class PCIeVC707PlacedOverlay(val shell: VC707Shell, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
extends PCIePlacedOverlay[XilinxVC707PCIeX1Pads](name, designInput, shellInput)
{
- val pcie = LazyModule(new XilinxVC707PCIeX1)
- val ioNode = BundleBridgeSource(() => pcie.module.io.cloneType)
+ val pcie = LazyModule(new XilinxVC707PCIeX1)
+ val ioNode = BundleBridgeSource(() => pcie.module.io.cloneType)
val topIONode = shell { ioNode.makeSink() }
val axiClk = shell { ClockSourceNode(freqMHz = 125) }
val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
areset := designInput.wrangler := axiClk
val slaveSide = TLIdentityNode()
- pcie.crossTLIn(pcie.slave) := slaveSide
+ pcie.crossTLIn(pcie.slave) := slaveSide
pcie.crossTLIn(pcie.control) := slaveSide
val node = NodeHandle(slaveSide, pcie.crossTLOut(pcie.master))
val intnode = pcie.crossIntOut(pcie.intnode)
diff --git a/src/main/scala/shell/xilinx/VC709NewShell.scala b/src/main/scala/shell/xilinx/VC709NewShell.scala
new file mode 100644
index 00000000..e80266df
--- /dev/null
+++ b/src/main/scala/shell/xilinx/VC709NewShell.scala
@@ -0,0 +1,255 @@
+// See LICENSE for license details.
+package sifive.fpgashells.shell.xilinx
+
+import chisel3._
+import chisel3.experimental.{attach, IO, withClockAndReset}
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
+import sifive.fpgashells.clocks._
+import sifive.fpgashells.shell._
+import sifive.fpgashells.ip.xilinx._
+import sifive.blocks.devices.chiplink._
+import sifive.fpgashells.devices.xilinx.xilinxvc709mig._
+import sifive.fpgashells.devices.xilinx.xilinxvc709pcie._
+
+class SysClockVC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
+ extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ val node = shell { ClockSourceNode(freqMHz = 200, jitterPS = 50)(ValName(name)) }
+
+ shell { InModuleBody {
+ shell.xdc.addBoardPin(io.p, "clk_p")
+ shell.xdc.addBoardPin(io.n, "clk_n")
+ } }
+}
+
+class SysClockVC709ShellPlacer(shell: VC709ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
+ extends ClockInputShellPlacer[VC709ShellBasicOverlays]
+{
+ def place(designInput: ClockInputDesignInput) = new SysClockVC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class UARTVC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
+ extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
+{
+ shell { InModuleBody {
+ val packagePinsWithPackageIOs = Seq(("AR34", IOPin(io.rtsn.get)),
+ ("AT32", IOPin(io.ctsn.get)),
+ ("AU36", IOPin(io.txd)),
+ ("AU33", IOPin(io.rxd)))
+
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addIOB(io)
+ } }
+ } }
+}
+class UARTVC709ShellPlacer(val shell: VC709ShellBasicOverlays, val shellInput: UARTShellInput)(implicit val valName: ValName)
+ extends UARTShellPlacer[VC709ShellBasicOverlays] {
+ def place(designInput: UARTDesignInput) = new UARTVC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+object LEDVC709PinConstraints {
+ val pins = Seq("AM39","AN39","AR37","AT37","AR35","AP41","AP42","AU39")
+}
+class LEDVC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: LEDDesignInput, val shellInput: LEDShellInput)
+ extends LEDXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(LEDVC709PinConstraints.pins(shellInput.number)), ioStandard = "LVCMOS18")
+class LEDVC709ShellPlacer(val shell: VC709ShellBasicOverlays, val shellInput: LEDShellInput)(implicit val valName: ValName)
+ extends LEDShellPlacer[VC709ShellBasicOverlays] {
+ def place(designInput: LEDDesignInput) = new LEDVC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+object SwitchVC709PinConstraints {
+ val pins = Seq("AV30","AY33","BA31","BA32","AW30","AY30","BA30","BB31")
+}
+class SwitchVC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: SwitchDesignInput, val shellInput: SwitchShellInput)
+ extends SwitchXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(SwitchVC709PinConstraints.pins(shellInput.number)), ioStandard = "LVCMOS18")
+class SwitchVC709ShellPlacer(val shell: VC709ShellBasicOverlays, val shellInput: SwitchShellInput)(implicit val valName: ValName)
+ extends SwitchShellPlacer[VC709ShellBasicOverlays] {
+ def place(designInput: SwitchDesignInput) = new SwitchVC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+object ButtonVC709PinConstraints {
+ val pins = Seq("AR40","AU38","AP40","AW40","AV39")
+}
+class ButtonVC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: ButtonDesignInput, val shellInput: ButtonShellInput)
+ extends ButtonXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(ButtonVC709PinConstraints.pins(shellInput.number)), ioStandard = "LVCMOS18")
+class ButtonVC709ShellPlacer(val shell: VC709ShellBasicOverlays, val shellInput: ButtonShellInput)(implicit val valName: ValName)
+ extends ButtonShellPlacer[VC709ShellBasicOverlays] {
+ def place(designInput: ButtonDesignInput) = new ButtonVC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+// TODO: JTAG is untested
+class JTAGDebugVC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: JTAGDebugDesignInput, val shellInput: JTAGDebugShellInput)
+ extends JTAGDebugXilinxPlacedOverlay(name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ shell.sdc.addClock("JTCK", IOPin(io.jtag_TCK), 10)
+ shell.sdc.addGroup(clocks = Seq("JTCK"))
+ shell.xdc.clockDedicatedRouteFalse(IOPin(io.jtag_TCK))
+/* if old method
+ val packagePinsWithPackageIOs = Seq(("R32", IOPin(io.jtag_TCK)),
+ ("W36", IOPin(io.jtag_TMS)),
+ ("W37", IOPin(io.jtag_TDI)),
+ ("V40", IOPin(io.jtag_TDO)))
+*/
+ /*
+ #Olimex Pin Olimex Function LCD Pin LCD Function FPGA Pin
+ #1 VREF 14 5V
+ #3 TTRST_N 1 LCD_DB7 AN40
+ #5 TTDI 2 LCD_DB6 AR39
+ #7 TTMS 3 LCD_DB5 AR38
+ #9 TTCK 4 LCD_DB4 AT42
+ #11 TRTCK NC NC NC
+ #13 TTDO 9 LCD_E AT40
+ #15 TSRST_N 10 LCD_RW AR42
+ #2 VREF 14 5V
+ #18 GND 13 GND
+ */
+ val packagePinsWithPackageIOs = Seq(("AT42", IOPin(io.jtag_TCK)),
+ ("AR38", IOPin(io.jtag_TMS)),
+ ("AR39", IOPin(io.jtag_TDI)),
+ ("AR42", IOPin(io.srst_n)),
+ ("AT40", IOPin(io.jtag_TDO)))
+ packagePinsWithPackageIOs foreach { case (pin, io) => {
+ shell.xdc.addPackagePin(io, pin)
+ shell.xdc.addIOStandard(io, "LVCMOS18")
+ shell.xdc.addPullup(io)
+ } }
+ } }
+}
+class JTAGDebugVC709ShellPlacer(val shell: VC709ShellBasicOverlays, val shellInput: JTAGDebugShellInput)(implicit val valName: ValName)
+ extends JTAGDebugShellPlacer[VC709ShellBasicOverlays] {
+ def place(designInput: JTAGDebugDesignInput) = new JTAGDebugVC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class DDR3VC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: DDRDesignInput, val shellInput: DDRShellInput)
+ extends DDR3XilinxPlacedOverlay(shell, name, designInput, shellInput)
+{
+ shell { InModuleBody {
+ require (shell.sys_clock.get.isDefined, "Use of DDR3VC709PlacedOverlay depends on SysClockVC709PlacedOverlay")
+ val (sys, _) = shell.sys_clock.get.get.overlayOutput.node.out(0)
+ val (ui, _) = ddrUI.out(0)
+ val (ar, _) = areset.in(0)
+ val port = topIONode.bundle.port
+
+ io <> port
+
+ // This is modified for vc709
+ ui.clock := port.ui_clk
+ ui.reset := !port.mmcm_locked || port.ui_clk_sync_rst
+ port.sys_clk_i := sys.clock.asUInt
+ port.sys_rst := sys.reset // pllReset
+ port.aresetn := !ar.reset
+ } }
+
+ shell.sdc.addGroup(pins = Seq(mig.island.module.blackbox.io.ui_clk))
+}
+class DDR3VC709ShellPlacer(shell: VC709ShellBasicOverlays, val shellInput: DDRShellInput)(implicit val valName: ValName)
+ extends DDRShellPlacer[VC709ShellBasicOverlays] {
+ def place(designInput: DDRDesignInput) = new DDR3VC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+class PCIeVC709PlacedOverlay(val shell: VC709ShellBasicOverlays, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
+ extends PCIePlacedOverlay[XilinxVC709PCIePads](name, designInput, shellInput)
+{
+ val pcie = LazyModule(new XilinxVC709PCIe)
+ val bridge = BundleBridgeSource(() => pcie.module.io.cloneType)
+ val topBridge = shell { bridge.makeSink() }
+ val axiClk = shell { ClockSourceNode(freqMHz = 125) }
+ val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
+ areset := designInput.wrangler := axiClk
+
+ val slaveSide = TLIdentityNode()
+ pcie.crossTLIn(pcie.slave) := slaveSide
+ pcie.crossTLIn(pcie.control) := slaveSide
+ val masterSide = pcie.crossTLOut(pcie.master)
+
+ val pcieNode = NodeHandle(slaveSide, masterSide)
+ val intNode = pcie.crossIntOut(pcie.intnode)
+
+ def overlayOutput = PCIeOverlayOutput(pcieNode, intNode)
+ def ioFactory = new XilinxVC709PCIePads
+
+ InModuleBody { bridge.bundle <> pcie.module.io }
+
+ shell { InModuleBody {
+ val (axi, _) = axiClk.out(0)
+ val (ar, _) = areset.in(0)
+ val port = topBridge.bundle.port
+ io <> port
+ axi.clock := port.axi_aclk
+ // axi.reset := !port.mmcm_lock // mmcm_lock is removed in 3.0
+ port.axi_aresetn := !ar.reset
+ port.axi_ctl_aresetn := !ar.reset
+
+ def bind(io: Seq[IOPin], pad: Seq[String]) {
+ (io zip pad) foreach { case (io, pad) => shell.xdc.addPackagePin(io, pad) }
+ }
+
+ val txn = Seq("W1", "AA1", "AC1", "AE1", "AG1", "AH3", "AJ1", "AK3") /* [0-7] */
+ val txp = Seq("W2", "AA2", "AC2", "AE2", "AG2", "AH4", "AJ2", "AK4") /* [0-7] */
+ val rxn = Seq("Y3", "AA5", "AB3", "AC5", "AD3", "AE5", "AF3", "AG5") /* [0-7] */
+ val rxp = Seq("Y4", "AA6", "AB4", "AC6", "AD4", "AE6", "AF4", "AG6") /* [0-7] */
+
+ IOPin.of(io).foreach { shell.xdc.addPackagePin(_, "") }
+ bind(IOPin.of(io.REFCLK_rxp), Seq("AB8"))
+ bind(IOPin.of(io.REFCLK_rxn), Seq("AB7"))
+ bind(IOPin.of(io.pci_exp_rxp), rxp)
+ bind(IOPin.of(io.pci_exp_rxn), rxn)
+ bind(IOPin.of(io.pci_exp_txp), txp)
+ bind(IOPin.of(io.pci_exp_txn), txn)
+
+ shell.sdc.addClock(s"${name}_ref_clk", io.REFCLK_rxp, 100)
+ } }
+
+ shell.sdc.addGroup(clocks = Seq("txoutclk", "userclk1"))
+}
+class PCIeVC709ShellPlacer(val shell: VC709ShellBasicOverlays, val shellInput: PCIeShellInput)(implicit val valName: ValName)
+ extends PCIeShellPlacer[VC709ShellBasicOverlays] {
+ def place(designInput: PCIeDesignInput) = new PCIeVC709PlacedOverlay(shell, valName.name, designInput, shellInput)
+}
+
+abstract class VC709ShellBasicOverlays()(implicit p: Parameters) extends Series7Shell
+{
+ // PLL reset causes
+ val pllReset = InModuleBody { Wire(Bool()) }
+
+ // Order matters; ddr depends on sys_clock
+ val sys_clock = Overlay(ClockInputOverlayKey, new SysClockVC709ShellPlacer(this, ClockInputShellInput()))
+ val led = Seq.tabulate(8)(i => Overlay(LEDOverlayKey, new LEDVC709ShellPlacer(this, LEDShellInput(color = "red", number = i))(valName = ValName(s"led_$i"))))
+ val switch = Seq.tabulate(8)(i => Overlay(SwitchOverlayKey, new SwitchVC709ShellPlacer(this, SwitchShellInput(number = i))(valName = ValName(s"switch_$i"))))
+ val button = Seq.tabulate(5)(i => Overlay(ButtonOverlayKey, new ButtonVC709ShellPlacer(this, ButtonShellInput(number = i))(valName = ValName(s"button_$i"))))
+ val uart0 = Seq.tabulate(1)(i => Overlay(UARTOverlayKey, new UARTVC709ShellPlacer(this, UARTShellInput(index = i))))
+ val jtag = Overlay(JTAGDebugOverlayKey, new JTAGDebugVC709ShellPlacer(this, JTAGDebugShellInput()))
+ val ddr0 = Overlay(DDROverlayKey, new DDR3VC709ShellPlacer(this, DDRShellInput()))
+ val pcie = Overlay(PCIeOverlayKey, new PCIeVC709ShellPlacer(this, PCIeShellInput())(valName = ValName(s"pcie")))
+}
+
+class VC709BaseShell()(implicit p: Parameters) extends VC709ShellBasicOverlays
+{
+ val topDesign = LazyModule(p(DesignKey)(designParameters))
+
+ // Place the sys_clock at the Shell if the user didn't ask for it
+ p(ClockInputOverlayKey).foreach(_.place(ClockInputDesignInput()))
+
+ override lazy val module = new LazyRawModuleImp(this) {
+ val reset = IO(Input(Bool()))
+ xdc.addBoardPin(reset, "reset")
+
+ val reset_ibuf = Module(new IBUF)
+ reset_ibuf.io.I := reset
+
+ val sysclk: Clock = sys_clock.get() match {
+ case Some(x: SysClockVC709PlacedOverlay) => x.clock
+ }
+ val powerOnReset = PowerOnResetFPGAOnly(sysclk)
+ sdc.addAsyncPath(Seq(powerOnReset))
+
+ pllReset :=
+ reset_ibuf.io.O || powerOnReset || false.B
+ }
+}
diff --git a/src/main/scala/shell/xilinx/XilinxShell.scala b/src/main/scala/shell/xilinx/XilinxShell.scala
index 72ed6476..5a62c8e2 100644
--- a/src/main/scala/shell/xilinx/XilinxShell.scala
+++ b/src/main/scala/shell/xilinx/XilinxShell.scala
@@ -86,4 +86,4 @@ abstract class UltraScaleShell()(implicit p: Parameters) extends XilinxShell
override def designParameters = super.designParameters.alterPartial {
case PLLFactoryKey => pllFactory
}
-}
+}
\ No newline at end of file
diff --git a/xilinx/common/tcl/boards.tcl b/xilinx/common/tcl/boards.tcl
index af1c686b..fd73fb83 100644
--- a/xilinx/common/tcl/boards.tcl
+++ b/xilinx/common/tcl/boards.tcl
@@ -6,4 +6,5 @@ set ::program::boards::spec [dict create \
arty [dict create iface spix4 size 16 bitaddr 0x0 memdev {n25q128-3.3v-spi-x1_x2_x4}] \
arty_a7_100 [dict create iface spix4 size 16 bitaddr 0x0 memdev {s25fl128sxxxxxx0-spi-x1_x2_x4}] \
vc707 [dict create iface bpix16 size 128 bitaddr 0x3000000 ] \
+ vc709 [dict create iface bpix16 size 128 bitaddr 0x3000000 memdev {mt28gu01gaax1e-bpi-x16}] \
vcu118 [dict create iface spix8 size 256 bitaddr 0x0 memdev {mt25qu01g-spi-x1_x2_x4_x8}]]
diff --git a/xilinx/common/tcl/boot.tcl b/xilinx/common/tcl/boot.tcl
new file mode 100644
index 00000000..a24e18c2
--- /dev/null
+++ b/xilinx/common/tcl/boot.tcl
@@ -0,0 +1,13 @@
+if {$argc < 1 || $argc > 1} {
+ puts $argc
+ puts {Error: Invalid number of arguments}
+ puts {Usage: boot.tcl board}
+ exit 1
+}
+lassign $argv board
+
+open_hw
+connect_hw_server
+open_hw_target
+current_hw_device [get_hw_devices $board]
+boot_hw_device [lindex [get_hw_devices $board] 0]
\ No newline at end of file
diff --git a/xilinx/common/tcl/upload_mcs.tcl b/xilinx/common/tcl/upload_mcs.tcl
new file mode 100644
index 00000000..3b2a5184
--- /dev/null
+++ b/xilinx/common/tcl/upload_mcs.tcl
@@ -0,0 +1,54 @@
+# Upload an MCS-format memory configuration file to the board.
+
+if {$argc < 3 || $argc > 3} {
+ puts $argc
+ puts {Error: Invalid number of arguments}
+ puts {Usage: upload_mcs.tcl board mcsfile prmfile}
+ exit 1
+}
+lassign $argv board mcsfile prmfile
+
+open_hw
+connect_hw_server
+open_hw_target
+
+current_hw_device [get_hw_devices $board]
+refresh_hw_device -update_hw_probes false [lindex [get_hw_devices $board] 0]
+refresh_hw_device [lindex [get_hw_devices $board] 0]
+
+create_hw_cfgmem -hw_device [lindex [get_hw_devices $board] 0] [lindex [get_cfgmem_parts {mt28gu01gaax1e-bpi-x16}] 0]
+set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.CHECKSUM 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+refresh_hw_device [lindex [get_hw_devices $board] 0]
+
+set_property PROGRAM.ADDRESS_RANGE {use_file} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.FILES [list $mcsfile ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.BPI_RS_PINS {none} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.CHECKSUM 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.PRM_FILES [list $prmfile ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.ADDRESS_RANGE {use_file} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.FILES [list $mcsfile ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.PRM_FILE { $prmfile } [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.BPI_RS_PINS {none} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+set_property PROGRAM.CHECKSUM 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
+
+startgroup
+
+if {![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices $board] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]]]] } {
+ create_hw_bitstream -hw_device [lindex [get_hw_devices $board] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices $board] 0]];
+ program_hw_devices [lindex [get_hw_devices $board] 0];
+};
+program_hw_cfgmem -hw_cfgmem [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $board] 0]]
diff --git a/xilinx/common/tcl/vivado.tcl b/xilinx/common/tcl/vivado.tcl
index 46f26145..5ebdc709 100644
--- a/xilinx/common/tcl/vivado.tcl
+++ b/xilinx/common/tcl/vivado.tcl
@@ -1,4 +1,5 @@
# See LICENSE for license details.
+set_param general.maxThreads 8
# Set the variable for the directory that includes all scripts
set scriptdir [file dirname [info script]]
diff --git a/xilinx/vc709/constraints/vc709-master.xdc b/xilinx/vc709/constraints/vc709-master.xdc
new file mode 100644
index 00000000..cdbe7437
--- /dev/null
+++ b/xilinx/vc709/constraints/vc709-master.xdc
@@ -0,0 +1,10 @@
+#-------------- MCS Generation ----------------------
+set_property CFGBVS GND [current_design]
+set_property CONFIG_VOLTAGE 1.8 [current_design]
+
+set_property EXTRACT_ENABLE YES [get_cells dut_/spi_0_1/mac/phy/txd_reg*]
+set_property EXTRACT_ENABLE YES [get_cells dut_/spi_0_1/mac/phy/sck_reg]
+
+
+
+
diff --git a/xilinx/vc709/tcl/board.tcl b/xilinx/vc709/tcl/board.tcl
new file mode 100644
index 00000000..8637a367
--- /dev/null
+++ b/xilinx/vc709/tcl/board.tcl
@@ -0,0 +1,4 @@
+# See LICENSE for license details.
+set name {vc709}
+set part_fpga {xc7vx690tffg1761-2}
+set part_board {xilinx.com:vc709:part0:1.8}
diff --git a/xilinx/vc709/tcl/clocks.tcl b/xilinx/vc709/tcl/clocks.tcl
new file mode 100644
index 00000000..69014fcf
--- /dev/null
+++ b/xilinx/vc709/tcl/clocks.tcl
@@ -0,0 +1,50 @@
+if { [llength [get_ports -quiet chiplink_b2c_clk]] > 0 } {
+ create_clock -name chiplink_b2c_clock -period 10 [get_ports chiplink_b2c_clk]
+ create_generated_clock -name {chiplink_c2b_clock} \
+ -divide_by 1 \
+ -source [ get_pins { vc709_sys_clock_mmcm0/inst/mmcm_adv_inst/CLKOUT6 } ] \
+ [ get_ports { chiplink_c2b_clk } ]
+
+ # RX side: want to latch almost anywhere except on the rising edge of the clock
+ # The data signals coming from Aloe have: clock - 1.2 <= transition <= clock + 0.8
+ # Let's add 0.6ns of safety for trace jitter+skew on both sides:
+ # min = hold = - 1.2 - 0.6
+ # max = period - setup = 0.8 + 0.6
+ set_input_delay -min -1.8 -clock {chiplink_b2c_clock} [ get_ports { chiplink_b2c_data* chiplink_b2c_rst chiplink_b2c_send } ]
+ set_input_delay -max 1.4 -clock {chiplink_b2c_clock} [ get_ports { chiplink_b2c_data* chiplink_b2c_rst chiplink_b2c_send } ]
+
+ # TX side: want to transition almost anywhere except on the rising edge of the clock
+ # The data signals going to Aloe must have: clock - 1.85 <= NO transition <= clock + 0.65
+ # Let's add 1ns of safey for trace jitter+skew on both sides:
+ # min = -hold = -0.65 - 0.6
+ # max = setup = 1.85 + 0.6
+ set_output_delay -min -1.25 -clock {chiplink_c2b_clock} [ get_ports { chiplink_c2b_data* chiplink_c2b_rst chiplink_c2b_send } ]
+ set_output_delay -max 2.45 -clock {chiplink_c2b_clock} [ get_ports { chiplink_c2b_data* chiplink_c2b_rst chiplink_c2b_send } ]
+}
+
+set group_mem [get_clocks -quiet {clk_pll_i}]
+set group_sys [get_clocks -quiet {sys_diff_clk \
+ clk_out*_vc709_sys_clock_mmcm1 \
+ clk_out*_vc709_sys_clock_mmcm2 \
+ chiplink_c2b_clock}]
+set group_cl [get_clocks -quiet {chiplink_b2c_clock \
+ clk_out*_vc709_sys_clock_mmcm3}]
+set group_pci [get_clocks -quiet {userclk1 txoutclk}]
+
+set group_jtag [get_clocks -quiet {JTCK}]
+
+puts "group_mem: $group_mem"
+puts "group_sys: $group_sys"
+puts "group_pci: $group_pci"
+puts "group_cl: $group_cl"
+puts "group_jtag: $group_jtag"
+
+set groups [list]
+if { [llength $group_mem] > 0 } { lappend groups -group $group_mem }
+if { [llength $group_sys] > 0 } { lappend groups -group $group_sys }
+if { [llength $group_pci] > 0 } { lappend groups -group $group_pci }
+if { [llength $group_cl] > 0 } { lappend groups -group $group_cl }
+if { [llength $group_jtag] > 0 } { lappend groups -group $group_jtag }
+
+puts "set_clock_groups -asynchronous $groups"
+set_clock_groups -asynchronous {*}$groups
diff --git a/xilinx/vc709/tcl/ios.tcl b/xilinx/vc709/tcl/ios.tcl
new file mode 100644
index 00000000..4a6c1df0
--- /dev/null
+++ b/xilinx/vc709/tcl/ios.tcl
@@ -0,0 +1,65 @@
+#---------------Physical Constraints-----------------
+
+#get_port_part_pins
+#clk_n clk_p dip_switches_tri_i_0 dip_switches_tri_i_1 dip_switches_tri_i_2 dip_switches_tri_i_3 dip_switches_tri_i_4 dip_switches_tri_i_5 dip_switches_tri_i_6 dip_switches_tri_i_7 iic_main_scl_i iic_main_sda_i lcd_7bits_tri_o_0 lcd_7bits_tri_o_1 lcd_7bits_tri_o_2 lcd_7bits_tri_o_3 lcd_7bits_tri_o_4 lcd_7bits_tri_o_5 lcd_7bits_tri_o_6 leds_8bits_tri_o_0 leds_8bits_tri_o_1 leds_8bits_tri_o_2 leds_8bits_tri_o_3 leds_8bits_tri_o_4 leds_8bits_tri_o_5 leds_8bits_tri_o_6 leds_8bits_tri_o_7 linear_flash_addr_1 linear_flash_addr_10 linear_flash_addr_11 linear_flash_addr_12 linear_flash_addr_13 linear_flash_addr_14 linear_flash_addr_15 linear_flash_addr_16 linear_flash_addr_17 linear_flash_addr_18 linear_flash_addr_19 linear_flash_addr_2 linear_flash_addr_20 linear_flash_addr_21 linear_flash_addr_22 linear_flash_addr_23 linear_flash_addr_24 linear_flash_addr_25 linear_flash_addr_26 linear_flash_addr_3 linear_flash_addr_4 linear_flash_addr_5 linear_flash_addr_6 linear_flash_addr_7 linear_flash_addr_8 linear_flash_addr_9 linear_flash_adv_ldn linear_flash_ce_n linear_flash_dq_i_0 linear_flash_dq_i_1 linear_flash_dq_i_10 linear_flash_dq_i_11 linear_flash_dq_i_12 linear_flash_dq_i_13 linear_flash_dq_i_14 linear_flash_dq_i_15 linear_flash_dq_i_2 linear_flash_dq_i_3 linear_flash_dq_i_4 linear_flash_dq_i_5 linear_flash_dq_i_6 linear_flash_dq_i_7 linear_flash_dq_i_8 linear_flash_dq_i_9 linear_flash_oen linear_flash_wen mdc mdio_i phy_rst_out push_buttons_5bits_tri_i_0 push_buttons_5bits_tri_i_1 push_buttons_5bits_tri_i_2 push_buttons_5bits_tri_i_3 push_buttons_5bits_tri_i_4 reset rotary_inca_push_incb_tri_i_0 rotary_inca_push_incb_tri_i_1 rotary_inca_push_incb_tri_i_2 rs232_uart_rxd rs232_uart_txd sfp_rxn sfp_rxp sfp_sgmii_txn sfp_sgmii_txp sgmii_mgt_clkn sgmii_mgt_clkp sgmii_rxn sgmii_rxp sgmii_txn sgmii_txp sma_lvds_rxn sma_lvds_rxp sma_lvds_txn sma_lvds_txp sma_mgt_clkn sma_mgt_clkp sma_sfp_rxn sma_sfp_rxp sma_sfp_txn sma_sfp_txp
+
+set_property BOARD_PIN {clk_p} [get_ports sys_diff_clock_clk_p]
+set_property BOARD_PIN {clk_n} [get_ports sys_diff_clock_clk_n]
+set_property BOARD_PIN {reset} [get_ports reset]
+
+create_clock -name sys_diff_clk -period 5.0 [get_ports sys_diff_clock_clk_p]
+set_input_jitter [get_clocks -of_objects [get_ports sys_diff_clock_clk_p]] 0.5
+
+## LED
+set_property BOARD_PIN {leds_8bits_tri_o_0} [get_ports led_0]
+set_property BOARD_PIN {leds_8bits_tri_o_1} [get_ports led_1]
+set_property BOARD_PIN {leds_8bits_tri_o_2} [get_ports led_2]
+set_property BOARD_PIN {leds_8bits_tri_o_3} [get_ports led_3]
+set_property BOARD_PIN {leds_8bits_tri_o_4} [get_ports led_4]
+set_property BOARD_PIN {leds_8bits_tri_o_5} [get_ports led_5]
+set_property BOARD_PIN {leds_8bits_tri_o_6} [get_ports led_6]
+set_property BOARD_PIN {leds_8bits_tri_o_7} [get_ports led_7]
+
+## BUTTON
+set_property BOARD_PIN {push_buttons_5bits_tri_i_0} [get_ports btn_0]
+set_property BOARD_PIN {push_buttons_5bits_tri_i_1} [get_ports btn_1]
+set_property BOARD_PIN {push_buttons_5bits_tri_i_2} [get_ports btn_2]
+set_property BOARD_PIN {push_buttons_5bits_tri_i_3} [get_ports btn_3]
+set_property BOARD_PIN {push_buttons_5bits_tri_i_4} [get_ports btn_4]
+
+## SWITCH
+set_property BOARD_PIN {dip_switches_tri_i_0} [get_ports sw_0]
+set_property BOARD_PIN {dip_switches_tri_i_1} [get_ports sw_1]
+set_property BOARD_PIN {dip_switches_tri_i_2} [get_ports sw_2]
+set_property BOARD_PIN {dip_switches_tri_i_3} [get_ports sw_3]
+set_property BOARD_PIN {dip_switches_tri_i_4} [get_ports sw_4]
+set_property BOARD_PIN {dip_switches_tri_i_5} [get_ports sw_5]
+set_property BOARD_PIN {dip_switches_tri_i_6} [get_ports sw_6]
+set_property BOARD_PIN {dip_switches_tri_i_7} [get_ports sw_7]
+
+## UART
+# RX
+set_property PACKAGE_PIN AU33 [get_ports uart_rx]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_rx]
+set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports uart_rx]]]
+# CTSN
+set_property PACKAGE_PIN AT32 [get_ports uart_ctsn]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_ctsn]
+set_property IOB TRUE [get_ports uart_ctsn]
+# TX
+set_property PACKAGE_PIN AU36 [get_ports uart_tx]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_tx]
+set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports uart_tx]]]
+# RTSN
+set_property PACKAGE_PIN AR34 [get_ports uart_rtsn]
+set_property IOSTANDARD LVCMOS18 [get_ports uart_rtsn]
+set_property IOB TRUE [get_ports uart_rtsn]
+
+## I2C
+set_property PACKAGE_PIN AU32 [get_ports i2c_sda]
+set_property IOSTANDARD LVCMOS18 [get_ports i2c_sda]
+set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports i2c_sda]]]
+
+set_property PACKAGE_PIN AT35 [get_ports i2c_scl]
+set_property IOSTANDARD LVCMOS18 [get_ports i2c_scl]
+set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports i2c_scl]]]
\ No newline at end of file
diff --git a/xilinx/vc709/vsrc/vc709reset.v b/xilinx/vc709/vsrc/vc709reset.v
new file mode 100644
index 00000000..4e2cc021
--- /dev/null
+++ b/xilinx/vc709/vsrc/vc709reset.v
@@ -0,0 +1,78 @@
+// See LICENSE for license details.
+`timescale 1ns/1ps
+`default_nettype none
+`define RESET_SYNC 4
+`define DEBOUNCE_BITS 8
+
+module vc709reset(
+ // Asynchronous reset input, should be held high until
+ // all clocks are locked and power is stable.
+ input wire areset,
+ // Clock domains are brought up in increasing order
+ // All clocks are reset for at least 2^DEBOUNCE_BITS * period(clock1)
+ input wire clock1,
+ output wire reset1,
+ input wire clock2,
+ output wire reset2,
+ input wire clock3,
+ output wire reset3,
+ input wire clock4,
+ output wire reset4
+);
+ sifive_reset_hold hold_clock0(areset, clock1, reset1);
+ sifive_reset_sync sync_clock2(reset1, clock2, reset2);
+ sifive_reset_sync sync_clock3(reset2, clock3, reset3);
+ sifive_reset_sync sync_clock4(reset3, clock4, reset4);
+endmodule
+
+// Assumes that areset is held for more than one clock
+// Allows areset to be deasserted asynchronously
+module sifive_reset_sync(
+ input wire areset,
+ input wire clock,
+ output wire reset
+);
+ reg [`RESET_SYNC-1:0] gen_reset = {`RESET_SYNC{1'b1}};
+ always @(posedge clock, posedge areset) begin
+ if (areset) begin
+ gen_reset <= {`RESET_SYNC{1'b1}};
+ end else begin
+ gen_reset <= {1'b0,gen_reset[`RESET_SYNC-1:1]};
+ end
+ end
+ assign reset = gen_reset[0];
+endmodule
+
+module sifive_reset_hold(
+ input wire areset,
+ input wire clock,
+ output wire reset
+);
+ wire raw_reset;
+ reg [`RESET_SYNC-1:0] sync_reset = {`RESET_SYNC{1'b1}};
+ reg [`DEBOUNCE_BITS:0] debounce_reset = {`DEBOUNCE_BITS{1'b1}};
+ wire out_reset;
+
+ // Captures reset even if clock is not running
+ sifive_reset_sync capture(areset, clock, raw_reset);
+
+ // Remove any glitches due to runt areset
+ always @(posedge clock) begin
+ sync_reset <= {raw_reset,sync_reset[`RESET_SYNC-1:1]};
+ end
+
+ // Debounce the reset
+ assign out_reset = debounce_reset[`DEBOUNCE_BITS];
+ always @(posedge clock) begin
+ if (sync_reset[0]) begin
+ debounce_reset <= {(`DEBOUNCE_BITS+1){1'b1}};
+ end else begin
+ debounce_reset <= debounce_reset - out_reset;
+ end
+ end
+
+ assign reset = out_reset;
+
+endmodule
+
+`default_nettype wire