4acb0cf7989f3c4e9df381831ad08303d244b557
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)',
56 'SYS': 'System Control',
57 'MSPI0': 'SPI Master 0 (general)',
60 'EINT': 'External Interrupt',
62 'QSPI': 'QSPI Master',
66 ps
= PinSpec(pinbanks
, fixedpins
, function_names
)
68 #ps.sdram1("", ('W', 0), 0, 15, 6, rev=True) # AD4-9, turned round
69 #ps.vdd("E", ('W', 6), 0, 0, 1)
70 #ps.vss("E", ('W', 7), 0, 0, 1)
71 #ps.vdd("I", ('W', 8), 0, 0, 1)
72 #ps.vss("I", ('W', 9), 0, 0, 1)
73 #ps.sdram1("", ('W', 10), 0, 0, 15, rev=True) # SDRAM DAM0, D0-7, AD0-3
74 #ps.mi2c("", ('W', 26), 0, 0, 2)
75 #ps.vss("I", ('W', 28), 0, 1, 1)
76 #ps.vdd("I", ('W', 29), 0, 1, 1)
82 ps
.vdd("I", ('W', 0), 0, 0, 1)
83 ps
.vss("I", ('W', 1), 0, 0, 1)
84 ps
.vdd("E", ('W', 2), 0, 0, 1)
85 ps
.vss("E", ('W', 3), 0, 0, 1)
86 ps
.ulpi("0", ('W', 4), 0, 0, 12)
87 ps
.vdd("I", ('W', 16), 0, 1, 1)
88 ps
.vss("I", ('W', 17), 0, 1, 1)
89 ps
.ulpi("1", ('W', 18), 0, 0, 12)
90 ps
.vdd("E", ('W', 30), 0, 1, 1)
91 ps
.vss("E", ('W', 31), 0, 1, 1)
92 ps
.uart("0", ('W', 32), 0)
93 ps
.vdd("I", ('W', 34), 0, 2, 1)
94 ps
.vss("I", ('W', 35), 0, 2, 1)
95 ps
.eint("", ('W', 36), 0, 0, 3)
96 ps
.vdd("E", ('W', 42), 0, 2, 1)
97 ps
.vss("E", ('W', 43), 0, 2, 1)
98 ps
.gpio("", ('W', 44), 0, 0, 16) # GPIO 0-16
99 ps
.vdd("I", ('W', 60), 0, 3, 1)
100 ps
.vss("I", ('W', 61), 0, 3, 1)
101 ps
.vdd("E", ('W', 62), 0, 3, 1)
102 ps
.vss("E", ('W', 63), 0, 3, 1)
105 #ps.sdram2("", ('S', 0), 0, 0, 4) # 1st 4, AD10-12,DQM1
106 ps
.vdd("E", ('S', 4), 0, 2, 1)
107 ps
.vss("E", ('S', 5), 0, 2, 1)
108 ps
.vdd("I", ('S', 6), 0, 2, 1)
109 ps
.vss("I", ('S', 7), 0, 2, 1)
110 #ps.sdram2("", ('S', 8), 0, 4, 8) # D8-15
111 #ps.sdram1("", ('S', 16), 0, 21, 9) # clk etc.
112 #ps.vss("I", ('S', 22), 0, 3, 1)
113 #ps.vdd("I", ('S', 23), 0, 3, 1)
114 #ps.vss("E", ('S', 24), 0, 3, 1)
115 #ps.vdd("E", ('S', 25), 0, 3, 1)
116 #ps.mspi("0", ('S', 28), 0)
119 ps
.vss("E", ('E', 0), 0, 0, 1)
120 ps
.vdd("E", ('E', 1), 0, 0, 1)
121 #ps.sdram1("", ('W', 0), 0, 0, 6)
122 ps
.vss("E", ('E', 20), 0, 4, 1)
123 ps
.vdd("E", ('E', 21), 0, 4, 1)
124 ps
.vss("E", ('E', 40), 0, 4, 1)
125 ps
.vdd("E", ('E', 41), 0, 4, 1)
126 ps
.vss("I", ('E', 60), 0, 4, 1)
127 ps
.vdd("I", ('E', 61), 0, 4, 1)
128 #ps.vdd("I", ('E', 8), 0, 4, 1)
129 #ps.vss("I", ('E', 9), 0, 4, 1)
130 #ps.gpio("", ('E', 10), 0, 6, 3) # GPIO 6-8
131 #ps.jtag("", ('E', 13), 0, 0, 4)
132 #ps.gpio("", ('E', 17), 0, 9, 5) # GPIO 9-13
133 #ps.vss("I", ('E', 22), 0, 5, 1)
134 #ps.vdd("I", ('E', 23), 0, 5, 1)
135 #ps.vss("E", ('E', 24), 0, 5, 1)
136 #ps.vdd("E", ('E', 25), 0, 5, 1)
137 #ps.gpio("", ('E', 26), 0, 14, 2) # GPIO 14-15
139 ps
.sys("", ('E', 63), 0, 5, 1) # analog VCO out in right top
141 ps
.vss("E", ('N', 0), 0, 0, 1)
142 ps
.vdd("E", ('N', 1), 0, 0, 1)
143 ps
.vdd("I", ('N', 2), 0, 0, 1)
144 ps
.vss("I", ('N', 3), 0, 0, 1)
145 ps
.sdram1("", ('N', 4), 0, 0, 39)
147 #ps.pwm("", ('N', 2), 0, 0, 2) comment out (litex problem 25mar2021)
148 #ps.mspi("1", ('N', 7), 0) comment out (litex problem 25mar2021)
149 #ps.sdmmc("0", ('N', 11), 0) # comment out (litex problem 25mar2021)
150 ps
.sys("", ('N', 59), 0, 0, 5) # all but analog out in top right
151 ps
.vss("I", ('N', 54), 0, 0, 1)
152 ps
.vdd("I", ('N', 55), 0, 0, 1)
153 ps
.vss("E", ('N', 56), 0, 0, 1)
154 ps
.vdd("E", ('N', 57), 0, 0, 1)
156 ps
.rgmii("0", ('E', 42), 0, 0, 18)
157 ps
.rgmii("1", ('E', 22), 0, 0, 18)
158 ps
.rgmii("2", ('E', 2), 0, 0, 18)
159 ps
.rgmii("3", ('S', 44), 0, 0, 18)
160 ps
.rgmii("4", ('S', 24), 0, 0, 18)
161 #ps.mquadspi("1", ('S', 0), 0)
163 print ("ps clocks", ps
.clocks
)
165 # Scenarios below can be spec'd out as either "find first interface"
166 # by name/number e.g. SPI1, or as "find in bank/mux" which must be
167 # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
168 # EINT and PWM are grouped together, specially, but may still be spec'd
169 # using "BM:Name". Pins are removed in-order as listed from
170 # lists (interfaces, EINTs, PWMs) from available pins.
172 'RG0', 'RG1', 'RG2', 'RG3', 'RG4',
183 ngi_router_pwm
= []#['B0:PWM_0']
185 'SD0': 'user-facing: internal (on Card), multiplexed with JTAG\n'
186 'and UART2, for debug purposes',
195 'B1:LCD/22': '18-bit RGB/TTL LCD',
196 'ULPI0/8': 'user-facing: internal (on Card), USB-OTG ULPI PHY',
197 'ULPI1': 'dual USB2 Host ULPI PHY'
200 ps
.add_scenario("NGI ROUTER Libre-SOC 180nm", ngi_router
, ngi_router_eint
, ngi_router_pwm
,
206 # map pins to litex name conventions, primarily for use in coriolis2
207 # yes this is a mess. it'll do the job though. improvements later
208 def pinparse(psp
, pinspec
):
209 p
= Parse(pinspec
, verify
=False)
213 print (p
.muxed_cells
)
214 print (p
.muxed_cells_bank
)
216 # TODO - Turn the number of pins per side into a variable?
221 pads
= {'N': pn
, 'S': ps
, 'E': pe
, 'W': pw
}
229 for (padnum
, name
, x
), bank
in zip(p
.muxed_cells
, p
.muxed_cells_bank
):
232 domain
= None # TODO, get this from the PinSpec. sigh
234 start
= p
.bankstart
[bank
]
235 banknum
= padnum
- start
236 print ("bank", bank
, banknum
, "padname", name
, padnum
, x
)
240 if name
.startswith('vss'):
241 name
= 'p_%s_' % name
[:-2] + name
[-1]
243 name
= 'ground_' + name
[-1]
246 name
= 'ioground_' + name
[-1]
250 elif name
.startswith('vdd'):
253 name
= 'power_' + name
[-1]
257 name
= 'iopower_' + name
[-1]
261 elif name
.startswith('sys'):
263 if name
== 'sys_pllclk':
264 pad
= ["p_"+name
, name
, name
]
265 elif name
== 'sys_rst':
266 #name = 'p_sys_rst_1'
267 pad
= [name
, name
, name
]
268 padbank
[banknum
] = name
269 print ("sys_rst add", bank
, banknum
, name
)
271 elif name
== 'sys_pllclk':
273 elif name
== 'sys_pllvcout':
274 name
= 'sys_pll_vco_o'
275 pad
= ['p_' + name
, name
, name
, "A"] # A for Analog
276 elif name
== 'sys_plltestout':
277 name
= 'sys_pll_testout_o'
278 pad
= ['p_' + name
, name
, name
]
279 elif name
.startswith('sys_pllsel'):
281 name2
= 'sys_clksel_i(%s)' % i
282 name
= 'p_sys_clksel_' + i
283 pad
= [name
, name2
, name2
]
285 # iopads.append([pname, name, name])
286 print ("sys pad", name
)
288 elif name
.startswith('mspi0') or name
.startswith('mspi1'):
293 elif suffix
== 'nss':
295 if name
.startswith('mspi0'):
296 prefix
= 'spimaster_'
298 prefix
= 'spisdcard_'
299 litex_name
= name
[:6] + suffix
300 name
= prefix
+ suffix
301 pad
= ['p_' + name
, name
, name
]
303 elif name
.startswith('sd0'):
305 if name
.startswith('sd0_d'):
307 name
= 'sdcard_data' + i
308 name2
= 'sdcard_data_%%s(%s)' % i
309 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
310 elif name
.startswith('sd0_cmd'):
312 name2
= 'sdcard_cmd_%s'
313 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
315 name
= 'sdcard_' + name
[4:]
316 pad
= ['p_' + name
, name
, name
]
317 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
319 elif name
.startswith('sdr'):
321 if name
== 'sdr_clk':
323 pad
= ['p_' + name
, name
, name
]
324 elif name
.startswith('sdr_ad'):
326 name
= 'sdram_a_' + i
327 name2
= 'sdram_a(%s)' % i
328 pad
= ['p_' + name
, name2
, name2
]
329 elif name
.startswith('sdr_ba'):
331 name
= 'sdram_ba_' + i
332 name2
= 'sdram_ba(%s)' % i
333 pad
= ['p_' + name
, name2
, name2
]
334 elif name
.startswith('sdr_dqm'):
336 name
= 'sdram_dm_' + i
337 name2
= 'sdram_dm(%s)' % i
338 pad
= ['p_' + name
, name2
, name2
]
339 elif name
.startswith('sdr_d'):
341 name
= 'sdram_dq_' + i
342 name2
= 'sdram_dq_%%s(%s)' % i
343 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
344 elif name
== 'sdr_csn0':
346 pad
= ['p_' + name
, name
, name
]
347 elif name
[-1] == 'n':
348 name
= 'sdram_' + name
[4:-1] + '_n'
349 pad
= ['p_' + name
, name
, name
]
351 name
= 'sdram_' + name
[4:]
352 pad
= ['p_' + name
, name
, name
]
353 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
355 elif name
.startswith('uart'):
357 name
= 'uart_' + name
[6:]
358 pad
= ['p_' + name
, name
, name
]
360 elif name
.startswith('gpio'):
365 name2
= 'gpio_%%s(%s)' % i
366 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
367 print ("GPIO pad", name
, pad
)
368 litex_name
= "gpio_%s" % gbank
+ "_".join(name
.split("_")[1:])
370 elif name
.startswith('mtwi'):
373 litex_name
= 'mtwi' + suffix
374 name
= 'i2c' + suffix
375 if name
.startswith('i2c_sda'):
377 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
378 print ("I2C pad", name
, pad
)
380 pad
= ['p_' + name
, name
, name
]
382 elif name
.startswith('twi'):
384 name
= 'i2c' + name
[3:]
386 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
387 print ("I2C pad", name
, pad
)
389 elif name
.startswith('eint'):
393 name2
= 'eint_%s' % i
394 pad
= ['p_' + name
, name2
, name2
]
396 elif name
.startswith('pwm'):
400 name2
= 'pwm(%s)' % i
401 pad
= ['p_' + name
, name2
, name2
]
403 pad
= ['p_' + name
, name
, name
]
404 print ("GPIO pad", name
, pad
)
406 if litex_name
is None:
410 if name
and name
.startswith('jtag'):
413 if name
and not name
.startswith('p_'):
414 if 'power' not in name
and 'ground' not in name
:
417 padbank
[banknum
] = name
419 if domain
is not None:
420 if domain
not in domains
:
422 domains
[domain
].append(name
)
424 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
425 clk
= psp
.clocks
[domain
]
426 if clk
.lower() in orig_name
: # TODO, might over-match
427 clocks
[domain
] = name
429 pinmap
[orig_name
] = name
430 litexmap
[litex_name
] = name
433 if domain
and pad
is not None:
434 # append direction from spec/domain. damn awkward processing
436 fn
, name
= orig_name
.split("_")
441 for k
in psp
.byspec
.keys():
442 if k
.startswith(domain
):
444 print ("spec found", domain
, spec
)
445 assert spec
is not None
448 if pname
.lower().startswith(name
):
450 print ("found spec", found
)
451 assert found
is not None
452 # whewwww. add the direction onto the pad spec list
459 elif pad
is not None:
464 for pl
in [pe
, pw
, pn
, ps
]:
465 for i
in range(len(pl
)):
467 name
= 'nc_%d' % nc_idx
468 name2
= 'nc(%d)' % nc_idx
471 iopads
.append([name
, name2
, name2
, "-"])
487 print ("chip domains (excluding sys-default)")
489 print ("chip clocks (excluding sys-default)")
499 'pads.instances' : iopads
,
500 'pins.specs' : psp
.byspec
,
502 'litex.map' : litexmap
,
503 'chip.domains' : domains
,
504 'chip.clocks' : clocks
,
505 'chip.n_intpower': n_intpower
,
506 'chip.n_extpower': n_extpower
,