f06d80bfb9ea5bc07d48329795d35603e7a9d404
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, 7) # 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 litex_name
= name
[:6] + suffix
230 name
= prefix
+ suffix
231 pad
= ['p_' + name
, name
, name
]
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
= orig_name
[:4] + "_".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
= orig_name
[:4] + "_".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'):
295 name2
= 'gpio_%%s(%s)' % i
296 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
297 print ("GPIO pad", name
, pad
)
298 litex_name
= "gpio_%s" % gbank
+ "_".join(name
.split("_")[1:])
300 elif name
.startswith('mtwi'):
303 litex_name
= 'mtwi' + suffix
304 name
= 'i2c' + suffix
305 if name
.startswith('i2c_sda'):
307 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
308 print ("I2C pad", name
, pad
)
310 pad
= ['p_' + name
, name
, name
]
312 elif name
.startswith('twi'):
314 name
= 'i2c' + name
[3:]
316 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
317 print ("I2C pad", name
, pad
)
319 elif name
.startswith('eint'):
323 name2
= 'eint_%s' % i
324 pad
= ['p_' + name
, name2
, name2
]
326 elif name
.startswith('pwm'):
330 name2
= 'pwm(%s)' % i
331 pad
= ['p_' + name
, name2
, name2
]
333 pad
= ['p_' + name
, name
, name
]
334 print ("GPIO pad", name
, pad
)
336 if litex_name
is None:
340 if name
and name
.startswith('jtag'):
343 if name
and not name
.startswith('p_'):
344 if 'power' not in name
and 'ground' not in name
:
347 padbank
[banknum
] = name
349 if domain
is not None:
350 if domain
not in domains
:
352 domains
[domain
].append(name
)
354 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
355 clk
= psp
.clocks
[domain
]
356 if clk
.lower() in orig_name
: # TODO, might over-match
357 clocks
[domain
] = name
359 pinmap
[orig_name
] = name
360 litexmap
[litex_name
] = name
363 if domain
and pad
is not None:
364 # append direction from spec/domain. damn awkward processing
366 fn
, name
= orig_name
.split("_")
371 for k
in psp
.byspec
.keys():
372 if k
.startswith(domain
):
374 print "spec found", domain
, spec
375 assert spec
is not None
378 if pname
.lower().startswith(name
):
380 print "found spec", found
381 assert found
is not None
382 # whewwww. add the direction onto the pad spec list
383 pad
.append(found
[-1])
385 elif pad
is not None:
390 for pl
in [pe
, pw
, pn
, ps
]:
391 for i
in range(len(pl
)):
393 name
= 'nc_%d' % nc_idx
394 name2
= 'nc(%d)' % nc_idx
397 iopads
.append([name
, name2
, name2
, "-"])
413 print "chip domains (excluding sys-default)"
415 print "chip clocks (excluding sys-default)"
425 'pads.instances' : iopads
,
426 'pins.specs' : psp
.byspec
,
428 'litex.map' : litexmap
,
429 'chip.domains' : domains
,
430 'chip.clocks' : clocks
,
431 'chip.n_intpower': n_intpower
,
432 'chip.n_extpower': n_extpower
,