match up VSS/VDD numbers
[pinmux.git] / src / spec / ls180.py
1 #!/usr/bin/env python
2 # see https://bugs.libre-soc.org/show_bug.cgi?id=304
3
4 from spec.base import PinSpec
5 from parse import Parse
6 import json
7
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
12
13 def pinspec():
14 pinbanks = OrderedDict((
15 ('N', (32, 2)),
16 ('E', (32, 2)),
17 ('S', (32, 2)),
18 ('W', (32, 2)),
19 ))
20 fixedpins = {
21 'CTRL_SYS': [
22 'TEST',
23 'JTAG_SEL',
24 'UBOOT_SEL',
25 'NMI#',
26 'RESET#',
27 'CLK24M_IN',
28 'CLK24M_OUT',
29 'PLLTEST',
30 'PLLREGIO',
31 'PLLVP25',
32 'PLLDV',
33 'PLLVREG',
34 'PLLGND',
35 ],
36 'POWER_GPIO': [
37 'VDD_GPIOB',
38 'GND_GPIOB',
39 ]}
40 fixedpins = {}
41 function_names = {
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',
47 'GPIO': 'GPIO',
48 'EINT': 'External Interrupt',
49 'PWM': 'PWM',
50 'JTAG': 'JTAG',
51 'TWI': 'I2C Master 1',
52 'SD0': 'SD/MMC 1',
53 'SDR': 'SDRAM',
54 'VDD': 'Power',
55 'VSS': 'GND',
56 #'LPC1': 'Low Pincount Interface 1',
57 #'LPC2': 'Low Pincount Interface 2',
58 }
59
60 ps = PinSpec(pinbanks, fixedpins, function_names)
61
62 ps.vss("I", ('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("E", ('N', 30), 0, 0, 1)
66 ps.vdd("I", ('N', 31), 0, 0, 1)
67
68 ps.vss("E", ('E', 0), 0, 1, 1)
69 ps.sdram2("", ('E', 1), 0, 0, 12)
70 ps.vdd("E", ('E', 13), 0, 1, 1)
71 ps.gpio("", ('E', 14), 0, 8, 8)
72 ps.vss("I", ('E', 23), 0, 1, 1)
73 ps.jtag("", ('E', 24), 0, 0, 4)
74 ps.vdd("I", ('E', 31), 0, 1, 1)
75
76 ps.vss("I", ('S', 0), 0, 2, 1)
77 ps.sys("", ('S', 1), 0, 0, 7)
78 ps.vdd("I", ('S', 8), 0, 2, 1)
79 ps.i2c("", ('S', 9), 0, 0, 2)
80 ps.mspi("0", ('S', 15), 0)
81 ps.uart("0", ('S', 20), 0)
82 ps.vss("I", ('S', 22), 0, 3, 1)
83 ps.gpio("", ('S', 23), 0, 0, 8)
84 ps.vdd("I", ('S', 31), 0, 3, 1)
85
86 ps.vss("I", ('W', 0), 0, 4, 1)
87 ps.pwm("", ('W', 1), 0, 0, 2)
88 ps.eint("", ('W', 3), 0, 0, 3)
89 ps.mspi("1", ('W', 6), 0)
90 ps.vdd("E", ('W', 10), 0, 2, 1)
91 ps.sdmmc("0", ('W', 11), 0)
92 ps.vss("E", ('W', 17), 0, 2, 1)
93 ps.vdd("I", ('W', 31), 0, 4, 1)
94 #ps.mspi("0", ('W', 8), 0)
95 #ps.mspi("1", ('W', 8), 0)
96
97 #ps.mquadspi("1", ('S', 0), 0)
98
99 print "ps clocks", ps.clocks
100
101 # Scenarios below can be spec'd out as either "find first interface"
102 # by name/number e.g. SPI1, or as "find in bank/mux" which must be
103 # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
104 # EINT and PWM are grouped together, specially, but may still be spec'd
105 # using "BM:Name". Pins are removed in-order as listed from
106 # lists (interfaces, EINTs, PWMs) from available pins.
107
108 ls180 = ['SD0', 'UART0', 'GPIOS', 'GPIOE', 'JTAG', 'PWM', 'EINT',
109 'VDD', 'VSS', 'SYS',
110 'TWI', 'MSPI0', 'MSPI1', 'SDR']
111 ls180_eint = []
112 ls180_pwm = []#['B0:PWM_0']
113 descriptions = {
114 'SD0': 'user-facing: internal (on Card), multiplexed with JTAG\n'
115 'and UART2, for debug purposes',
116 'TWI': 'I2C.\n',
117 'E2:SD1': '',
118 'MSPI1': '',
119 'UART0': '',
120 'LPC1': '',
121 'SYS': '',
122 'LPC2': '',
123 'SDR': '',
124 'B1:LCD/22': '18-bit RGB/TTL LCD',
125 'ULPI0/8': 'user-facing: internal (on Card), USB-OTG ULPI PHY',
126 'ULPI1': 'dual USB2 Host ULPI PHY'
127 }
128
129 ps.add_scenario("Libre-SOC 180nm", ls180, ls180_eint, ls180_pwm,
130 descriptions)
131
132 return ps
133
134
135 # map pins to litex name conventions, primarily for use in coriolis2
136 def pinparse(psp, pinspec):
137 p = Parse(pinspec, verify=False)
138 pinmap = {}
139
140 print p.muxed_cells
141 print p.muxed_cells_bank
142
143 ps = [''] * 32
144 pn = [''] * 32
145 pe = [''] * 32
146 pw = [''] * 32
147 pads = {'N': pn, 'S': ps, 'E': pe, 'W': pw}
148
149 iopads = []
150 domains = {}
151 clocks = {}
152
153 n_intpower = 0
154 n_extpower = 0
155 for (padnum, name, _), bank in zip(p.muxed_cells, p.muxed_cells_bank):
156 orig_name = name
157 domain = None # TODO, get this from the PinSpec. sigh
158 padnum = int(padnum)
159 start = p.bankstart[bank]
160 banknum = padnum - start
161 print banknum, name, bank
162 padbank = pads[bank]
163 # VSS
164 if name.startswith('vss'):
165 name = 'p_%sck_' % name[:-2] + name[-1]
166 # VDD
167 elif name.startswith('vdd'):
168 if 'i' in name:
169 n_intpower += 1
170 else:
171 n_extpower += 1
172 name = 'p_%sck_' % name[:-2] + name[-1]
173 # SYS
174 elif name.startswith('sys'):
175 domain = 'SYS'
176 if name == 'sys_clk':
177 name = 'p_sys_clk_0'
178 elif name == 'sys_rst':
179 #name = 'p_sys_rst_1'
180 iopads.append([name, name, name])
181 padbank[banknum] = name
182 print "sys_rst add", bank, banknum, name
183 name = None
184 elif name == 'sys_pllclk':
185 name = None # ignore
186 elif name == 'sys_pllout':
187 name = 'sys_pll_48_o'
188 iopads.append(['p_' + name, name, name])
189 elif name.startswith('sys_csel'):
190 i = name[-1]
191 name2 = 'sys_clksel_i(%s)' % i
192 name = 'p_sys_clksel_' + i
193 iopads.append([name, name2, name2])
194 #if name:
195 # iopads.append([pname, name, name])
196 print "sys pad", name
197 # SPI Card
198 elif name.startswith('mspi0') or name.startswith('mspi1'):
199 domain = 'MSPI'
200 suffix = name[6:]
201 if suffix == 'ck':
202 suffix = 'clk'
203 elif suffix == 'nss':
204 suffix = 'cs_n'
205 if name.startswith('mspi1'):
206 prefix = 'spi_master_'
207 else:
208 prefix = 'spisdcard_'
209 name = prefix + suffix
210 iopads.append(['p_' + name, name, name])
211 # SD/MMC
212 elif name.startswith('sd0'):
213 domain = 'SD'
214 if name.startswith('sd0_d'):
215 i = name[5:]
216 name = 'sdcard_data' + i
217 name2 = 'sdcard_data_%%s(%s)' % i
218 pad = ['p_' + name, name, name2 % 'o', name2 % 'i',
219 'sdcard_data_oe']
220 iopads.append(pad)
221 elif name.startswith('sd0_cmd'):
222 name = 'sdcard_cmd'
223 name2 = 'sdcard_cmd_%s'
224 pad = ['p_' + name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
225 iopads.append(pad)
226 else:
227 name = 'sdcard_' + name[4:]
228 iopads.append(['p_' + name, name, name])
229 # SDRAM
230 elif name.startswith('sdr'):
231 domain = 'SDR'
232 if name == 'sdr_clk':
233 name = 'sdram_clock'
234 iopads.append(['p_' + name, name, name])
235 elif name.startswith('sdr_ad'):
236 i = name[6:]
237 name = 'sdram_a_' + i
238 name2 = 'sdram_a(%s)' % i
239 iopads.append(['p_' + name, name2, name2])
240 elif name.startswith('sdr_ba'):
241 i = name[-1]
242 name = 'sdram_ba_' + i
243 name2 = 'sdram_ba(%s)' % i
244 iopads.append(['p_' + name, name2, name2])
245 elif name.startswith('sdr_dqm'):
246 i = name[-1]
247 name = 'sdram_dm_' + i
248 name2 = 'sdram_dm(%s)' % i
249 iopads.append(['p_' + name, name2, name2])
250 elif name.startswith('sdr_d'):
251 i = name[5:]
252 name = 'sdram_dq_' + i
253 name2 = 'sdram_dq_%%s(%s)' % i
254 pad = ['p_' + name, name, name2 % 'o', name2 % 'i', 'sdram_dq_oe']
255 iopads.append(pad)
256 elif name == 'sdr_csn0':
257 name = 'sdram_cs_n'
258 iopads.append(['p_' + name, name, name])
259 elif name[-1] == 'n':
260 name = 'sdram_' + name[4:-1] + '_n'
261 iopads.append(['p_' + name, name, name])
262 else:
263 name = 'sdram_' + name[4:]
264 iopads.append(['p_' + name, name, name])
265 # UART
266 elif name.startswith('uart'):
267 domain = 'UART'
268 name = 'uart_' + name[6:]
269 iopads.append(['p_' + name, name, name])
270 # GPIO
271 elif name.startswith('gpio'):
272 domain = 'GPIO'
273 i = name[7:]
274 name = 'gpio_' + i
275 name2 = 'gpio_%%s(%s)' % i
276 pad = ['p_' + name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
277 print ("GPIO pad", name, pad)
278 iopads.append(pad)
279 # I2C
280 elif name.startswith('twi'):
281 domain = 'TWI'
282 name = 'i2c' + name[3:]
283 if name.startswith('i2c_sda'):
284 name2 = 'i2c_sda_%s'
285 pad = ['p_' + name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
286 print ("I2C pad", name, pad)
287 iopads.append(pad)
288 else:
289 iopads.append(['p_' + name, name, name])
290 # EINT
291 elif name.startswith('eint'):
292 i = name[-1]
293 name = 'eint_%s' % i
294 name2 = 'eint(%s)' % i
295 pad = ['p_' + name, name2, name2]
296 iopads.append(pad)
297 # PWM
298 elif name.startswith('pwm'):
299 name = name[:-4]
300 pad = ['p_' + name, name, name]
301 iopads.append(pad)
302 else:
303 pad = ['p_' + name, name, name]
304 iopads.append(pad)
305 print ("GPIO pad", name, pad)
306
307 # JTAG domain
308 if name and name.startswith('jtag'):
309 domain = 'JTAG'
310
311 if name and not name.startswith('p_'):
312 name = 'p_' + name
313 if name is not None:
314 padbank[banknum] = name
315 # create domains
316 if domain is not None:
317 if domain not in domains:
318 domains[domain] = []
319 domains[domain].append(name)
320 dl = domain.lower()
321 if domain in psp.clocks and orig_name.startswith(dl):
322 clk = psp.clocks[domain]
323 if clk.lower() in orig_name: # TODO, might over-match
324 clocks[domain] = name
325 # record remap
326 pinmap[orig_name] = name
327
328 # not connected
329 nc_idx = 0
330 for pl in [pe, pw, pn, ps]:
331 for i in range(len(pl)):
332 if pl[i] == '':
333 pl[i] = 'nc_%d' % nc_idx
334 nc_idx += 1
335
336 print p.bankstart
337 pprint(psp.clocks)
338
339 print
340 print "N pads", pn
341 print "S pads", ps
342 print "E pads", pe
343 print "W pads", pw
344
345 # do not want these
346 del clocks['SYS']
347 del domains['SYS']
348
349 print "chip domains (excluding sys-default)"
350 pprint(domains)
351 print "chip clocks (excluding sys-default)"
352 pprint(clocks)
353
354 chip = {
355 'pads.south' : ps,
356 'pads.east' : pe,
357 'pads.north' : pn,
358 'pads.west' : pw,
359 'pads.instances' : iopads,
360 'chip.domains' : domains,
361 'chip.clocks' : clocks,
362 'chip.n_intpower': n_intpower,
363 'chip.n_extpower': n_extpower,
364 }
365
366 chip = json.dumps(chip)
367 with open("ls180/litex_pinpads.json", "w") as f:
368 f.write(chip)
369
370 return pinmap