Skip to content

Add support for Xilinx Virtex-7 FPGA VC709 board #160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
351a6de
add support for vc709 in fpga-shells
mbs0221 Feb 1, 2021
4c26de2
add support for vc709
mbs0221 Feb 2, 2021
9f2252d
support for two memory controllers
mbs0221 Feb 6, 2021
f58eef3
add support for PCIe and DDR3 in Xilinx vc709
mbs0221 Feb 6, 2021
e6f890d
add support for dual memory channels
mbs0221 Feb 6, 2021
8ef984c
support two memory channels
mbs0221 Feb 6, 2021
cd7e3ca
support pcie for vc709 board
mbs0221 Mar 2, 2021
423d0f7
update DDR3Overlay
mbs0221 Mar 4, 2021
ce62c04
support PCIeX8 for vc709
mbs0221 Mar 8, 2021
ab19d86
update support for vc709 board
mbs0221 Mar 13, 2021
ca1182a
update support for PCIe Endpoint Device ip
mbs0221 Mar 17, 2021
891b7ab
update support for PCIe Endpoint Device
mbs0221 Mar 17, 2021
77cf5e0
support I2C for vc709
mbs0221 Mar 18, 2021
7bde86f
updata support PCIe in vc709
mbs0221 Mar 20, 2021
03f1381
revert mofification of vc707
mbs0221 Mar 25, 2021
db60f06
remove irrelavent files
mbs0221 Mar 25, 2021
c6d0a67
update ios.tcl
mbs0221 Mar 25, 2021
1b6f6d3
add tcl scripts for uploading and booting from mcs files
mbs0221 Mar 27, 2021
9f1ca65
update PCIe support for vc709
mbs0221 Apr 1, 2021
7ee68ad
update support for pcie
mbs0221 Apr 1, 2021
6775874
update support for PCIe
mbs0221 Apr 1, 2021
0142088
update support for PCIe
mbs0221 Apr 1, 2021
6428e4a
update VC709NewShell
mbs0221 Aug 1, 2021
f354403
Merge branch 'vc709-dev' of https://github.com/mbs0221/fpga-shells in…
mbs0221 Aug 1, 2021
f67e638
update I2C module
mbs0221 Aug 27, 2021
17bb3ee
update support for vc709mig
mbs0221 Sep 1, 2021
1488d0a
Merge branch 'vc709-dev' of https://github.com/mbs0221/fpga-shells in…
mbs0221 Sep 24, 2021
ad40b2b
fix dual MIGs
mbs0221 Nov 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions src/main/scala/devices/xilinx/xilinxvc709mig/XilinxVC709MIG.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// See LICENSE for license details.
package sifive.fpgashells.devices.xilinx.xilinxvc709mig

import Chisel._
import chisel3.experimental.{Analog,attach}
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts._
import sifive.fpgashells.ip.xilinx.vc709mig.{VC709MIGIOClocksReset, VC709MIGIODDR, vc709mig}

case class XilinxVC709MIGParams(
address : Seq[AddressSet]
)

class XilinxVC709MIGPads(depth : BigInt) extends VC709MIGIODDR(depth) {
def this(c : XilinxVC709MIGParams) {
this(AddressRange.fromSets(c.address).head.size)
}
}

class XilinxVC709MIGIO(depth : BigInt) extends VC709MIGIODDR(depth) with VC709MIGIOClocksReset

class XilinxVC709MIGIsland(c : XilinxVC709MIGParams)(implicit p: Parameters) extends LazyModule with CrossesToOnlyOneClockDomain {
val ranges = AddressRange.fromSets(c.address)
require (ranges.size == 1, "DDR range must be contiguous")
val offset = ranges.head.base
val depth = ranges.head.size
val crossing = AsynchronousCrossing(8)
require((depth<=0x100000000L),"vc709mig supports upto 4GB depth configuraton")

val device = new MemoryDevice
val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters(
address = c.address,
resources = device.reg,
regionType = RegionType.UNCACHED,
executable = true,
supportsWrite = TransferSizes(1, 128),
supportsRead = TransferSizes(1, 128))),
beatBytes = 8)))

