1
0

Compare commits

..

35 Commits

Author SHA1 Message Date
b49f5cfa78 Reduce crossing and queue depths to save space and ease timing 2018-05-14 20:07:01 +02:00
700e6b640d Document address extraction for the mig 2018-05-13 19:52:38 +02:00
12cb1c2fa5 Implement XilinxML507MIGToTL TL to MIG converter 2018-05-10 21:40:52 +02:00
7e53be49f9 Fix memory controller signal name 2018-05-10 02:27:31 +02:00
77694a6741 Add clock generation for the mig 2018-05-10 01:04:52 +02:00
589e9960c0 Move XilinxML507MIGToTL and MIG into a separate clock domain 2018-05-10 00:30:23 +02:00
2707fa59a4 Add XilinxML507MIG periphery and connect top level signals 2018-05-10 00:29:22 +02:00
3797385a8c Import ml507 mig TL implementation stub 2018-05-09 23:17:08 +02:00
79b53cf2ae Add dip switches and clean up top interface 2018-05-01 00:07:58 +02:00
5bcc4e82fd Generate separate processor and terminal clocks 2018-04-30 22:52:02 +02:00
9c06418352 Add terminal/dvi io (unsing the same clock for now) 2018-04-30 00:41:05 +02:00
b2b19cc822 Add clock and proper reset feedback to ml507 2018-04-19 01:29:15 +02:00
5db71d11c2 Fix polarity of buttons and dips on the ml507 2018-04-19 01:28:36 +02:00
f4ae1d469f Remove unused signals (pcie, mem) from ml507 shell 2018-04-19 01:27:35 +02:00
0b421d5645 Remove incorrect jtag pin constraints form ml507 2018-04-19 01:26:15 +02:00
8329b232e2 Hold ml507 in reset while clock not locked 2018-04-19 01:25:31 +02:00
2ff28e6af6 Add status indication led for the reset button 2018-04-18 00:26:43 +02:00
41362a1cb5 Remove unused UART signals (rs and cs) from ml507 2018-04-18 00:26:00 +02:00
e9625bf8ee Add initial ML507Shell stub based on VC707Shell 2018-04-12 00:42:46 +02:00
9d02f530fc vc707shell: work-around too many '++'s => stack overflow issue 2018-03-22 18:08:32 -07:00
080119ec7a chiplink: add pinout (#20) 2018-03-22 17:13:25 -07:00
0ca9f2bb66 periphery: bus api update (#17)
* periphery: bus api update

* Update XilinxVC707MIGPeriphery.scala
2018-03-01 01:16:04 -08:00
1dda525578 prologue: support the absence of an xdc/tcl constraint file 2018-02-25 15:21:03 -08:00
6df6db25de Merge pull request #18 from sifive/dynamic-clock-groups
Dynamic clock groups -- fixes timing closure problem for vc707 designs without ChipLink
2018-02-25 15:08:15 -08:00
4386187016 vc707: add clock groups dynamically iff they exist 2018-02-25 14:33:32 -08:00
b7afc83a34 xilinx prologue: support tcl for constraints 2018-02-25 14:32:39 -08:00
17e13a3a50 Merge pull request #16 from sifive/chiplink-100
Chiplink 100
2018-02-08 15:40:16 -08:00
8519ba8d4e vc707: setup 100MHz PLL 2018-02-08 07:21:45 -08:00
506d2da883 vc707: update constraints to match correct mmcm 2018-02-08 07:21:45 -08:00
9c38f20333 vc707 axi: move addresses to line up with ChipLink 2018-02-08 07:21:44 -08:00
61ece0bf00 VC707 Shell : additional skewed clocks 2018-02-08 07:21:44 -08:00
0fdbb778bf VC707 Shell : move DebugJTAG pins and connect function into a separate mix-in 2018-02-08 07:21:44 -08:00
045b290fbd VC707 JTAG support throught XM105 FMC or reuse of LCD header 2018-02-08 07:21:44 -08:00
f9dc552ddc Xilinx unisim typo 2018-02-08 07:21:44 -08:00
33c88b8cc4 Move Xilinx unisims into separate file 2018-02-08 07:21:44 -08:00
14 changed files with 1326 additions and 163 deletions

View File

@ -0,0 +1,199 @@
// See LICENSE.SiFive for license details.
package sifive.fpgashells.devices.xilinx.xilinxml507mig
import Chisel._
import chisel3.core.{Input, Output}
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.{AsynchronousCrossing, HasCrossing}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
case class XilinxML507MIGParams(
address: Seq[AddressSet]
)
class MemoryController extends BlackBox {
val io = IO(new Bundle {
val sys = new MemorySysIO
val ddr2 = new MemoryDDR2IO
val request_addr = Input(UInt(28.W))
val request_type = Input(Bool())
val request_data = Input(UInt(256.W))
val request_mask = Input(UInt(32.W))
val request_valid = Input(Bool())
val request_ready = Output(Bool())
val response_data = Output(UInt(256.W))
val response_valid = Output(Bool())
// no ready, as the mig does not wait
})
override def desiredName: String = "memory_controller"
}
class ResponseQueueIO extends Bundle {
val read = Bool()
val source = UInt()
val size = UInt()
}
class XilinxML507MIGToTL(c: XilinxML507MIGParams)(implicit p: Parameters) extends LazyModule with HasCrossing {
// Corresponds to MIG interface with 64 bit width and a burst length of 4
val width = 256
val beatBytes = width/8 // 32 byte (half a cache-line, fragmented)
val address_range = AddressRange.fromSets(c.address).head
require(log2Ceil(address_range.size) == 28, "Max 256MiB DIMMs supported")
val crossing = AsynchronousCrossing(1)
val device = new MemoryDevice
val node = TLManagerNode(
Seq(TLManagerPortParameters(
Seq(TLManagerParameters(
address = c.address,
resources = device.reg,
regionType = RegionType.UNCACHED,
executable = true,
supportsGet = TransferSizes(1, beatBytes),
supportsPutFull = TransferSizes(1, beatBytes),
fifoId = Some(0) // in-order
)),
beatBytes = beatBytes
))
)
// We could possibly also support supportsPutPartial, as we need support
// for masks anyway because of the possibility of transfers smaller that
// the data width (size signal, see below).
// Seems we can: TL$7.3
lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val port_sys = new MemorySysIO
val port_ddr2 = new MemoryDDR2IO
})
val controller = Module(new MemoryController)
io.port_sys <> controller.io.sys
io.port_ddr2 <> controller.io.ddr2
// in: TLBundle, edge: TLEdgeIn
val (in, edge) = node.in(0)
// Due to the TLFragmenter defined below, all messages are 32 bytes or
// smaller. The data signal of the TL channels is also 32 bytes, so
// all messages will be transfered in a single beat.
// Also, TL guarantees (see TL$4.6) that the payload of a data message
// is always aligned to the width of the beat, e.g. in case of a 32
// byte data signal, data[7:0] will always have address 0x***00000 and
// data[255:247] address 0x***11111. It is also guaranteed that the
// mask bits always correctly reflect the active bytes inside the beat
// with respect to the size and address. So we can directly forward
// the mask, (relative) address and data to the MIG interface.
// An AddressSet is always aligned, so we don't need to subtract the
// base address, we can just take the lower bits. The lowest 5 bits
// are used for indexing the 32 byte word of the MIG.
val address = in.a.bits.address(27, 0) & "hFFFFFE0".U
// Save the source, size and type of the requests in a queue so we
// can synthesize the right responses in fifo order. The length also
// determines the maximum number of in-flight requests.
val ack_queue = Module(new Queue(new ResponseQueueIO, 2))
// Pass data directly to the controller
controller.io.request_addr := address
controller.io.request_type := !edge.hasData(in.a.bits)
controller.io.request_data := in.a.bits.data
// TL uses high to indicate valid data while mig uses low
controller.io.request_mask := ~ in.a.bits.mask
ack_queue.io.enq.bits.read := !edge.hasData(in.a.bits)
ack_queue.io.enq.bits.source := in.a.bits.source
ack_queue.io.enq.bits.size := in.a.bits.size
// We are ready when the controller and the queue input are ready
in.a.ready := controller.io.request_ready && ack_queue.io.enq.ready
// Both queues only latch data if the other is ready, so that data
// is latched into both queues or not at all
controller.io.request_valid := in.a.valid && ack_queue.io.enq.ready
ack_queue.io.enq.valid := in.a.valid && controller.io.request_ready
// We have to buffer the responses from the MIG as it has no internal
// buffer and will output its read responses only for one cycle. To
// avoid losing any responses, this queue *must* be at least as wide
// as the ack queue, so that we can catch all responses, even if the
// ack queue is completely filled with read requests.
val response_queue = Module(new Queue(controller.io.response_data, 2))
response_queue.io.enq.bits := controller.io.response_data
response_queue.io.enq.valid := controller.io.response_valid
// MIG does not support delaying a response, so we ignore enq.ready.
// This will result in lost reads and returning wrong data in further
// AccessAckData messages, so this must be avoided (see above).
// Acks may or may not contain data depending on the request, but we
// can always pass the data, even if it is invalid in the write case,
// because it is ignored for AccessAck responses
val response_read = ack_queue.io.deq.bits.read
in.d.bits.opcode := Mux(response_read, TLMessages.AccessAckData, TLMessages.AccessAck)
in.d.bits.param := UInt(0) // reserved, must be 0
in.d.bits.size := ack_queue.io.deq.bits.size
in.d.bits.source := ack_queue.io.deq.bits.source
in.d.bits.sink := UInt(0) // ignored
in.d.bits.data := response_queue.io.deq.bits
in.d.bits.error := Bool(false)
// The data is valid when the ack queue data is valid (write case) or
// when the ack *and* response queues are valid (read case)
in.d.valid := ack_queue.io.deq.valid && (!response_read ||
response_queue.io.deq.valid)
// Let the ack queue dequeue when the master is ready (write case) or
// when the master is ready *and* there is a valid response (read case)
ack_queue.io.deq.ready := in.d.ready && (!response_read ||
response_queue.io.deq.valid)
// Let the response queue dequeue when the master is ready and there
// is a valid read ack waiting
response_queue.io.deq.ready := in.d.ready && response_read &&
ack_queue.io.deq.valid
// Tie off unused channels
in.b.valid := Bool(false)
in.c.ready := Bool(true)
in.e.ready := Bool(true)
}
}
class XilinxML507MIG(c : XilinxML507MIGParams)(implicit p: Parameters) extends LazyModule {
// The Fragmenter will not fragment messages <= 32 bytes, so all
// slaves have to support this size. 64 byte specifies the maximum
// supported transfer size that the slave side of the fragmenter supports
// against the master (here the main memory bus). Specifying alwaysMin as
// true results in all messages being fragmented to the minimal size
// (32 byte). In TL1 terms, slaves correspond roughly to managers and
// masters to clients (confusingly…).
val fragmenter = LazyModule(new TLFragmenter(32, 64, alwaysMin=true))
val island = LazyModule(new XilinxML507MIGToTL(c))
val node: TLInwardNode =
island.node := island.crossTLIn := fragmenter.node
lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val port_sys = new MemorySysIO
val port_ddr2 = new MemoryDDR2IO
})
io.port_sys <> island.module.io.port_sys
io.port_ddr2 <> island.module.io.port_ddr2
// The MIGToTL module lives in a separate clock domain together with
// the MIG, which is why it is called "island".
island.module.clock := io.port_sys.clk0
island.module.reset := io.port_sys.reset
}
}

