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 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'):
302 name
= 'i2c' + name
[4:]
303 if name
.startswith('i2c_sda'):
305 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
306 print ("I2C pad", name
, pad
)
308 pad
= ['p_' + name
, name
, name
]
310 elif name
.startswith('twi'):
312 name
= 'i2c' + name
[3:]
314 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
315 print ("I2C pad", name
, pad
)
317 elif name
.startswith('eint'):
321 name2
= 'eint_%s' % i
322 pad
= ['p_' + name
, name2
, name2
]
324 elif name
.startswith('pwm'):
328 name2
= 'pwm(%s)' % i
329 pad
= ['p_' + name
, name2
, name2
]
331 pad
= ['p_' + name
, name
, name
]
332 print ("GPIO pad", name
, pad
)
334 if litex_name
is None:
338 if name
and name
.startswith('jtag'):
341 if name
and not name
.startswith('p_'):
342 if 'power' not in name
and 'ground' not in name
:
345 padbank
[banknum
] = name
347 if domain
is not None:
348 if domain
not in domains
:
350 domains
[domain
].append(name
)
352 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
353 clk
= psp
.clocks
[domain
]
354 if clk
.lower() in orig_name
: # TODO, might over-match
355 clocks
[domain
] = name
357 pinmap
[orig_name
] = name
358 litexmap
[litex_name
] = name
361 if domain
and pad
is not None:
362 # append direction from spec/domain. damn awkward processing
364 fn
, name
= orig_name
.split("_")
369 for k
in psp
.byspec
.keys():
370 if k
.startswith(domain
):
372 print "spec found", domain
, spec
373 assert spec
is not None
376 if pname
.lower().startswith(name
):
378 print "found spec", found
379 assert found
is not None
380 # whewwww. add the direction onto the pad spec list
381 pad
.append(found
[-1])
383 elif pad
is not None:
388 for pl
in [pe
, pw
, pn
, ps
]:
389 for i
in range(len(pl
)):
391 name
= 'nc_%d' % nc_idx
392 name2
= 'nc(%d)' % nc_idx
395 iopads
.append([name
, name2
, name2
, "-"])
411 print "chip domains (excluding sys-default)"
413 print "chip clocks (excluding sys-default)"
423 'pads.instances' : iopads
,
424 'pins.specs' : psp
.byspec
,
426 'litex.map' : litexmap
,
427 'chip.domains' : domains
,
428 'chip.clocks' : clocks
,
429 'chip.n_intpower': n_intpower
,
430 'chip.n_extpower': n_extpower
,