lazy val module = new LazyRawModuleImp(this) {
val io = IO(new Bundle {
val port = new XilinxVC709MIGIO(depth)
})

childClock := io.port.ui_clk
childReset := io.port.ui_clk_sync_rst

//MIG black box instantiation
val blackbox = Module(new vc709mig(depth))
val (axi_async, _) = node.in(0)

//pins to top level

//inouts
//#[DDR3 SODIMM 0]
attach(io.port.ddr3_dq,blackbox.io.ddr3_dq)
attach(io.port.ddr3_dqs_n,blackbox.io.ddr3_dqs_n)
attach(io.port.ddr3_dqs_p,blackbox.io.ddr3_dqs_p)

//outputs
//#[DDR3 SODIMM 0]
io.port.ddr3_addr := blackbox.io.ddr3_addr
io.port.ddr3_ba := blackbox.io.ddr3_ba
io.port.ddr3_ras_n := blackbox.io.ddr3_ras_n
io.port.ddr3_cas_n := blackbox.io.ddr3_cas_n
io.port.ddr3_we_n := blackbox.io.ddr3_we_n
io.port.ddr3_reset_n := blackbox.io.ddr3_reset_n
io.port.ddr3_ck_p := blackbox.io.ddr3_ck_p
io.port.ddr3_ck_n := blackbox.io.ddr3_ck_n
io.port.ddr3_cke := blackbox.io.ddr3_cke
io.port.ddr3_cs_n := blackbox.io.ddr3_cs_n
io.port.ddr3_dm := blackbox.io.ddr3_dm
io.port.ddr3_odt := blackbox.io.ddr3_odt

//inputs
//NO_BUFFER clock
blackbox.io.sys_clk_i := io.port.sys_clk_i

//#[DDR3 SODIMM 0]
io.port.ui_clk := blackbox.io.ui_clk
io.port.ui_clk_sync_rst := blackbox.io.ui_clk_sync_rst
io.port.mmcm_locked := blackbox.io.mmcm_locked
blackbox.io.aresetn := io.port.aresetn
blackbox.io.app_sr_req := Bool(false)
blackbox.io.app_ref_req := Bool(false)
blackbox.io.app_zq_req := Bool(false)
//app_sr_active := unconnected
//app_ref_ack := unconnected
//app_zq_ack := unconnected

val awaddr = axi_async.aw.bits.addr - UInt(offset)
val araddr = axi_async.ar.bits.addr - UInt(offset)

// [DDR3 SODIMM 0]
//slave AXI interface write address ports
blackbox.io.s_axi_awid := axi_async.aw.bits.id
blackbox.io.s_axi_awaddr := awaddr //truncated
blackbox.io.s_axi_awlen := axi_async.aw.bits.len
blackbox.io.s_axi_awsize := axi_async.aw.bits.size
blackbox.io.s_axi_awburst := axi_async.aw.bits.burst
blackbox.io.s_axi_awlock := axi_async.aw.bits.lock
blackbox.io.s_axi_awcache := UInt("b0011")
blackbox.io.s_axi_awprot := axi_async.aw.bits.prot
blackbox.io.s_axi_awqos := axi_async.aw.bits.qos
blackbox.io.s_axi_awvalid := axi_async.aw.valid
axi_async.aw.ready := blackbox.io.s_axi_awready

//slave interface write data ports
blackbox.io.s_axi_wdata := axi_async.w.bits.data
blackbox.io.s_axi_wstrb := axi_async.w.bits.strb
blackbox.io.s_axi_wlast := axi_async.w.bits.last
blackbox.io.s_axi_wvalid := axi_async.w.valid
axi_async.w.ready := blackbox.io.s_axi_wready

//slave interface write response
blackbox.io.s_axi_bready := axi_async.b.ready
axi_async.b.bits.id := blackbox.io.s_axi_bid
axi_async.b.bits.resp := blackbox.io.s_axi_bresp
axi_async.b.valid := blackbox.io.s_axi_bvalid

//slave AXI interface read address ports
blackbox.io.s_axi_arid := axi_async.ar.bits.id
blackbox.io.s_axi_araddr := araddr // truncated
blackbox.io.s_axi_arlen := axi_async.ar.bits.len
blackbox.io.s_axi_arsize := axi_async.ar.bits.size
blackbox.io.s_axi_arburst := axi_async.ar.bits.burst
blackbox.io.s_axi_arlock := axi_async.ar.bits.lock
blackbox.io.s_axi_arcache := UInt("b0011")
blackbox.io.s_axi_arprot := axi_async.ar.bits.prot
blackbox.io.s_axi_arqos := axi_async.ar.bits.qos
blackbox.io.s_axi_arvalid := axi_async.ar.valid

axi_async.ar.ready := blackbox.io.s_axi_arready

//slace AXI interface read data ports
blackbox.io.s_axi_rready := axi_async.r.ready
axi_async.r.bits.id := blackbox.io.s_axi_rid
axi_async.r.bits.data := blackbox.io.s_axi_rdata
axi_async.r.bits.resp := blackbox.io.s_axi_rresp
axi_async.r.bits.last := blackbox.io.s_axi_rlast
axi_async.r.valid := blackbox.io.s_axi_rvalid

//misc
io.port.init_calib_complete := blackbox.io.init_calib_complete

blackbox.io.sys_rst :=io.port.sys_rst
//mig.device_temp_i :- unconnected
//mig.device_temp :- unconnceted
}
}