View File

@ -0,0 +1,58 @@
// See LICENSE.SiFive for license details.
package sifive.fpgashells.devices.xilinx.xilinxml507mig
import Chisel._
import chisel3.core.{Input, Output}
import chisel3.experimental.Analog
import freechips.rocketchip.config.Field
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.BaseSubsystem
case object MemoryML507Key extends Field[XilinxML507MIGParams]
trait HasMemoryML507 { this: BaseSubsystem =>
val memory = LazyModule(new XilinxML507MIG(p(MemoryML507Key)))
memory.node := memBuses.head.toDRAMController(Some("xilinxml507mig"))()
}
class MemorySysIO extends Bundle {
val clk0 = Input(Clock())
val clk90 = Input(Clock())
val clkdiv0 = Input(Clock())
val clk_locked = Input(Bool())
val clk_idelay = Input(Clock())
val reset = Input(Bool())
}
class MemoryDDR2IO extends Bundle {
val dq = Analog(64.W)
val a = Output(Bits(13.W))
val ba = Output(Bits(2.W))
val ras_n = Output(Bits(1.W))
val cas_n = Output(Bits(1.W))
val we_n = Output(Bits(1.W))
val cs_n = Output(Bits(1.W))
val odt = Output(Bits(1.W))
val cke = Output(Bits(1.W))
val dm = Output(Bits(8.W))
val dqs = Analog(8.W)
val dqs_n = Analog(8.W)
val ck = Output(Bits(2.W))
val ck_n = Output(Bits(2.W))
}
trait HasMemoryML507Bundle {
val ddr_sys: MemorySysIO
val ddr2: MemoryDDR2IO
}
trait HasMemoryML507ModuleImp extends LazyModuleImp with HasMemoryML507Bundle {
val outer: HasMemoryML507
val ddr_sys = IO(new MemorySysIO)
val ddr2 = IO(new MemoryDDR2IO)
ddr_sys <> outer.memory.module.io.port_sys
ddr2 <> outer.memory.module.io.port_ddr2
}

View File

@ -5,7 +5,7 @@ import Chisel._
import chisel3.experimental.{Analog,attach} import chisel3.experimental.{Analog,attach}
import freechips.rocketchip.amba.axi4._ import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.config.Parameters import freechips.rocketchip.config.Parameters
import freechips.rocketchip.coreplex._ import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._ import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts._ import freechips.rocketchip.interrupts._

View File

