b46a5004d7842c6ef54f344fa2cda0bc85767b5b
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", ('W', 0), 0, 0, 1)
63 ps
.vss("E", ('W', 1), 0, 0, 1)
64 ps
.vdd("I", ('W', 2), 0, 0, 1)
65 ps
.vss("I", ('W', 3), 0, 0, 1)
66 ps
.mi2c("", ('W', 4), 0, 0, 2)
67 ps
.sdram1("", ('W', 6), 0, 0, 15) # SDRAM DAM0, D0-7, AD0-3
68 ps
.vss("I", ('W', 22), 0, 1, 1)
69 ps
.vdd("I", ('W', 23), 0, 1, 1)
70 ps
.vss("E", ('W', 24), 0, 1, 1)
71 ps
.vdd("E", ('W', 25), 0, 1, 1)
72 ps
.sdram1("", ('W', 26), 0, 15, 6) # AD4-9
74 ps
.sdram2("", ('S', 0), 0, 0, 4) # 1st 4, AD10-12,DQM1
75 ps
.vdd("E", ('S', 4), 0, 2, 1)
76 ps
.vss("E", ('S', 5), 0, 2, 1)
77 ps
.vdd("I", ('S', 6), 0, 2, 1)
78 ps
.vss("I", ('S', 7), 0, 2, 1)
79 ps
.sdram2("", ('S', 8), 0, 4, 8) # D8-15
80 ps
.sdram1("", ('S', 16), 0, 21, 9) # clk etc.
81 ps
.vss("I", ('S', 22), 0, 3, 1)
82 ps
.vdd("I", ('S', 23), 0, 3, 1)
83 ps
.vss("E", ('S', 24), 0, 3, 1)
84 ps
.vdd("E", ('S', 25), 0, 3, 1)
85 ps
.uart("0", ('S', 26), 0)
86 ps
.mspi("0", ('S', 28), 0)
88 ps
.sys("", ('E', 0), 0, 5, 1) # analog VCO out in right top
89 ps
.gpio("", ('E', 1), 0, 0, 5) # GPIO 0-4
90 ps
.vss("E", ('E', 6), 0, 4, 1)
91 ps
.vdd("E", ('E', 7), 0, 4, 1)
92 ps
.vdd("I", ('E', 8), 0, 4, 1)
93 ps
.vss("I", ('E', 9), 0, 4, 1)
94 ps
.gpio("", ('E', 10), 0, 5, 3) # GPIO 5-7
95 ps
.jtag("", ('E', 13), 0, 0, 4)
96 ps
.gpio("", ('E', 17), 0, 8, 5) # GPIO 8-12
97 ps
.vss("I", ('E', 22), 0, 5, 1)
98 ps
.vdd("I", ('E', 23), 0, 5, 1)
99 ps
.vss("E", ('E', 24), 0, 5, 1)
100 ps
.vdd("E", ('E', 25), 0, 5, 1)
101 ps
.gpio("", ('E', 26), 0, 13, 3) # GPIO 13-15
102 ps
.eint("", ('E', 29), 0, 0, 3)
104 ps
.vss("E", ('N', 6), 0, 6, 1)
105 ps
.vdd("E", ('N', 7), 0, 6, 1)
106 ps
.vdd("I", ('N', 8), 0, 6, 1)
107 ps
.vss("I", ('N', 9), 0, 6, 1)
108 #ps.pwm("", ('N', 2), 0, 0, 2) comment out (litex problem 25mar2021)
109 #ps.mspi("1", ('N', 7), 0) comment out (litex problem 25mar2021)
110 #ps.sdmmc("0", ('N', 11), 0) # comment out (litex problem 25mar2021)
111 ps
.sys("", ('N', 27), 0, 0, 5) # all but analog out in top right
112 ps
.vss("I", ('N', 22), 0, 7, 1)
113 ps
.vdd("I", ('N', 23), 0, 7, 1)
114 ps
.vss("E", ('N', 24), 0, 7, 1)
115 ps
.vdd("E", ('N', 25), 0, 7, 1)
117 #ps.mquadspi("1", ('S', 0), 0)
119 print "ps clocks", ps
.clocks
121 # Scenarios below can be spec'd out as either "find first interface"
122 # by name/number e.g. SPI1, or as "find in bank/mux" which must be
123 # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
124 # EINT and PWM are grouped together, specially, but may still be spec'd
125 # using "BM:Name". Pins are removed in-order as listed from
126 # lists (interfaces, EINTs, PWMs) from available pins.
129 # 'SD0', litex problem 25mar2021
130 'UART0', 'GPIOS', 'GPIOE', 'JTAG', 'PWM', 'EINT',
133 # 'MSPI1', litex problem 25mar2021
136 ls180_pwm
= []#['B0:PWM_0']
138 'SD0': 'user-facing: internal (on Card), multiplexed with JTAG\n'
139 'and UART2, for debug purposes',
148 'B1:LCD/22': '18-bit RGB/TTL LCD',
149 'ULPI0/8': 'user-facing: internal (on Card), USB-OTG ULPI PHY',
150 'ULPI1': 'dual USB2 Host ULPI PHY'
153 ps
.add_scenario("Libre-SOC 180nm", ls180
, ls180_eint
, ls180_pwm
,
159 # map pins to litex name conventions, primarily for use in coriolis2
160 # yes this is a mess. it'll do the job though. improvements later
161 def pinparse(psp
, pinspec
):
162 p
= Parse(pinspec
, verify
=False)
167 print p
.muxed_cells_bank
173 pads
= {'N': pn
, 'S': ps
, 'E': pe
, 'W': pw
}
181 for (padnum
, name
, x
), bank
in zip(p
.muxed_cells
, p
.muxed_cells_bank
):
184 domain
= None # TODO, get this from the PinSpec. sigh
186 start
= p
.bankstart
[bank
]
187 banknum
= padnum
- start
188 print "bank", bank
, banknum
, "padname", name
, padnum
, x
192 if name
.startswith('vss'):
193 name
= 'p_%s_' % name
[:-2] + name
[-1]
195 name
= 'ground_' + name
[-1]
198 name
= 'ioground_' + name
[-1]
202 elif name
.startswith('vdd'):
205 name
= 'power_' + name
[-1]
209 name
= 'iopower_' + name
[-1]
213 elif name
.startswith('sys'):
215 if name
== 'sys_pllclk':
216 pad
= ["p_"+name
, name
, name
]
217 elif name
== 'sys_rst':
218 #name = 'p_sys_rst_1'
219 pad
= [name
, name
, name
]
220 padbank
[banknum
] = name
221 print "sys_rst add", bank
, banknum
, name
223 elif name
== 'sys_pllclk':
225 elif name
== 'sys_pllvcout':
226 name
= 'sys_pll_vco_o'
227 pad
= ['p_' + name
, name
, name
, "A"] # A for Analog
228 elif name
== 'sys_plltestout':
229 name
= 'sys_pll_testout_o'
230 pad
= ['p_' + name
, name
, name
]
231 elif name
.startswith('sys_pllsel'):
233 name2
= 'sys_clksel_i(%s)' % i
234 name
= 'p_sys_clksel_' + i
235 pad
= [name
, name2
, name2
]
237 # iopads.append([pname, name, name])
238 print "sys pad", name
240 elif name
.startswith('mspi0') or name
.startswith('mspi1'):
245 elif suffix
== 'nss':
247 if name
.startswith('mspi0'):
248 prefix
= 'spimaster_'
250 prefix
= 'spisdcard_'
251 litex_name
= name
[:6] + suffix
252 name
= prefix
+ suffix
253 pad
= ['p_' + name
, name
, name
]
255 elif name
.startswith('sd0'):
257 if name
.startswith('sd0_d'):
259 name
= 'sdcard_data' + i
260 name2
= 'sdcard_data_%%s(%s)' % i
261 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
262 elif name
.startswith('sd0_cmd'):
264 name2
= 'sdcard_cmd_%s'
265 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
267 name
= 'sdcard_' + name
[4:]
268 pad
= ['p_' + name
, name
, name
]
269 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
271 elif name
.startswith('sdr'):
273 if name
== 'sdr_clk':
275 pad
= ['p_' + name
, name
, name
]
276 elif name
.startswith('sdr_ad'):
278 name
= 'sdram_a_' + i
279 name2
= 'sdram_a(%s)' % i
280 pad
= ['p_' + name
, name2
, name2
]
281 elif name
.startswith('sdr_ba'):
283 name
= 'sdram_ba_' + i
284 name2
= 'sdram_ba(%s)' % i
285 pad
= ['p_' + name
, name2
, name2
]
286 elif name
.startswith('sdr_dqm'):
288 name
= 'sdram_dm_' + i
289 name2
= 'sdram_dm(%s)' % i
290 pad
= ['p_' + name
, name2
, name2
]
291 elif name
.startswith('sdr_d'):
293 name
= 'sdram_dq_' + i
294 name2
= 'sdram_dq_%%s(%s)' % i
295 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
296 elif name
== 'sdr_csn0':
298 pad
= ['p_' + name
, name
, name
]
299 elif name
[-1] == 'n':
300 name
= 'sdram_' + name
[4:-1] + '_n'
301 pad
= ['p_' + name
, name
, name
]
303 name
= 'sdram_' + name
[4:]
304 pad
= ['p_' + name
, name
, name
]
305 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
307 elif name
.startswith('uart'):
309 name
= 'uart_' + name
[6:]
310 pad
= ['p_' + name
, name
, name
]
312 elif name
.startswith('gpio'):
317 name2
= 'gpio_%%s(%s)' % i
318 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
319 print ("GPIO pad", name
, pad
)
320 litex_name
= "gpio_%s" % gbank
+ "_".join(name
.split("_")[1:])
322 elif name
.startswith('mtwi'):
325 litex_name
= 'mtwi' + suffix
326 name
= 'i2c' + suffix
327 if name
.startswith('i2c_sda'):
329 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
330 print ("I2C pad", name
, pad
)
332 pad
= ['p_' + name
, name
, name
]
334 elif name
.startswith('twi'):
336 name
= 'i2c' + name
[3:]
338 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
339 print ("I2C pad", name
, pad
)
341 elif name
.startswith('eint'):
345 name2
= 'eint_%s' % i
346 pad
= ['p_' + name
, name2
, name2
]
348 elif name
.startswith('pwm'):
352 name2
= 'pwm(%s)' % i
353 pad
= ['p_' + name
, name2
, name2
]
355 pad
= ['p_' + name
, name
, name
]
356 print ("GPIO pad", name
, pad
)
358 if litex_name
is None:
362 if name
and name
.startswith('jtag'):
365 if name
and not name
.startswith('p_'):
366 if 'power' not in name
and 'ground' not in name
:
369 padbank
[banknum
] = name
371 if domain
is not None:
372 if domain
not in domains
:
374 domains
[domain
].append(name
)
376 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
377 clk
= psp
.clocks
[domain
]
378 if clk
.lower() in orig_name
: # TODO, might over-match
379 clocks
[domain
] = name
381 pinmap
[orig_name
] = name
382 litexmap
[litex_name
] = name
385 if domain
and pad
is not None:
386 # append direction from spec/domain. damn awkward processing
388 fn
, name
= orig_name
.split("_")
393 for k
in psp
.byspec
.keys():
394 if k
.startswith(domain
):
396 print "spec found", domain
, spec
397 assert spec
is not None
400 if pname
.lower().startswith(name
):
402 print "found spec", found
403 assert found
is not None
404 # whewwww. add the direction onto the pad spec list
411 elif pad
is not None:
416 for pl
in [pe
, pw
, pn
, ps
]:
417 for i
in range(len(pl
)):
419 name
= 'nc_%d' % nc_idx
420 name2
= 'nc(%d)' % nc_idx
423 iopads
.append([name
, name2
, name2
, "-"])
439 print "chip domains (excluding sys-default)"
441 print "chip clocks (excluding sys-default)"
451 'pads.instances' : iopads
,
452 'pins.specs' : psp
.byspec
,
454 'litex.map' : litexmap
,
455 'chip.domains' : domains
,
456 'chip.clocks' : clocks
,
457 'chip.n_intpower': n_intpower
,
458 'chip.n_extpower': n_extpower
,