Skip to content

Commit 5c50e95

Browse files
committed
first HSPI loopback version for Kintex 420T, not working yet
1 parent 2525913 commit 5c50e95

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

gateware/kintex-420t-mandelbrot.py

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2021 Hans Baier <[email protected]>
4+
# SPDX-License-Identifier: CERN-OHL-W-2.0
5+
import os
6+
import code
7+
8+
from amaranth import *
9+
from amaranth.lib.fifo import SyncFIFOBuffered
10+
from amaranth.lib.cdc import ResetSynchronizer
11+
from amaranth.build import *
12+
13+
from amaranth_boards.resources import *
14+
from amaranth_boards.hpc_xc7k420t import HPCStoreXC7K420TPlatform
15+
16+
from amlib.debug.ila import StreamILA, ILACoreParameters
17+
from amlib.stream import connect_stream_to_fifo, connect_fifo_to_stream
18+
19+
from fractalmanager import FractalManager
20+
21+
from hspi import HSPITransmitter, HSPIReceiver
22+
23+
odd_pins = list(range(1, 75, 2))
24+
even_pins = list(range(2, 76, 2))
25+
26+
GND = None
27+
btb_odd = [GND, None, None,
28+
GND, "HD12", "HD13", "HD14", "HD15",
29+
GND, "HD16", "HD17", "HD18", "HD19",
30+
GND, "HD20", "HD21", "HD22", "HD23",
31+
GND, "HD24", "HD25", "HD26", "HD27",
32+
GND, "HD28", "HD29", "HD30", "HD31",
33+
GND, "LED1", "LED2"]
34+
35+
btb_even = [GND, "HD10", "HD11",
36+
GND, "HRCLK", "HRACT", "HRVLD", "HTRDY",
37+
GND, "HD0", "HD1", "HD2", "HD3",
38+
GND, "HD4", "HD5", "HD6", "HD7",
39+
GND, "HD8", "HD9", "HTVLD", "HTREQ",
40+
GND, "HTACK", "HTCLK"]
41+
42+
even = list(zip(btb_even, even_pins))
43+
odd = list(zip(btb_odd, odd_pins))
44+
45+
pinmap = dict(filter(lambda t: t[0] != None, even + odd))
46+
hd_pins = " ".join([f"BTB_0:{pinmap[pin]}" for pin in [f"HD{i}" for i in range(0, 32)]])
47+
control_pin = lambda pin: "BTB_0:" + str(pinmap[pin])
48+
49+
#code.interact(local=locals())
50+
51+
class KintexMandelbrotPlatform(HPCStoreXC7K420TPlatform):
52+
def __init__(self, io_voltage="3.3V", toolchain="Vivado"):
53+
self.resources += [
54+
# HSPI
55+
Resource("hspi", 0,
56+
Subsignal("hd", Pins(hd_pins, dir="io")),
57+
58+
Subsignal("tx_ack", Pins(control_pin('HTRDY'), dir="o")),
59+
Subsignal("tx_ready", Pins(control_pin('HTACK'), dir="i")),
60+
61+
Subsignal("tx_req", Pins(control_pin('HRACT'), dir="o")),
62+
Subsignal("rx_act", Pins(control_pin('HTREQ'), dir="i")),
63+
64+
Subsignal("tx_valid", Pins(control_pin('HRVLD'), dir="o")),
65+
Subsignal("rx_valid", Pins(control_pin('HTVLD'), dir="i")),
66+
Attrs(IOSTANDARD="LVCMOS33")
67+
),
68+
Resource("hspi-clocks", 0,
69+
Subsignal("tx_clk", Pins(control_pin('HRCLK'), dir="o")),
70+
Subsignal("rx_clk", Pins(control_pin('HTCLK'), dir="i")),
71+
Attrs(IOSTANDARD="LVCMOS33")
72+
),
73+
]
74+
super().__init__(io_voltage, toolchain)
75+
76+
@property
77+
def file_templates(self):
78+
templates = super().file_templates
79+
templates["{{name}}.xdc"] += "\nset_property CLOCK_DEDICATED_ROUTE FALSE [get_nets pin_hspi-clocks_0__rx_clk/crg_hspi-clocks_0__rx_clk__i]"
80+
return templates
81+
82+
class Xilinx7SeriesClockDomainGenerator(Elaboratable):
83+
DUTY_CYCLE = 0.5
84+
NO_PHASE_SHIFT = 0
85+
86+
def wire_up_reset(self, m, reset):
87+
m.submodules.reset_sync_sync = ResetSynchronizer(reset, domain="sync")
88+
m.submodules.reset_sync_hspi = ResetSynchronizer(reset, domain="hspi")
89+
90+
def __init__(self):
91+
pass
92+
93+
def elaborate(self, platform):
94+
m = Module()
95+
96+
# Create our domains
97+
m.domains.sync = ClockDomain("sync")
98+
m.domains.hspi = ClockDomain("hspi")
99+
100+
clk = platform.request(platform.default_clk)
101+
102+
hspi_clocks = platform.request("hspi-clocks", 0)
103+
main_clock = Signal()
104+
main_locked = Signal()
105+
hspi_clock = Signal()
106+
hspi_locked = Signal()
107+
reset = Signal()
108+
109+
mainpll_feedback = Signal()
110+
hspipll_feedback = Signal()
111+
112+
mainpll_led = platform.request("led", 0)
113+
hspipll_led = platform.request("led", 1)
114+
pol_led = platform.request("led", 2)
115+
116+
m.submodules.mainpll = Instance("PLLE2_ADV",
117+
p_CLKIN1_PERIOD = 10,
118+
p_BANDWIDTH = "OPTIMIZED",
119+
p_COMPENSATION = "ZHOLD",
120+
p_STARTUP_WAIT = "FALSE",
121+
122+
p_DIVCLK_DIVIDE = 1,
123+
p_CLKFBOUT_MULT = 12,
124+
p_CLKFBOUT_PHASE = self.NO_PHASE_SHIFT,
125+
126+
# 100MHz
127+
p_CLKOUT0_DIVIDE = 12,
128+
p_CLKOUT0_PHASE = self.NO_PHASE_SHIFT,
129+
p_CLKOUT0_DUTY_CYCLE = self.DUTY_CYCLE,
130+
131+
i_CLKFBIN = mainpll_feedback,
132+
o_CLKFBOUT = mainpll_feedback,
133+
i_CLKIN1 = clk,
134+
o_CLKOUT0 = main_clock,
135+
o_LOCKED = main_locked,
136+
)
137+
138+
m.submodules.hspipll = Instance("PLLE2_ADV",
139+
p_CLKIN1_PERIOD = 10.416666666, # 96MHz
140+
p_BANDWIDTH = "OPTIMIZED",
141+
p_COMPENSATION = "ZHOLD",
142+
p_STARTUP_WAIT = "FALSE",
143+
144+
p_DIVCLK_DIVIDE = 1,
145+
p_CLKFBOUT_MULT = 12,
146+
p_CLKFBOUT_PHASE = self.NO_PHASE_SHIFT,
147+
148+
# 96MHz
149+
p_CLKOUT0_DIVIDE = 12,
150+
p_CLKOUT0_PHASE = self.NO_PHASE_SHIFT,
151+
p_CLKOUT0_DUTY_CYCLE = self.DUTY_CYCLE,
152+
153+
i_CLKFBIN = hspipll_feedback,
154+
o_CLKFBOUT = hspipll_feedback,
155+
i_CLKIN1 = hspi_clocks.rx_clk,
156+
o_CLKOUT0 = hspi_clock,
157+
o_LOCKED = hspi_locked,
158+
)
159+
160+
m.d.comb += [
161+
reset.eq(~(main_locked & hspi_locked)),
162+
ClockSignal("sync").eq(main_clock),
163+
ClockSignal("hspi").eq(hspi_clock),
164+
mainpll_led.eq(main_locked),
165+
hspipll_led.eq(hspi_locked),
166+
pol_led.eq(0),
167+
]
168+
169+
self.wire_up_reset(m, reset)
170+
171+
return m
172+
173+
class MandelbrotAccelerator(Elaboratable):
174+
def elaborate(self, platform):
175+
m = Module()
176+
m.submodules.crg = Xilinx7SeriesClockDomainGenerator()
177+
178+
hspi_pads = platform.request("hspi", 0)
179+
180+
m.submodules.hspi_tx = hspi_tx = HSPITransmitter(domain="hspi")
181+
m.submodules.hspi_rx = hspi_rx = HSPIReceiver(domain="hspi")
182+
m.submodules.output_fifo = output_fifo = DomainRenamer("hspi")(SyncFIFOBuffered(width=34, depth=4096))
183+
184+
m.d.comb += [
185+
## connect HSPI receiver
186+
*hspi_rx.connect_to_pads(hspi_pads),
187+
188+
## connect HSPI transmitter
189+
hspi_tx.user_id0_in.eq(0x3ABCDEF),
190+
hspi_tx.user_id1_in.eq(0x3456789),
191+
hspi_tx.tll_2b_in.eq(0b11),
192+
hspi_tx.sequence_nr_in.eq(hspi_rx.sequence_nr_out),
193+
194+
*hspi_tx.connect_to_pads(hspi_pads),
195+
hspi_tx.send_ack.eq(0),
196+
197+
*connect_stream_to_fifo(hspi_rx.stream_out, output_fifo, firstBit=-2, lastBit=-1),
198+
*connect_fifo_to_stream(output_fifo, hspi_tx.stream_in, firstBit=-2, lastBit=-1),
199+
]
200+
201+
return m
202+
203+
if __name__ == "__main__":
204+
top = MandelbrotAccelerator()
205+
KintexMandelbrotPlatform(toolchain="Vivado").build(top, do_program=False)

0 commit comments

Comments
 (0)