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_pllvcout':
202 name
= 'sys_pll_vco_o'
203 pad
= ['p_' + name
, name
, name
]
204 elif name
== 'sys_plltestout':
205 name
= 'sys_pll_testout_o'
206 pad
= ['p_' + name
, name
, name
]
207 elif name
.startswith('sys_pllsel'):
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', name2
% 'oe']
237 elif name
.startswith('sd0_cmd'):
239 name2
= 'sdcard_cmd_%s'
240 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
242 name
= 'sdcard_' + name
[4:]
243 pad
= ['p_' + name
, name
, name
]
245 elif name
.startswith('sdr'):
247 if name
== 'sdr_clk':
249 pad
= ['p_' + name
, name
, name
]
250 elif name
.startswith('sdr_ad'):
252 name
= 'sdram_a_' + i
253 name2
= 'sdram_a(%s)' % i
254 pad
= ['p_' + name
, name2
, name2
]
255 elif name
.startswith('sdr_ba'):
257 name
= 'sdram_ba_' + i
258 name2
= 'sdram_ba(%s)' % i
259 pad
= ['p_' + name
, name2
, name2
]
260 elif name
.startswith('sdr_dqm'):
262 name
= 'sdram_dm_' + i
263 name2
= 'sdram_dm(%s)' % i
264 pad
= ['p_' + name
, name2
, name2
]
265 elif name
.startswith('sdr_d'):
267 name
= 'sdram_dq_' + i
268 name2
= 'sdram_dq_%%s(%s)' % i
269 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
270 elif name
== 'sdr_csn0':
272 pad
= ['p_' + name
, name
, name
]
273 elif name
[-1] == 'n':
274 name
= 'sdram_' + name
[4:-1] + '_n'
275 pad
= ['p_' + name
, name
, name
]
277 name
= 'sdram_' + name
[4:]
278 pad
= ['p_' + name
, name
, name
]
280 elif name
.startswith('uart'):
282 name
= 'uart_' + name
[6:]
283 pad
= ['p_' + name
, name
, name
]
285 elif name
.startswith('gpio'):
289 name2
= 'gpio_%%s(%s)' % i
290 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
291 print ("GPIO pad", name
, pad
)
293 elif name
.startswith('mtwi'):
295 name
= 'i2c' + name
[4:]
296 if name
.startswith('i2c_sda'):
298 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
299 print ("I2C pad", name
, pad
)
301 pad
= ['p_' + name
, name
, name
]
303 elif name
.startswith('twi'):
305 name
= 'i2c' + name
[3:]
307 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
308 print ("I2C pad", name
, pad
)
310 elif name
.startswith('eint'):
314 name2
= 'eint_%s' % i
315 pad
= ['p_' + name
, name2
, name2
]
317 elif name
.startswith('pwm'):
321 name2
= 'pwm(%s)' % i
322 pad
= ['p_' + name
, name2
, name2
]
324 pad
= ['p_' + name
, name
, name
]
325 print ("GPIO pad", name
, pad
)
328 if name
and name
.startswith('jtag'):
331 if name
and not name
.startswith('p_'):
332 if 'power' not in name
and 'ground' not in name
:
335 padbank
[banknum
] = name
337 if domain
is not None:
338 if domain
not in domains
:
340 domains
[domain
].append(name
)
342 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
343 clk
= psp
.clocks
[domain
]
344 if clk
.lower() in orig_name
: # TODO, might over-match
345 clocks
[domain
] = name
347 pinmap
[orig_name
] = name
350 if domain
and pad
is not None:
351 # append direction from spec/domain. damn awkward processing
353 fn
, name
= orig_name
.split("_")
358 for k
in psp
.byspec
.keys():
359 if k
.startswith(domain
):
361 print "spec found", domain
, spec
362 assert spec
is not None
365 if pname
.lower().startswith(name
):
367 print "found spec", found
368 assert found
is not None
369 # whewwww. add the direction onto the pad spec list
370 pad
.append(found
[-1])
372 elif pad
is not None:
377 for pl
in [pe
, pw
, pn
, ps
]:
378 for i
in range(len(pl
)):
380 name
= 'nc_%d' % nc_idx
381 name2
= 'nc(%d)' % nc_idx
384 iopads
.append([name
, name2
, name2
, "-"])
400 print "chip domains (excluding sys-default)"
402 print "chip clocks (excluding sys-default)"
412 'pads.instances' : iopads
,
413 'pins.specs' : psp
.byspec
,
415 'chip.domains' : domains
,
416 'chip.clocks' : clocks
,
417 'chip.n_intpower': n_intpower
,
418 'chip.n_extpower': n_extpower
,