@ -3,18 +3,18 @@ package sifive.fpgashells.devices.xilinx.xilinxvc707mig
import Chisel._ import Chisel._
import freechips.rocketchip.config._ import freechips.rocketchip.config._
import freechips.rocketchip.coreplex.HasMemoryBus import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressRange}
case object MemoryXilinxDDRKey extends Field[XilinxVC707MIGParams] case object MemoryXilinxDDRKey extends Field[XilinxVC707MIGParams]
trait HasMemoryXilinxVC707MIG extends HasMemoryBus { trait HasMemoryXilinxVC707MIG { this: BaseSubsystem =>
val module: HasMemoryXilinxVC707MIGModuleImp val module: HasMemoryXilinxVC707MIGModuleImp
val xilinxvc707mig = LazyModule(new XilinxVC707MIG(p(MemoryXilinxDDRKey))) val xilinxvc707mig = LazyModule(new XilinxVC707MIG(p(MemoryXilinxDDRKey)))
require(nMemoryChannels == 1, "Coreplex must have 1 master memory port") require(nMemoryChannels == 1, "Core complex must have 1 master memory port")
xilinxvc707mig.node := memBuses.head.toDRAMController xilinxvc707mig.node := memBuses.head.toDRAMController(Some("xilinxvc707mig"))()
} }
trait HasMemoryXilinxVC707MIGBundle { trait HasMemoryXilinxVC707MIGBundle {

View File

@ -3,12 +3,11 @@ package sifive.fpgashells.devices.xilinx.xilinxvc707pciex1
import Chisel._ import Chisel._
import freechips.rocketchip.amba.axi4._ import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.coreplex.CacheBlockBytes
import freechips.rocketchip.config.Parameters import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._ import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts._ import freechips.rocketchip.interrupts._
import freechips.rocketchip.coreplex.{HasCrossing,AsynchronousCrossing} import freechips.rocketchip.subsystem.{HasCrossing, AsynchronousCrossing, CacheBlockBytes}
import sifive.fpgashells.ip.xilinx.vc707axi_to_pcie_x1.{VC707AXIToPCIeX1, VC707AXIToPCIeX1IOClocksReset, VC707AXIToPCIeX1IOSerial} import sifive.fpgashells.ip.xilinx.vc707axi_to_pcie_x1.{VC707AXIToPCIeX1, VC707AXIToPCIeX1IOClocksReset, VC707AXIToPCIeX1IOSerial}
import sifive.fpgashells.ip.xilinx.ibufds_gte2.IBUFDS_GTE2 import sifive.fpgashells.ip.xilinx.ibufds_gte2.IBUFDS_GTE2

View File

@ -2,17 +2,17 @@
package sifive.fpgashells.devices.xilinx.xilinxvc707pciex1 package sifive.fpgashells.devices.xilinx.xilinxvc707pciex1
import Chisel._ import Chisel._
import freechips.rocketchip.coreplex.{HasInterruptBus, HasSystemBus}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams}
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.tilelink.{TLAsyncCrossingSource, TLAsyncCrossingSink} import freechips.rocketchip.tilelink.{TLAsyncCrossingSource, TLAsyncCrossingSink}
import freechips.rocketchip.interrupts.IntSyncCrossingSink import freechips.rocketchip.interrupts.IntSyncCrossingSink
trait HasSystemXilinxVC707PCIeX1 extends HasSystemBus with HasInterruptBus { trait HasSystemXilinxVC707PCIeX1 { this: BaseSubsystem =>
val xilinxvc707pcie = LazyModule(new XilinxVC707PCIeX1) val xilinxvc707pcie = LazyModule(new XilinxVC707PCIeX1)
private val name = Some("xilinxvc707pcie")
sbus.fromSyncFIFOMaster(BufferParams.none) := xilinxvc707pcie.crossTLOut := xilinxvc707pcie.master sbus.fromMaster(name) { xilinxvc707pcie.crossTLOut } := xilinxvc707pcie.master
xilinxvc707pcie.slave := xilinxvc707pcie.crossTLIn := sbus.toFixedWidthSlaves xilinxvc707pcie.slave := sbus.toFixedWidthSlave(name) { xilinxvc707pcie.crossTLIn }
xilinxvc707pcie.control := xilinxvc707pcie.crossTLIn := sbus.toFixedWidthSlaves xilinxvc707pcie.control := sbus.toFixedWidthSlave(name) { xilinxvc707pcie.crossTLIn }
ibus.fromSync := xilinxvc707pcie.crossIntOut := xilinxvc707pcie.intnode ibus.fromSync := xilinxvc707pcie.crossIntOut := xilinxvc707pcie.intnode
} }

View File

@ -0,0 +1,320 @@
// See LICENSE for license details.
package sifive.fpgashells.ip.xilinx
import Chisel._
import chisel3.{Input, Output}
import chisel3.experimental.{Analog, attach, StringParam, RawParam, IntParam, DoubleParam}
import sifive.blocks.devices.pinctrl.{BasePin}
object booleanToVerilogVectorParam extends (Boolean => RawParam) {
def apply(b : Boolean) : RawParam = if(b) RawParam("1") else RawParam("0")
}
object booleanToVerilogStringParam extends (Boolean => StringParam) {
def apply(b : Boolean) : StringParam = if(b) StringParam("""TRUE""") else StringParam("""FALSE""")
}
/** IBUFDS -- SelectIO Differential Input */
class IBUFDS(
CAPACITANCE : String = "DONT_CARE",
DIFF_TERM : Boolean = false,
DQS_BIAS : Boolean = false,
IBUF_DELAY_VALUE : Int = 0,
IBUF_LOW_PWR : Boolean = true,
IFD_DELAY_VALUE : String = "AUTO",
IOSTANDARD : String = "DEFAULT"
)
extends BlackBox(
Map(
"CAPACITANCE" -> StringParam(CAPACITANCE),
"DIFF_TERM" -> booleanToVerilogStringParam(DIFF_TERM),
"DQS_BIAS" -> booleanToVerilogStringParam(DQS_BIAS),
"IBUF_DELAY_VALUE" -> IntParam(IBUF_DELAY_VALUE),
"IBUF_LOW_PWR" -> booleanToVerilogStringParam(IBUF_LOW_PWR),
"IFD_DELAY_VALUE" -> StringParam(IFD_DELAY_VALUE),
"IOSTANDARD" -> StringParam(IOSTANDARD)
)
) {
val io = IO(new Bundle {
val O = Bool(OUTPUT)
val I = Bool(INPUT)
val IB = Bool(INPUT)
})
}
/** IBUFG -- Clock Input Buffer */
class IBUFG extends BlackBox {
val io = 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
}
}
/** IBUFDS_GTE2 -- Differential Signaling Input Buffer */
class IBUFDS_GTE2(
CLKCM_CFG : Boolean = true,
CLKRCV_TRST : Boolean = true,
CLKSWING_CFG : Int = 3
)
extends BlackBox(
Map(
"CLKCM_CFG" -> booleanToVerilogStringParam(CLKCM_CFG),
"CLKRCV_TRST" -> booleanToVerilogStringParam(CLKCM_CFG),
"CLKSWING_CFG" -> IntParam(CLKSWING_CFG)
)
) {
val io = IO(new Bundle {
val O = Bool(OUTPUT)
val ODIV2 = Bool(OUTPUT)
val CEB = Bool(INPUT)
val I = Bool(INPUT)
val IB = Bool(INPUT)
})
}
/** IDDR - 7 Series SelectIO DDR flop */
class IDDR(
DDR_CLK_EDGE : String = "OPPOSITE_EDGE",
INIT_Q1 : Boolean = false,
INIT_Q2 : Boolean = false,
IS_C_INVERTED : Boolean = false,
IS_D_INVERTED : Boolean = false,
SRTYPE : String = "SYNC"
)
extends BlackBox(
Map(
"DDR_CLK_EDGE" -> StringParam(DDR_CLK_EDGE),
"INIT_Q1" -> booleanToVerilogVectorParam(INIT_Q1),
"INIT_Q2" -> booleanToVerilogVectorParam(INIT_Q2),
"IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
"IS_D_INVERTED" -> booleanToVerilogVectorParam(IS_D_INVERTED),
"SRTYPE" -> StringParam(SRTYPE)
)
) {
val io = IO(new Bundle {
val Q1 = Output(Bool())
val Q2 = Output(Bool())
val C = Input(Bool())
val CE = Input(Bool())
val D = Input(Bool())
val R = Input(Bool())
val S = Input(Bool())
})
}
/** IDELAYCTRL - 7 Series SelectIO */
class IDELAYCTRL(
sim_device : String = "7SERIES"
)
extends BlackBox(
Map(
"SIM_DEVICE" -> StringParam(sim_device)
)
) {
val io = IO(new Bundle {
val RDY = Output(Bool())
val REFCLK = Input(Bool())
val RST = Input(Bool())
})
}
/** IDELAYE2 -- 7 Series SelectIO ILogic programmable delay. */
class IDELAYE2(
CINVCTRL_SEL : Boolean = false,
DELAY_SRC : String = "IDATAIN",
HIGH_PERFORMANCE_MODE : Boolean = false,
IDELAY_TYPE : String = "FIXED",
IDELAY_VALUE : Int = 0,
IS_C_INVERTED : Boolean = false,
IS_DATAIN_INVERTED : Boolean = false,
IS_IDATAIN_INVERTED : Boolean = false,
PIPE_SEL : Boolean = false,
REFCLK_FREQUENCY : Double = 200.0,
SIGNAL_PATTERN : String = "DATA",
SIM_DELAY_D : Int = 0
)
extends BlackBox(
Map(
"CINVCTRL_SEL" -> booleanToVerilogStringParam(CINVCTRL_SEL),
"DELAY_SRC" -> StringParam(DELAY_SRC),
"HIGH_PERFORMANCE_MODE" -> booleanToVerilogStringParam(HIGH_PERFORMANCE_MODE),
"IDELAY_TYPE" -> StringParam(IDELAY_TYPE),
"IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
"IS_DATAIN_INVERTED" -> booleanToVerilogVectorParam(IS_DATAIN_INVERTED),
"IS_IDATAIN_INVERTED" -> booleanToVerilogVectorParam(IS_IDATAIN_INVERTED),
"PIPE_SEL" -> booleanToVerilogStringParam(PIPE_SEL),
"REFCLK_FREQUENCY" -> DoubleParam(REFCLK_FREQUENCY),
"SIGNAL_PATTERN" -> StringParam(SIGNAL_PATTERN),
"SIM_DELAY_D" -> IntParam(SIM_DELAY_D)
)
) {
val io = IO(new Bundle {
val DATAOUT = Output(Bool())
val CNTVALUEOUT = Output(UInt(5.W))
val C = Input(Bool())
val CE = Input(Bool())
val CINVCTRL = Input(Bool())
val DATAIN = Input(Bool())
val IDATAIN = Input(Bool())
val INC = Input(Bool())
val LD = Input(Bool())
val LDPIPEEN = Input(Bool())
val REGRST = Input(Bool())
val CNTVALUEIN = Input(UInt(5.W))
})
}
/** IOBUF -- Bidirectional IO Buffer. */
//Cannot convert to BlackBox because of line
//val IO = IO(Analog(1.W))
//is illegal
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
}
}
/** ODDR - 7 Series SelectIO DDR flop */
class ODDR(
DDR_CLK_EDGE : String = "OPPOSITE_EDGE",
INIT : Boolean = false,
IS_C_INVERTED : Boolean = false,
IS_D1_INVERTED : Boolean = false,
IS_D2_INVERTED : Boolean = false,
SRTYPE : String = "SYNC"
)
extends BlackBox(
Map(
"DDR_CLK_EDGE" -> StringParam(DDR_CLK_EDGE),
"INIT" -> booleanToVerilogVectorParam(INIT),
"IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
"IS_D1_INVERTED" -> booleanToVerilogVectorParam(IS_D1_INVERTED),
"IS_D2_INVERTED" -> booleanToVerilogVectorParam(IS_D2_INVERTED),
"SRTYPE" -> StringParam(SRTYPE)
)
) {
val io = IO(new Bundle {
val Q = Output(Bool())
val C = Input(Bool())
val CE = Input(Bool())
val D1 = Input(Bool())
val D2 = Input(Bool())
val R = Input(Bool())
val S = Input(Bool())
})
}
/** ODELAYE2 -- 7 Series SelectIO OLogic programmable delay. */
class ODELAYE2(
CINVCTRL_SEL : Boolean = false,
DELAY_SRC : String = "ODATAIN",
HIGH_PERFORMANCE_MODE : Boolean = false,
IS_C_INVERTED : Boolean = false,
IS_ODATAIN_INVERTED : Boolean = false,
ODELAY_TYPE : String = "FIXED",
ODELAY_VALUE : Int = 0,
PIPE_SEL : Boolean = false,
REFCLK_FREQUENCY : Double = 200.0,
SIGNAL_PATTERN : String = "DATA",
SIM_DELAY_D : Int = 0
)
extends BlackBox(
Map(
"CINVCTRL_SEL" -> booleanToVerilogStringParam(CINVCTRL_SEL),
"DELAY_SRC" -> StringParam(DELAY_SRC),
"HIGH_PERFORMANCE_MODE" -> booleanToVerilogStringParam(HIGH_PERFORMANCE_MODE),
"IS_C_INVERTED" -> booleanToVerilogVectorParam(IS_C_INVERTED),
"IS_ODATAIN_INVERTED" -> booleanToVerilogVectorParam(IS_ODATAIN_INVERTED),
"ODELAY_TYPE" -> StringParam(ODELAY_TYPE),
"PIPE_SEL" -> booleanToVerilogStringParam(PIPE_SEL),
"REFCLK_FREQUENCY" -> DoubleParam(REFCLK_FREQUENCY),
"SIGNAL_PATTERN" -> StringParam(SIGNAL_PATTERN),
"SIM_DELAY_D" -> IntParam(SIM_DELAY_D)
)
) {
val io = IO(new Bundle {
val DATAOUT = Output(Bool())
val CNTVALUEOUT = Output(UInt(5.W))
val C = Input(Bool())
val CE = Input(Bool())
val CINVCTRL = Input(Bool())
val CLKIN = Input(Bool())
val INC = Input(Bool())
val LD = Input(Bool())
val LDPIPEEN = Input(Bool())
val ODATAIN = Input(Bool())
val REGRST = Input(Bool())
val CNTVALUEIN = Input(UInt(5.W))
})
}
/** PULLUP : can be applied to Input to add a Pullup. */
class PULLUP extends BlackBox {
val io = 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)
}
}

