/
VCU118NewShell.scala
454 lines (402 loc) · 21.7 KB
/
VCU118NewShell.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
// See LICENSE for license details.
package sifive.fpgashells.shell.xilinx
import chisel3._
import chisel3.experimental.{attach, Analog, IO, withClockAndReset}
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.SyncResetSynchronizerShiftReg
import sifive.fpgashells.clocks._
import sifive.fpgashells.shell._
import sifive.fpgashells.ip.xilinx._
import sifive.blocks.devices.chiplink._
import sifive.fpgashells.devices.xilinx.xilinxvcu118mig._
import sifive.fpgashells.devices.xilinx.xdma._
import sifive.fpgashells.ip.xilinx.xxv_ethernet._
class SysClockVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput)
{
val node = shell { ClockSourceNode(name, freqMHz = 250, jitterPS = 50) }
shell { InModuleBody {
shell.xdc.addPackagePin(io.p, "E12")
shell.xdc.addPackagePin(io.n, "D12")
shell.xdc.addIOStandard(io.p, "DIFF_SSTL12")
shell.xdc.addIOStandard(io.n, "DIFF_SSTL12")
} }
}
class SysClockVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
extends ClockInputShellPlacer[VCU118ShellBasicOverlays]
{
def place(designInput: ClockInputDesignInput) = new SysClockVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class RefClockVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput)
extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput) {
val node = shell { ClockSourceNode(name, freqMHz = 125, jitterPS = 50) }
shell { InModuleBody {
shell.xdc.addPackagePin(io.p, "AY24")
shell.xdc.addPackagePin(io.n, "AY23")
shell.xdc.addIOStandard(io.p, "LVDS")
shell.xdc.addIOStandard(io.n, "LVDS")
} }
}
class RefClockVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName)
extends ClockInputShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: ClockInputDesignInput) = new RefClockVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class SDIOVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: SDIODesignInput, val shellInput: SDIOShellInput)
extends SDIOXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
val packagePinsWithPackageIOs = Seq(("AV15", IOPin(io.sdio_clk)),
("AY15", IOPin(io.sdio_cmd)),
("AW15", IOPin(io.sdio_dat_0)),
("AV16", IOPin(io.sdio_dat_1)),
("AU16", IOPin(io.sdio_dat_2)),
("AY14", IOPin(io.sdio_dat_3)))
packagePinsWithPackageIOs foreach { case (pin, io) => {
shell.xdc.addPackagePin(io, pin)
shell.xdc.addIOStandard(io, "LVCMOS18")
shell.xdc.addIOB(io)
} }
packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
shell.xdc.addPullup(io)
} }
} }
}
class SDIOVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: SDIOShellInput)(implicit val valName: ValName)
extends SDIOShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: SDIODesignInput) = new SDIOVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class SPIFlashVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: SPIFlashDesignInput, val shellInput: SPIFlashShellInput)
extends SPIFlashXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
val packagePinsWithPackageIOs = Seq(("AF13", IOPin(io.qspi_sck)),
("AJ11", IOPin(io.qspi_cs)),
("AP11", IOPin(io.qspi_dq(0))),
("AN11", IOPin(io.qspi_dq(1))),
("AM11", IOPin(io.qspi_dq(2))),
("AL11", IOPin(io.qspi_dq(3))))
packagePinsWithPackageIOs foreach { case (pin, io) => {
shell.xdc.addPackagePin(io, pin)
// shell.xdc.addIOStandard(io, "LVCMOS18")
} }
//packagePinsWithPackageIOs drop 1 foreach { case (pin, io) => {
// shell.xdc.addPullup(io)
//} }
} }
}
class SPIFlashVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: SPIFlashShellInput)(implicit val valName: ValName)
extends SPIFlashShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: SPIFlashDesignInput) = new SPIFlashVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class UARTVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
{
shell { InModuleBody {
val packagePinsWithPackageIOs = Seq(("AY25", IOPin(io.ctsn.get)),
("BB22", IOPin(io.rtsn.get)),
("AW25", IOPin(io.rxd)),
("BB21", IOPin(io.txd)))
packagePinsWithPackageIOs foreach { case (pin, io) => {
shell.xdc.addPackagePin(io, pin)
shell.xdc.addIOStandard(io, "LVCMOS18")
shell.xdc.addIOB(io)
} }
} }
}
class UARTVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: UARTShellInput)(implicit val valName: ValName)
extends UARTShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: UARTDesignInput) = new UARTVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class QSFP1VCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: EthernetDesignInput, val shellInput: EthernetShellInput)
extends EthernetUltraScalePlacedOverlay(name, designInput, shellInput, XXVEthernetParams(name = name, speed = 10, dclkMHz = 125))
{
val dclkSource = shell { BundleBridgeSource(() => Clock()) }
val dclkSink = dclkSource.makeSink()
InModuleBody {
dclk := dclkSink.bundle
}
shell { InModuleBody {
dclkSource.bundle := shell.ref_clock.get.get.overlayOutput.node.out(0)._1.clock
shell.xdc.addPackagePin(io.tx_p, "V7")
shell.xdc.addPackagePin(io.tx_n, "V6")
shell.xdc.addPackagePin(io.rx_p, "Y2")
shell.xdc.addPackagePin(io.rx_n, "Y1")
shell.xdc.addPackagePin(io.refclk_p, "W9")
shell.xdc.addPackagePin(io.refclk_n, "W8")
} }
}
class QSFP1VCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: EthernetShellInput)(implicit val valName: ValName)
extends EthernetShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: EthernetDesignInput) = new QSFP1VCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class QSFP2VCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: EthernetDesignInput, val shellInput: EthernetShellInput)
extends EthernetUltraScalePlacedOverlay(name, designInput, shellInput, XXVEthernetParams(name = name, speed = 10, dclkMHz = 125))
{
val dclkSource = shell { BundleBridgeSource(() => Clock()) }
val dclkSink = dclkSource.makeSink()
InModuleBody {
dclk := dclkSink.bundle
}
shell { InModuleBody {
dclkSource.bundle := shell.ref_clock.get.get.overlayOutput.node.out(0)._1.clock
shell.xdc.addPackagePin(io.tx_p, "L5")
shell.xdc.addPackagePin(io.tx_n, "L4")
shell.xdc.addPackagePin(io.rx_p, "T2")
shell.xdc.addPackagePin(io.rx_n, "T1")
shell.xdc.addPackagePin(io.refclk_p, "R9")
shell.xdc.addPackagePin(io.refclk_n, "R8")
} }
}
class QSFP2VCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: EthernetShellInput)(implicit val valName: ValName)
extends EthernetShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: EthernetDesignInput) = new QSFP2VCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
object LEDVCU118PinConstraints {
val pins = Seq("AT32", "AV34", "AY30", "BB32", "BF32", "AU37", "AV36", "BA37")
}
class LEDVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: LEDDesignInput, val shellInput: LEDShellInput)
extends LEDXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(LEDVCU118PinConstraints.pins(shellInput.number)), ioStandard = "LVCMOS12")
class LEDVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: LEDShellInput)(implicit val valName: ValName)
extends LEDShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: LEDDesignInput) = new LEDVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
object SwitchVCU118PinConstraints {
val pins = Seq("B17", "G16", "J16", "D21")
}
class SwitchVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: SwitchDesignInput, val shellInput: SwitchShellInput)
extends SwitchXilinxPlacedOverlay(name, designInput, shellInput, packagePin = Some(SwitchVCU118PinConstraints.pins(shellInput.number)), ioStandard = "LVCMOS12")
class SwitchVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: SwitchShellInput)(implicit val valName: ValName)
extends SwitchShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: SwitchDesignInput) = new SwitchVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class ChipLinkVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ChipLinkDesignInput, val shellInput: ChipLinkShellInput)
extends ChipLinkXilinxPlacedOverlay(name, designInput, shellInput, rxPhase= -120, txPhase= -90, rxMargin=0.6, txMargin=0.5)
{
val ereset_n = shell { InModuleBody {
val ereset_n = IO(Analog(1.W))
ereset_n.suggestName("ereset_n")
val pin = IOPin(ereset_n, 0)
shell.xdc.addPackagePin(pin, "BC8")
shell.xdc.addIOStandard(pin, "LVCMOS18")
shell.xdc.addTermination(pin, "NONE")
shell.xdc.addPullup(pin)
val iobuf = Module(new IOBUF)
iobuf.suggestName("chiplink_ereset_iobuf")
attach(ereset_n, iobuf.io.IO)
iobuf.io.T := true.B // !oe
iobuf.io.I := false.B
iobuf.io.O
} }
shell { InModuleBody {
val dir1 = Seq("BC9", "AV8", "AV9", /* clk, rst, send */
"AY9", "BA9", "BF10", "BF9", "BC11", "BD11", "BD12", "BE12",
"BF12", "BF11", "BE14", "BF14", "BD13", "BE13", "BC15", "BD15",
"BE15", "BF15", "BA14", "BB14", "BB13", "BB12", "BA16", "BA15",
"BC14", "BC13", "AY8", "AY7", "AW8", "AW7", "BB16", "BC16")
val dir2 = Seq("AV14", "AK13", "AK14", /* clk, rst, send */
"AR14", "AT14", "AP12", "AR12", "AW12", "AY12", "AW11", "AY10",
"AU11", "AV11", "AW13", "AY13", "AN16", "AP16", "AP13", "AR13",
"AT12", "AU12", "AK15", "AL15", "AL14", "AM14", "AV10", "AW10",
"AN15", "AP15", "AK12", "AL12", "AM13", "AM12", "AJ13", "AJ12")
(IOPin.of(io.b2c) zip dir1) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
(IOPin.of(io.c2b) zip dir2) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
} }
}
class ChipLinkVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ChipLinkShellInput)(implicit val valName: ValName)
extends ChipLinkShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: ChipLinkDesignInput) = new ChipLinkVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
// TODO: JTAG is untested
class JTAGDebugVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: JTAGDebugDesignInput, val shellInput: JTAGDebugShellInput)
extends JTAGDebugXilinxPlacedOverlay(name, designInput, shellInput)
{
shell { InModuleBody {
shell.sdc.addClock("JTCK", IOPin(io.jtag_TCK), 10)
shell.sdc.addGroup(clocks = Seq("JTCK"))
shell.xdc.clockDedicatedRouteFalse(IOPin(io.jtag_TCK))
val packagePinsWithPackageIOs = Seq(("P29", IOPin(io.jtag_TCK)),
("L31", IOPin(io.jtag_TMS)),
("M31", IOPin(io.jtag_TDI)),
("R29", IOPin(io.jtag_TDO)))
packagePinsWithPackageIOs foreach { case (pin, io) => {
shell.xdc.addPackagePin(io, pin)
shell.xdc.addIOStandard(io, "LVCMOS18")
shell.xdc.addPullup(io)
} }
} }
}
class JTAGDebugVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: JTAGDebugShellInput)(implicit val valName: ValName)
extends JTAGDebugShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: JTAGDebugDesignInput) = new JTAGDebugVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
case object VCU118DDRSize extends Field[BigInt](0x40000000L * 2) // 2GB
class DDRVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: DDRDesignInput, val shellInput: DDRShellInput)
extends DDRPlacedOverlay[XilinxVCU118MIGPads](name, designInput, shellInput)
{
val size = p(VCU118DDRSize)
val sdcClockName = "userClock1"
val migParams = XilinxVCU118MIGParams(address = AddressSet.misaligned(designInput.baseAddress, size))
val mig = LazyModule(new XilinxVCU118MIG(migParams))
val ioNode = BundleBridgeSource(() => mig.module.io.cloneType)
val topIONode = shell { ioNode.makeSink() }
val ddrUI = shell { ClockSourceNode(sdcClockName, freqMHz = 200) }
val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) }
areset := designInput.wrangler := ddrUI
def overlayOutput = DDROverlayOutput(ddr = mig.node)
def ioFactory = new XilinxVCU118MIGPads(size)
InModuleBody { ioNode.bundle <> mig.module.io }
shell { InModuleBody {
require (shell.sys_clock.get.isDefined, "Use of DDRVCU118Overlay depends on SysClockVCU118Overlay")
val (sys, _) = shell.sys_clock.get.get.overlayOutput.node.out(0)
val (ui, _) = ddrUI.out(0)
val (ar, _) = areset.in(0)
val port = topIONode.bundle.port
io <> port
ui.clock := port.c0_ddr4_ui_clk
ui.reset := /*!port.mmcm_locked ||*/ port.c0_ddr4_ui_clk_sync_rst
port.c0_sys_clk_i := sys.clock.asUInt
port.sys_rst := sys.reset // pllReset
port.c0_ddr4_aresetn := !ar.reset
val allddrpins = Seq( "D14", "B15", "B16", "C14", "C15", "A13", "A14",
"A15", "A16", "B12", "C12", "B13", "C13", "D15", "H14", "H15", "F15",
"H13", "G15", "G13", "N20", "E13", "E14", "F14", "A10", "F13", "C8",
"F11", "E11", "F10", "F9", "H12", "G12", "E9", "D9", "R19", "P19",
"M18", "M17", "N19", "N18", "N17", "M16", "L16", "K16", "L18", "K18",
"J17", "H17", "H19", "H18", "F19", "F18", "E19", "E18", "G20", "F20",
"E17", "D16", "D17", "C17", "C19", "C18", "D20", "D19", "C20", "B20",
"N23", "M23", "R21", "P21", "R22", "P22", "T23", "R23", "K24", "J24",
"M21", "L21", "K21", "J21", "K22", "J22", "H23", "H22", "E23", "E22",
"F21", "E21", "F24", "F23", "D10", "P16", "J19", "E16", "A18", "M22",
"L20", "G23", "D11", "P17", "K19", "F16", "A19", "N22", "M20", "H24",
"G11", "R18", "K17", "G18", "B18", "P20", "L23", "G22")
(IOPin.of(io) zip allddrpins) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) }
} }
shell.sdc.addGroup(clocks = Seq("userClock1"))
}
class DDRVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: DDRShellInput)(implicit val valName: ValName)
extends DDRShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: DDRDesignInput) = new DDRVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
}
class PCIeVCU118FMCPlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
extends PCIeUltraScalePlacedOverlay(name, designInput, shellInput, XDMAParams(
name = "fmc_xdma",
location = "X0Y3",
bars = designInput.bars,
control = designInput.ecam,
lanes = 4))
{
shell { InModuleBody {
// Work-around incorrectly pre-assigned pins
IOPin.of(io).foreach { shell.xdc.addPackagePin(_, "") }
// We need some way to connect both of these to reach x8
val ref126 = Seq("V38", "V39") /* [pn] GBT0 Bank 126 */
val ref121 = Seq("AK38", "AK39") /* [pn] GBT0 Bank 121 */
val ref = ref126
// Bank 126 (DP5, DP6, DP4, DP7), Bank 121 (DP3, DP2, DP1, DP0)
val rxp = Seq("U45", "R45", "W45", "N45", "AJ45", "AL45", "AN45", "AR45") /* [0-7] */
val rxn = Seq("U46", "R46", "W46", "N46", "AJ46", "AL46", "AN46", "AR46") /* [0-7] */
val txp = Seq("P42", "M42", "T42", "K42", "AL40", "AM42", "AP42", "AT42") /* [0-7] */
val txn = Seq("P43", "M43", "T43", "K43", "AL41", "AM43", "AP43", "AT43") /* [0-7] */
def bind(io: Seq[IOPin], pad: Seq[String]) {
(io zip pad) foreach { case (io, pad) => shell.xdc.addPackagePin(io, pad) }
}
bind(IOPin.of(io.refclk), ref)
// We do these individually so that zip falls off the end of the lanes:
bind(IOPin.of(io.lanes.pci_exp_txp), txp)
bind(IOPin.of(io.lanes.pci_exp_txn), txn)
bind(IOPin.of(io.lanes.pci_exp_rxp), rxp)
bind(IOPin.of(io.lanes.pci_exp_rxn), rxn)
} }
}
class PCIeVCU118FMCShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: PCIeShellInput)(implicit val valName: ValName)
extends PCIeShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: PCIeDesignInput) = new PCIeVCU118FMCPlacedOverlay(shell, valName.name, designInput, shellInput)
}
class PCIeVCU118EdgePlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: PCIeDesignInput, val shellInput: PCIeShellInput)
extends PCIeUltraScalePlacedOverlay(name, designInput, shellInput, XDMAParams(
name = "edge_xdma",
location = "X1Y2",
bars = designInput.bars,
control = designInput.ecam,
lanes = 8))
{
shell { InModuleBody {
// Work-around incorrectly pre-assigned pins
IOPin.of(io).foreach { shell.xdc.addPackagePin(_, "") }
// PCIe Edge connector U2
// Lanes 00-03 Bank 227
// Lanes 04-07 Bank 226
// Lanes 08-11 Bank 225
// Lanes 12-15 Bank 224
// FMC+ J22
val ref227 = Seq("AC9", "AC8") /* [pn] Bank 227 PCIE_CLK2_*/
val ref = ref227
// PCIe Edge connector U2 : Bank 227, 226
val rxp = Seq("AA4", "AB2", "AC4", "AD2", "AE4", "AF2", "AG4", "AH2") // [0-7]
val rxn = Seq("AA3", "AB1", "AC3", "AD1", "AE3", "AF1", "AG3", "AH1") // [0-7]
val txp = Seq("Y7", "AB7", "AD7", "AF7", "AH7", "AK7", "AM7", "AN5") // [0-7]
val txn = Seq("Y6", "AB6", "AD6", "AF6", "AH6", "AK6", "AM6", "AN4") // [0-7]
def bind(io: Seq[IOPin], pad: Seq[String]) {
(io zip pad) foreach { case (io, pad) => shell.xdc.addPackagePin(io, pad) }
}
bind(IOPin.of(io.refclk), ref)
// We do these individually so that zip falls off the end of the lanes:
bind(IOPin.of(io.lanes.pci_exp_txp), txp)
bind(IOPin.of(io.lanes.pci_exp_txn), txn)
bind(IOPin.of(io.lanes.pci_exp_rxp), rxp)
bind(IOPin.of(io.lanes.pci_exp_rxn), rxn)
} }
}
class PCIeVCU118EdgeShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: PCIeShellInput)(implicit val valName: ValName)
extends PCIeShellPlacer[VCU118ShellBasicOverlays] {
def place(designInput: PCIeDesignInput) = new PCIeVCU118EdgePlacedOverlay(shell, valName.name, designInput, shellInput)
}
abstract class VCU118ShellBasicOverlays()(implicit p: Parameters) extends UltraScaleShell{
val sys_clock = Overlay(ClockInputOverlayKey, new SysClockVCU118ShellPlacer(this, ClockInputShellInput()))
val ref_clock = Overlay(ClockInputOverlayKey, new RefClockVCU118ShellPlacer(this, ClockInputShellInput()))
val led = Seq.tabulate(8)(i => Overlay(LEDOverlayKey, new LEDVCU118ShellPlacer(this, LEDShellInput(color = "red", number = i))(valName = ValName(s"led_$i"))))
val switch = Seq.tabulate(4)(i => Overlay(SwitchOverlayKey, new SwitchVCU118ShellPlacer(this, SwitchShellInput(number = i))(valName = ValName(s"switch_$i"))))
val ddr = Overlay(DDROverlayKey, new DDRVCU118ShellPlacer(this, DDRShellInput()))
val uart = Overlay(UARTOverlayKey, new UARTVCU118ShellPlacer(this, UARTShellInput()))
val sdio = Overlay(SDIOOverlayKey, new SDIOVCU118ShellPlacer(this, SDIOShellInput()))
val jtag = Overlay(JTAGDebugOverlayKey, new JTAGDebugVCU118ShellPlacer(this, JTAGDebugShellInput()))
val qsfp1 = Overlay(EthernetOverlayKey, new QSFP1VCU118ShellPlacer(this, EthernetShellInput()))
val qsfp2 = Overlay(EthernetOverlayKey, new QSFP2VCU118ShellPlacer(this, EthernetShellInput()))
val chiplink = Overlay(ChipLinkOverlayKey, new ChipLinkVCU118ShellPlacer(this, ChipLinkShellInput()))
val spi_flash = Overlay(SPIFlashOverlayKey, new SPIFlashVCU118ShellPlacer(this, SPIFlashShellInput()))
}
class VCU118Shell()(implicit p: Parameters) extends VCU118ShellBasicOverlays
{
// PLL reset causes
val pllReset = InModuleBody { Wire(Bool()) }
// Order matters; ddr depends on sys_clock
val fmc = Overlay(PCIeOverlayKey, new PCIeVCU118FMCShellPlacer(this, PCIeShellInput()))
val edge = Overlay(PCIeOverlayKey, new PCIeVCU118EdgeShellPlacer(this, PCIeShellInput()))
val topDesign = LazyModule(p(DesignKey)(designParameters))
// Place the sys_clock at the Shell if the user didn't ask for it
designParameters(ClockInputOverlayKey).foreach { unused =>
val source = unused.place(ClockInputDesignInput()).overlayOutput.node
val sink = ClockSinkNode(Seq(ClockSinkParameters()))
sink := source
}
override lazy val module = new LazyRawModuleImp(this) {
val reset = IO(Input(Bool()))
xdc.addPackagePin(reset, "L19")
xdc.addIOStandard(reset, "LVCMOS12")
val reset_ibuf = Module(new IBUF)
reset_ibuf.io.I := reset
val sysclk: Clock = sys_clock.get() match {
case Some(x: SysClockVCU118PlacedOverlay) => x.clock
}
val powerOnReset: Bool = PowerOnResetFPGAOnly(sysclk)
sdc.addAsyncPath(Seq(powerOnReset))
val ereset: Bool = chiplink.get() match {
case Some(x: ChipLinkVCU118PlacedOverlay) => !x.ereset_n
case _ => false.B
}
pllReset := (reset_ibuf.io.O || powerOnReset || ereset)
val hi = "hi"
}
}