2 # see https://bugs.libre-soc.org/show_bug.cgi?id=304
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 pinbanks
= OrderedDict((
42 'PWM': 'PWM (pulse-width modulation)',
43 'MSPI0': 'SPI Master 1 (general)',
44 'MSPI1': 'SPI Master 2 (SDCard)',
45 'UART0': 'UART (TX/RX) 1',
46 'SYS': 'System Control',
48 'EINT': 'External Interrupt',
51 'MTWI': 'I2C Master 1',
56 #'LPC1': 'Low Pincount Interface 1',
57 #'LPC2': 'Low Pincount Interface 2',
60 ps
= PinSpec(pinbanks
, fixedpins
, function_names
)
62 ps
.vss("E", ('N', 0), 0, 0, 1)
63 ps
.vdd("E", ('N', 1), 0, 0, 1)
64 ps
.sdram1("", ('N', 2), 0, 0, 30)
65 ps
.vss("I", ('N', 30), 0, 0, 1)
66 ps
.vdd("I", ('N', 31), 0, 0, 1)
68 ps
.vss("E", ('E', 0), 0, 1, 1)
69 ps
.vdd("E", ('E', 1), 0, 1, 1)
70 ps
.sdram2("", ('E', 2), 0, 0, 12)
71 ps
.vss("I", ('E', 14), 0, 1, 1)
72 ps
.vdd("I", ('E', 15), 0, 1, 1)
73 ps
.gpio("", ('E', 16), 0, 8, 8)
74 ps
.jtag("", ('E', 25), 0, 0, 4)
76 ps
.vss("I", ('S', 0), 0, 2, 1)
77 ps
.vdd("I", ('S', 1), 0, 2, 1)
78 ps
.mi2c("", ('S', 2), 0, 0, 2)
79 ps
.mspi("0", ('S', 8), 0)
80 ps
.uart("0", ('S', 13), 0)
81 ps
.gpio("", ('S', 15), 0, 0, 8)
82 ps
.sys("", ('S', 23), 0, 0, 2) # should be 7, to do all PLL pins
83 ps
.vss("I", ('S', 30), 0, 3, 1)
84 ps
.vdd("I", ('S', 31), 0, 3, 1)
86 ps
.vss("E", ('W', 0), 0, 2, 1)
87 ps
.vdd("E", ('W', 1), 0, 2, 1)
88 #ps.pwm("", ('W', 2), 0, 0, 2) comment out (litex problem 25mar2021)
89 ps
.eint("", ('W', 4), 0, 0, 3)
90 #ps.mspi("1", ('W', 7), 0) comment out (litex problem 25mar2021)
91 #ps.sdmmc("0", ('W', 11), 0) # comment out (litex problem 25mar2021)
92 ps
.vss("I", ('W', 30), 0, 4, 1)
93 ps
.vdd("I", ('W', 31), 0, 4, 1)
95 #ps.mquadspi("1", ('S', 0), 0)
97 print "ps clocks", ps
.clocks
99 # Scenarios below can be spec'd out as either "find first interface"
100 # by name/number e.g. SPI1, or as "find in bank/mux" which must be
101 # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
102 # EINT and PWM are grouped together, specially, but may still be spec'd
103 # using "BM:Name". Pins are removed in-order as listed from
104 # lists (interfaces, EINTs, PWMs) from available pins.
107 # 'SD0', litex problem 25mar2021
108 'UART0', 'GPIOS', 'GPIOE', 'JTAG', 'PWM', 'EINT',
111 # 'MSPI1', litex problem 25mar2021
114 ls180_pwm
= []#['B0:PWM_0']
116 'SD0': 'user-facing: internal (on Card), multiplexed with JTAG\n'
117 'and UART2, for debug purposes',
126 'B1:LCD/22': '18-bit RGB/TTL LCD',
127 'ULPI0/8': 'user-facing: internal (on Card), USB-OTG ULPI PHY',
128 'ULPI1': 'dual USB2 Host ULPI PHY'
131 ps
.add_scenario("Libre-SOC 180nm", ls180
, ls180_eint
, ls180_pwm
,
137 # map pins to litex name conventions, primarily for use in coriolis2
138 # yes this is a mess. it'll do the job though. improvements later
139 def pinparse(psp
, pinspec
):
140 p
= Parse(pinspec
, verify
=False)
145 print p
.muxed_cells_bank
151 pads
= {'N': pn
, 'S': ps
, 'E': pe
, 'W': pw
}
159 for (padnum
, name
, x
), bank
in zip(p
.muxed_cells
, p
.muxed_cells_bank
):
162 domain
= None # TODO, get this from the PinSpec. sigh
164 start
= p
.bankstart
[bank
]
165 banknum
= padnum
- start
166 print "bank", bank
, banknum
, "padname", name
, padnum
, x
170 if name
.startswith('vss'):
171 name
= 'p_%s_' % name
[:-2] + name
[-1]
173 name
= 'ground_' + name
[-1]
176 name
= 'ioground_' + name
[-1]
180 elif name
.startswith('vdd'):
183 name
= 'power_' + name
[-1]
187 name
= 'iopower_' + name
[-1]
191 elif name
.startswith('sys'):
193 if name
== 'sys_clk':
194 pad
= ["p_"+name
, name
, name
]
195 elif name
== 'sys_rst':
196 #name = 'p_sys_rst_1'
197 pad
= [name
, name
, name
]
198 padbank
[banknum
] = name
199 print "sys_rst add", bank
, banknum
, name
201 elif name
== 'sys_pllclk':
203 elif name
== 'sys_pllvcout':
204 name
= 'sys_pll_vco_o'
205 pad
= ['p_' + name
, name
, name
]
206 elif name
== 'sys_plltestout':
207 name
= 'sys_pll_testout_o'
208 pad
= ['p_' + name
, name
, name
]
209 elif name
.startswith('sys_pllsel'):
211 name2
= 'sys_clksel_i(%s)' % i
212 name
= 'p_sys_clksel_' + i
213 pad
= [name
, name2
, name2
]
215 # iopads.append([pname, name, name])
216 print "sys pad", name
218 elif name
.startswith('mspi0') or name
.startswith('mspi1'):
223 elif suffix
== 'nss':
225 if name
.startswith('mspi0'):
226 prefix
= 'spimaster_'
228 prefix
= 'spisdcard_'
229 name
= prefix
+ suffix
230 pad
= ['p_' + name
, name
, name
]
231 litex_name
= name
[:6] + suffix
233 elif name
.startswith('sd0'):
235 if name
.startswith('sd0_d'):
237 name
= 'sdcard_data' + i
238 name2
= 'sdcard_data_%%s(%s)' % i
239 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
240 elif name
.startswith('sd0_cmd'):
242 name2
= 'sdcard_cmd_%s'
243 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
245 name
= 'sdcard_' + name
[4:]
246 pad
= ['p_' + name
, name
, name
]
247 litex_name
= name
[:6] + "_".join(name
.split("_")[1:])
249 elif name
.startswith('sdr'):
251 if name
== 'sdr_clk':
253 pad
= ['p_' + name
, name
, name
]
254 elif name
.startswith('sdr_ad'):
256 name
= 'sdram_a_' + i
257 name2
= 'sdram_a(%s)' % i
258 pad
= ['p_' + name
, name2
, name2
]
259 elif name
.startswith('sdr_ba'):
261 name
= 'sdram_ba_' + i
262 name2
= 'sdram_ba(%s)' % i
263 pad
= ['p_' + name
, name2
, name2
]
264 elif name
.startswith('sdr_dqm'):
266 name
= 'sdram_dm_' + i
267 name2
= 'sdram_dm(%s)' % i
268 pad
= ['p_' + name
, name2
, name2
]
269 elif name
.startswith('sdr_d'):
271 name
= 'sdram_dq_' + i
272 name2
= 'sdram_dq_%%s(%s)' % i
273 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
274 elif name
== 'sdr_csn0':
276 pad
= ['p_' + name
, name
, name
]
277 elif name
[-1] == 'n':
278 name
= 'sdram_' + name
[4:-1] + '_n'
279 pad
= ['p_' + name
, name
, name
]
281 name
= 'sdram_' + name
[4:]
282 pad
= ['p_' + name
, name
, name
]
283 litex_name
= name
[:5] + "_".join(name
.split("_")[1:])
285 elif name
.startswith('uart'):
287 name
= 'uart_' + name
[6:]
288 pad
= ['p_' + name
, name
, name
]
290 elif name
.startswith('gpio'):
294 name2
= 'gpio_%%s(%s)' % i
295 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
296 print ("GPIO pad", name
, pad
)
298 elif name
.startswith('mtwi'):
300 name
= 'i2c' + name
[4:]
301 if name
.startswith('i2c_sda'):
303 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
304 print ("I2C pad", name
, pad
)
306 pad
= ['p_' + name
, name
, name
]
308 elif name
.startswith('twi'):
310 name
= 'i2c' + name
[3:]
312 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
313 print ("I2C pad", name
, pad
)
315 elif name
.startswith('eint'):
319 name2
= 'eint_%s' % i
320 pad
= ['p_' + name
, name2
, name2
]
322 elif name
.startswith('pwm'):
326 name2
= 'pwm(%s)' % i
327 pad
= ['p_' + name
, name2
, name2
]
329 pad
= ['p_' + name
, name
, name
]
330 print ("GPIO pad", name
, pad
)
332 if litex_name
is None:
336 if name
and name
.startswith('jtag'):
339 if name
and not name
.startswith('p_'):
340 if 'power' not in name
and 'ground' not in name
:
343 padbank
[banknum
] = name
345 if domain
is not None:
346 if domain
not in domains
:
348 domains
[domain
].append(name
)
350 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
351 clk
= psp
.clocks
[domain
]
352 if clk
.lower() in orig_name
: # TODO, might over-match
353 clocks
[domain
] = name
355 pinmap
[orig_name
] = name
356 litexmap
[litex_name
] = name
359 if domain
and pad
is not None:
360 # append direction from spec/domain. damn awkward processing
362 fn
, name
= orig_name
.split("_")
367 for k
in psp
.byspec
.keys():
368 if k
.startswith(domain
):
370 print "spec found", domain
, spec
371 assert spec
is not None
374 if pname
.lower().startswith(name
):
376 print "found spec", found
377 assert found
is not None
378 # whewwww. add the direction onto the pad spec list
379 pad
.append(found
[-1])
381 elif pad
is not None:
386 for pl
in [pe
, pw
, pn
, ps
]:
387 for i
in range(len(pl
)):
389 name
= 'nc_%d' % nc_idx
390 name2
= 'nc(%d)' % nc_idx
393 iopads
.append([name
, name2
, name2
, "-"])
409 print "chip domains (excluding sys-default)"
411 print "chip clocks (excluding sys-default)"
421 'pads.instances' : iopads
,
422 'pins.specs' : psp
.byspec
,
424 'litex.map' : litexmap
,
425 'chip.domains' : domains
,
426 'chip.clocks' : clocks
,
427 'chip.n_intpower': n_intpower
,
428 'chip.n_extpower': n_extpower
,