View File

@ -13,99 +13,6 @@ import sifive.blocks.devices.pinctrl.{BasePin}
// BlackBox modules used in the Xilinx FPGA flows // 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
@ -187,6 +94,37 @@ object PowerOnResetFPGAOnly {
} }
} }
//-------------------------------------------------------------------------
// ml507 clocks (DCM_ADV)
//-------------------------------------------------------------------------
class ml507_sys_clock extends BlackBox {
val io = new Bundle {
val CLKIN_IN = Clock(INPUT)
val CLKFX_OUT = Clock(OUTPUT)
val LOCKED_OUT = Bool(OUTPUT)
}
}
class ml507_dvi_clock extends BlackBox {
val io = new Bundle {
val CLKIN_IN = Clock(INPUT)
val CLKFX_OUT = Clock(OUTPUT)
val LOCKED_OUT = Bool(OUTPUT)
}
}
class ml507_ddr2_clock extends BlackBox {
val io = new Bundle {
val CLKIN_P_IN = Clock(INPUT)
val CLKIN_N_IN = Clock(INPUT)
val CLK0_OUT = Clock(OUTPUT)
val CLK90_OUT = Clock(OUTPUT)
val CLKDV_OUT = Clock(OUTPUT)
val LOCKED_OUT = Bool(OUTPUT)
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// vc707_sys_clock_mmcm // vc707_sys_clock_mmcm
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -303,6 +241,102 @@ class vc707_sys_clock_mmcm1 extends BlackBox {
) )
} }
class vc707_sys_clock_mmcm2 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)
}
ElaborationArtefacts.add(
"vc707_sys_clock_mmcm2.vivado.tcl",
"""create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name vc707_sys_clock_mmcm2 -dir $ipdir -force
set_property -dict [list \
CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \
CONFIG.PRIM_SOURCE {No_buffer} \
CONFIG.CLKOUT1_USED {true} \
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 {100} \
CONFIG.CLKOUT7_REQUESTED_PHASE {180} \
CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \
CONFIG.PRIM_IN_FREQ {200.000} \
CONFIG.CLKIN1_JITTER_PS {50.0} \
CONFIG.MMCM_DIVCLK_DIVIDE {2} \
CONFIG.MMCM_CLKFBOUT_MULT_F {9.0} \
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 {9} \
CONFIG.NUM_OUT_CLKS {7} \
CONFIG.CLKOUT1_JITTER {206.010} \
CONFIG.CLKOUT1_PHASE_ERROR {105.461} \
CONFIG.CLKOUT2_JITTER {180.172} \
CONFIG.CLKOUT2_PHASE_ERROR {105.461} \
CONFIG.CLKOUT3_JITTER {166.503} \
CONFIG.CLKOUT3_PHASE_ERROR {105.461} \
CONFIG.CLKOUT4_JITTER {157.199} \
CONFIG.CLKOUT4_PHASE_ERROR {105.461} \
CONFIG.CLKOUT5_JITTER {136.686} \
CONFIG.CLKOUT5_PHASE_ERROR {105.461} \
CONFIG.CLKOUT6_JITTER {126.399} \
CONFIG.CLKOUT6_PHASE_ERROR {105.461} \
CONFIG.CLKOUT7_JITTER {206.010} \
CONFIG.CLKOUT7_PHASE_ERROR {136.686}] [get_ips vc707_sys_clock_mmcm2] """
)
}
class vc707_sys_clock_mmcm3 extends BlackBox {
val io = new Bundle {
val clk_in1 = Bool(INPUT)
val clk_out1 = Clock(OUTPUT)
val reset = Bool(INPUT)
val locked = Bool(OUTPUT)
}
ElaborationArtefacts.add(
"vc707_sys_clock_mmcm3.vivado.tcl",
"""create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name vc707_sys_clock_mmcm3 -dir $ipdir -force
set_property -dict [list \
CONFIG.PRIM_SOURCE {No_buffer} \
CONFIG.PRIM_IN_FREQ {100} \
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {100} \
CONFIG.CLKOUT1_REQUESTED_PHASE {180} \
CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \
CONFIG.CLKIN1_JITTER_PS {100.0} \
CONFIG.MMCM_DIVCLK_DIVIDE {1} \
CONFIG.MMCM_CLKFBOUT_MULT_F {10.000} \
CONFIG.MMCM_CLKIN1_PERIOD {10.0} \
CONFIG.MMCM_CLKOUT0_DIVIDE_F {10.000} \
CONFIG.MMCM_CLKOUT1_DIVIDE {10} \
CONFIG.MMCM_CLKOUT1_PHASE {180.000} \
CONFIG.NUM_OUT_CLKS {1} \
CONFIG.CLKOUT1_JITTER {130.958} \
CONFIG.CLKOUT1_PHASE_ERROR {98.575}] [get_ips vc707_sys_clock_mmcm3] """
)
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// vc707reset // vc707reset
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

View File

@ -193,7 +193,7 @@ class VC707AXIToPCIeX1(implicit p:Parameters) extends LazyModule
val slave = AXI4SlaveNode(Seq(AXI4SlavePortParameters( val slave = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters( slaves = Seq(AXI4SlaveParameters(
address = List(AddressSet(0x60000000L, 0x1fffffffL)), address = List(AddressSet(0x40000000L, 0x1fffffffL)),
resources = Seq(Resource(device, "ranges")), resources = Seq(Resource(device, "ranges")),
executable = true, executable = true,
supportsWrite = TransferSizes(1, 128), supportsWrite = TransferSizes(1, 128),
@ -202,7 +202,7 @@ class VC707AXIToPCIeX1(implicit p:Parameters) extends LazyModule
val control = AXI4SlaveNode(Seq(AXI4SlavePortParameters( val control = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters( slaves = Seq(AXI4SlaveParameters(
address = List(AddressSet(0x50000000L, 0x03ffffffL)), address = List(AddressSet(0x2000000000L, 0x3ffffffL)), // when truncated to 32-bits, is 0
resources = device.reg("control"), resources = device.reg("control"),
supportsWrite = TransferSizes(1, 4), supportsWrite = TransferSizes(1, 4),
supportsRead = TransferSizes(1, 4), supportsRead = TransferSizes(1, 4),
@ -402,13 +402,13 @@ class VC707AXIToPCIeX1(implicit p:Parameters) extends LazyModule
""" """
create_ip -vendor xilinx.com -library ip -version 2.8 -name axi_pcie -module_name vc707axi_to_pcie_x1 -dir $ipdir -force 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 \ set_property -dict [list \
CONFIG.AXIBAR2PCIEBAR_0 {0x60000000} \ CONFIG.AXIBAR2PCIEBAR_0 {0x40000000} \
CONFIG.AXIBAR2PCIEBAR_1 {0x00000000} \ CONFIG.AXIBAR2PCIEBAR_1 {0x00000000} \
CONFIG.AXIBAR2PCIEBAR_2 {0x00000000} \ CONFIG.AXIBAR2PCIEBAR_2 {0x00000000} \
CONFIG.AXIBAR2PCIEBAR_3 {0x00000000} \ CONFIG.AXIBAR2PCIEBAR_3 {0x00000000} \
CONFIG.AXIBAR2PCIEBAR_4 {0x00000000} \ CONFIG.AXIBAR2PCIEBAR_4 {0x00000000} \
CONFIG.AXIBAR2PCIEBAR_5 {0x00000000} \ CONFIG.AXIBAR2PCIEBAR_5 {0x00000000} \
CONFIG.AXIBAR_0 {0x60000000} \ CONFIG.AXIBAR_0 {0x40000000} \
CONFIG.AXIBAR_1 {0xFFFFFFFF} \ CONFIG.AXIBAR_1 {0xFFFFFFFF} \
CONFIG.AXIBAR_2 {0xFFFFFFFF} \ CONFIG.AXIBAR_2 {0xFFFFFFFF} \
CONFIG.AXIBAR_3 {0xFFFFFFFF} \ CONFIG.AXIBAR_3 {0xFFFFFFFF} \
@ -420,7 +420,7 @@ class VC707AXIToPCIeX1(implicit p:Parameters) extends LazyModule
CONFIG.AXIBAR_AS_3 {false} \ CONFIG.AXIBAR_AS_3 {false} \
CONFIG.AXIBAR_AS_4 {false} \ CONFIG.AXIBAR_AS_4 {false} \
CONFIG.AXIBAR_AS_5 {false} \ CONFIG.AXIBAR_AS_5 {false} \
CONFIG.AXIBAR_HIGHADDR_0 {0x7FFFFFFF} \ CONFIG.AXIBAR_HIGHADDR_0 {0x5FFFFFFF} \
CONFIG.AXIBAR_HIGHADDR_1 {0x00000000} \ CONFIG.AXIBAR_HIGHADDR_1 {0x00000000} \
CONFIG.AXIBAR_HIGHADDR_2 {0x00000000} \ CONFIG.AXIBAR_HIGHADDR_2 {0x00000000} \
CONFIG.AXIBAR_HIGHADDR_3 {0x00000000} \ CONFIG.AXIBAR_HIGHADDR_3 {0x00000000} \
@ -440,14 +440,14 @@ class VC707AXIToPCIeX1(implicit p:Parameters) extends LazyModule
CONFIG.BAR2_SIZE {8} \ CONFIG.BAR2_SIZE {8} \
CONFIG.BAR2_TYPE {N/A} \ CONFIG.BAR2_TYPE {N/A} \
CONFIG.BAR_64BIT {true} \ CONFIG.BAR_64BIT {true} \
CONFIG.BASEADDR {0x50000000} \ CONFIG.BASEADDR {0x00000000} \
CONFIG.BASE_CLASS_MENU {Bridge_device} \ CONFIG.BASE_CLASS_MENU {Bridge_device} \
CONFIG.CLASS_CODE {0x060400} \ CONFIG.CLASS_CODE {0x060400} \
CONFIG.COMP_TIMEOUT {50ms} \ CONFIG.COMP_TIMEOUT {50ms} \
CONFIG.Component_Name {design_1_axi_pcie_1_0} \ CONFIG.Component_Name {design_1_axi_pcie_1_0} \
CONFIG.DEVICE_ID {0x7111} \ CONFIG.DEVICE_ID {0x7111} \
CONFIG.ENABLE_CLASS_CODE {true} \ CONFIG.ENABLE_CLASS_CODE {true} \
CONFIG.HIGHADDR {0x53FFFFFF} \ CONFIG.HIGHADDR {0x03FFFFFF} \
CONFIG.INCLUDE_BAROFFSET_REG {true} \ CONFIG.INCLUDE_BAROFFSET_REG {true} \
CONFIG.INCLUDE_RC {Root_Port_of_PCI_Express_Root_Complex} \ CONFIG.INCLUDE_RC {Root_Port_of_PCI_Express_Root_Complex} \
CONFIG.INTERRUPT_PIN {false} \ CONFIG.INTERRUPT_PIN {false} \

View File

@ -0,0 +1,249 @@
// See LICENSE for license details.
package sifive.fpgashells.shell.xilinx.ml507shell
import Chisel._
import chisel3.core.{Input, Output, attach}
import chisel3.experimental.{RawModule, Analog, withClockAndReset}
import freechips.rocketchip.config._
import freechips.rocketchip.devices.debug._
import freechips.rocketchip.util.{SyncResetSynchronizerShiftReg, ElaborationArtefacts, HeterogeneousBag}
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.spi._
import sifive.blocks.devices.uart._
import sifive.blocks.devices.chiplink._
import sifive.blocks.devices.terminal._
import sifive.fpgashells.devices.xilinx.xilinxml507mig._
import sifive.fpgashells.ip.xilinx.{PowerOnResetFPGAOnly, sdio_spi_bridge, ml507_ddr2_clock, ml507_dvi_clock, ml507_sys_clock, vc707reset}
//-------------------------------------------------------------------------
// ML507Shell
//-------------------------------------------------------------------------
// TODO: trait HasDDR2 { … }
trait HasDebugJTAG { this: ML507Shell =>
// 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()))
def connectDebugJTAG(dut: HasPeripheryDebugModuleImp, fmcxm105: Boolean = true): SystemJTAGIO = {
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
djtag
}
}
abstract class ML507Shell(implicit val p: Parameters) extends RawModule {
//-----------------------------------------------------------------------
// Interface
//-----------------------------------------------------------------------
// 100Mhz sysclk
val sys_clock = IO(Input(Clock()))
// 200MHz ddrclk
val ddr_clock_p = IO(Input(Clock()))
val ddr_clock_n = IO(Input(Clock()))
// active high async reset
val reset = IO(Input(Bool()))
// LED
val led = IO(Output(Vec(8, Bool())))
// DIP switches
val dip = IO(Input(Vec(8, Bool())))
// UART
val uart_tx = IO(Output(Bool()))
val uart_rx = IO(Input(Bool()))
// SDIO
val sdio_clk = IO(Output(Bool()))
val sdio_cmd = IO(Analog(1.W))
val sdio_dat = IO(Analog(4.W))
// Feedback
val clock_led = IO(Output(Clock()))
val reset_led = IO(Output(Bool()))
val dvi = IO(new TerminalDVIIO)
val ddr2 = IO(new MemoryDDR2IO)
//-----------------------------------------------------------------------
// Wire declrations
//-----------------------------------------------------------------------
// async resets
val sys_reset = Wire(Bool())
val do_reset = Wire(Bool())
val dut_ndreset = Wire(Bool())
val dut_clock = Wire(Clock())
val dut_reset = Wire(Bool())
val dvi_clock = Wire(Clock())
val dvi_reset = Wire(Bool())
val ddr_clk0 = Wire(Clock())
val ddr_clk90 = Wire(Clock())
val ddr_clkdiv0 = Wire(Clock())
val ddr_clk_locked = Wire(Bool())
val ddr_reset = 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 clk_locked = Wire(Bool())
//-----------------------------------------------------------------------
// System reset
//-----------------------------------------------------------------------
// Allow the debug module to reset everything. Resets the MIG
sys_reset := reset | dut_ndreset
//-----------------------------------------------------------------------
// Clock generators
//-----------------------------------------------------------------------
// 80 MHz (processor clock)
val ml507_sys_clock = Module(new ml507_sys_clock)
ml507_sys_clock.io.CLKIN_IN := sys_clock
dut_clock := ml507_sys_clock.io.CLKFX_OUT
// 48 MHz (DVI pixel clock for SDR 640x480x60)
val ml507_dvi_clock = Module(new ml507_dvi_clock)
ml507_dvi_clock.io.CLKIN_IN := sys_clock
dvi_clock := ml507_dvi_clock.io.CLKFX_OUT
// 200 MHz (DDR2 and IDELAY clock)
val ml507_ddr2_clock = Module(new ml507_ddr2_clock)
ml507_ddr2_clock.io.CLKIN_P_IN := ddr_clock_p
ml507_ddr2_clock.io.CLKIN_N_IN := ddr_clock_n
ddr_clk0 := ml507_ddr2_clock.io.CLK0_OUT
ddr_clk90 := ml507_ddr2_clock.io.CLK90_OUT
ddr_clkdiv0 := ml507_ddr2_clock.io.CLKDV_OUT
ddr_clk_locked := ml507_ddr2_clock.io.LOCKED_OUT
// Clocks locked?
clk_locked := ml507_sys_clock.io.LOCKED_OUT &
ml507_dvi_clock.io.LOCKED_OUT &
ddr_clk_locked
//-----------------------------------------------------------------------
// System reset
//-----------------------------------------------------------------------
do_reset := !clk_locked || sys_reset
// synchronize async resets
val safe_reset = Module(new vc707reset)
safe_reset.io.areset := do_reset
safe_reset.io.clock1 := ddr_clk0
ddr_reset := safe_reset.io.reset1
safe_reset.io.clock2 := dut_clock
safe_reset.io.clock3 := dvi_clock
dvi_reset := safe_reset.io.reset3
safe_reset.io.clock4 := dut_clock
dut_reset := safe_reset.io.reset4
// Setup feedback
clock_led := dut_clock
reset_led := dut_reset
//-----------------------------------------------------------------------
// Terminal
//-----------------------------------------------------------------------
def connectTerminal(dut: HasPeripheryTerminalModuleImp): Unit = {
dvi <> dut.dvi
dut.terminal.clk := dvi_clock
dut.terminal.reset := dvi_reset
}
//-----------------------------------------------------------------------
// Memory controller
//-----------------------------------------------------------------------
def connectDDRMemory(dut: HasMemoryML507ModuleImp): Unit = {
ddr2 <> dut.ddr2
dut.ddr_sys.clk0 := ddr_clk0
dut.ddr_sys.clk90 := ddr_clk90
dut.ddr_sys.clkdiv0 := ddr_clkdiv0
dut.ddr_sys.clk_locked := ddr_clk_locked
dut.ddr_sys.clk_idelay := ddr_clk0
dut.ddr_sys.reset := ddr_reset
}
//-----------------------------------------------------------------------
// UART
//-----------------------------------------------------------------------
def connectUART(dut: HasPeripheryUARTModuleImp): Unit = {
val uartParams = p(PeripheryUARTKey)
if (!uartParams.isEmpty) {
// uart connections
dut.uart(0).rxd := SyncResetSynchronizerShiftReg(uart_rx, 2, init = Bool(true), name=Some("uart_rxd_sync"))
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
}
}

View File

@ -7,16 +7,17 @@ import chisel3.experimental.{RawModule, Analog, withClockAndReset}
import freechips.rocketchip.config._ import freechips.rocketchip.config._
import freechips.rocketchip.devices.debug._ import freechips.rocketchip.devices.debug._
import freechips.rocketchip.util.{SyncResetSynchronizerShiftReg} import freechips.rocketchip.util.{SyncResetSynchronizerShiftReg, ElaborationArtefacts, HeterogeneousBag}
import sifive.blocks.devices.gpio._ import sifive.blocks.devices.gpio._
import sifive.blocks.devices.spi._ import sifive.blocks.devices.spi._
import sifive.blocks.devices.uart._ import sifive.blocks.devices.uart._
import sifive.blocks.devices.chiplink._
import sifive.fpgashells.devices.xilinx.xilinxvc707mig._ import sifive.fpgashells.devices.xilinx.xilinxvc707mig._
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._ import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._
import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, vc707_sys_clock_mmcm0, import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, vc707_sys_clock_mmcm0,
vc707_sys_clock_mmcm1, vc707reset} vc707_sys_clock_mmcm1, vc707_sys_clock_mmcm2 , vc707reset}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// VC707Shell // VC707Shell
@ -55,6 +56,328 @@ trait HasPCIe { this: VC707Shell =>
} }
} }
trait HasDebugJTAG { this: VC707Shell =>
// 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()))
def connectDebugJTAG(dut: HasPeripheryDebugModuleImp, fmcxm105: Boolean = true): SystemJTAGIO = {
ElaborationArtefacts.add(
"""debugjtag.vivado.tcl""",
"""set vc707debugjtag_vivado_tcl_dir [file dirname [file normalize [info script]]]
add_files -fileset [current_fileset -constrset] [glob -directory $vc707debugjtag_vivado_tcl_dir {*.vc707debugjtag.xdc}]"""
)
if(fmcxm105) {
//VC707 constraints for Xilinx FMC XM105 Debug Card
ElaborationArtefacts.add(
"""vc707debugjtag.xdc""",
"""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}] """
)
} else {
//VC707 constraints for Olimex connect to LCD panel header
ElaborationArtefacts.add(
"""vc707debugjtag.xdc""",
"""
#Olimex Pin Olimex Function LCD Pin LCD Function FPGA Pin
#1 VREF 14 5V
#3 TTRST_N 1 LCD_DB7 AN40
#5 TTDI 2 LCD_DB6 AR39
#7 TTMS 3 LCD_DB5 AR38
#9 TTCK 4 LCD_DB4 AT42
#11 TRTCK NC NC NC
#13 TTDO 9 LCD_E AT40
#15 TSRST_N 10 LCD_RW AR42
#2 VREF 14 5V
#18 GND 13 GND
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_TCK_IBUF]
set_property -dict { PACKAGE_PIN AT42 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TCK}]
set_property -dict { PACKAGE_PIN AR38 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TMS}]
set_property -dict { PACKAGE_PIN AR39 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDI}]
set_property -dict { PACKAGE_PIN AT40 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports {jtag_TDO}] """
)
}
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
djtag
}
}
trait HasVC707ChipLink { this: VC707Shell =>
val chiplink = IO(new WideDataLayerPort(ChipLinkParams(Nil,Nil)))
val ereset_n = IO(Bool(INPUT))
def constrainChipLink(iofpga: Boolean = false): Unit = {
val direction0Pins = if(iofpga) "chiplink_b2c" else "chiplink_c2b"
val direction1Pins = if(iofpga) "chiplink_c2b" else "chiplink_b2c"
ElaborationArtefacts.add(
"""vc707chiplink.vivado.tcl""",
"""set vc707chiplink_vivado_tcl_dir [file dirname [file normalize [info script]]]
add_files -fileset [current_fileset -constrset] [glob -directory $vc707chiplink_vivado_tcl_dir {*.vc707chiplink.xdc}]"""
)
ElaborationArtefacts.add(
"""vc707chiplink.xdc""", s"""
set_property PACKAGE_PIN AF39 [get_ports ${direction0Pins}_clk]
set_property PACKAGE_PIN AD40 [get_ports {${direction0Pins}_data[0]}]
set_property PACKAGE_PIN AD41 [get_ports {${direction0Pins}_data[1]}]
set_property PACKAGE_PIN AF41 [get_ports {${direction0Pins}_data[2]}]
set_property PACKAGE_PIN AG41 [get_ports {${direction0Pins}_data[3]}]
set_property PACKAGE_PIN AK39 [get_ports {${direction0Pins}_data[4]}]
set_property PACKAGE_PIN AL39 [get_ports {${direction0Pins}_data[5]}]
set_property PACKAGE_PIN AJ42 [get_ports {${direction0Pins}_data[6]}]
set_property PACKAGE_PIN AK42 [get_ports {${direction0Pins}_data[7]}]
set_property PACKAGE_PIN AL41 [get_ports {${direction0Pins}_data[8]}]
set_property PACKAGE_PIN AL42 [get_ports {${direction0Pins}_data[9]}]
set_property PACKAGE_PIN AF42 [get_ports {${direction0Pins}_data[10]}]
set_property PACKAGE_PIN AG42 [get_ports {${direction0Pins}_data[11]}]
set_property PACKAGE_PIN AD38 [get_ports {${direction0Pins}_data[12]}]
set_property PACKAGE_PIN AE38 [get_ports {${direction0Pins}_data[13]}]
set_property PACKAGE_PIN AC40 [get_ports {${direction0Pins}_data[14]}]
set_property PACKAGE_PIN AC41 [get_ports {${direction0Pins}_data[15]}]
set_property PACKAGE_PIN AD42 [get_ports {${direction0Pins}_data[16]}]
set_property PACKAGE_PIN AE42 [get_ports {${direction0Pins}_data[17]}]
set_property PACKAGE_PIN AJ38 [get_ports {${direction0Pins}_data[18]}]
set_property PACKAGE_PIN AK38 [get_ports {${direction0Pins}_data[19]}]
set_property PACKAGE_PIN AB41 [get_ports {${direction0Pins}_data[20]}]
set_property PACKAGE_PIN AB42 [get_ports {${direction0Pins}_data[21]}]
set_property PACKAGE_PIN Y42 [get_ports {${direction0Pins}_data[22]}]
set_property PACKAGE_PIN AA42 [get_ports {${direction0Pins}_data[23]}]
set_property PACKAGE_PIN Y39 [get_ports {${direction0Pins}_data[24]}]
set_property PACKAGE_PIN AA39 [get_ports {${direction0Pins}_data[25]}]
set_property PACKAGE_PIN W40 [get_ports {${direction0Pins}_data[26]}]
set_property PACKAGE_PIN Y40 [get_ports {${direction0Pins}_data[27]}]
set_property PACKAGE_PIN AB38 [get_ports {${direction0Pins}_data[28]}]
set_property PACKAGE_PIN AB39 [get_ports {${direction0Pins}_data[29]}]
set_property PACKAGE_PIN AC38 [get_ports {${direction0Pins}_data[30]}]
set_property PACKAGE_PIN AC39 [get_ports {${direction0Pins}_data[31]}]
set_property PACKAGE_PIN AJ40 [get_ports ${direction0Pins}_send]
set_property PACKAGE_PIN AJ41 [get_ports ${direction0Pins}_rst]
set_property PACKAGE_PIN U39 [get_ports ${direction1Pins}_clk]
set_property PACKAGE_PIN U37 [get_ports {${direction1Pins}_data[0]}]
set_property PACKAGE_PIN U38 [get_ports {${direction1Pins}_data[1]}]
set_property PACKAGE_PIN U36 [get_ports {${direction1Pins}_data[2]}]
set_property PACKAGE_PIN T37 [get_ports {${direction1Pins}_data[3]}]
set_property PACKAGE_PIN U32 [get_ports {${direction1Pins}_data[4]}]
set_property PACKAGE_PIN U33 [get_ports {${direction1Pins}_data[5]}]
set_property PACKAGE_PIN V33 [get_ports {${direction1Pins}_data[6]}]
set_property PACKAGE_PIN V34 [get_ports {${direction1Pins}_data[7]}]
set_property PACKAGE_PIN P35 [get_ports {${direction1Pins}_data[8]}]
set_property PACKAGE_PIN P36 [get_ports {${direction1Pins}_data[9]}]
set_property PACKAGE_PIN W32 [get_ports {${direction1Pins}_data[10]}]
set_property PACKAGE_PIN W33 [get_ports {${direction1Pins}_data[11]}]
set_property PACKAGE_PIN R38 [get_ports {${direction1Pins}_data[12]}]
set_property PACKAGE_PIN R39 [get_ports {${direction1Pins}_data[13]}]
set_property PACKAGE_PIN U34 [get_ports {${direction1Pins}_data[14]}]
set_property PACKAGE_PIN T35 [get_ports {${direction1Pins}_data[15]}]
set_property PACKAGE_PIN R33 [get_ports {${direction1Pins}_data[16]}]
set_property PACKAGE_PIN R34 [get_ports {${direction1Pins}_data[17]}]
set_property PACKAGE_PIN N33 [get_ports {${direction1Pins}_data[18]}]
set_property PACKAGE_PIN N34 [get_ports {${direction1Pins}_data[19]}]
set_property PACKAGE_PIN P32 [get_ports {${direction1Pins}_data[20]}]
set_property PACKAGE_PIN P33 [get_ports {${direction1Pins}_data[21]}]
set_property PACKAGE_PIN V35 [get_ports {${direction1Pins}_data[22]}]
set_property PACKAGE_PIN V36 [get_ports {${direction1Pins}_data[23]}]
set_property PACKAGE_PIN W36 [get_ports {${direction1Pins}_data[24]}]
set_property PACKAGE_PIN W37 [get_ports {${direction1Pins}_data[25]}]
set_property PACKAGE_PIN T32 [get_ports {${direction1Pins}_data[26]}]
set_property PACKAGE_PIN R32 [get_ports {${direction1Pins}_data[27]}]
set_property PACKAGE_PIN V39 [get_ports {${direction1Pins}_data[28]}]
set_property PACKAGE_PIN V40 [get_ports {${direction1Pins}_data[29]}]
set_property PACKAGE_PIN P37 [get_ports {${direction1Pins}_data[30]}]
set_property PACKAGE_PIN P38 [get_ports {${direction1Pins}_data[31]}]
set_property PACKAGE_PIN T36 [get_ports ${direction1Pins}_send]
set_property PACKAGE_PIN R37 [get_ports ${direction1Pins}_rst]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[31]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[30]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[29]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[28]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[27]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[26]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[25]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[24]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[23]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[22]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[21]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[20]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[19]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[18]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[17]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[16]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[15]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[14]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[13]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[12]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[11]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[10]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[9]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[8]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[7]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[6]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[5]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[4]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction0Pins}_data[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[31]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[30]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[29]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[28]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[27]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[26]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[25]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[24]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[23]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[22]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[21]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[20]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[19]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[18]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[17]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[16]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[15]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[14]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[13]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[12]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[11]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[10]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[9]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[8]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[7]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[6]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[5]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[4]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {${direction1Pins}_data[0]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[31]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[30]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[29]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[28]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[27]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[26]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[25]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[24]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[23]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[22]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[21]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[20]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[19]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[18]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[17]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[16]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[15]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[14]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[13]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[12]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[11]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[10]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[9]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[8]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[7]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[6]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[5]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[4]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[3]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[2]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[1]}]
set_property SLEW FAST [get_ports {${direction1Pins}_data[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_clk]
set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_rst]
set_property IOSTANDARD LVCMOS18 [get_ports ${direction0Pins}_send]
set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_clk]
set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_rst]
set_property IOSTANDARD LVCMOS18 [get_ports ${direction1Pins}_send]
set_property SLEW FAST [get_ports ${direction1Pins}_clk]
set_property SLEW FAST [get_ports ${direction1Pins}_rst]
set_property SLEW FAST [get_ports ${direction1Pins}_send]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[31]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[30]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[29]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[28]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[27]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[26]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[25]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[24]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[23]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[22]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[21]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[20]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[19]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[18]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[17]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[16]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[15]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[14]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[13]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[12]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[11]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[10]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[9]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[8]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[7]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[6]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[5]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[4]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[3]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[2]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[1]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_data[0]]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_send]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_clk]
set_property OFFCHIP_TERM NONE [get_ports ${direction1Pins}_rst]
# Aloe reset sent to FPGA
set_property IOSTANDARD LVCMOS18 [get_ports ereset_n]
set_property PACKAGE_PIN AF40 [get_ports ereset_n]
#Put first level RX/TX flops in IOB
set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports "chiplink_b2c_data*"]]]
set_property IOB TRUE [get_cells -of_objects [all_fanout -flat -endpoints_only [get_ports "chiplink_b2c_send"]]]
set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports "chiplink_c2b_data*"]]]
set_property IOB TRUE [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports "chiplink_c2b_send"]]]
"""
)
}
def connectChipLink(dut: { val chiplink: HeterogeneousBag[WideDataLayerPort] } , iofpga: Boolean = false): Unit = {
constrainChipLink(iofpga)
chiplink <> dut.chiplink(0)
//dut.chiplink_xilinx_7series_phy.get.idelayctrl_refclk := sys_clock
}
}
abstract class VC707Shell(implicit val p: Parameters) extends RawModule { abstract class VC707Shell(implicit val p: Parameters) extends RawModule {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@ -82,12 +405,6 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule {
val sdio_cmd = IO(Analog(1.W)) val sdio_cmd = IO(Analog(1.W))
val sdio_dat = IO(Analog(4.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()))
//Buttons //Buttons
val btn_0 = IO(Analog(1.W)) val btn_0 = IO(Analog(1.W))
val btn_1 = IO(Analog(1.W)) val btn_1 = IO(Analog(1.W))
@ -163,7 +480,7 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
//25MHz and multiples //25MHz and multiples
val vc707_sys_clock_mmcm0 = Module(new vc707_sys_clock_mmcm0) val vc707_sys_clock_mmcm0 = Module(new vc707_sys_clock_mmcm2)
vc707_sys_clock_mmcm0.io.clk_in1 := sys_clock.asUInt vc707_sys_clock_mmcm0.io.clk_in1 := sys_clock.asUInt
vc707_sys_clock_mmcm0.io.reset := reset vc707_sys_clock_mmcm0.io.reset := reset
val clk12_5 = vc707_sys_clock_mmcm0.io.clk_out1 val clk12_5 = vc707_sys_clock_mmcm0.io.clk_out1
@ -173,6 +490,7 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule {
val clk100 = vc707_sys_clock_mmcm0.io.clk_out5 val clk100 = vc707_sys_clock_mmcm0.io.clk_out5
val clk150 = vc707_sys_clock_mmcm0.io.clk_out6 val clk150 = vc707_sys_clock_mmcm0.io.clk_out6
val clk75 = vc707_sys_clock_mmcm0.io.clk_out7 val clk75 = vc707_sys_clock_mmcm0.io.clk_out7
val clk100_180 = vc707_sys_clock_mmcm0.io.clk_out7
val vc707_sys_clock_mmcm0_locked = vc707_sys_clock_mmcm0.io.locked val vc707_sys_clock_mmcm0_locked = vc707_sys_clock_mmcm0.io.locked
//65MHz and multiples //65MHz and multiples
@ -218,24 +536,7 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule {
mig_mmcm_locked := UInt("b1") mig_mmcm_locked := UInt("b1")
mmcm_lock_pcie := UInt("b1") mmcm_lock_pcie := UInt("b1")
//---------------------------------------------------------------------
// Debug JTAG
//---------------------------------------------------------------------
def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): SystemJTAGIO = {
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
djtag
}
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// UART // UART

View File

@ -115,4 +115,5 @@ if {[get_filesets -quiet constrs_1] eq ""} {
} }
set obj [current_fileset -constrset] set obj [current_fileset -constrset]
add_files -norecurse -fileset $obj [glob -directory $constraintsdir {*.xdc}] add_files -quiet -norecurse -fileset $obj [glob -directory $constraintsdir -nocomplain {*.xdc}]
add_files -quiet -norecurse -fileset $obj [glob -directory $constraintsdir -nocomplain {*.tcl}]

View File

@ -0,0 +1,25 @@
if { [llength [get_ports -quiet chiplink_b2c_clk]] > 0 } {
create_clock -name chiplink_b2c_clock -period 10 [get_ports chiplink_b2c_clk]
}
set group_mem [get_clocks -quiet {clk_pll_i}]
set group_sys [get_clocks -quiet {sys_diff_clk \
clk_out*_vc707_sys_clock_mmcm1 \
clk_out*_vc707_sys_clock_mmcm2}]
set group_cl [get_clocks -quiet {chiplink_b2c_clock \
clk_out*_vc707_sys_clock_mmcm3}]
set group_pci [get_clocks -quiet -include_generated_clocks -of_objects [get_pins -hier -filter {name =~ *pcie*TXOUTCLK}]]
puts "group_mem: $group_mem"
puts "group_sys: $group_sys"
puts "group_pci: $group_pci"
puts "group_cl: $group_cl"
set groups [list]
if { [llength $group_mem] > 0 } { lappend groups -group $group_mem }
if { [llength $group_sys] > 0 } { lappend groups -group $group_sys }
if { [llength $group_pci] > 0 } { lappend groups -group $group_pci }
if { [llength $group_cl] > 0 } { lappend groups -group $group_cl }
puts "set_clock_groups -asynchronous $groups"
set_clock_groups -asynchronous {*}$groups

View File

@ -64,13 +64,6 @@ set_property PACKAGE_PIN H3 [get_ports {pcie_pci_exp_txn}]
set_property PACKAGE_PIN G6 [get_ports {pcie_pci_exp_rxp}] set_property PACKAGE_PIN G6 [get_ports {pcie_pci_exp_rxp}]
set_property PACKAGE_PIN G5 [get_ports {pcie_pci_exp_rxn}] set_property PACKAGE_PIN G5 [get_ports {pcie_pci_exp_rxn}]
# 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 # SDIO
set_property -dict { PACKAGE_PIN AN30 IOSTANDARD LVCMOS18 IOB TRUE } [get_ports {sdio_clk}] 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 AP30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_cmd}]
@ -78,19 +71,3 @@ set_property -dict { PACKAGE_PIN AR30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRU
set_property -dict { PACKAGE_PIN AU31 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRUE } [get_ports {sdio_dat[1]}] 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 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_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_vc707_sys_clock_mmcm0 \
clk_out2_vc707_sys_clock_mmcm0 \
clk_out3_vc707_sys_clock_mmcm0 \
clk_out4_vc707_sys_clock_mmcm0 \
clk_out5_vc707_sys_clock_mmcm0 \
clk_out6_vc707_sys_clock_mmcm0 \
clk_out7_vc707_sys_clock_mmcm0 } \
-group { \
clk_out1_vc707_sys_clock_mmcm1 \
clk_out2_vc707_sys_clock_mmcm1 } \
-group [list [get_clocks -include_generated_clocks -of_objects [get_pins -hier -filter {name =~ *pcie*TXOUTCLK}]]]