2 # see https://bugs.libre-soc.org/show_bug.cgi?id=739
4 from spec
.base
import PinSpec
5 from parse
import Parse
8 from pprint
import pprint
9 from spec
.ifaceprint
import display
, display_fns
, check_functions
10 from spec
.ifaceprint
import display_fixed
11 from collections
import OrderedDict
14 # TODO - Turn the number of pins per side into a variable?
15 pinbanks
= OrderedDict((
44 'RG0': 'Gigabit Ethernet 0',
45 'RG1': 'Gigabit Ethernet 1',
46 'RG2': 'Gigabit Ethernet 2',
47 'RG3': 'Gigabit Ethernet 3',
48 'RG4': 'Gigabit Ethernet 4',
49 'ULPI0': 'USB ULPI0 PHY',
50 'ULPI1': 'USB ULPI1 PHY',
52 'UART0': 'UART (TX/RX)',
54 'VDD': '1.8V Core Power',
55 'VSS': '1.8V Core GND',
56 'VDD': '3.3V I/O Power',
57 'VSS': '3.3V I/O GND',
58 'SYS': 'System Control',
59 'MSPI0': 'SPI Master 0 (general)',
62 'EINT': 'External Interrupt',
64 'QSPI': 'QSPI Master',
68 ps
= PinSpec(pinbanks
, fixedpins
, function_names
)
70 ps
.sdram1("", ('W', 0), 0, 15, 6, rev
=True) # AD4-9, turned round
71 ps
.vdd("E", ('W', 6), 0, 0, 1)
72 ps
.vss("E", ('W', 7), 0, 0, 1)
73 ps
.vdd("I", ('W', 8), 0, 0, 1)
74 ps
.vss("I", ('W', 9), 0, 0, 1)
75 ps
.sdram1("", ('W', 10), 0, 0, 15, rev
=True) # SDRAM DAM0, D0-7, AD0-3
76 ps
.mi2c("", ('W', 26), 0, 0, 2)
77 ps
.vss("I", ('W', 28), 0, 1, 1)
78 ps
.vdd("I", ('W', 29), 0, 1, 1)
79 ps
.vss("E", ('W', 30), 0, 1, 1)
80 ps
.vdd("E", ('W', 31), 0, 1, 1)
82 ps
.sdram2("", ('S', 0), 0, 0, 4) # 1st 4, AD10-12,DQM1
83 ps
.vdd("E", ('S', 4), 0, 2, 1)
84 ps
.vss("E", ('S', 5), 0, 2, 1)
85 ps
.vdd("I", ('S', 6), 0, 2, 1)
86 ps
.vss("I", ('S', 7), 0, 2, 1)
87 ps
.sdram2("", ('S', 8), 0, 4, 8) # D8-15
88 ps
.sdram1("", ('S', 16), 0, 21, 9) # clk etc.
89 ps
.vss("I", ('S', 22), 0, 3, 1)
90 ps
.vdd("I", ('S', 23), 0, 3, 1)
91 ps
.vss("E", ('S', 24), 0, 3, 1)
92 ps
.vdd("E", ('S', 25), 0, 3, 1)
93 ps
.uart("0", ('S', 26), 0)
94 ps
.mspi("0", ('S', 28), 0)
96 ps
.gpio("", ('E', 0), 0, 0, 6) # GPIO 0-5
97 ps
.vss("E", ('E', 6), 0, 4, 1)
98 ps
.vdd("E", ('E', 7), 0, 4, 1)
99 ps
.vdd("I", ('E', 8), 0, 4, 1)
100 ps
.vss("I", ('E', 9), 0, 4, 1)
101 ps
.gpio("", ('E', 10), 0, 6, 3) # GPIO 6-8
102 ps
.jtag("", ('E', 13), 0, 0, 4)
103 ps
.gpio("", ('E', 17), 0, 9, 5) # GPIO 9-13
104 ps
.vss("I", ('E', 22), 0, 5, 1)
105 ps
.vdd("I", ('E', 23), 0, 5, 1)
106 ps
.vss("E", ('E', 24), 0, 5, 1)
107 ps
.vdd("E", ('E', 25), 0, 5, 1)
108 ps
.gpio("", ('E', 26), 0, 14, 2) # GPIO 14-15
109 ps
.eint("", ('E', 28), 0, 0, 3)
110 ps
.rgmii("0", ('E', 31), 0, 0, 18)
111 ps
.sys("", ('E', 63), 0, 5, 1) # analog VCO out in right top
113 ps
.vss("E", ('N', 6), 0, 6, 1)
114 ps
.vdd("E", ('N', 7), 0, 6, 1)
115 ps
.vdd("I", ('N', 8), 0, 6, 1)
116 ps
.vss("I", ('N', 9), 0, 6, 1)
117 ps
.rgmii("1", ('N', 10), 0, 0, 18)
118 #ps.pwm("", ('N', 2), 0, 0, 2) comment out (litex problem 25mar2021)
119 #ps.mspi("1", ('N', 7), 0) comment out (litex problem 25mar2021)
120 #ps.sdmmc("0", ('N', 11), 0) # comment out (litex problem 25mar2021)
121 ps
.sys("", ('N', 59), 0, 0, 5) # all but analog out in top right
122 ps
.vss("I", ('N', 54), 0, 7, 1)
123 ps
.vdd("I", ('N', 55), 0, 7, 1)
124 ps
.vss("E", ('N', 56), 0, 7, 1)
125 ps
.vdd("E", ('N', 57), 0, 7, 1)
127 ps
.rgmii("2", ('N', 31), 0, 0, 18)
128 #ps.mquadspi("1", ('S', 0), 0)
130 print ("ps clocks", ps
.clocks
)
132 # Scenarios below can be spec'd out as either "find first interface"
133 # by name/number e.g. SPI1, or as "find in bank/mux" which must be
134 # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
135 # EINT and PWM are grouped together, specially, but may still be spec'd
136 # using "BM:Name". Pins are removed in-order as listed from
137 # lists (interfaces, EINTs, PWMs) from available pins.
140 # 'SD0', litex problem 25mar2021
141 'UART0', 'GPIOS', 'GPIOE', 'JTAG', 'PWM', 'EINT',
144 'RG0', 'RG1', 'RG2', 'RG3', 'RG4',
145 # 'MSPI1', litex problem 25mar2021
148 ngi_router_pwm
= []#['B0:PWM_0']
150 'SD0': 'user-facing: internal (on Card), multiplexed with JTAG\n'
151 'and UART2, for debug purposes',
160 'B1:LCD/22': '18-bit RGB/TTL LCD',
161 'ULPI0/8': 'user-facing: internal (on Card), USB-OTG ULPI PHY',
162 'ULPI1': 'dual USB2 Host ULPI PHY'
165 ps
.add_scenario("NGI ROUTER Libre-SOC 180nm", ngi_router
, ngi_router_eint
, ngi_router_pwm
,
171 # map pins to litex name conventions, primarily for use in coriolis2
172 # yes this is a mess. it'll do the job though. improvements later
173 def pinparse(psp
, pinspec
):
174 p
= Parse(pinspec
, verify
=False)
178 print (p
.muxed_cells
)
179 print (p
.muxed_cells_bank
)
181 # TODO - Turn the number of pins per side into a variable?
186 pads
= {'N': pn
, 'S': ps
, 'E': pe
, 'W': pw
}
194 for (padnum
, name
, x
), bank
in zip(p
.muxed_cells
, p
.muxed_cells_bank
):
197 domain
= None # TODO, get this from the PinSpec. sigh
199 start
= p
.bankstart
[bank
]
200 banknum
= padnum
- start
201 print ("bank", bank
, banknum
, "padname", name
, padnum
, x
)
205 if name
.startswith('vss'):
206 name
= 'p_%s_' % name
[:-2] + name
[-1]
208 name
= 'ground_' + name
[-1]
211 name
= 'ioground_' + name
[-1]
215 elif name
.startswith('vdd'):
218 name
= 'power_' + name
[-1]
222 name
= 'iopower_' + name
[-1]
226 elif name
.startswith('sys'):
228 if name
== 'sys_pllclk':
229 pad
= ["p_"+name
, name
, name
]
230 elif name
== 'sys_rst':
231 #name = 'p_sys_rst_1'
232 pad
= [name
, name
, name
]
233 padbank
[banknum
] = name
234 print ("sys_rst add", bank
, banknum
, name
)
236 elif name
== 'sys_pllclk':
238 elif name
== 'sys_pllvcout':
239 name
= 'sys_pll_vco_o'
240 pad
= ['p_' + name
, name
, name
, "A"] # A for Analog
241 elif name
== 'sys_plltestout':
242 name
= 'sys_pll_testout_o'
243 pad
= ['p_' + name
, name
, name
]
244 elif name
.startswith('sys_pllsel'):
246 name2
= 'sys_clksel_i(%s)' % i
247 name
= 'p_sys_clksel_' + i
248 pad
= [name
, name2
, name2
]
250 # iopads.append([pname, name, name])
251 print ("sys pad", name
)
253 elif name
.startswith('mspi0') or name
.startswith('mspi1'):
258 elif suffix
== 'nss':
260 if name
.startswith('mspi0'):
261 prefix
= 'spimaster_'
263 prefix
= 'spisdcard_'
264 litex_name
= name
[:6] + suffix
265 name
= prefix
+ suffix
266 pad
= ['p_' + name
, name
, name
]
268 elif name
.startswith('sd0'):
270 if name
.startswith('sd0_d'):
272 name
= 'sdcard_data' + i
273 name2
= 'sdcard_data_%%s(%s)' % i
274 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
275 elif name
.startswith('sd0_cmd'):
277 name2
= 'sdcard_cmd_%s'
278 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
280 name
= 'sdcard_' + name
[4:]
281 pad
= ['p_' + name
, name
, name
]
282 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
284 elif name
.startswith('sdr'):
286 if name
== 'sdr_clk':
288 pad
= ['p_' + name
, name
, name
]
289 elif name
.startswith('sdr_ad'):
291 name
= 'sdram_a_' + i
292 name2
= 'sdram_a(%s)' % i
293 pad
= ['p_' + name
, name2
, name2
]
294 elif name
.startswith('sdr_ba'):
296 name
= 'sdram_ba_' + i
297 name2
= 'sdram_ba(%s)' % i
298 pad
= ['p_' + name
, name2
, name2
]
299 elif name
.startswith('sdr_dqm'):
301 name
= 'sdram_dm_' + i
302 name2
= 'sdram_dm(%s)' % i
303 pad
= ['p_' + name
, name2
, name2
]
304 elif name
.startswith('sdr_d'):
306 name
= 'sdram_dq_' + i
307 name2
= 'sdram_dq_%%s(%s)' % i
308 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
309 elif name
== 'sdr_csn0':
311 pad
= ['p_' + name
, name
, name
]
312 elif name
[-1] == 'n':
313 name
= 'sdram_' + name
[4:-1] + '_n'
314 pad
= ['p_' + name
, name
, name
]
316 name
= 'sdram_' + name
[4:]
317 pad
= ['p_' + name
, name
, name
]
318 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
320 elif name
.startswith('uart'):
322 name
= 'uart_' + name
[6:]
323 pad
= ['p_' + name
, name
, name
]
325 elif name
.startswith('gpio'):
330 name2
= 'gpio_%%s(%s)' % i
331 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
332 print ("GPIO pad", name
, pad
)
333 litex_name
= "gpio_%s" % gbank
+ "_".join(name
.split("_")[1:])
335 elif name
.startswith('mtwi'):
338 litex_name
= 'mtwi' + suffix
339 name
= 'i2c' + suffix
340 if name
.startswith('i2c_sda'):
342 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
343 print ("I2C pad", name
, pad
)
345 pad
= ['p_' + name
, name
, name
]
347 elif name
.startswith('twi'):
349 name
= 'i2c' + name
[3:]
351 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
352 print ("I2C pad", name
, pad
)
354 elif name
.startswith('eint'):
358 name2
= 'eint_%s' % i
359 pad
= ['p_' + name
, name2
, name2
]
361 elif name
.startswith('pwm'):
365 name2
= 'pwm(%s)' % i
366 pad
= ['p_' + name
, name2
, name2
]
368 pad
= ['p_' + name
, name
, name
]
369 print ("GPIO pad", name
, pad
)
371 if litex_name
is None:
375 if name
and name
.startswith('jtag'):
378 if name
and not name
.startswith('p_'):
379 if 'power' not in name
and 'ground' not in name
:
382 padbank
[banknum
] = name
384 if domain
is not None:
385 if domain
not in domains
:
387 domains
[domain
].append(name
)
389 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
390 clk
= psp
.clocks
[domain
]
391 if clk
.lower() in orig_name
: # TODO, might over-match
392 clocks
[domain
] = name
394 pinmap
[orig_name
] = name
395 litexmap
[litex_name
] = name
398 if domain
and pad
is not None:
399 # append direction from spec/domain. damn awkward processing
401 fn
, name
= orig_name
.split("_")
406 for k
in psp
.byspec
.keys():
407 if k
.startswith(domain
):
409 print ("spec found", domain
, spec
)
410 assert spec
is not None
413 if pname
.lower().startswith(name
):
415 print ("found spec", found
)
416 assert found
is not None
417 # whewwww. add the direction onto the pad spec list
424 elif pad
is not None:
429 for pl
in [pe
, pw
, pn
, ps
]:
430 for i
in range(len(pl
)):
432 name
= 'nc_%d' % nc_idx
433 name2
= 'nc(%d)' % nc_idx
436 iopads
.append([name
, name2
, name2
, "-"])
452 print ("chip domains (excluding sys-default)")
454 print ("chip clocks (excluding sys-default)")
464 'pads.instances' : iopads
,
465 'pins.specs' : psp
.byspec
,
467 'litex.map' : litexmap
,
468 'chip.domains' : domains
,
469 'chip.clocks' : clocks
,
470 'chip.n_intpower': n_intpower
,
471 'chip.n_extpower': n_extpower
,