From ab8cf0775fbdd0b4f60e5e7aa176daa09b739d7b Mon Sep 17 00:00:00 2001 From: Shreesha Srinath Date: Wed, 16 Aug 2017 11:23:45 -0700 Subject: [PATCH] Initial commit for fpga-shells --- .gitignore | 1 + build.sbt | 9 + .../xilinxvc707mig/XilinxVC707MIG.scala | 157 +++++++ .../XilinxVC707MIGPeriphery.scala | 30 ++ .../xilinxvc707pciex1/XilinxVC707PCIeX1.scala | 76 ++++ .../XilinxVC707PCIeX1Periphery.scala | 33 ++ src/main/scala/ip/xilinx/Xilinx.scala | 244 +++++++++++ .../ip/xilinx/ibufds_gte2/ibufds_gte2.scala | 18 + .../vc707axi_to_pcie_x1.scala | 401 ++++++++++++++++++ .../scala/ip/xilinx/vc707mig/vc707mig.scala | 105 +++++ src/main/scala/shell/xilinx/ArtyShell.scala | 247 +++++++++++ src/main/scala/shell/xilinx/VC707Shell.scala | 306 +++++++++++++ xilinx/Makefile | 42 ++ xilinx/arty/constraints/arty-config.xdc | 5 + xilinx/arty/constraints/arty-master.xdc | 240 +++++++++++ xilinx/arty/tcl/board.tcl | 5 + xilinx/arty/tcl/ip.tcl | 44 ++ xilinx/common/tcl/bitstream.tcl | 10 + xilinx/common/tcl/boards.tcl | 7 + xilinx/common/tcl/init.tcl | 38 ++ xilinx/common/tcl/opt.tcl | 7 + xilinx/common/tcl/place.tcl | 13 + xilinx/common/tcl/post-impl-debug.tcl | 3 + xilinx/common/tcl/pre-impl-debug.tcl | 3 + xilinx/common/tcl/prologue.tcl | 64 +++ xilinx/common/tcl/report.tcl | 44 ++ xilinx/common/tcl/route.tcl | 10 + xilinx/common/tcl/synth.tcl | 10 + xilinx/common/tcl/util.tcl | 24 ++ xilinx/common/tcl/vivado.tcl | 25 ++ xilinx/common/tcl/write_cfgmem.tcl | 26 ++ xilinx/common/vsrc/PowerOnResetFPGAOnly.v | 15 + xilinx/vc707/constraints/vc707-master.xdc | 75 ++++ xilinx/vc707/tcl/board.tcl | 4 + xilinx/vc707/tcl/ip.tcl | 140 ++++++ xilinx/vc707/tcl/mig.prj | 202 +++++++++ xilinx/vc707/vsrc/sdio.v | 59 +++ xilinx/vc707/vsrc/vc707reset.v | 78 ++++ 38 files changed, 2820 insertions(+) create mode 100644 .gitignore create mode 100644 build.sbt create mode 100644 src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIG.scala create mode 100644 src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIGPeriphery.scala create mode 100644 src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1.scala create mode 100644 src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1Periphery.scala create mode 100644 src/main/scala/ip/xilinx/Xilinx.scala create mode 100644 src/main/scala/ip/xilinx/ibufds_gte2/ibufds_gte2.scala create mode 100644 src/main/scala/ip/xilinx/vc707axi_to_pcie_x1/vc707axi_to_pcie_x1.scala create mode 100644 src/main/scala/ip/xilinx/vc707mig/vc707mig.scala create mode 100644 src/main/scala/shell/xilinx/ArtyShell.scala create mode 100644 src/main/scala/shell/xilinx/VC707Shell.scala create mode 100644 xilinx/Makefile create mode 100644 xilinx/arty/constraints/arty-config.xdc create mode 100644 xilinx/arty/constraints/arty-master.xdc create mode 100644 xilinx/arty/tcl/board.tcl create mode 100644 xilinx/arty/tcl/ip.tcl create mode 100644 xilinx/common/tcl/bitstream.tcl create mode 100644 xilinx/common/tcl/boards.tcl create mode 100644 xilinx/common/tcl/init.tcl create mode 100644 xilinx/common/tcl/opt.tcl create mode 100644 xilinx/common/tcl/place.tcl create mode 100644 xilinx/common/tcl/post-impl-debug.tcl create mode 100644 xilinx/common/tcl/pre-impl-debug.tcl create mode 100644 xilinx/common/tcl/prologue.tcl create mode 100644 xilinx/common/tcl/report.tcl create mode 100644 xilinx/common/tcl/route.tcl create mode 100644 xilinx/common/tcl/synth.tcl create mode 100644 xilinx/common/tcl/util.tcl create mode 100644 xilinx/common/tcl/vivado.tcl create mode 100644 xilinx/common/tcl/write_cfgmem.tcl create mode 100644 xilinx/common/vsrc/PowerOnResetFPGAOnly.v create mode 100644 xilinx/vc707/constraints/vc707-master.xdc create mode 100644 xilinx/vc707/tcl/board.tcl create mode 100644 xilinx/vc707/tcl/ip.tcl create mode 100644 xilinx/vc707/tcl/mig.prj create mode 100644 xilinx/vc707/vsrc/sdio.v create mode 100644 xilinx/vc707/vsrc/vc707reset.v diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..ebc8ff3 --- /dev/null +++ b/build.sbt @@ -0,0 +1,9 @@ +// See LICENSE for license details. + +organization := "com.sifive" + +version := "1.0" + +name := "fpga-shells" + +scalaVersion := "2.11.7" diff --git a/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIG.scala b/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIG.scala new file mode 100644 index 0000000..ab18860 --- /dev/null +++ b/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIG.scala @@ -0,0 +1,157 @@ +// See LICENSE for license details. +package sifive.fpgashells.devices.xilinx.xilinxvc707mig + +import Chisel._ +import chisel3.experimental.{Analog,attach} +import freechips.rocketchip.amba.axi4._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.coreplex._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import sifive.blocks.ip.xilinx.vc707mig.{VC707MIGIOClocksReset, VC707MIGIODDR, vc707mig} + +trait HasXilinxVC707MIGParameters { +} + +class XilinxVC707MIGPads extends Bundle with VC707MIGIODDR + +class XilinxVC707MIGIO extends Bundle with VC707MIGIODDR + with VC707MIGIOClocksReset + +class XilinxVC707MIG(implicit p: Parameters) extends LazyModule with HasXilinxVC707MIGParameters { + val device = new MemoryDevice + val node = TLInputNode() + val axi4 = AXI4InternalOutputNode(Seq(AXI4SlavePortParameters( + slaves = Seq(AXI4SlaveParameters( + address = Seq(AddressSet(p(ExtMem).base, p(ExtMem).size-1)), + resources = device.reg, + regionType = RegionType.UNCACHED, + executable = true, + supportsWrite = TransferSizes(1, 256*8), + supportsRead = TransferSizes(1, 256*8))), + beatBytes = 8))) + + val xing = LazyModule(new TLAsyncCrossing) + val toaxi4 = LazyModule(new TLToAXI4(beatBytes = 8, adapterName = Some("mem"), stripBits = 1)) + val indexer = LazyModule(new AXI4IdIndexer(idBits = 4)) + val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes))) + val yank = LazyModule(new AXI4UserYanker) + val buffer = LazyModule(new AXI4Buffer) + + xing.node := node + val monitor = (toaxi4.node := xing.node) + axi4 := buffer.node + buffer.node := yank.node + yank.node := deint.node + deint.node := indexer.node + indexer.node := toaxi4.node + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val port = new XilinxVC707MIGIO + val tl = node.bundleIn + } + + //MIG black box instantiation + val blackbox = Module(new vc707mig) + + //pins to top level + + //inouts + 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 + 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 + + //user interface signals + val axi_async = axi4.bundleIn(0) + xing.module.io.in_clock := clock + xing.module.io.in_reset := reset + xing.module.io.out_clock := blackbox.io.ui_clk + xing.module.io.out_reset := blackbox.io.ui_clk_sync_rst + (Seq(toaxi4, indexer, deint, yank, buffer) ++ monitor) foreach { lm => + lm.module.clock := blackbox.io.ui_clk + lm.module.reset := blackbox.io.ui_clk_sync_rst + } + + 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 + + //slave AXI interface write address ports + blackbox.io.s_axi_awid := axi_async.aw.bits.id + blackbox.io.s_axi_awaddr := axi_async.aw.bits.addr //truncation ?? + 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 := axi_async.ar.bits.addr //truncation ?? + 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 :- unconnceted + } +} diff --git a/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIGPeriphery.scala b/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIGPeriphery.scala new file mode 100644 index 0000000..5d80226 --- /dev/null +++ b/src/main/scala/devices/xilinx/xilinxvc707mig/XilinxVC707MIGPeriphery.scala @@ -0,0 +1,30 @@ +// See LICENSE for license details. +package sifive.fpgashells.devices.xilinx.xilinxvc707mig + +import Chisel._ +import freechips.rocketchip.coreplex.HasMemoryBus +import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp} + +trait HasMemoryXilinxVC707MIG extends HasMemoryBus { + val module: HasMemoryXilinxVC707MIGModuleImp + + val xilinxvc707mig = LazyModule(new XilinxVC707MIG) + + require(nMemoryChannels == 1, "Coreplex must have 1 master memory port") + xilinxvc707mig.node := memBuses.head.toDRAMController +} + +trait HasMemoryXilinxVC707MIGBundle { + val xilinxvc707mig: XilinxVC707MIGIO + def connectXilinxVC707MIGToPads(pads: XilinxVC707MIGPads) { + pads <> xilinxvc707mig + } +} + +trait HasMemoryXilinxVC707MIGModuleImp extends LazyMultiIOModuleImp + with HasMemoryXilinxVC707MIGBundle { + val outer: HasMemoryXilinxVC707MIG + val xilinxvc707mig = IO(new XilinxVC707MIGIO) + + xilinxvc707mig <> outer.xilinxvc707mig.module.io.port +} diff --git a/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1.scala b/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1.scala new file mode 100644 index 0000000..5d88d29 --- /dev/null +++ b/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1.scala @@ -0,0 +1,76 @@ +// See LICENSE for license details. +package sifive.fpgashells.devices.xilinx.xilinxvc707pciex1 + +import Chisel._ +import freechips.rocketchip.amba.axi4._ +import freechips.rocketchip.coreplex.CacheBlockBytes +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import sifive.fpgashells.ip.xilinx.vc707axi_to_pcie_x1.{VC707AXIToPCIeX1, VC707AXIToPCIeX1IOClocksReset, VC707AXIToPCIeX1IOSerial} +import sifive.fpgashells.ip.xilinx.ibufds_gte2.IBUFDS_GTE2 + +class XilinxVC707PCIeX1Pads extends Bundle with VC707AXIToPCIeX1IOSerial + +class XilinxVC707PCIeX1IO extends Bundle + with VC707AXIToPCIeX1IOSerial + with VC707AXIToPCIeX1IOClocksReset { + val axi_ctl_aresetn = Bool(INPUT) + val REFCLK_rxp = Bool(INPUT) + val REFCLK_rxn = Bool(INPUT) +} + +class XilinxVC707PCIeX1(implicit p: Parameters) extends LazyModule { + val slave = TLAsyncInputNode() + val control = TLAsyncInputNode() + val master = TLAsyncOutputNode() + val intnode = IntOutputNode() + + val axi_to_pcie_x1 = LazyModule(new VC707AXIToPCIeX1) + + axi_to_pcie_x1.slave := + AXI4Buffer()( + AXI4UserYanker()( + AXI4Deinterleaver(p(CacheBlockBytes))( + AXI4IdIndexer(idBits=4)( + TLToAXI4(beatBytes=8, adapterName = Some("pcie-slave"))( + TLAsyncCrossingSink()( + slave)))))) + + axi_to_pcie_x1.control := + AXI4Buffer()( + AXI4UserYanker(capMaxFlight = Some(2))( + TLToAXI4(beatBytes=4)( + TLFragmenter(4, p(CacheBlockBytes))( + TLAsyncCrossingSink()( + control))))) + + master := + TLAsyncCrossingSource()( + TLWidthWidget(8)( + AXI4ToTL()( + AXI4UserYanker(capMaxFlight=Some(8))( + AXI4Fragmenter()( + axi_to_pcie_x1.master))))) + + intnode := axi_to_pcie_x1.intnode + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val port = new XilinxVC707PCIeX1IO + val slave_in = slave.bundleIn + val control_in = control.bundleIn + val master_out = master.bundleOut + val interrupt = intnode.bundleOut + } + + io.port <> axi_to_pcie_x1.module.io.port + + //PCIe Reference Clock + val ibufds_gte2 = Module(new IBUFDS_GTE2) + axi_to_pcie_x1.module.io.REFCLK := ibufds_gte2.io.O + 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/xilinxvc707pciex1/XilinxVC707PCIeX1Periphery.scala b/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1Periphery.scala new file mode 100644 index 0000000..ac1c487 --- /dev/null +++ b/src/main/scala/devices/xilinx/xilinxvc707pciex1/XilinxVC707PCIeX1Periphery.scala @@ -0,0 +1,33 @@ +// See LICENSE for license details. +package sifive.fpgashells.devices.xilinx.xilinxvc707pciex1 + +import Chisel._ +import freechips.rocketchip.coreplex.{HasInterruptBus, HasSystemBus} +import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp} + +trait HasSystemXilinxVC707PCIeX1 extends HasSystemBus with HasInterruptBus { + val xilinxvc707pcie = LazyModule(new XilinxVC707PCIeX1) + + sbus.fromAsyncFIFOMaster() := xilinxvc707pcie.master + xilinxvc707pcie.slave := sbus.toAsyncFixedWidthSlaves() + xilinxvc707pcie.control := sbus.toAsyncFixedWidthSlaves() + ibus.fromAsync := xilinxvc707pcie.intnode +} + +trait HasSystemXilinxVC707PCIeX1Bundle { + val xilinxvc707pcie: XilinxVC707PCIeX1IO + def connectXilinxVC707PCIeX1ToPads(pads: XilinxVC707PCIeX1Pads) { + pads <> xilinxvc707pcie + } +} + +trait HasSystemXilinxVC707PCIeX1ModuleImp extends LazyMultiIOModuleImp + with HasSystemXilinxVC707PCIeX1Bundle { + val outer: HasSystemXilinxVC707PCIeX1 + val xilinxvc707pcie = IO(new XilinxVC707PCIeX1IO) + + xilinxvc707pcie <> outer.xilinxvc707pcie.module.io.port + + outer.xilinxvc707pcie.module.clock := outer.xilinxvc707pcie.module.io.port.axi_aclk_out + outer.xilinxvc707pcie.module.reset := ~xilinxvc707pcie.axi_aresetn +} diff --git a/src/main/scala/ip/xilinx/Xilinx.scala b/src/main/scala/ip/xilinx/Xilinx.scala new file mode 100644 index 0000000..d92fe3f --- /dev/null +++ b/src/main/scala/ip/xilinx/Xilinx.scala @@ -0,0 +1,244 @@ +// See LICENSE for license details. +package sifive.fpgashells.ip.xilinx + +import Chisel._ +import chisel3.core.{Input, Output, attach} +import chisel3.experimental.{Analog} + +import sifive.blocks.devices.pinctrl.{BasePin} + +//======================================================================== +// This file contains common devices used by our Xilinx FPGA flows and some +// BlackBox modules used in the Xilinx FPGA flows +//======================================================================== + +//------------------------------------------------------------------------- +// IBUFDS +//------------------------------------------------------------------------- +//IP : xilinx unisim IBUFDS. SelectIO Differential Signaling Input +// Buffer unparameterized + +class IBUFDS extends BlackBox { + val io = new Bundle { + val O = Bool(OUTPUT) + val I = Bool(INPUT) + val IB = Bool(INPUT) + } +} + +//------------------------------------------------------------------------- +// IBUFG +//------------------------------------------------------------------------- +/** IBUFG -- Clock Input Buffer */ + +class IBUFG extends BlackBox { + val io = new Bundle { + val O = Output(Clock()) + val I = Input(Clock()) + } +} + +object IBUFG { + def apply (pin: Clock): Clock = { + val pad = Module (new IBUFG()) + pad.io.I := pin + pad.io.O + } +} + +//------------------------------------------------------------------------- +// IOBUF +//------------------------------------------------------------------------- +/** IOBUF -- Bidirectional IO Buffer. */ + +class IOBUF extends BlackBox { + val io = new Bundle { + val O = Output(Bool()) + val IO = Analog(1.W) + val I = Input(Bool()) + val T = Input(Bool()) + } +} + +object IOBUF { + def apply (pin: Analog, ctrl: BasePin): Bool = { + val pad = Module(new IOBUF()) + pad.io.I := ctrl.o.oval + pad.io.T := ~ctrl.o.oe + ctrl.i.ival := pad.io.O & ctrl.o.ie + attach(pad.io.IO, pin) + pad.io.O & ctrl.o.ie + } + + // Creates an output IOBUF + def apply (pin: Analog, in: Bool): Unit = { + val pad = Module(new IOBUF()) + pad.io.I := in + pad.io.T := false.B + attach(pad.io.IO, pin) + } + + // Creates an input IOBUF + def apply (pin: Analog): Bool = { + val pad = Module(new IOBUF()) + pad.io.I := false.B + pad.io.T := true.B + attach(pad.io.IO, pin) + pad.io.O + } +} + +//------------------------------------------------------------------------- +// PULLUP +//------------------------------------------------------------------------- +/** PULLUP : can be applied to Input to add a Pullup. */ + +class PULLUP extends BlackBox { + val io = new Bundle { + val O = Analog(1.W) + } +} + +object PULLUP { + def apply (pin: Analog): Unit = { + val pullup = Module(new PULLUP()) + attach(pullup.io.O, pin) + } +} + +//------------------------------------------------------------------------- +// mmcm +//------------------------------------------------------------------------- +/** mmcm: This is generated by the Xilinx IP Generation Scripts */ + +class mmcm extends BlackBox { + val io = new Bundle { + val clk_in1 = Input(Clock()) + val clk_out1 = Output(Clock()) + val clk_out2 = Output(Clock()) + val clk_out3 = Output(Clock()) + val resetn = Input(Bool()) + val locked = Output(Bool()) + } +} + +//------------------------------------------------------------------------- +// reset_sys +//------------------------------------------------------------------------- +/** reset_sys: This is generated by the Xilinx IP Generation Scripts */ + +class reset_sys extends BlackBox { + val io = new Bundle { + val slowest_sync_clk = Input(Clock()) + val ext_reset_in = Input(Bool()) + val aux_reset_in = Input(Bool()) + val mb_debug_sys_rst = Input(Bool()) + val dcm_locked = Input(Bool()) + val mb_reset = Output(Bool()) + val bus_struct_reset = Output(Bool()) + val peripheral_reset = Output(Bool()) + val interconnect_aresetn = Output(Bool()) + val peripheral_aresetn = Output(Bool()) + } +} + +//------------------------------------------------------------------------- +// reset_mig +//------------------------------------------------------------------------- +/** reset_mig: This is generated by the Xilinx IP Generation Scripts */ + +class reset_mig extends BlackBox { + val io = new Bundle { + val slowest_sync_clk = Input(Clock()) + val ext_reset_in = Input(Bool()) + val aux_reset_in = Input(Bool()) + val mb_debug_sys_rst = Input(Bool()) + val dcm_locked = Input(Bool()) + val mb_reset = Output(Bool()) + val bus_struct_reset = Output(Bool()) + val peripheral_reset = Output(Bool()) + val interconnect_aresetn = Output(Bool()) + val peripheral_aresetn = Output(Bool()) + } +} + +//------------------------------------------------------------------------- +// PowerOnResetFPGAOnly +//------------------------------------------------------------------------- +/** PowerOnResetFPGAOnly -- this generates a power_on_reset signal using + * initial blocks. It is synthesizable on FPGA flows only. + */ + +// This is a FPGA-Only construct, which uses +// 'initial' constructions +class PowerOnResetFPGAOnly extends BlackBox { + val io = new Bundle { + val clock = Input(Clock()) + val power_on_reset = Output(Bool()) + } +} + +object PowerOnResetFPGAOnly { + def apply (clk: Clock): Bool = { + val por = Module(new PowerOnResetFPGAOnly()) + por.io.clock := clk + por.io.power_on_reset + } +} + +//------------------------------------------------------------------------- +// vc707clk_wiz_sync +//------------------------------------------------------------------------- +//IP : xilinx mmcm with "NO_BUFFER" input clock + +class vc707clk_wiz_sync extends BlackBox { + val io = new Bundle { + val clk_in1 = Bool(INPUT) + val clk_out1 = Clock(OUTPUT) + val clk_out2 = Clock(OUTPUT) + val clk_out3 = Clock(OUTPUT) + val clk_out4 = Clock(OUTPUT) + val clk_out5 = Clock(OUTPUT) + val clk_out6 = Clock(OUTPUT) + val clk_out7 = Clock(OUTPUT) + val reset = Bool(INPUT) + val locked = Bool(OUTPUT) + } +} + +//------------------------------------------------------------------------- +// vc707reset +//------------------------------------------------------------------------- + +class vc707reset() extends BlackBox +{ + val io = new Bundle{ + val areset = Bool(INPUT) + val clock1 = Clock(INPUT) + val reset1 = Bool(OUTPUT) + val clock2 = Clock(INPUT) + val reset2 = Bool(OUTPUT) + val clock3 = Clock(INPUT) + val reset3 = Bool(OUTPUT) + val clock4 = Clock(INPUT) + val reset4 = Bool(OUTPUT) + } +} + +//------------------------------------------------------------------------- +// sdio_spi_bridge +//------------------------------------------------------------------------- + +class sdio_spi_bridge() extends BlackBox +{ + val io = new Bundle{ + val clk = Clock(INPUT) + val reset = Bool(INPUT) + val sd_cmd = Analog(1.W) + val sd_dat = Analog(4.W) + val spi_sck = Bool(INPUT) + val spi_cs = Bool(INPUT) + val spi_dq_o = Bits(INPUT,4) + val spi_dq_i = Bits(OUTPUT,4) + } +} diff --git a/src/main/scala/ip/xilinx/ibufds_gte2/ibufds_gte2.scala b/src/main/scala/ip/xilinx/ibufds_gte2/ibufds_gte2.scala new file mode 100644 index 0000000..90f58f5 --- /dev/null +++ b/src/main/scala/ip/xilinx/ibufds_gte2/ibufds_gte2.scala @@ -0,0 +1,18 @@ +// See LICENSE for license details. +package sifive.fpgashells.ip.xilinx.ibufds_gte2 + +import Chisel._ + +//IP : xilinx unisim IBUFDS_GTE2 +//Differential Signaling Input Buffer +//unparameterized + +class IBUFDS_GTE2 extends BlackBox { + val io = new Bundle { + val O = Bool(OUTPUT) + val ODIV2 = Bool(OUTPUT) + val CEB = Bool(INPUT) + val I = Bool(INPUT) + val IB = Bool(INPUT) + } +} diff --git a/src/main/scala/ip/xilinx/vc707axi_to_pcie_x1/vc707axi_to_pcie_x1.scala b/src/main/scala/ip/xilinx/vc707axi_to_pcie_x1/vc707axi_to_pcie_x1.scala new file mode 100644 index 0000000..8f3eece --- /dev/null +++ b/src/main/scala/ip/xilinx/vc707axi_to_pcie_x1/vc707axi_to_pcie_x1.scala @@ -0,0 +1,401 @@ +// See LICENSE for license details. +package sifive.fpgashells.ip.xilinx.vc707axi_to_pcie_x1 + +import Chisel._ +import freechips.rocketchip.config._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.amba.axi4._ +import freechips.rocketchip.tilelink.{IntSourceNode, IntSourcePortSimple} + +// IP VLNV: xilinx.com:customize_ip:vc707pcietoaxi:1.0 +// Black Box +// Signals named _exactly_ as per Vivado generated verilog +// s : -{lock, cache, prot, qos} + +trait VC707AXIToPCIeX1IOSerial extends Bundle { + //serial external pins + val pci_exp_txp = Bool(OUTPUT) + val pci_exp_txn = Bool(OUTPUT) + val pci_exp_rxp = Bool(INPUT) + val pci_exp_rxn = Bool(INPUT) +} + +trait VC707AXIToPCIeX1IOClocksReset extends Bundle { + //clock, reset, control + val axi_aresetn = Bool(INPUT) + val axi_aclk_out = Clock(OUTPUT) + val axi_ctl_aclk_out = Clock(OUTPUT) + val mmcm_lock = Bool(OUTPUT) +} + +//scalastyle:off +//turn off linter: blackbox name must match verilog module +class vc707axi_to_pcie_x1() extends BlackBox +{ + val io = new Bundle with VC707AXIToPCIeX1IOSerial + with VC707AXIToPCIeX1IOClocksReset { + //refclk + val REFCLK = Bool(INPUT) + + //clock, reset, control + val INTX_MSI_Request = Bool(INPUT) + val INTX_MSI_Grant = Bool(OUTPUT) + val MSI_enable = Bool(OUTPUT) + val MSI_Vector_Num = Bits(INPUT,5) + val MSI_Vector_Width = Bits(OUTPUT,3) + + //interrupt + val interrupt_out = Bool(OUTPUT) + + //axi slave + //-{lock, cache, prot, qos} + //slave interface write address + val s_axi_awid = Bits(INPUT,4) + val s_axi_awaddr = Bits(INPUT,32) + 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_awlock = Bool(INPUT) + //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 + val s_axi_wdata = Bits(INPUT,64) + 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 + 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 + val s_axi_arid = Bits(INPUT,4) + val s_axi_araddr = Bits(INPUT,32) + 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_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 + val s_axi_rready = Bool(INPUT) + val s_axi_rid = Bits(OUTPUT,4) + val s_axi_rdata = Bits(OUTPUT,64) + val s_axi_rresp = Bits(OUTPUT,2) + val s_axi_rlast = Bool(OUTPUT) + val s_axi_rvalid = Bool(OUTPUT) + + //axi master + //-{id,region,qos} + //slave interface write address ports + //val m_axi_awid = Bits(OUTPUT,4) + val m_axi_awaddr = Bits(OUTPUT,32) + //val m_axi_awregion = Bits(OUTPUT,4) + val m_axi_awlen = Bits(OUTPUT,8) + val m_axi_awsize = Bits(OUTPUT,3) + val m_axi_awburst = Bits(OUTPUT,2) + val m_axi_awlock = Bool(OUTPUT) + val m_axi_awcache = Bits(OUTPUT,4) + val m_axi_awprot = Bits(OUTPUT,3) + //val m_axi_awqos = Bits(OUTPUT,4) + val m_axi_awvalid = Bool(OUTPUT) + val m_axi_awready = Bool(INPUT) + //slave interface write data ports + val m_axi_wdata = Bits(OUTPUT,64) + val m_axi_wstrb = Bits(OUTPUT,8) + val m_axi_wlast = Bool(OUTPUT) + val m_axi_wvalid = Bool(OUTPUT) + val m_axi_wready = Bool(INPUT) + //slave interface write response ports + val m_axi_bready = Bool(OUTPUT) + //val m_axi_bid = Bits(INPUT,4) + val m_axi_bresp = Bits(INPUT,2) + val m_axi_bvalid = Bool(INPUT) + //slave interface read address ports + //val m_axi_arid = Bits(OUTPUT,4) + val m_axi_araddr = Bits(OUTPUT,32) + //val m_axi_arregion = Bits(OUTPUT,4) + val m_axi_arlen = Bits(OUTPUT,8) + val m_axi_arsize = Bits(OUTPUT,3) + val m_axi_arburst = Bits(OUTPUT,2) + val m_axi_arlock = Bits(OUTPUT,1) + val m_axi_arcache = Bits(OUTPUT,4) + val m_axi_arprot = Bits(OUTPUT,3) + //val m_axi_arqos = Bits(OUTPUT,4) + val m_axi_arvalid = Bool(OUTPUT) + val m_axi_arready = Bool(INPUT) + //slave interface read data ports + val m_axi_rready = Bool(OUTPUT) + //val m_axi_rid = Bits(INPUT,4) + val m_axi_rdata = Bits(INPUT,64) + val m_axi_rresp = Bits(INPUT,2) + val m_axi_rlast = Bool(INPUT) + val m_axi_rvalid = Bool(INPUT) + + //axi lite slave for control + val s_axi_ctl_awaddr = Bits(INPUT,32) + 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,32) + 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 vc707_axi_to_pcie_x1 black box in Nasti Bundles + +class VC707AXIToPCIeX1(implicit p:Parameters) extends LazyModule +{ + 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 { 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(0x60000000L, 0x1fffffffL)), + resources = Seq(Resource(device, "ranges")), + executable = true, + supportsWrite = TransferSizes(1, 256), + supportsRead = TransferSizes(1, 256))), + beatBytes = 8))) + + val control = AXI4SlaveNode(Seq(AXI4SlavePortParameters( + slaves = Seq(AXI4SlaveParameters( + address = List(AddressSet(0x50000000L, 0x03ffffffL)), + 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 = "VC707 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.edgesIn(0).master.endId == 1) + // Must have exactly the right number of idBits + require (slave.edgesIn(0).bundle.idBits == 4) + + class VC707AXIToPCIeX1IOBundle extends Bundle with VC707AXIToPCIeX1IOSerial + with VC707AXIToPCIeX1IOClocksReset; + + val io = new Bundle { + val port = new VC707AXIToPCIeX1IOBundle + val slave_in = slave.bundleIn + val control_in = control.bundleIn + val master_out = master.bundleOut + val REFCLK = Bool(INPUT) + val interrupt_out = intnode.bundleOut + } + + val blackbox = Module(new vc707axi_to_pcie_x1) + + val s = io.slave_in(0) + val c = io.control_in(0) + val m = io.master_out(0) + + //to top level + blackbox.io.axi_aresetn := io.port.axi_aresetn + io.port.axi_aclk_out := blackbox.io.axi_aclk_out + io.port.axi_ctl_aclk_out := blackbox.io.axi_ctl_aclk_out + io.port.mmcm_lock := blackbox.io.mmcm_lock + 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 + io.interrupt_out(0)(0) := blackbox.io.interrupt_out + blackbox.io.REFCLK := io.REFCLK + + //s + //AXI4 signals ordered as per AXI4 Specification (Release D) Section A.2 + //-{lock, cache, prot, qos} + //-{aclk, aresetn, awuser, wid, wuser, buser, ruser} + //global signals + //aclk := + //aresetn := + //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_awlock := s.aw.bits.lock + //blackbox.io.s_axi_awcache := s.aw.bits.cache + //blackbox.io.s_axi_awprot := s.aw.bits.prot + //blackbox.io.s_axi_awqos := s.aw.bits.qos + blackbox.io.s_axi_awregion := UInt(0) + //blackbox.io.awuser := s.aw.bits.user + blackbox.io.s_axi_awvalid := s.aw.valid + s.aw.ready := blackbox.io.s_axi_awready + //slave interface write data ports + //blackbox.io.s_axi_wid := s.w.bits.id + 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_wuser := s.w.bits.user + blackbox.io.s_axi_wvalid := s.w.valid + s.w.ready := blackbox.io.s_axi_wready + //slave interface write response + s.b.bits.id := blackbox.io.s_axi_bid + s.b.bits.resp := blackbox.io.s_axi_bresp + //s.b.bits.user := blackbox.io.s_axi_buser + s.b.valid := blackbox.io.s_axi_bvalid + blackbox.io.s_axi_bready := s.b.ready + //slave AXI interface read address ports + 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_arlock := s.ar.bits.lock + //blackbox.io.s_axi_arcache := s.ar.bits.cache + //blackbox.io.s_axi_arprot := s.ar.bits.prot + //blackbox.io.s_axi_arqos := s.ar.bits.qos + blackbox.io.s_axi_arregion := UInt(0) + //blackbox.io.s_axi_aruser := s.ar.bits.user + blackbox.io.s_axi_arvalid := s.ar.valid + s.ar.ready := blackbox.io.s_axi_arready + //slave AXI interface read data ports + 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.bits.ruser := blackbox.io.s_axi_ruser + s.r.valid := blackbox.io.s_axi_rvalid + blackbox.io.s_axi_rready := s.r.ready + + //ctl + //axi-lite slave 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 + //axi-lite slave interface write data ports + 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 + //axi-lite slave interface 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 + //axi-lite slave AXI interface read address ports + 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 + //slave AXI interface read data ports + 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 + + //m + //AXI4 signals ordered per AXI4 Specification (Release D) Section A.2 + //-{id,region,qos} + //-{aclk, aresetn, awuser, wid, wuser, buser, ruser} + //global signals + //aclk := + //aresetn := + //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.lock := blackbox.io.m_axi_awlock + m.aw.bits.cache := blackbox.io.m_axi_awcache + m.aw.bits.prot := blackbox.io.m_axi_awprot + m.aw.bits.qos := UInt(0) + //m.aw.bits.region := blackbox.io.m_axi_awregion + //m.aw.bits.user := blackbox.io.m_axi_awuser + m.aw.valid := blackbox.io.m_axi_awvalid + blackbox.io.m_axi_awready := m.aw.ready + + //master interface write data ports + 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.bits.user := blackbox.io.m_axi_wuser + m.w.valid := blackbox.io.m_axi_wvalid + blackbox.io.m_axi_wready := m.w.ready + + //master interface write response + //blackbox.io.m_axi_bid := m.b.bits.id + blackbox.io.m_axi_bresp := m.b.bits.resp + //blackbox.io.m_axi_buser := m.b.bits.user + blackbox.io.m_axi_bvalid := m.b.valid + m.b.ready := blackbox.io.m_axi_bready + + //master AXI interface read address ports + 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.bits.region := blackbox.io.m_axi_arregion + //m.ar.bits.user := blackbox.io.s_axi_aruser + m.ar.valid := blackbox.io.m_axi_arvalid + blackbox.io.m_axi_arready := m.ar.ready + + //master AXI interface read data ports + //blackbox.io.m_axi_rid := m.r.bits.id + 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.s_axi_ruser := s.bits.ruser + blackbox.io.m_axi_rvalid := m.r.valid + m.r.ready := blackbox.io.m_axi_rready + } +} diff --git a/src/main/scala/ip/xilinx/vc707mig/vc707mig.scala b/src/main/scala/ip/xilinx/vc707mig/vc707mig.scala new file mode 100644 index 0000000..d06b68c --- /dev/null +++ b/src/main/scala/ip/xilinx/vc707mig/vc707mig.scala @@ -0,0 +1,105 @@ +// See LICENSE for license details. +package sifive.fpgashells.ip.xilinx.vc707mig + +import Chisel._ +import chisel3.experimental.{Analog,attach} +import freechips.rocketchip.config._ + +// IP VLNV: xilinx.com:customize_ip:vc707mig:1.0 +// Black Box + +trait VC707MIGIODDR extends Bundle { + val ddr3_addr = Bits(OUTPUT,14) + 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_dm = Bits(OUTPUT,8) + val ddr3_odt = Bits(OUTPUT,1) + + 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.xilinxvc707mig +trait VC707MIGIOClocksReset 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 vc707mig(implicit val p:Parameters) extends BlackBox +{ + val io = new Bundle with VC707MIGIODDR + with VC707MIGIOClocksReset { + // 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,30) + 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,64) + 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,30) + 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,64) + val s_axi_rresp = Bits(OUTPUT,2) + val s_axi_rlast = Bool(OUTPUT) + val s_axi_rvalid = Bool(OUTPUT) + //misc + val device_temp = Bits(OUTPUT,12) + } +} +//scalastyle:on diff --git a/src/main/scala/shell/xilinx/ArtyShell.scala b/src/main/scala/shell/xilinx/ArtyShell.scala new file mode 100644 index 0000000..b067b77 --- /dev/null +++ b/src/main/scala/shell/xilinx/ArtyShell.scala @@ -0,0 +1,247 @@ +// See LICENSE for license details. +package sifive.fpgashells.shell.xilinx.artyshell + +import Chisel._ +import chisel3.core.{Input, Output, attach} +import chisel3.experimental.{RawModule, Analog, withClockAndReset} + +import freechips.rocketchip.config._ +import freechips.rocketchip.devices.debug._ + +import sifive.blocks.devices.gpio._ +import sifive.blocks.devices.pwm._ +import sifive.blocks.devices.spi._ +import sifive.blocks.devices.uart._ +import sifive.blocks.devices.pinctrl.{BasePin} + +import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, mmcm, reset_sys, PowerOnResetFPGAOnly} + +//------------------------------------------------------------------------- +// ArtyShell +//------------------------------------------------------------------------- + +abstract class ArtyShell(implicit val p: Parameters) extends RawModule { + + //----------------------------------------------------------------------- + // Interface + //----------------------------------------------------------------------- + + // Clock & Reset + val CLK100MHZ = IO(Input(Clock())) + val ck_rst = IO(Input(Bool())) + + // Green LEDs + val led_0 = IO(Analog(1.W)) + val led_1 = IO(Analog(1.W)) + val led_2 = IO(Analog(1.W)) + val led_3 = IO(Analog(1.W)) + + // RGB LEDs, 3 pins each + val led0_r = IO(Analog(1.W)) + val led0_g = IO(Analog(1.W)) + val led0_b = IO(Analog(1.W)) + + val led1_r = IO(Analog(1.W)) + val led1_g = IO(Analog(1.W)) + val led1_b = IO(Analog(1.W)) + + val led2_r = IO(Analog(1.W)) + val led2_g = IO(Analog(1.W)) + val led2_b = IO(Analog(1.W)) + + // Sliding switches + val sw_0 = IO(Analog(1.W)) + val sw_1 = IO(Analog(1.W)) + val sw_2 = IO(Analog(1.W)) + val sw_3 = IO(Analog(1.W)) + + // Buttons. First 3 used as GPIO, the last is used as wakeup + val btn_0 = IO(Analog(1.W)) + val btn_1 = IO(Analog(1.W)) + val btn_2 = IO(Analog(1.W)) + val btn_3 = IO(Analog(1.W)) + + // Dedicated QSPI interface + val qspi_cs = IO(Analog(1.W)) + val qspi_sck = IO(Analog(1.W)) + val qspi_dq = IO(Vec(4, Analog(1.W))) + + // UART0 + val uart_rxd_out = IO(Analog(1.W)) + val uart_txd_in = IO(Analog(1.W)) + + // JA (Used for more generic GPIOs) + val ja_0 = IO(Analog(1.W)) + val ja_1 = IO(Analog(1.W)) + val ja_2 = IO(Analog(1.W)) + val ja_3 = IO(Analog(1.W)) + val ja_4 = IO(Analog(1.W)) + val ja_5 = IO(Analog(1.W)) + val ja_6 = IO(Analog(1.W)) + val ja_7 = IO(Analog(1.W)) + + // JD (used for JTAG connection) + val jd_0 = IO(Analog(1.W)) // TDO + val jd_1 = IO(Analog(1.W)) // TRST_n + val jd_2 = IO(Analog(1.W)) // TCK + val jd_4 = IO(Analog(1.W)) // TDI + val jd_5 = IO(Analog(1.W)) // TMS + val jd_6 = IO(Analog(1.W)) // SRST_n + + // ChipKit Digital I/O Pins + val ck_io = IO(Vec(20, Analog(1.W))) + + // ChipKit SPI + val ck_miso = IO(Analog(1.W)) + val ck_mosi = IO(Analog(1.W)) + val ck_ss = IO(Analog(1.W)) + val ck_sck = IO(Analog(1.W)) + + //----------------------------------------------------------------------- + // Wire declrations + //----------------------------------------------------------------------- + + // Note: these frequencies are approximate. + val clock_8MHz = Wire(Clock()) + val clock_32MHz = Wire(Clock()) + val clock_65MHz = Wire(Clock()) + + val mmcm_locked = Wire(Bool()) + + val reset_core = Wire(Bool()) + val reset_bus = Wire(Bool()) + val reset_periph = Wire(Bool()) + val reset_intcon_n = Wire(Bool()) + val reset_periph_n = Wire(Bool()) + + val SRST_n = Wire(Bool()) + + val dut_jtag_TCK = Wire(Clock()) + val dut_jtag_TMS = Wire(Bool()) + val dut_jtag_TDI = Wire(Bool()) + val dut_jtag_TDO = Wire(Bool()) + val dut_jtag_reset = Wire(Bool()) + val dut_ndreset = Wire(Bool()) + + //----------------------------------------------------------------------- + // Clock Generator + //----------------------------------------------------------------------- + // Mixed-mode clock generator + + val ip_mmcm = Module(new mmcm()) + + ip_mmcm.io.clk_in1 := CLK100MHZ + clock_8MHz := ip_mmcm.io.clk_out1 // 8.388 MHz = 32.768 kHz * 256 + clock_65MHz := ip_mmcm.io.clk_out2 // 65 Mhz + clock_32MHz := ip_mmcm.io.clk_out3 // 65/2 Mhz + ip_mmcm.io.resetn := ck_rst + mmcm_locked := ip_mmcm.io.locked + + //----------------------------------------------------------------------- + // System Reset + //----------------------------------------------------------------------- + // processor system reset module + + val ip_reset_sys = Module(new reset_sys()) + + ip_reset_sys.io.slowest_sync_clk := clock_8MHz + ip_reset_sys.io.ext_reset_in := ck_rst & SRST_n + ip_reset_sys.io.aux_reset_in := true.B + ip_reset_sys.io.mb_debug_sys_rst := dut_ndreset + ip_reset_sys.io.dcm_locked := mmcm_locked + + reset_core := ip_reset_sys.io.mb_reset + reset_bus := ip_reset_sys.io.bus_struct_reset + reset_periph := ip_reset_sys.io.peripheral_reset + reset_intcon_n := ip_reset_sys.io.interconnect_aresetn + reset_periph_n := ip_reset_sys.io.peripheral_aresetn + + //----------------------------------------------------------------------- + // SPI Flash + //----------------------------------------------------------------------- + + def connectSPIFlash(dut: HasPeripherySPIFlashModuleImp): Unit = { + val qspiParams = p(PeripherySPIFlashKey) + if (!qspiParams.isEmpty) { + val qspi_params = qspiParams(0) + val qspi_pins = Wire(new SPIPins(() => {new BasePin()}, qspi_params)) + + qspi_pins.fromPort( + dut.qspi(0), + dut.clock, + dut.reset, + syncStages = qspi_params.sampleDelay + ) + + IOBUF(qspi_sck, dut.qspi(0).sck) + IOBUF(qspi_cs, dut.qspi(0).cs(0)) + + (qspi_dq zip qspi_pins.dq).foreach { + case(a, b) => IOBUF(a,b) + } + } + } + + //--------------------------------------------------------------------- + // Debug JTAG + //--------------------------------------------------------------------- + + def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): SystemJTAGIO = { + + //------------------------------------------------------------------- + // JTAG Reset + //------------------------------------------------------------------- + + val jtag_power_on_reset = PowerOnResetFPGAOnly(clock_32MHz) + + dut_jtag_reset := jtag_power_on_reset + + //------------------------------------------------------------------- + // JTAG IOBUFs + //------------------------------------------------------------------- + + dut_jtag_TCK := IBUFG(IOBUF(jd_2).asClock) + + dut_jtag_TMS := IOBUF(jd_5) + PULLUP(jd_5) + + dut_jtag_TDI := IOBUF(jd_4) + PULLUP(jd_4) + + IOBUF(jd_0, dut_jtag_TDO) + + SRST_n := IOBUF(jd_6) + PULLUP(jd_6) + + //------------------------------------------------------------------- + // JTAG PINS + //------------------------------------------------------------------- + + val djtag = dut.debug.systemjtag.get + + djtag.jtag.TCK := dut_jtag_TCK + djtag.jtag.TMS := dut_jtag_TMS + djtag.jtag.TDI := dut_jtag_TDI + dut_jtag_TDO := djtag.jtag.TDO.data + + djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W) + + djtag.reset := dut_jtag_reset + dut_ndreset := dut.debug.ndreset + + djtag + } + + //--------------------------------------------------------------------- + // UART + //--------------------------------------------------------------------- + + def connectUART(dut: HasPeripheryUARTModuleImp): Unit = { + val uartParams = p(PeripheryUARTKey) + if (!uartParams.isEmpty) { + IOBUF(uart_rxd_out, dut.uart(0).txd) + dut.uart(0).rxd := IOBUF(uart_txd_in) + } + } + +} diff --git a/src/main/scala/shell/xilinx/VC707Shell.scala b/src/main/scala/shell/xilinx/VC707Shell.scala new file mode 100644 index 0000000..c87c357 --- /dev/null +++ b/src/main/scala/shell/xilinx/VC707Shell.scala @@ -0,0 +1,306 @@ +// See LICENSE for license details. +package sifive.fpgashells.shell.xilinx.vc707shell + +import Chisel._ +import chisel3.core.{Input, Output, attach} +import chisel3.experimental.{RawModule, Analog, withClockAndReset} + +import freechips.rocketchip.config._ +import freechips.rocketchip.devices.debug._ + +import sifive.blocks.devices.gpio._ +import sifive.blocks.devices.spi._ +import sifive.blocks.devices.uart._ + +import sifive.fpgashells.devices.xilinx.xilinxvc707mig._ +import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._ +import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, vc707clk_wiz_sync, vc707reset} + +//------------------------------------------------------------------------- +// VC707Shell +//------------------------------------------------------------------------- + +abstract class VC707Shell(implicit val p: Parameters) extends RawModule { + + //----------------------------------------------------------------------- + // Interface + //----------------------------------------------------------------------- + + // 200Mhz differential sysclk + val sys_diff_clock_clk_n = IO(Input(Bool())) + val sys_diff_clock_clk_p = IO(Input(Bool())) + + // active high reset + val reset = IO(Input(Bool())) + + // DDR SDRAM + val ddr3_addr = IO(Output(UInt(14.W))) + val ddr3_ba = IO(Output(UInt(3.W))) + val ddr3_cas_n = IO(Output(Bool())) + val ddr3_ck_p = IO(Output(Bool())) + val ddr3_ck_n = IO(Output(Bool())) + val ddr3_cke = IO(Output(Bool())) + val ddr3_cs_n = IO(Output(Bool())) + val ddr3_dm = IO(Output(UInt(8.W))) + val ddr3_dq = IO(Analog(64.W)) + val ddr3_dqs_n = IO(Analog(8.W)) + val ddr3_dqs_p = IO(Analog(8.W)) + val ddr3_odt = IO(Output(Bool())) + val ddr3_ras_n = IO(Output(Bool())) + val ddr3_reset_n = IO(Output(Bool())) + val ddr3_we_n = IO(Output(Bool())) + + // LED + val led = IO(Vec(8, Output(Bool()))) + + // UART + val uart_tx = IO(Output(Bool())) + val uart_rx = IO(Input(Bool())) + val uart_rtsn = IO(Output(Bool())) + val uart_ctsn = IO(Input(Bool())) + + // SDIO + val sdio_clk = IO(Output(Bool())) + val sdio_cmd = IO(Analog(1.W)) + val sdio_dat = IO(Analog(4.W)) + + // JTAG + val jtag_TCK = IO(Input(Clock())) + val jtag_TMS = IO(Input(Bool())) + val jtag_TDI = IO(Input(Bool())) + val jtag_TDO = IO(Output(Bool())) + + // PCIe + val pci_exp_txp = IO(Output(Bool())) + val pci_exp_txn = IO(Output(Bool())) + val pci_exp_rxp = IO(Input(Bool())) + val pci_exp_rxn = IO(Input(Bool())) + val pci_exp_refclk_rxp = IO(Input(Bool())) + val pci_exp_refclk_rxn = IO(Input(Bool())) + + //----------------------------------------------------------------------- + // Wire declrations + //----------------------------------------------------------------------- + + val sys_clock = Wire(Clock()) + val sys_reset = Wire(Bool()) + + val dut_clock = Wire(Clock()) + val dut_reset = Wire(Bool()) + val dut_resetn = Wire(Bool()) + + val dut_ndreset = Wire(Bool()) + + val sd_spi_sck = Wire(Bool()) + val sd_spi_cs = Wire(Bool()) + val sd_spi_dq_i = Wire(Vec(4, Bool())) + val sd_spi_dq_o = Wire(Vec(4, Bool())) + + val do_reset = Wire(Bool()) + + val mig_mmcm_locked = Wire(Bool()) + val mig_sys_reset = Wire(Bool()) + + val mig_clock = Wire(Clock()) + val mig_reset = Wire(Bool()) + val mig_resetn = Wire(Bool()) + + val pcie_dat_reset = Wire(Bool()) + val pcie_dat_resetn = Wire(Bool()) + val pcie_cfg_reset = Wire(Bool()) + val pcie_cfg_resetn = Wire(Bool()) + val pcie_dat_clock = Wire(Clock()) + val pcie_cfg_clock = Wire(Clock()) + val mmcm_lock_pcie = Wire(Bool()) + + //----------------------------------------------------------------------- + // Differential clock + //----------------------------------------------------------------------- + + val sys_clk_ibufds = Module(new IBUFDS) + sys_clk_ibufds.io.I := sys_diff_clock_clk_p + sys_clk_ibufds.io.IB := sys_diff_clock_clk_n + + //----------------------------------------------------------------------- + // System clock and reset + //----------------------------------------------------------------------- + + // Clock that drives the clock generator and the MIG + sys_clock := sys_clk_ibufds.io.O.asClock + + // Allow the debug module to reset everything. Resets the MIG + sys_reset := reset | dut_ndreset + + //----------------------------------------------------------------------- + // Clock Generator + //----------------------------------------------------------------------- + + val coreplex_mmcm = Module(new vc707clk_wiz_sync) + coreplex_mmcm.io.clk_in1 := sys_clock.asUInt + coreplex_mmcm.io.reset := mig_sys_reset + + val clk12_5 = coreplex_mmcm.io.clk_out1 + val clk25 = coreplex_mmcm.io.clk_out2 + val clk37_5 = coreplex_mmcm.io.clk_out3 + val clk50 = coreplex_mmcm.io.clk_out4 + val clk100 = coreplex_mmcm.io.clk_out5 + val clk150 = coreplex_mmcm.io.clk_out6 + val clk75 = coreplex_mmcm.io.clk_out7 + val coreplex_mmcm_locked = coreplex_mmcm.io.locked + + // DUT clock + dut_clock := clk37_5 + + //----------------------------------------------------------------------- + // System reset + //----------------------------------------------------------------------- + + do_reset := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset || !coreplex_mmcm_locked + mig_resetn := !mig_reset + dut_resetn := !dut_reset + pcie_dat_resetn := !pcie_dat_reset + pcie_cfg_resetn := !pcie_cfg_reset + + val safe_reset = Module(new vc707reset) + + safe_reset.io.areset := do_reset + safe_reset.io.clock1 := mig_clock + mig_reset := safe_reset.io.reset1 + safe_reset.io.clock2 := pcie_dat_clock + pcie_dat_reset := safe_reset.io.reset2 + safe_reset.io.clock3 := pcie_cfg_clock + pcie_cfg_reset := safe_reset.io.reset3 + safe_reset.io.clock4 := dut_clock + dut_reset := safe_reset.io.reset4 + + //--------------------------------------------------------------------- + // Debug JTAG + //--------------------------------------------------------------------- + + def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): Unit = { + val djtag = dut.debug.systemjtag.get + + djtag.jtag.TCK := jtag_TCK + djtag.jtag.TMS := jtag_TMS + djtag.jtag.TDI := jtag_TDI + jtag_TDO := djtag.jtag.TDO.data + + djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W) + + djtag.reset := PowerOnResetFPGAOnly(dut_clock) + dut_ndreset := dut.debug.ndreset + } + + //----------------------------------------------------------------------- + // UART + //----------------------------------------------------------------------- + + uart_rtsn := false.B + + def connectUART(dut: HasPeripheryUARTModuleImp): Unit = { + val uartParams = p(PeripheryUARTKey) + if (!uartParams.isEmpty) { + // synchronize uart_rx + val uart_rx_sync_reg0 = RegInit(true.B) + uart_rx_sync_reg0 := uart_rx + + val uart_rx_sync_reg1 = RegInit(true.B) + uart_rx_sync_reg1 := uart_rx_sync_reg0 + + // uart connections + dut.uart(0).rxd := uart_rx_sync_reg1 + uart_tx := dut.uart(0).txd + } + } + + //----------------------------------------------------------------------- + // SPI + //----------------------------------------------------------------------- + + def connectSPI(dut: HasPeripherySPIModuleImp): Unit = { + // SPI + sd_spi_sck := dut.spi(0).sck + sd_spi_cs := dut.spi(0).cs(0) + + dut.spi(0).dq.zipWithIndex.foreach { + case(pin, idx) => + sd_spi_dq_o(idx) := pin.o + pin.i := sd_spi_dq_i(idx) + } + + //------------------------------------------------------------------- + // SDIO <> SPI Bridge + //------------------------------------------------------------------- + + val ip_sdio_spi = Module(new sdio_spi_bridge()) + + ip_sdio_spi.io.clk := dut_clock + ip_sdio_spi.io.reset := dut_reset + + // SDIO + attach(sdio_dat, ip_sdio_spi.io.sd_dat) + attach(sdio_cmd, ip_sdio_spi.io.sd_cmd) + sdio_clk := ip_sdio_spi.io.spi_sck + + // SPI + ip_sdio_spi.io.spi_sck := sd_spi_sck + ip_sdio_spi.io.spi_cs := sd_spi_cs + sd_spi_dq_i := ip_sdio_spi.io.spi_dq_i.toBools + ip_sdio_spi.io.spi_dq_o := sd_spi_dq_o.asUInt + } + + //--------------------------------------------------------------------- + // MIG + //--------------------------------------------------------------------- + + def connectMIG(dut: HasMemoryXilinxVC707MIGModuleImp): Unit = { + + // Clock & Reset + dut.xilinxvc707mig.sys_clk_i := sys_clock.asUInt + mig_clock := dut.xilinxvc707mig.ui_clk + mig_sys_reset := dut.xilinxvc707mig.ui_clk_sync_rst + mig_mmcm_locked := dut.xilinxvc707mig.mmcm_locked + dut.xilinxvc707mig.aresetn := mig_resetn + dut.xilinxvc707mig.sys_rst := sys_reset + + // Outputs + ddr3_addr := dut.xilinxvc707mig.ddr3_addr + ddr3_ba := dut.xilinxvc707mig.ddr3_ba + ddr3_ras_n := dut.xilinxvc707mig.ddr3_ras_n + ddr3_cas_n := dut.xilinxvc707mig.ddr3_cas_n + ddr3_we_n := dut.xilinxvc707mig.ddr3_we_n + ddr3_reset_n := dut.xilinxvc707mig.ddr3_reset_n + ddr3_ck_p := dut.xilinxvc707mig.ddr3_ck_p + ddr3_ck_n := dut.xilinxvc707mig.ddr3_ck_n + ddr3_cke := dut.xilinxvc707mig.ddr3_cke + ddr3_cs_n := dut.xilinxvc707mig.ddr3_cs_n + ddr3_dm := dut.xilinxvc707mig.ddr3_dm + ddr3_odt := dut.xilinxvc707mig.ddr3_odt + + attach(ddr3_dq, dut.xilinxvc707mig.ddr3_dq) + attach(ddr3_dqs_n, dut.xilinxvc707mig.ddr3_dqs_n) + attach(ddr3_dqs_p, dut.xilinxvc707mig.ddr3_dqs_p) + } + + //--------------------------------------------------------------------- + // PCIE + //--------------------------------------------------------------------- + + def connectPCIe(dut: HasSystemXilinxVC707PCIeX1ModuleImp): Unit = { + // Clock & Reset + dut.xilinxvc707pcie.axi_aresetn := pcie_dat_resetn + pcie_dat_clock := dut.xilinxvc707pcie.axi_aclk_out + pcie_cfg_clock := dut.xilinxvc707pcie.axi_ctl_aclk_out + mmcm_lock_pcie := dut.xilinxvc707pcie.mmcm_lock + dut.xilinxvc707pcie.axi_ctl_aresetn := pcie_dat_resetn + dut.xilinxvc707pcie.REFCLK_rxp := pci_exp_refclk_rxp + dut.xilinxvc707pcie.REFCLK_rxn := pci_exp_refclk_rxn + + // PCIeX1 connections + pci_exp_txp := dut.xilinxvc707pcie.pci_exp_txp + pci_exp_txn := dut.xilinxvc707pcie.pci_exp_txn + dut.xilinxvc707pcie.pci_exp_rxp := pci_exp_rxp + dut.xilinxvc707pcie.pci_exp_rxn := pci_exp_rxn + } + +} diff --git a/xilinx/Makefile b/xilinx/Makefile new file mode 100644 index 0000000..ec6c75f --- /dev/null +++ b/xilinx/Makefile @@ -0,0 +1,42 @@ +VIVADO ?= vivado +VIVADOFLAGS := \ + -nojournal -mode batch \ + -source $(fpga_board_script_dir)/board.tcl \ + -source $(fpga_common_script_dir)/prologue.tcl + +# Path to a program in raw binary format to be flashed into the address that the +# bootrom jumps to. +# FIXME: This variable should probably be communicated by a higher-level Makefile +FLASHED_PROGRAM ?= + +# Init project +init = $(FPGA_BUILD_DIR)/.init +$(init): $(fpga_common_script_dir)/init.tcl + mkdir -p $(FPGA_BUILD_DIR) && \ + cd $(FPGA_BUILD_DIR) && \ + VSRCS="$(VSRCS)" $(VIVADO) $(VIVADOFLAGS) -source $< + +.PHONY: init +init: $(init) + +# Generate bitstream +bit := $(FPGA_BUILD_DIR)/obj/$(FPGA_TOP_SYSTEM).bit +$(bit): $(fpga_common_script_dir)/vivado.tcl $(init) + cd $(FPGA_BUILD_DIR) && \ + VSRCS="$(VSRCS)" $(VIVADO) $(VIVADOFLAGS) -source $< + +.PHONY: bit +bit: $(bit) + +# Generate mcs +mcs := $(FPGA_BUILD_DIR)/obj/system.mcs +$(mcs): $(bit) + cd $(FPGA_BUILD_DIR) && \ + $(VIVADO) $(VIVADOFLAGS) $(fpga_common_script_dir)/write_cfgmem.tcl -tclargs $(BOARD) $@ $^ $(FLASHED_PROGRAM) + +.PHONY: mcs +mcs: $(mcs) + +.PHONY: clean +clean:: + rm -rf $(FPGA_BUILD_DIR) diff --git a/xilinx/arty/constraints/arty-config.xdc b/xilinx/arty/constraints/arty-config.xdc new file mode 100644 index 0000000..a455c22 --- /dev/null +++ b/xilinx/arty/constraints/arty-config.xdc @@ -0,0 +1,5 @@ +set_property -dict [list \ + CONFIG_VOLTAGE {3.3} \ + CFGBVS {VCCO} \ + BITSTREAM.CONFIG.SPI_BUSWIDTH {4} \ + ] [current_design] diff --git a/xilinx/arty/constraints/arty-master.xdc b/xilinx/arty/constraints/arty-master.xdc new file mode 100644 index 0000000..be9ff37 --- /dev/null +++ b/xilinx/arty/constraints/arty-master.xdc @@ -0,0 +1,240 @@ +## This file is a general .xdc for the ARTY Rev. B +## To use it in a project: +## - uncomment the lines corresponding to used pins +## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project + +## Clock signal + +set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100] +create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100MHZ}]; +create_clock -add -name JTCK -period 100 -waveform {0 50} [get_ports {jd_2}]; + +##Switches + +set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { sw_0 }]; #IO_L12N_T1_MRCC_16 Sch=sw[0] +set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { sw_1 }]; #IO_L13P_T2_MRCC_16 Sch=sw[1] +set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { sw_2 }]; #IO_L13N_T2_MRCC_16 Sch=sw[2] +set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { sw_3 }]; #IO_L14P_T2_SRCC_16 Sch=sw[3] + +##RGB LEDs + +set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { led0_b }]; #IO_L18N_T2_35 Sch=led0_b +set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { led0_g }]; #IO_L19N_T3_VREF_35 Sch=led0_g +set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { led0_r }]; #IO_L19P_T3_35 Sch=led0_r +set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { led1_b }]; #IO_L20P_T3_35 Sch=led1_b +set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { led1_g }]; #IO_L21P_T3_DQS_35 Sch=led1_g +set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { led1_r }]; #IO_L20N_T3_35 Sch=led1_r +set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { led2_b }]; #IO_L21N_T3_DQS_35 Sch=led2_b +set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { led2_g }]; #IO_L22N_T3_35 Sch=led2_g +set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { led2_r }]; #IO_L22P_T3_35 Sch=led2_r +#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { led3_b }]; #IO_L23P_T3_35 Sch=led3_b +#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { led3_g }]; #IO_L24P_T3_35 Sch=led3_g +#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { led3_r }]; #IO_L23N_T3_35 Sch=led3_r + +##LEDs + +set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { led_0 }]; #IO_L24N_T3_35 Sch=led[4] +set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { led_1 }]; #IO_25_35 Sch=led[5] +set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { led_2 }]; #IO_L24P_T3_A01_D17_14 Sch=led[6] +set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { led_3 }]; #IO_L24N_T3_A00_D16_14 Sch=led[7] + +##Buttons + +set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { btn_0 }]; #IO_L6N_T0_VREF_16 Sch=btn[0] +set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { btn_1 }]; #IO_L11P_T1_SRCC_16 Sch=btn[1] +set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { btn_2 }]; #IO_L11N_T1_SRCC_16 Sch=btn[2] +set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { btn_3 }]; #IO_L12P_T1_MRCC_16 Sch=btn[3] + +##Pmod Header JA + +set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { ja_0 }]; #IO_0_15 Sch=ja[1] +set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { ja_1 }]; #IO_L4P_T0_15 Sch=ja[2] +set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { ja_2 }]; #IO_L4N_T0_15 Sch=ja[3] +set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { ja_3 }]; #IO_L6P_T0_15 Sch=ja[4] +set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { ja_4 }]; #IO_L6N_T0_VREF_15 Sch=ja[7] +set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { ja_5 }]; #IO_L10P_T1_AD11P_15 Sch=ja[8] +set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { ja_6 }]; #IO_L10N_T1_AD11N_15 Sch=ja[9] +set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { ja_7 }]; #IO_25_15 Sch=ja[10] + +##Pmod Header JB + +#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { jb_0 }]; #IO_L11P_T1_SRCC_15 Sch=jb_p[1] +#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { jb_1 }]; #IO_L11N_T1_SRCC_15 Sch=jb_n[1] +#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { jb_2 }]; #IO_L12P_T1_MRCC_15 Sch=jb_p[2] +#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { jb_3 }]; #IO_L12N_T1_MRCC_15 Sch=jb_n[2] +#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { jb_4 }]; #IO_L23P_T3_FOE_B_15 Sch=jb_p[3] +#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { jb_5 }]; #IO_L23N_T3_FWE_B_15 Sch=jb_n[3] +#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { jb_6 }]; #IO_L24P_T3_RS1_15 Sch=jb_p[4] +#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { jb_7 }]; #IO_L24N_T3_RS0_15 Sch=jb_n[4] + +##Pmod Header JC + +#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L20P_T3_A08_D24_14 Sch=jc_p[1] +#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L20N_T3_A07_D23_14 Sch=jc_n[1] +#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L21P_T3_DQS_14 Sch=jc_p[2] +#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=jc_n[2] +#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L22P_T3_A05_D21_14 Sch=jc_p[3] +#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L22N_T3_A04_D20_14 Sch=jc_n[3] +#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L23P_T3_A03_D19_14 Sch=jc_p[4] +#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L23N_T3_A02_D18_14 Sch=jc_n[4] + +##Pmod Header JD + +set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { jd_0 }]; #IO_L11N_T1_SRCC_35 Sch=jd[1] +set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { jd_1 }]; #IO_L12N_T1_MRCC_35 Sch=jd[2] +set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { jd_2 }]; #IO_L13P_T2_MRCC_35 Sch=jd[3] +#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd_3 }]; #IO_L13N_T2_MRCC_35 Sch=jd[4] +set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { jd_4 }]; #IO_L14P_T2_SRCC_35 Sch=jd[7] +set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { jd_5 }]; #IO_L14N_T2_SRCC_35 Sch=jd[8] +set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd_6 }]; #IO_L15P_T2_DQS_35 Sch=jd[9] +#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { jd_7 }]; #IO_L15N_T2_DQS_35 Sch=jd[10] + +##USB-UART Interface (FTDI FT2232H) + +set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L19N_T3_VREF_16 Sch=uart_rxd_out +set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L14N_T2_SRCC_16 Sch=uart_txd_in + + +##ChipKit Single Ended Analog Inputs +##NOTE: The ck_an_p pins can be used as single ended analog inputs with voltages from 0-3.3V (Chipkit Analog pins A0-A5). +## These signals should only be connected to the XADC core. When using these pins as digital I/O, use pins ck_io[14-19]. + +#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[0] }]; #IO_L1N_T0_AD4N_35 Sch=ck_an_n[0] +#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[0] }]; #IO_L1P_T0_AD4P_35 Sch=ck_an_p[0] +#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=ck_an_n[1] +#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[1] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=ck_an_p[1] +#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[2] }]; #IO_L7N_T1_AD6N_35 Sch=ck_an_n[2] +#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[2] }]; #IO_L7P_T1_AD6P_35 Sch=ck_an_p[2] +#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[3] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=ck_an_n[3] +#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[3] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=ck_an_p[3] +#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[4] }]; #IO_L10N_T1_AD15N_35 Sch=ck_an_n[4] +#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[4] }]; #IO_L10P_T1_AD15P_35 Sch=ck_an_p[4] +#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_n[5] }]; #IO_L1N_T0_AD0N_15 Sch=ck_an_n[5] +#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { ck_an_p[5] }]; #IO_L1P_T0_AD0P_15 Sch=ck_an_p[5] + +##ChipKit Digital I/O Low + +set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_0 }]; #IO_L16P_T2_CSI_B_14 Sch=ck_io[0] +set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_1 }]; #IO_L18P_T2_A12_D28_14 Sch=ck_io[1] +set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { ck_io_2 }]; #IO_L8N_T1_D12_14 Sch=ck_io[2] +set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { ck_io_3 }]; #IO_L19P_T3_A10_D26_14 Sch=ck_io[3] +set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { ck_io_4 }]; #IO_L5P_T0_D06_14 Sch=ck_io[4] +set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { ck_io_5 }]; #IO_L14P_T2_SRCC_14 Sch=ck_io[5] +set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_6 }]; #IO_L14N_T2_SRCC_14 Sch=ck_io[6] +set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_7 }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=ck_io[7] +set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { ck_io_8 }]; #IO_L11P_T1_SRCC_14 Sch=ck_io[8] +set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { ck_io_9 }]; #IO_L10P_T1_D14_14 Sch=ck_io[9] +set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_10 }]; #IO_L18N_T2_A11_D27_14 Sch=ck_io[10] +set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { ck_io_11 }]; #IO_L17N_T2_A13_D29_14 Sch=ck_io[11] +set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_12 }]; #IO_L12N_T1_MRCC_14 Sch=ck_io[12] +set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { ck_io_13 }]; #IO_L12P_T1_MRCC_14 Sch=ck_io[13] + +##ChipKit Digital I/O On Outer Analog Header +##NOTE: These pins should be used when using the analog header signals A0-A5 as digital I/O (Chipkit digital pins 14-19) + +set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { ck_io_14 }]; #IO_0_35 Sch=ck_a[0] +set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { ck_io_15 }]; #IO_L4P_T0_35 Sch=ck_a[1] +set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_16 }]; #IO_L4N_T0_35 Sch=ck_a[2] +set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_17 }]; #IO_L6P_T0_35 Sch=ck_a[3] +set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { ck_io_18 }]; #IO_L6N_T0_VREF_35 Sch=ck_a[4] +set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ck_io_19 }]; #IO_L11P_T1_SRCC_35 Sch=ck_a[5] + +##ChipKit Digital I/O On Inner Analog Header +##NOTE: These pins will need to be connected to the XADC core when used as differential analog inputs (Chipkit analog pins A6-A11) + +#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { ck_io[20] }]; #IO_L2P_T0_AD12P_35 Sch=ad_p[12] +#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[21] }]; #IO_L2N_T0_AD12N_35 Sch=ad_n[12] +#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { ck_io[22] }]; #IO_L5P_T0_AD13P_35 Sch=ad_p[13] +#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { ck_io[23] }]; #IO_L5N_T0_AD13N_35 Sch=ad_n[13] +#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { ck_io[24] }]; #IO_L8P_T1_AD14P_35 Sch=ad_p[14] +#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { ck_io[25] }]; #IO_L8N_T1_AD14N_35 Sch=ad_n[14] + +##ChipKit Digital I/O High + +#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[26] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=ck_io[26] +#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[27] }]; #IO_L16N_T2_A15_D31_14 Sch=ck_io[27] +#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[28] }]; #IO_L6N_T0_D08_VREF_14 Sch=ck_io[28] +#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { ck_io[29] }]; #IO_25_14 Sch=ck_io[29] +#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { ck_io[30] }]; #IO_0_14 Sch=ck_io[30] +#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { ck_io[31] }]; #IO_L5N_T0_D07_14 Sch=ck_io[31] +#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[32] }]; #IO_L13N_T2_MRCC_14 Sch=ck_io[32] +#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ck_io[33] }]; #IO_L13P_T2_MRCC_14 Sch=ck_io[33] +#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[34] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=ck_io[34] +#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { ck_io[35] }]; #IO_L11N_T1_SRCC_14 Sch=ck_io[35] +#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { ck_io[36] }]; #IO_L8P_T1_D11_14 Sch=ck_io[36] +#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[37] }]; #IO_L17P_T2_A14_D30_14 Sch=ck_io[37] +#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[38] }]; #IO_L7N_T1_D10_14 Sch=ck_io[38] +#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[39] }]; #IO_L7P_T1_D09_14 Sch=ck_io[39] +#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { ck_io[40] }]; #IO_L9N_T1_DQS_D13_14 Sch=ck_io[40] +#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { ck_io[41] }]; #IO_L9P_T1_DQS_14 Sch=ck_io[41] + +## ChipKit SPI + +set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { ck_miso }]; #IO_L17N_T2_35 Sch=ck_miso +set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { ck_mosi }]; #IO_L17P_T2_35 Sch=ck_mosi +set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { ck_sck }]; #IO_L18P_T2_35 Sch=ck_sck +set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { ck_ss }]; #IO_L16N_T2_35 Sch=ck_ss + +## ChipKit I2C + +#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { ck_scl }]; #IO_L4P_T0_D04_14 Sch=ck_scl +#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { ck_sda }]; #IO_L4N_T0_D05_14 Sch=ck_sda +#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { scl_pup }]; #IO_L9N_T1_DQS_AD3N_15 Sch=scl_pup +#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { sda_pup }]; #IO_L9P_T1_DQS_AD3P_15 Sch=sda_pup + +##Misc. ChipKit signals + +#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { ck_ioa }]; #IO_L10N_T1_D15_14 Sch=ck_ioa +set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ck_rst }]; #IO_L16P_T2_35 Sch=ck_rst + +##SMSC Ethernet PHY + +#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { eth_col }]; #IO_L16N_T2_A27_15 Sch=eth_col +#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs +#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { eth_mdc }]; #IO_L14N_T2_SRCC_15 Sch=eth_mdc +#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { eth_mdio }]; #IO_L17P_T2_A26_15 Sch=eth_mdio +#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }]; #IO_L22P_T3_A17_15 Sch=eth_ref_clk +#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L20P_T3_A20_15 Sch=eth_rstn +#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_clk }]; #IO_L14P_T2_SRCC_15 Sch=eth_rx_clk +#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_dv }]; #IO_L13N_T2_MRCC_15 Sch=eth_rx_dv +#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0] +#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L16P_T2_A28_15 Sch=eth_rxd[1] +#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[2] }]; #IO_L21P_T3_DQS_15 Sch=eth_rxd[2] +#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[3] }]; #IO_L18N_T2_A23_15 Sch=eth_rxd[3] +#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr +#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_clk }]; #IO_L13P_T2_MRCC_15 Sch=eth_tx_clk +#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en +#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0] +#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1] +#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[2] }]; #IO_L17N_T2_A25_15 Sch=eth_txd[2] +#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[3] }]; #IO_L18P_T2_A24_15 Sch=eth_txd[3] + +##Quad SPI Flash + +set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 IOB TRUE } [get_ports { qspi_sck }]; +create_clock -add -name qspi_sck_pin -period 20.00 -waveform {0 10} [get_ports { qspi_sck }]; +set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 IOB TRUE } [get_ports { qspi_cs }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs +set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_0 }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] +set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_1 }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] +set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_2 }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] +set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 IOB TRUE PULLUP TRUE } [get_ports { qspi_dq_3 }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] + +##Power Measurements + +#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_n }]; #IO_L7N_T1_AD2N_15 Sch=ad_n[2] +#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { vsnsvu_p }]; #IO_L7P_T1_AD2P_15 Sch=ad_p[2] +#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_n }]; #IO_L3N_T0_DQS_AD1N_15 Sch=ad_n[1] +#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { vsns5v0_p }]; #IO_L3P_T0_DQS_AD1P_15 Sch=ad_p[1] +#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_n }]; #IO_L5N_T0_AD9N_15 Sch=ad_n[9] +#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { isns5v0_p }]; #IO_L5P_T0_AD9P_15 Sch=ad_p[9] +#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_n }]; #IO_L8N_T1_AD10N_15 Sch=ad_n[10] +#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_p }]; #IO_L8P_T1_AD10P_15 Sch=ad_p[10] + +set_clock_groups -asynchronous \ + -group [list \ + [get_clocks -include_generated_clocks -of_objects [get_ports jd_2]]] \ + -group [list \ + [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT0]]] \ + -group [list \ + [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT1]] \ + [get_clocks -of_objects [get_pins ip_mmcm/inst/mmcm_adv_inst/CLKOUT2]]] diff --git a/xilinx/arty/tcl/board.tcl b/xilinx/arty/tcl/board.tcl new file mode 100644 index 0000000..4eaed96 --- /dev/null +++ b/xilinx/arty/tcl/board.tcl @@ -0,0 +1,5 @@ +# See LICENSE for license details. +set name {arty} +set part_fpga {xc7a35ticsg324-1L} +set part_board {digilentinc.com:arty:part0:1.1} +set bootrom_inst {rom} diff --git a/xilinx/arty/tcl/ip.tcl b/xilinx/arty/tcl/ip.tcl new file mode 100644 index 0000000..fe07c37 --- /dev/null +++ b/xilinx/arty/tcl/ip.tcl @@ -0,0 +1,44 @@ +# See LICENSE for license details. + +create_ip -vendor xilinx.com -library ip -name clk_wiz -module_name mmcm -dir $ipdir -force +set_property -dict [list \ + CONFIG.PRIMITIVE {MMCM} \ + CONFIG.RESET_TYPE {ACTIVE_LOW} \ + CONFIG.CLKOUT1_USED {true} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {true} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {8.388} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {65.000} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {32.500} \ + ] [get_ips mmcm] + +create_ip -vendor xilinx.com -library ip -name proc_sys_reset -module_name reset_sys -dir $ipdir -force +set_property -dict [list \ + CONFIG.C_EXT_RESET_HIGH {false} \ + CONFIG.C_AUX_RESET_HIGH {false} \ + CONFIG.C_NUM_BUS_RST {1} \ + CONFIG.C_NUM_PERP_RST {1} \ + CONFIG.C_NUM_INTERCONNECT_ARESETN {1} \ + CONFIG.C_NUM_PERP_ARESETN {1} \ + ] [get_ips reset_sys] + +create_ip -vendor xilinx.com -library ip -name ila -module_name ila -dir $ipdir -force +set_property -dict [list \ + CONFIG.C_NUM_OF_PROBES {1} \ + CONFIG.C_TRIGOUT_EN {false} \ + CONFIG.C_TRIGIN_EN {false} \ + CONFIG.C_MONITOR_TYPE {Native} \ + CONFIG.C_ENABLE_ILA_AXI_MON {false} \ + CONFIG.C_PROBE0_WIDTH {4} \ + CONFIG.C_PROBE10_TYPE {1} \ + CONFIG.C_PROBE10_WIDTH {32} \ + CONFIG.C_PROBE11_TYPE {1} \ + CONFIG.C_PROBE11_WIDTH {32} \ + CONFIG.C_PROBE12_TYPE {1} \ + CONFIG.C_PROBE12_WIDTH {64} \ + CONFIG.C_PROBE13_TYPE {1} \ + CONFIG.C_PROBE13_WIDTH {64} \ + CONFIG.C_PROBE14_TYPE {1} \ + CONFIG.C_PROBE14_WIDTH {97} \ + ] [get_ips ila] + diff --git a/xilinx/common/tcl/bitstream.tcl b/xilinx/common/tcl/bitstream.tcl new file mode 100644 index 0000000..bf223f6 --- /dev/null +++ b/xilinx/common/tcl/bitstream.tcl @@ -0,0 +1,10 @@ +# See LICENSE for license details. + +# Write a bitstream for the current design +write_bitstream -force [file join $wrkdir "${top}.bit"] + +# Save the timing delays for cells in the design in SDF format +write_sdf -force [file join $wrkdir "${top}.sdf"] + +# Export the current netlist in verilog format +write_verilog -mode timesim -force [file join ${wrkdir} "${top}.v"] diff --git a/xilinx/common/tcl/boards.tcl b/xilinx/common/tcl/boards.tcl new file mode 100644 index 0000000..8cba458 --- /dev/null +++ b/xilinx/common/tcl/boards.tcl @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +namespace eval ::program::boards {} + +set ::program::boards::spec [dict create \ + arty [dict create iface spix4 size 16 bitaddr 0x0 memdev {n25q128-3.3v-spi-x1_x2_x4}] \ + vc707 [dict create iface bpix16 size 128 bitaddr 0x3000000 ]] diff --git a/xilinx/common/tcl/init.tcl b/xilinx/common/tcl/init.tcl new file mode 100644 index 0000000..49b8dc5 --- /dev/null +++ b/xilinx/common/tcl/init.tcl @@ -0,0 +1,38 @@ +# See LICENSE for license details. + +# Include helper functions +source [file join $scriptdir "util.tcl"] + +# Create the diretory for IPs +file mkdir $ipdir + +# Update the IP catalog +update_ip_catalog -rebuild + +# Board specific IP implementation +source [file join $boarddir tcl ip.tcl] + +# AR 58526 +set_property GENERATE_SYNTH_CHECKPOINT {false} [get_files -all {*.xci}] + +# Get a list of IPs in the current design +set obj [get_ips] + +# Generate target data for the inlcuded IPs in the design +generate_target all $obj + +# Export the IP user files +export_ip_user_files -of_objects $obj -no_script -force + +# Get the list of active source and constraint files +set obj [current_fileset] + +#Xilinx bug workaround +#scrape IP tree for directories containing .vh files +#[get_property include_dirs] misses all IP core subdirectory includes if user has specified -dir flag in create_ip +set property_include_dirs [get_property include_dirs $obj] + +# Include generated files for the IPs in the design +set ip_include_dirs [concat $property_include_dirs [findincludedir $ipdir "*.vh"]] +set ip_include_dirs [concat $ip_include_dirs [findincludedir $srcdir "*.h"]] +set ip_include_dirs [concat $ip_include_dirs [findincludedir $srcdir "*.vh"]] diff --git a/xilinx/common/tcl/opt.tcl b/xilinx/common/tcl/opt.tcl new file mode 100644 index 0000000..81bf4ad --- /dev/null +++ b/xilinx/common/tcl/opt.tcl @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +# Optimize the netlist +opt_design -directive Explore + +# Checkpoint the current design +write_checkpoint -force [file join $wrkdir post_opt] diff --git a/xilinx/common/tcl/place.tcl b/xilinx/common/tcl/place.tcl new file mode 100644 index 0000000..ccc862a --- /dev/null +++ b/xilinx/common/tcl/place.tcl @@ -0,0 +1,13 @@ +# See LICENSE for license details. + +# Place the current design +place_design -directive Explore + +# Optimize the current placed netlist +phys_opt_design -directive Explore + +# Optimize dynamic power using intelligent clock gating +power_opt_design + +# Checkpoint the current design +write_checkpoint -force [file join $wrkdir post_place] diff --git a/xilinx/common/tcl/post-impl-debug.tcl b/xilinx/common/tcl/post-impl-debug.tcl new file mode 100644 index 0000000..240b1cc --- /dev/null +++ b/xilinx/common/tcl/post-impl-debug.tcl @@ -0,0 +1,3 @@ +# See LICENSE for license details. + +# Write debug probes, save MMI for BRAMs in the design diff --git a/xilinx/common/tcl/pre-impl-debug.tcl b/xilinx/common/tcl/pre-impl-debug.tcl new file mode 100644 index 0000000..0176f04 --- /dev/null +++ b/xilinx/common/tcl/pre-impl-debug.tcl @@ -0,0 +1,3 @@ +# See LICENSE for license details. + +# Instantiate ILAs diff --git a/xilinx/common/tcl/prologue.tcl b/xilinx/common/tcl/prologue.tcl new file mode 100644 index 0000000..77615fe --- /dev/null +++ b/xilinx/common/tcl/prologue.tcl @@ -0,0 +1,64 @@ +# See LICENSE for license details. + +# Set the variable for the directory that includes all scripts +set scriptdir [file dirname [info script]] + +# Set the variable for all the common files +set commondir [file dirname $scriptdir] + +# Set the variable that points to board specific files +set boarddir [file join [file dirname $commondir] $name] + +# Set the variable that points to board constraint files +set constraintsdir [file join $boarddir constraints] + +# Set the variable that points to common verilog sources +set srcdir [file join $commondir vsrc] + +# Creates a work directory +set wrkdir [file join [pwd] obj] + +# Create the directory for IPs +set ipdir [file join $wrkdir ip] + +# Set the top for the design based on an environment variable +set top $::env(FPGA_TOP_SYSTEM) + +# Create an in-memory project +create_project -part $part_fpga -in_memory + +# Set the board part, target language, default library, and IP directory +# paths for the current project +set_property -dict [list \ + BOARD_PART $part_board \ + TARGET_LANGUAGE {Verilog} \ + DEFAULT_LIB {xil_defaultlib} \ + IP_REPO_PATHS $ipdir \ + ] [current_project] + +if {[get_filesets -quiet sources_1] eq ""} { + create_fileset -srcset sources_1 +} +set obj [current_fileset] + +# Add verilog files from VSRCS environment variable +if {[info exists ::env(VSRCS)]} { + # Split string into words even with multiple consecutive spaces + # http://wiki.tcl.tk/989 + set vsrcs [regexp -inline -all -- {\S+} $::env(VSRCS)] + foreach vsrc $vsrcs { + add_files -norecurse -fileset $obj $vsrc + } +} + +if {[get_filesets -quiet sim_1] eq ""} { + create_fileset -simset sim_1 +} +set obj [current_fileset -simset] + +if {[get_filesets -quiet constrs_1] eq ""} { + create_fileset -constrset constrs_1 +} + +set obj [current_fileset -constrset] +add_files -norecurse -fileset $obj [glob -directory $constraintsdir {*.xdc}] diff --git a/xilinx/common/tcl/report.tcl b/xilinx/common/tcl/report.tcl new file mode 100644 index 0000000..a499537 --- /dev/null +++ b/xilinx/common/tcl/report.tcl @@ -0,0 +1,44 @@ +# See LICENSE for license details. + +# Create a report directory +set rptdir [file join $wrkdir report] +file mkdir $rptdir + +# Create a datasheet for the current design +report_datasheet -file [file join $rptdir datasheet.txt] + +# Report utilization of the current device +set rptutil [file join $rptdir utilization.txt] +report_utilization -hierarchical -file $rptutil + +# Report information about clock nets in the design +report_clock_utilization -file $rptutil -append + +# Report the RAM resources utilized in the implemented design +report_ram_utilization -file $rptutil -append -detail + +# Report timing summary for a max of 10 paths per group +report_timing_summary -file [file join $rptdir timing.txt] -max_paths 10 + +# Report the highest fanout of nets in the implemented design +report_high_fanout_nets -file [file join $rptdir fanout.txt] -timing -load_types -max_nets 25 + +# Run DRC +report_drc -file [file join $rptdir drc.txt] + +# Report details of the IO banks in the design +report_io -file [file join $rptdir io.txt] + +# Report a table of all clocks in the design +report_clocks -file [file join $rptdir clocks.txt] + +# Fail loudly if timing not met +# +# We would ideally elevate critical warning Route 35-39 to an error, but it is +# currently not being emitted with our flow for some reason. +# https://forums.xilinx.com/t5/Implementation/Making-timing-violations-fatal-to-the-Vivado-build/m-p/716957#M15979 +set timing_slack [get_property SLACK [get_timing_paths]] +if {$timing_slack < 0} { + puts "Failed to meet timing by $timing_slack, see [file join $rptdir timing.txt]" + exit 1 +} diff --git a/xilinx/common/tcl/route.tcl b/xilinx/common/tcl/route.tcl new file mode 100644 index 0000000..68fc84a --- /dev/null +++ b/xilinx/common/tcl/route.tcl @@ -0,0 +1,10 @@ +# See LICENSE for license details. + +# Route the current design +route_design -directive Explore + +# Optimize the current design post routing +phys_opt_design -directive Explore + +# Checkpoint the current design +write_checkpoint -force [file join $wrkdir post_route] diff --git a/xilinx/common/tcl/synth.tcl b/xilinx/common/tcl/synth.tcl new file mode 100644 index 0000000..f350185 --- /dev/null +++ b/xilinx/common/tcl/synth.tcl @@ -0,0 +1,10 @@ +# See LICENSE for license details. + +# Read the specified list of IP files +read_ip [glob -directory $ipdir [file join * {*.xci}]] + +# Synthesize the design +synth_design -top $top -flatten_hierarchy rebuilt + +# Checkpoint the current design +write_checkpoint -force [file join $wrkdir post_synth] diff --git a/xilinx/common/tcl/util.tcl b/xilinx/common/tcl/util.tcl new file mode 100644 index 0000000..eda723f --- /dev/null +++ b/xilinx/common/tcl/util.tcl @@ -0,0 +1,24 @@ +# See LICENSE for license details. + +# Helper function that recursively includes files given a directory and a +# pattern/suffix extensions +proc recglob { basedir pattern } { + set dirlist [glob -nocomplain -directory $basedir -type d *] + set findlist [glob -nocomplain -directory $basedir $pattern] + foreach dir $dirlist { + set reclist [recglob $dir $pattern] + set findlist [concat $findlist $reclist] + } + return $findlist +} + +# Helper function to find all subdirectories containing ".vh" files +proc findincludedir { basedir pattern } { + set vhfiles [recglob $basedir $pattern] + set vhdirs {} + foreach match $vhfiles { + lappend vhdirs [file dir $match] + } + set uniquevhdirs [lsort -unique $vhdirs] + return $uniquevhdirs +} diff --git a/xilinx/common/tcl/vivado.tcl b/xilinx/common/tcl/vivado.tcl new file mode 100644 index 0000000..fae8d28 --- /dev/null +++ b/xilinx/common/tcl/vivado.tcl @@ -0,0 +1,25 @@ +# See LICENSE for license details. + +# Synthesize the design +source [file join $scriptdir "synth.tcl"] + +# Pre-implementation debug +source [file join $scriptdir "pre-impl-debug.tcl"] + +# Post synthesis optimization +source [file join $scriptdir "opt.tcl"] + +# Place the design +source [file join $scriptdir "place.tcl"] + +# Route the design +source [file join $scriptdir "route.tcl"] + +# Generate bitstream and save verilog netlist +source [file join $scriptdir "bitstream.tcl"] + +# Post-implementation debug +source [file join $scriptdir "post-impl-debug.tcl"] + +# Create reports for the current implementation +source [file join $scriptdir "report.tcl"] diff --git a/xilinx/common/tcl/write_cfgmem.tcl b/xilinx/common/tcl/write_cfgmem.tcl new file mode 100644 index 0000000..ebce010 --- /dev/null +++ b/xilinx/common/tcl/write_cfgmem.tcl @@ -0,0 +1,26 @@ +# See LICENSE for license details. +# +# Create an MCS-format memory configuration file from a bitstream and an +# optional data file. + +set script_program_dir [file dirname [info script]] +source [file join $script_program_dir {boards.tcl}] + +if {$argc < 3 || $argc > 4} { + puts $argc + puts {Error: Invalid number of arguments} + puts {Usage: write_cfgmem.tcl board mcsfile bitfile [datafile]} + exit 1 +} +lassign $argv board mcsfile bitfile datafile + +if {![dict exists $::program::boards::spec $board]} { + puts {Unsupported board} + exit 1 +} +set board [dict get $::program::boards::spec $board] + +write_cfgmem -format mcs -interface [dict get $board iface] -size [dict get $board size] \ + -loadbit "up [dict get $board bitaddr] $bitfile" \ + -loaddata [expr {$datafile ne "" ? "up 0x400000 $datafile" : ""}] \ + -file $mcsfile -force diff --git a/xilinx/common/vsrc/PowerOnResetFPGAOnly.v b/xilinx/common/vsrc/PowerOnResetFPGAOnly.v new file mode 100644 index 0000000..bfb132c --- /dev/null +++ b/xilinx/common/vsrc/PowerOnResetFPGAOnly.v @@ -0,0 +1,15 @@ +// See LICENSE file for license details. + +module PowerOnResetFPGAOnly( + input clock, + output reg power_on_reset +); + + initial begin + power_on_reset <= 1'b1; + end + + always @(posedge clock) begin + power_on_reset <= 1'b0; + end +endmodule diff --git a/xilinx/vc707/constraints/vc707-master.xdc b/xilinx/vc707/constraints/vc707-master.xdc new file mode 100644 index 0000000..d5b4fff --- /dev/null +++ b/xilinx/vc707/constraints/vc707-master.xdc @@ -0,0 +1,75 @@ +#---------------Physical Constraints----------------- + +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 + +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] + +set_property PACKAGE_PIN AU33 [get_ports uart_rx] +set_property IOSTANDARD LVCMOS18 [get_ports uart_rx] +set_property IOB TRUE [get_ports uart_rx] +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] +set_property PACKAGE_PIN AU36 [get_ports uart_tx] +set_property IOSTANDARD LVCMOS18 [get_ports uart_tx] +set_property IOB TRUE [get_ports uart_tx] +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] + +# FIXME: shreesha: I need to see if these matter and add them back +# currently everything works without it.... +#set_property IOB TRUE [get_cells "top/RocketChipTop/uarts_0/txm/out_reg"] +#set_property IOB TRUE [get_cells "uart_rx_sync_reg[0]"] + +# PCI Express +#FMC 1 refclk +set_property PACKAGE_PIN A10 [get_ports {pci_exp_refclk_rxp}] +set_property PACKAGE_PIN A9 [get_ports {pci_exp_refclk_rxn}] +create_clock -name pcie_ref_clk -period 10 [get_ports pci_exp_refclk_rxp] +set_input_jitter [get_clocks -of_objects [get_ports pci_exp_refclk_rxp]] 0.5 + +set_property PACKAGE_PIN H4 [get_ports {pci_exp_txp[0]}] +set_property PACKAGE_PIN H3 [get_ports {pci_exp_txn[0]}] + +set_property PACKAGE_PIN G6 [get_ports {pci_exp_rxp[0]}] +set_property PACKAGE_PIN G5 [get_ports {pci_exp_rxn[0]}] + +# JTAG +set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_TCK_IBUF] +set_property -dict { PACKAGE_PIN R32 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TCK}] +set_property -dict { PACKAGE_PIN W36 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TMS}] +set_property -dict { PACKAGE_PIN W37 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDI}] +set_property -dict { PACKAGE_PIN V40 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDO}] + +# SDIO +set_property -dict { PACKAGE_PIN AN30 IOSTANDARD LVCMOS18 IOB TRUE } [get_ports {sdio_clk}] +set_property -dict { PACKAGE_PIN AP30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_cmd}] +set_property -dict { PACKAGE_PIN AR30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[0]}] +set_property -dict { PACKAGE_PIN AU31 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[1]}] +set_property -dict { PACKAGE_PIN AV31 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[2]}] +set_property -dict { PACKAGE_PIN AT30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[3]}] + +set_clock_groups -asynchronous \ + -group { clk_pll_i } \ + -group { \ + clk_out1_vc707clk_wiz_sync \ + clk_out2_vc707clk_wiz_sync \ + clk_out3_vc707clk_wiz_sync \ + clk_out4_vc707clk_wiz_sync \ + clk_out5_vc707clk_wiz_sync \ + clk_out6_vc707clk_wiz_sync \ + clk_out7_vc707clk_wiz_sync } \ + -group [list [get_clocks -include_generated_clocks -of_objects [get_pins -hier -filter {name =~ *pcie*TXOUTCLK}]]] diff --git a/xilinx/vc707/tcl/board.tcl b/xilinx/vc707/tcl/board.tcl new file mode 100644 index 0000000..1043fa2 --- /dev/null +++ b/xilinx/vc707/tcl/board.tcl @@ -0,0 +1,4 @@ +# See LICENSE for license details. +set name {vc707} +set part_fpga {xc7vx485tffg1761-2} +set part_board {xilinx.com:vc707:part0:1.3} diff --git a/xilinx/vc707/tcl/ip.tcl b/xilinx/vc707/tcl/ip.tcl new file mode 100644 index 0000000..82def13 --- /dev/null +++ b/xilinx/vc707/tcl/ip.tcl @@ -0,0 +1,140 @@ +# See LICENSE for license details. +#MIG +create_ip -vendor xilinx.com -library ip -name mig_7series -module_name vc707mig -dir $ipdir -force +set migprj [file join $boarddir tcl {mig.prj}] +set_property CONFIG.XML_INPUT_FILE $migprj [get_ips vc707mig] + +#AXI_PCIE +create_ip -vendor xilinx.com -library ip -version 2.8 -name axi_pcie -module_name vc707axi_to_pcie_x1 -dir $ipdir -force +set_property -dict [list \ +CONFIG.AXIBAR2PCIEBAR_0 {0x60000000} \ +CONFIG.AXIBAR2PCIEBAR_1 {0x00000000} \ +CONFIG.AXIBAR2PCIEBAR_2 {0x00000000} \ +CONFIG.AXIBAR2PCIEBAR_3 {0x00000000} \ +CONFIG.AXIBAR2PCIEBAR_4 {0x00000000} \ +CONFIG.AXIBAR2PCIEBAR_5 {0x00000000} \ +CONFIG.AXIBAR_0 {0x60000000} \ +CONFIG.AXIBAR_1 {0xFFFFFFFF} \ +CONFIG.AXIBAR_2 {0xFFFFFFFF} \ +CONFIG.AXIBAR_3 {0xFFFFFFFF} \ +CONFIG.AXIBAR_4 {0xFFFFFFFF} \ +CONFIG.AXIBAR_5 {0xFFFFFFFF} \ +CONFIG.AXIBAR_AS_0 {true} \ +CONFIG.AXIBAR_AS_1 {false} \ +CONFIG.AXIBAR_AS_2 {false} \ +CONFIG.AXIBAR_AS_3 {false} \ +CONFIG.AXIBAR_AS_4 {false} \ +CONFIG.AXIBAR_AS_5 {false} \ +CONFIG.AXIBAR_HIGHADDR_0 {0x7FFFFFFF} \ +CONFIG.AXIBAR_HIGHADDR_1 {0x00000000} \ +CONFIG.AXIBAR_HIGHADDR_2 {0x00000000} \ +CONFIG.AXIBAR_HIGHADDR_3 {0x00000000} \ +CONFIG.AXIBAR_HIGHADDR_4 {0x00000000} \ +CONFIG.AXIBAR_HIGHADDR_5 {0x00000000} \ +CONFIG.AXIBAR_NUM {1} \ +CONFIG.BAR0_ENABLED {true} \ +CONFIG.BAR0_SCALE {Gigabytes} \ +CONFIG.BAR0_SIZE {4} \ +CONFIG.BAR0_TYPE {Memory} \ +CONFIG.BAR1_ENABLED {false} \ +CONFIG.BAR1_SCALE {N/A} \ +CONFIG.BAR1_SIZE {8} \ +CONFIG.BAR1_TYPE {N/A} \ +CONFIG.BAR2_ENABLED {false} \ +CONFIG.BAR2_SCALE {N/A} \ +CONFIG.BAR2_SIZE {8} \ +CONFIG.BAR2_TYPE {N/A} \ +CONFIG.BAR_64BIT {true} \ +CONFIG.BASEADDR {0x50000000} \ +CONFIG.BASE_CLASS_MENU {Bridge_device} \ +CONFIG.CLASS_CODE {0x060400} \ +CONFIG.COMP_TIMEOUT {50ms} \ +CONFIG.Component_Name {design_1_axi_pcie_1_0} \ +CONFIG.DEVICE_ID {0x7111} \ +CONFIG.ENABLE_CLASS_CODE {true} \ +CONFIG.HIGHADDR {0x53FFFFFF} \ +CONFIG.INCLUDE_BAROFFSET_REG {true} \ +CONFIG.INCLUDE_RC {Root_Port_of_PCI_Express_Root_Complex} \ +CONFIG.INTERRUPT_PIN {false} \ +CONFIG.MAX_LINK_SPEED {2.5_GT/s} \ +CONFIG.MSI_DECODE_ENABLED {true} \ +CONFIG.M_AXI_ADDR_WIDTH {32} \ +CONFIG.M_AXI_DATA_WIDTH {64} \ +CONFIG.NO_OF_LANES {X1} \ +CONFIG.NUM_MSI_REQ {0} \ +CONFIG.PCIEBAR2AXIBAR_0_SEC {1} \ +CONFIG.PCIEBAR2AXIBAR_0 {0x00000000} \ +CONFIG.PCIEBAR2AXIBAR_1 {0xFFFFFFFF} \ +CONFIG.PCIEBAR2AXIBAR_1_SEC {1} \ +CONFIG.PCIEBAR2AXIBAR_2 {0xFFFFFFFF} \ +CONFIG.PCIEBAR2AXIBAR_2_SEC {1} \ +CONFIG.PCIE_BLK_LOCN {X1Y1} \ +CONFIG.PCIE_USE_MODE {GES_and_Production} \ +CONFIG.REF_CLK_FREQ {100_MHz} \ +CONFIG.REV_ID {0x00} \ +CONFIG.SLOT_CLOCK_CONFIG {true} \ +CONFIG.SUBSYSTEM_ID {0x0007} \ +CONFIG.SUBSYSTEM_VENDOR_ID {0x10EE} \ +CONFIG.SUB_CLASS_INTERFACE_MENU {Host_bridge} \ +CONFIG.S_AXI_ADDR_WIDTH {32} \ +CONFIG.S_AXI_DATA_WIDTH {64} \ +CONFIG.S_AXI_ID_WIDTH {4} \ +CONFIG.S_AXI_SUPPORTS_NARROW_BURST {false} \ +CONFIG.VENDOR_ID {0x10EE} \ +CONFIG.XLNX_REF_BOARD {None} \ +CONFIG.axi_aclk_loopback {false} \ +CONFIG.en_ext_ch_gt_drp {false} \ +CONFIG.en_ext_clk {false} \ +CONFIG.en_ext_gt_common {false} \ +CONFIG.en_ext_pipe_interface {false} \ +CONFIG.en_transceiver_status_ports {false} \ +CONFIG.no_slv_err {false} \ +CONFIG.rp_bar_hide {true} \ +CONFIG.shared_logic_in_core {false} ] [get_ips vc707axi_to_pcie_x1] + +#Coreplex clock generator +create_ip -name clk_wiz -vendor xilinx.com -library ip -version 5.3 -module_name vc707clk_wiz_sync -dir $ipdir -force +set_property -dict [list \ + CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \ + CONFIG.PRIM_SOURCE {No_buffer} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {true} \ + CONFIG.CLKOUT4_USED {true} \ + CONFIG.CLKOUT5_USED {true} \ + CONFIG.CLKOUT6_USED {true} \ + CONFIG.CLKOUT7_USED {true} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {12.5} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {25} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {37.5} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {50} \ + CONFIG.CLKOUT5_REQUESTED_OUT_FREQ {100} \ + CONFIG.CLKOUT6_REQUESTED_OUT_FREQ {150.000} \ + CONFIG.CLKOUT7_REQUESTED_OUT_FREQ {75} \ + CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \ + CONFIG.PRIM_IN_FREQ {200.000} \ + CONFIG.CLKIN1_JITTER_PS {50.0} \ + CONFIG.MMCM_DIVCLK_DIVIDE {1} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {4.500} \ + CONFIG.MMCM_CLKIN1_PERIOD {5.0} \ + CONFIG.MMCM_CLKOUT0_DIVIDE_F {72.000} \ + CONFIG.MMCM_CLKOUT1_DIVIDE {36} \ + CONFIG.MMCM_CLKOUT2_DIVIDE {24} \ + CONFIG.MMCM_CLKOUT3_DIVIDE {18} \ + CONFIG.MMCM_CLKOUT4_DIVIDE {9} \ + CONFIG.MMCM_CLKOUT5_DIVIDE {6} \ + CONFIG.MMCM_CLKOUT6_DIVIDE {12} \ + CONFIG.NUM_OUT_CLKS {7} \ + CONFIG.CLKOUT1_JITTER {168.247} \ + CONFIG.CLKOUT1_PHASE_ERROR {91.235} \ + CONFIG.CLKOUT2_JITTER {146.624} \ + CONFIG.CLKOUT2_PHASE_ERROR {91.235} \ + CONFIG.CLKOUT3_JITTER {135.178} \ + CONFIG.CLKOUT3_PHASE_ERROR {91.235} \ + CONFIG.CLKOUT4_JITTER {127.364} \ + CONFIG.CLKOUT4_PHASE_ERROR {91.235} \ + CONFIG.CLKOUT5_JITTER {110.629} \ + CONFIG.CLKOUT5_PHASE_ERROR {91.235} \ + CONFIG.CLKOUT6_JITTER {102.207} \ + CONFIG.CLKOUT6_PHASE_ERROR {91.235} \ + CONFIG.CLKOUT7_JITTER {117.249} \ + CONFIG.CLKOUT7_PHASE_ERROR {91.235}] [get_ips vc707clk_wiz_sync] diff --git a/xilinx/vc707/tcl/mig.prj b/xilinx/vc707/tcl/mig.prj new file mode 100644 index 0000000..e105154 --- /dev/null +++ b/xilinx/vc707/tcl/mig.prj @@ -0,0 +1,202 @@ + + + + vc707mig + 1 + 1 + OFF + 1024 + ON + Enabled + xc7vx485t-ffg1761/-2 + 3.0 + No Buffer + Use System Clock + ACTIVE HIGH + FALSE + 0 + 50 Ohms + 0 + + DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6 + 1250 + 2.0V + 4:1 + 200 + 0 + 800 + 1.000 + 1 + 1 + 1 + 1 + 64 + 1 + 1 + Disabled + Normal + FALSE + + 14 + 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 + 30 + 64 + 4 + 0 + + + + diff --git a/xilinx/vc707/vsrc/sdio.v b/xilinx/vc707/vsrc/sdio.v new file mode 100644 index 0000000..ff7ebc8 --- /dev/null +++ b/xilinx/vc707/vsrc/sdio.v @@ -0,0 +1,59 @@ +// See LICENSE for license details. +`timescale 1ns/1ps +`default_nettype none + +module sdio_spi_bridge ( + input wire clk, + input wire reset, + // SDIO + inout wire sd_cmd, + inout wire [3:0] sd_dat, + output wire sd_sck, + // QUAD SPI + input wire spi_sck, + input wire [3:0] spi_dq_o, + output wire [3:0] spi_dq_i, + output wire spi_cs +); + + wire mosi, miso; + reg miso_sync [1:0]; + + assign mosi = spi_dq_o[0]; + assign spi_dq_i = {2'b00, miso_sync[1], 1'b0}; + + assign sd_sck = spi_sck; + + IOBUF buf_cmd ( + .IO(sd_cmd), + .I(mosi), + .O(), + .T(1'b0) + ); + + IOBUF buf_dat0 ( + .IO(sd_dat[0]), + .I(), + .O(miso), + .T(1'b1) + ); + + IOBUF buf_dat3 ( + .IO(sd_dat[3]), + .I(spi_cs), + .O(), + .T(1'b0) + ); + + always @(posedge clk) begin + if (reset) begin + miso_sync[0] <= 1'b0; + miso_sync[1] <= 1'b0; + end else begin + miso_sync[0] <= miso; + miso_sync[1] <= miso_sync[0]; + end + end +endmodule + +`default_nettype wire diff --git a/xilinx/vc707/vsrc/vc707reset.v b/xilinx/vc707/vsrc/vc707reset.v new file mode 100644 index 0000000..8501027 --- /dev/null +++ b/xilinx/vc707/vsrc/vc707reset.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 vc707reset( + // 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