d0393eabf4bee6d0e4adef28cf92fb49c5d1918b
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
.vdd("E", ('S', 0), 0, 0, 1)
63 ps
.vss("E", ('S', 1), 0, 0, 1)
64 ps
.vdd("I", ('S', 2), 0, 5, 1)
65 ps
.vss("I", ('S', 3), 0, 5, 1)
66 ps
.sdram1("", ('S', 4), 0, 0, 21)
67 ps
.mi2c("", ('S', 26), 0, 0, 2)
68 ps
.vss("I", ('S', 28), 0, 6, 1)
69 ps
.vdd("I", ('S', 29), 0, 6, 1)
70 ps
.vss("E", ('S', 30), 0, 13, 1)
71 ps
.vdd("E", ('S', 31), 0, 13, 1)
73 ps
.vdd("E", ('W', 0), 0, 1, 1)
74 ps
.vss("E", ('W', 1), 0, 1, 1)
75 ps
.vdd("I", ('W', 2), 0, 7, 1)
76 ps
.vss("I", ('W', 3), 0, 7, 1)
77 ps
.sdram2("", ('W', 4), 0, 0, 12)
78 ps
.sdram1("", ('W', 16), 0, 21, 9)
79 ps
.uart("0", ('W', 22), 0)
80 ps
.jtag("", ('W', 24), 0, 0, 4)
81 ps
.vss("I", ('W', 28), 0, 14, 1)
82 ps
.vdd("I", ('W', 29), 0, 14, 1)
83 ps
.vss("E", ('W', 30), 0, 8, 1)
84 ps
.vdd("E", ('W', 31), 0, 8, 1)
86 ps
.vss("I", ('E', 0), 0, 2, 1)
87 ps
.vdd("I", ('E', 1), 0, 2, 1)
88 ps
.vdd("I", ('E', 2), 0, 10, 1)
89 ps
.vss("I", ('E', 3), 0, 10, 1)
90 ps
.mspi("0", ('E', 4), 0)
91 ps
.gpio("", ('E', 9), 0, 0, 16)
92 ps
.eint("", ('E', 25), 0, 0, 3)
93 ps
.vss("I", ('E', 28), 0, 9, 1)
94 ps
.vdd("I", ('E', 29), 0, 9, 1)
95 ps
.vss("I", ('E', 30), 0, 3, 1)
96 ps
.vdd("I", ('E', 31), 0, 3, 1)
98 ps
.vss("E", ('N', 0), 0, 2, 1)
99 ps
.vdd("E", ('N', 1), 0, 2, 1)
100 ps
.vdd("I", ('N', 2), 0, 12, 1)
101 ps
.vss("I", ('N', 3), 0, 12, 1)
102 #ps.pwm("", ('N', 2), 0, 0, 2) comment out (litex problem 25mar2021)
103 #ps.mspi("1", ('N', 7), 0) comment out (litex problem 25mar2021)
104 #ps.sdmmc("0", ('N', 11), 0) # comment out (litex problem 25mar2021)
105 ps
.sys("", ('N', 22), 0, 0, 6) # should be 6, to do all PLL pins
106 ps
.vss("I", ('N', 28), 0, 11, 1)
107 ps
.vdd("I", ('N', 29), 0, 11, 1)
108 ps
.vss("I", ('N', 30), 0, 4, 1)
109 ps
.vdd("I", ('N', 31), 0, 4, 1)
111 #ps.mquadspi("1", ('S', 0), 0)
113 print "ps clocks", ps
.clocks
115 # Scenarios below can be spec'd out as either "find first interface"
116 # by name/number e.g. SPI1, or as "find in bank/mux" which must be
117 # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
118 # EINT and PWM are grouped together, specially, but may still be spec'd
119 # using "BM:Name". Pins are removed in-order as listed from
120 # lists (interfaces, EINTs, PWMs) from available pins.
123 # 'SD0', litex problem 25mar2021
124 'UART0', 'GPIOS', 'GPIOE', 'JTAG', 'PWM', 'EINT',
127 # 'MSPI1', litex problem 25mar2021
130 ls180_pwm
= []#['B0:PWM_0']
132 'SD0': 'user-facing: internal (on Card), multiplexed with JTAG\n'
133 'and UART2, for debug purposes',
142 'B1:LCD/22': '18-bit RGB/TTL LCD',
143 'ULPI0/8': 'user-facing: internal (on Card), USB-OTG ULPI PHY',
144 'ULPI1': 'dual USB2 Host ULPI PHY'
147 ps
.add_scenario("Libre-SOC 180nm", ls180
, ls180_eint
, ls180_pwm
,
153 # map pins to litex name conventions, primarily for use in coriolis2
154 # yes this is a mess. it'll do the job though. improvements later
155 def pinparse(psp
, pinspec
):
156 p
= Parse(pinspec
, verify
=False)
161 print p
.muxed_cells_bank
167 pads
= {'N': pn
, 'S': ps
, 'E': pe
, 'W': pw
}
175 for (padnum
, name
, x
), bank
in zip(p
.muxed_cells
, p
.muxed_cells_bank
):
178 domain
= None # TODO, get this from the PinSpec. sigh
180 start
= p
.bankstart
[bank
]
181 banknum
= padnum
- start
182 print "bank", bank
, banknum
, "padname", name
, padnum
, x
186 if name
.startswith('vss'):
187 name
= 'p_%s_' % name
[:-2] + name
[-1]
189 name
= 'ground_' + name
[-1]
192 name
= 'ioground_' + name
[-1]
196 elif name
.startswith('vdd'):
199 name
= 'power_' + name
[-1]
203 name
= 'iopower_' + name
[-1]
207 elif name
.startswith('sys'):
209 if name
== 'sys_pllclk':
210 pad
= ["p_"+name
, name
, name
]
211 elif name
== 'sys_rst':
212 #name = 'p_sys_rst_1'
213 pad
= [name
, name
, name
]
214 padbank
[banknum
] = name
215 print "sys_rst add", bank
, banknum
, name
217 elif name
== 'sys_pllclk':
219 elif name
== 'sys_pllvcout':
220 name
= 'sys_pll_vco_o'
221 pad
= ['p_' + name
, name
, name
]
222 elif name
== 'sys_plltestout':
223 name
= 'sys_pll_testout_o'
224 pad
= ['p_' + name
, name
, name
]
225 elif name
.startswith('sys_pllsel'):
227 name2
= 'sys_clksel_i(%s)' % i
228 name
= 'p_sys_clksel_' + i
229 pad
= [name
, name2
, name2
]
231 # iopads.append([pname, name, name])
232 print "sys pad", name
234 elif name
.startswith('mspi0') or name
.startswith('mspi1'):
239 elif suffix
== 'nss':
241 if name
.startswith('mspi0'):
242 prefix
= 'spimaster_'
244 prefix
= 'spisdcard_'
245 litex_name
= name
[:6] + suffix
246 name
= prefix
+ suffix
247 pad
= ['p_' + name
, name
, name
]
249 elif name
.startswith('sd0'):
251 if name
.startswith('sd0_d'):
253 name
= 'sdcard_data' + i
254 name2
= 'sdcard_data_%%s(%s)' % i
255 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
256 elif name
.startswith('sd0_cmd'):
258 name2
= 'sdcard_cmd_%s'
259 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
261 name
= 'sdcard_' + name
[4:]
262 pad
= ['p_' + name
, name
, name
]
263 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
265 elif name
.startswith('sdr'):
267 if name
== 'sdr_clk':
269 pad
= ['p_' + name
, name
, name
]
270 elif name
.startswith('sdr_ad'):
272 name
= 'sdram_a_' + i
273 name2
= 'sdram_a(%s)' % i
274 pad
= ['p_' + name
, name2
, name2
]
275 elif name
.startswith('sdr_ba'):
277 name
= 'sdram_ba_' + i
278 name2
= 'sdram_ba(%s)' % i
279 pad
= ['p_' + name
, name2
, name2
]
280 elif name
.startswith('sdr_dqm'):
282 name
= 'sdram_dm_' + i
283 name2
= 'sdram_dm(%s)' % i
284 pad
= ['p_' + name
, name2
, name2
]
285 elif name
.startswith('sdr_d'):
287 name
= 'sdram_dq_' + i
288 name2
= 'sdram_dq_%%s(%s)' % i
289 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
290 elif name
== 'sdr_csn0':
292 pad
= ['p_' + name
, name
, name
]
293 elif name
[-1] == 'n':
294 name
= 'sdram_' + name
[4:-1] + '_n'
295 pad
= ['p_' + name
, name
, name
]
297 name
= 'sdram_' + name
[4:]
298 pad
= ['p_' + name
, name
, name
]
299 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
301 elif name
.startswith('uart'):
303 name
= 'uart_' + name
[6:]
304 pad
= ['p_' + name
, name
, name
]
306 elif name
.startswith('gpio'):
311 name2
= 'gpio_%%s(%s)' % i
312 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
313 print ("GPIO pad", name
, pad
)
314 litex_name
= "gpio_%s" % gbank
+ "_".join(name
.split("_")[1:])
316 elif name
.startswith('mtwi'):
319 litex_name
= 'mtwi' + suffix
320 name
= 'i2c' + suffix
321 if name
.startswith('i2c_sda'):
323 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
324 print ("I2C pad", name
, pad
)
326 pad
= ['p_' + name
, name
, name
]
328 elif name
.startswith('twi'):
330 name
= 'i2c' + name
[3:]
332 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
333 print ("I2C pad", name
, pad
)
335 elif name
.startswith('eint'):
339 name2
= 'eint_%s' % i
340 pad
= ['p_' + name
, name2
, name2
]
342 elif name
.startswith('pwm'):
346 name2
= 'pwm(%s)' % i
347 pad
= ['p_' + name
, name2
, name2
]
349 pad
= ['p_' + name
, name
, name
]
350 print ("GPIO pad", name
, pad
)
352 if litex_name
is None:
356 if name
and name
.startswith('jtag'):
359 if name
and not name
.startswith('p_'):
360 if 'power' not in name
and 'ground' not in name
:
363 padbank
[banknum
] = name
365 if domain
is not None:
366 if domain
not in domains
:
368 domains
[domain
].append(name
)
370 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
371 clk
= psp
.clocks
[domain
]
372 if clk
.lower() in orig_name
: # TODO, might over-match
373 clocks
[domain
] = name
375 pinmap
[orig_name
] = name
376 litexmap
[litex_name
] = name
379 if domain
and pad
is not None:
380 # append direction from spec/domain. damn awkward processing
382 fn
, name
= orig_name
.split("_")
387 for k
in psp
.byspec
.keys():
388 if k
.startswith(domain
):
390 print "spec found", domain
, spec
391 assert spec
is not None
394 if pname
.lower().startswith(name
):
396 print "found spec", found
397 assert found
is not None
398 # whewwww. add the direction onto the pad spec list
399 pad
.append(found
[-1])
401 elif pad
is not None:
406 for pl
in [pe
, pw
, pn
, ps
]:
407 for i
in range(len(pl
)):
409 name
= 'nc_%d' % nc_idx
410 name2
= 'nc(%d)' % nc_idx
413 iopads
.append([name
, name2
, name2
, "-"])
429 print "chip domains (excluding sys-default)"
431 print "chip clocks (excluding sys-default)"
441 'pads.instances' : iopads
,
442 'pins.specs' : psp
.byspec
,
444 'litex.map' : litexmap
,
445 'chip.domains' : domains
,
446 'chip.clocks' : clocks
,
447 'chip.n_intpower': n_intpower
,
448 'chip.n_extpower': n_extpower
,