class XilinxVC709MIG(c : XilinxVC709MIGParams)(implicit p: Parameters) extends LazyModule {
val ranges = AddressRange.fromSets(c.address)
val depth = ranges.head.size

// The data follows from top to down
val buffer = LazyModule(new TLBuffer)
val toaxi4 = LazyModule(new TLToAXI4(adapterName = Some("mem")))
val indexer = LazyModule(new AXI4IdIndexer(idBits = 4))
val deint = LazyModule(new AXI4Deinterleaver(p(CacheBlockBytes)))
val yank = LazyModule(new AXI4UserYanker)
val island = LazyModule(new XilinxVC709MIGIsland(c))

val node: TLInwardNode =
island.crossAXI4In(island.node) := yank.node := deint.node := indexer.node := toaxi4.node := buffer.node

lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val port = new XilinxVC709MIGIO(depth)
})

io.port <> island.module.io.port
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// See LICENSE for license details.
package sifive.fpgashells.devices.xilinx.xilinxvc709mig

import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange}

case object MemoryXilinxDDRKey extends Field[XilinxVC709MIGParams]

trait HasMemoryXilinxVC709MIG { this: BaseSubsystem =>
val module: HasMemoryXilinxVC709MIGModuleImp

val xilinxvc709mig = LazyModule(new XilinxVC709MIG(p(MemoryXilinxDDRKey)))

xilinxvc709mig.node := mbus.toDRAMController(Some("xilinxvc709mig"))()
}

trait HasMemoryXilinxVC709MIGBundle {
val xilinxvc709mig: XilinxVC709MIGIO
def connectXilinxVC709MIGToPads(pads: XilinxVC709MIGPads) {
pads <> xilinxvc709mig
}
}

trait HasMemoryXilinxVC709MIGModuleImp extends LazyModuleImp
with HasMemoryXilinxVC709MIGBundle {
val outer: HasMemoryXilinxVC709MIG
val ranges = AddressRange.fromSets(p(MemoryXilinxDDRKey).address)
require (ranges.size == 1, "DDR range must be contiguous")
val depth = ranges.head.size
val xilinxvc709mig = IO(new XilinxVC709MIGIO(depth))

xilinxvc709mig <> outer.xilinxvc709mig.module.io.port
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// See LICENSE for license details.
package sifive.fpgashells.devices.xilinx.xilinxvc709pcie

import Chisel._
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.subsystem.{CrossesToOnlyOneClockDomain, CacheBlockBytes}
import sifive.fpgashells.ip.xilinx.vc709axi_to_pcie.{VC709AXIToPCIe, VC709AXIToPCIeIOClocksReset, VC709AXIToPCIeIOSerial}
import sifive.fpgashells.ip.xilinx.ibufds_gte2.IBUFDS_GTE2

trait VC709AXIToPCIeRefClk extends Bundle{
val REFCLK_rxp = Bool(INPUT)
val REFCLK_rxn = Bool(INPUT)
}

class XilinxVC709PCIePads extends Bundle
with VC709AXIToPCIeIOSerial
with VC709AXIToPCIeRefClk

class XilinxVC709PCIeIO extends Bundle
with VC709AXIToPCIeRefClk
with VC709AXIToPCIeIOSerial
with VC709AXIToPCIeIOClocksReset {
val axi_ctl_aresetn = Bool(INPUT)
}

class XilinxVC709PCIe(implicit p: Parameters, val crossing: ClockCrossingType = AsynchronousCrossing(8))
extends LazyModule with CrossesToOnlyOneClockDomain
{
val axi_to_pcie = LazyModule(new VC709AXIToPCIe)

val slave: TLInwardNode =
(axi_to_pcie.slave
:= AXI4Buffer()
:= AXI4UserYanker()
:= AXI4Deinterleaver(p(CacheBlockBytes))
:= AXI4IdIndexer(idBits=4)
:= TLToAXI4(adapterName = Some("pcie-slave")))

val control: TLInwardNode =
(axi_to_pcie.control
:= AXI4Buffer()
:= AXI4UserYanker(capMaxFlight = Some(2))
:= TLToAXI4()
:= TLFragmenter(4, p(CacheBlockBytes), holdFirstDeny = true))

val master: TLOutwardNode =
(TLWidthWidget(8)
:= AXI4ToTL()
:= AXI4UserYanker(capMaxFlight=Some(8))
:= AXI4Fragmenter()
:= axi_to_pcie.master)

val intnode: IntOutwardNode = axi_to_pcie.intnode

lazy val module = new LazyRawModuleImp(this) {
val io = IO(new Bundle {
val port = new XilinxVC709PCIeIO
})

childClock := io.port.axi_aclk // axi_aclk_out is changed to axi_aclk
childReset := ~io.port.axi_aresetn //

io.port <> axi_to_pcie.module.io.port

//PCIe Reference Clock
val ibufds_gte2 = Module(new IBUFDS_GTE2)
axi_to_pcie.module.io.refclk := ibufds_gte2.io.O // REFCLK is changed to refclk
ibufds_gte2.io.CEB := UInt(0)
ibufds_gte2.io.I := io.port.REFCLK_rxp
ibufds_gte2.io.IB := io.port.REFCLK_rxn
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// See LICENSE for license details.
package sifive.fpgashells.devices.xilinx.xilinxvc709pcie

import Chisel._
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams}
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts.IntSyncCrossingSink

trait HasSystemXilinxVC709PCIe { this: BaseSubsystem =>
val xilinxvc709pcie = LazyModule(new XilinxVC709PCIe)
private val cname = "xilinxvc709pcie"
sbus.coupleFrom(s"master_named_$cname") { _ :=* TLFIFOFixer(TLFIFOFixer.all) :=* xilinxvc709pcie.crossTLOut(xilinxvc709pcie.master) }
sbus.coupleTo(s"slave_named_$cname") { xilinxvc709pcie.crossTLIn(xilinxvc709pcie.slave) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
sbus.coupleTo(s"controller_named_$cname") { xilinxvc709pcie.crossTLIn(xilinxvc709pcie.control) :*= TLWidthWidget(sbus.beatBytes) :*= _ }
ibus.fromSync := xilinxvc709pcie.crossIntOut(xilinxvc709pcie.intnode)
}

trait HasSystemXilinxVC709PCIeBundle {
val xilinxvc709pcie: XilinxVC709PCIeIO
def connectXilinxVC709PCIeToPads(pads: XilinxVC709PCIePads) {
pads <> xilinxvc709pcie
}
}

trait HasSystemXilinxVC709PCIeModuleImp extends LazyModuleImp
with HasSystemXilinxVC709PCIeBundle {
val outer: HasSystemXilinxVC709PCIe
val xilinxvc709pcie = IO(new XilinxVC709PCIeIO)

xilinxvc709pcie <> outer.xilinxvc709pcie.module.io.port
}
Loading