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)
144 print p
.muxed_cells_bank
150 pads
= {'N': pn
, 'S': ps
, 'E': pe
, 'W': pw
}
158 for (padnum
, name
, x
), bank
in zip(p
.muxed_cells
, p
.muxed_cells_bank
):
160 domain
= None # TODO, get this from the PinSpec. sigh
162 start
= p
.bankstart
[bank
]
163 banknum
= padnum
- start
164 print "bank", bank
, banknum
, "padname", name
, padnum
, x
168 if name
.startswith('vss'):
169 name
= 'p_%s_' % name
[:-2] + name
[-1]
171 name
= 'ground_' + name
[-1]
174 name
= 'ioground_' + name
[-1]
178 elif name
.startswith('vdd'):
181 name
= 'power_' + name
[-1]
185 name
= 'iopower_' + name
[-1]
189 elif name
.startswith('sys'):
191 if name
== 'sys_clk':
192 pad
= ["p_"+name
, name
, name
]
193 elif name
== 'sys_rst':
194 #name = 'p_sys_rst_1'
195 pad
= [name
, name
, name
]
196 padbank
[banknum
] = name
197 print "sys_rst add", bank
, banknum
, name
199 elif name
== 'sys_pllclk':
201 elif name
== 'sys_pllock':
202 name
= 'sys_pll_lck_o'
203 pad
= ['p_' + name
, name
, name
]
204 elif name
== 'sys_pllout':
205 name
= 'sys_pll_18_o'
206 pad
= ['p_' + name
, name
, name
]
207 elif name
.startswith('sys_csel'):
209 name2
= 'sys_clksel_i(%s)' % i
210 name
= 'p_sys_clksel_' + i
211 pad
= [name
, name2
, name2
]
213 # iopads.append([pname, name, name])
214 print "sys pad", name
216 elif name
.startswith('mspi0') or name
.startswith('mspi1'):
221 elif suffix
== 'nss':
223 if name
.startswith('mspi0'):
224 prefix
= 'spimaster_'
226 prefix
= 'spisdcard_'
227 name
= prefix
+ suffix
228 pad
= ['p_' + name
, name
, name
]
230 elif name
.startswith('sd0'):
232 if name
.startswith('sd0_d'):
234 name
= 'sdcard_data' + i
235 name2
= 'sdcard_data_%%s(%s)' % i
236 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i',
238 elif name
.startswith('sd0_cmd'):
240 name2
= 'sdcard_cmd_%s'
241 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
243 name
= 'sdcard_' + name
[4:]
244 pad
= ['p_' + name
, name
, name
]
246 elif name
.startswith('sdr'):
248 if name
== 'sdr_clk':
250 pad
= ['p_' + name
, name
, name
]
251 elif name
.startswith('sdr_ad'):
253 name
= 'sdram_a_' + i
254 name2
= 'sdram_a(%s)' % i
255 pad
= ['p_' + name
, name2
, name2
]
256 elif name
.startswith('sdr_ba'):
258 name
= 'sdram_ba_' + i
259 name2
= 'sdram_ba(%s)' % i
260 pad
= ['p_' + name
, name2
, name2
]
261 elif name
.startswith('sdr_dqm'):
263 name
= 'sdram_dm_' + i
264 name2
= 'sdram_dm(%s)' % i
265 pad
= ['p_' + name
, name2
, name2
]
266 elif name
.startswith('sdr_d'):
268 name
= 'sdram_dq_' + i
269 name2
= 'sdram_dq_%%s(%s)' % i
270 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', 'sdram_dq_oe']
271 elif name
== 'sdr_csn0':
273 pad
= ['p_' + name
, name
, name
]
274 elif name
[-1] == 'n':
275 name
= 'sdram_' + name
[4:-1] + '_n'
276 pad
= ['p_' + name
, name
, name
]
278 name
= 'sdram_' + name
[4:]
279 pad
= ['p_' + name
, name
, name
]
281 elif name
.startswith('uart'):
283 name
= 'uart_' + name
[6:]
284 pad
= ['p_' + name
, name
, name
]
286 elif name
.startswith('gpio'):
290 name2
= 'gpio_%%s(%s)' % i
291 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
292 print ("GPIO pad", name
, pad
)
294 elif name
.startswith('mtwi'):
296 name
= 'i2c' + name
[4:]
297 if name
.startswith('i2c_sda'):
299 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
300 print ("I2C pad", name
, pad
)
302 pad
= ['p_' + name
, name
, name
]
304 elif name
.startswith('twi'):
306 name
= 'i2c' + name
[3:]
308 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
309 print ("I2C pad", name
, pad
)
311 elif name
.startswith('eint'):
315 name2
= 'eint_%s' % i
316 pad
= ['p_' + name
, name2
, name2
]
318 elif name
.startswith('pwm'):
322 name2
= 'pwm(%s)' % i
323 pad
= ['p_' + name
, name2
, name2
]
325 pad
= ['p_' + name
, name
, name
]
326 print ("GPIO pad", name
, pad
)
329 if name
and name
.startswith('jtag'):
332 if name
and not name
.startswith('p_'):
333 if 'power' not in name
and 'ground' not in name
:
336 padbank
[banknum
] = name
338 if domain
is not None:
339 if domain
not in domains
:
341 domains
[domain
].append(name
)
343 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
344 clk
= psp
.clocks
[domain
]
345 if clk
.lower() in orig_name
: # TODO, might over-match
346 clocks
[domain
] = name
348 pinmap
[orig_name
] = name
351 if domain
and pad
is not None:
352 # append direction from spec/domain. damn awkward processing
354 fn
, name
= orig_name
.split("_")
359 for k
in psp
.byspec
.keys():
360 if k
.startswith(domain
):
362 print "spec found", domain
, spec
363 assert spec
is not None
366 if pname
.lower().startswith(name
):
368 print "found spec", found
369 assert found
is not None
370 # whewwww. add the direction onto the pad spec list
371 pad
.append(found
[-1])
373 elif pad
is not None:
378 for pl
in [pe
, pw
, pn
, ps
]:
379 for i
in range(len(pl
)):
381 name
= 'nc_%d' % nc_idx
382 name2
= 'nc(%d)' % nc_idx
385 iopads
.append([name
, name2
, name2
, "-"])
401 print "chip domains (excluding sys-default)"
403 print "chip clocks (excluding sys-default)"
413 'pads.instances' : iopads
,
414 'pins.specs' : psp
.byspec
,
416 'chip.domains' : domains
,
417 'chip.clocks' : clocks
,
418 'chip.n_intpower': n_intpower
,
419 'chip.n_extpower': n_extpower
,
422 chip
= json
.dumps(chip
)
423 with
open("ls180/litex_pinpads.json", "w") as f
: