getting microtest to work again (adapting json output)
[pinmux.git] / src / jsoncreate.py
1 from parse import Parse
2 from pprint import pprint
3 import json
4
5 # map pins to litex name conventions, primarily for use in coriolis2
6 # yes this is a mess. it'll do the job though. improvements later
7 def pinparse(psp, pinspec):
8 p = Parse(pinspec, verify=False)
9 pinmap = {}
10 litexmap = {}
11
12 print ("muxed cells", p.muxed_cells)
13 print ("muxed cell banks", p.muxed_cells_bank)
14
15 pads = {}
16 for pname, psize in p.bankwidths.items():
17 pads[pname] = [''] * psize
18
19 iopads = []
20 domains = {}
21 clocks = {}
22
23 n_intpower = 0
24 n_extpower = 0
25 for clist, bank in zip(p.muxed_cells, p.muxed_cells_bank):
26 print ("cell", clist, bank)
27 padnum = clist[0]
28 name = clist[1]
29 x = clist[2]
30 orig_name = name
31 litex_name = None
32 domain = None # TODO, get this from the PinSpec. sigh
33 padnum = int(padnum)
34 start = p.bankstart[bank]
35 banknum = padnum - start
36 print ("bank", bank, banknum, "padname", name, padnum, x)
37 padbank = pads[bank]
38 pad = None
39 # VSS
40 if name.startswith('vss'):
41 name = 'p_%s_' % name[:-2] + name[-1]
42 if 'i' in name:
43 name = 'ground_' + name[-1]
44 name2 = 'vss'
45 else:
46 name = 'ioground_' + name[-1]
47 name2 = 'iovss'
48 pad = [name, name2]
49 # VDD
50 elif name.startswith('vdd'):
51 if 'i' in name:
52 n_intpower += 1
53 name = 'power_' + name[-1]
54 name2 = 'vdd'
55 else:
56 n_extpower += 1
57 name = 'iopower_' + name[-1]
58 name2 = 'iovdd'
59 pad = [name, name2]
60 # SYS
61 elif name.startswith('sys'):
62 domain = 'SYS'
63 if name == 'sys_pllclk':
64 pad = ["p_"+name, name, name]
65 elif name == 'sys_rst':
66 #name = 'p_sys_rst_1'
67 pad = [name, name, name]
68 padbank[banknum] = name
69 print ("sys_rst add", bank, banknum, name)
70 name = None
71 elif name == 'sys_pllclk':
72 name = None # ignore
73 elif name == 'sys_pllvcout':
74 name = 'sys_pll_vco_o'
75 pad = ['p_' + name, name, name, "A"] # A for Analog
76 elif name == 'sys_plltestout':
77 name = 'sys_pll_testout_o'
78 pad = ['p_' + name, name, name]
79 elif name.startswith('sys_pllsel'):
80 i = name[-1]
81 name2 = 'sys_clksel_i(%s)' % i
82 name = 'p_sys_clksel_' + i
83 pad = [name, name2, name2]
84 #if name:
85 # iopads.append([pname, name, name])
86 print ("sys pad", name)
87 # SPI Card
88 elif name.startswith('mspi0') or name.startswith('mspi1'):
89 domain = 'MSPI'
90 suffix = name[6:]
91 if suffix == 'ck':
92 suffix = 'clk'
93 elif suffix == 'nss':
94 suffix = 'cs_n'
95 if name.startswith('mspi0'):
96 prefix = 'spimaster_'
97 else:
98 prefix = 'spisdcard_'
99 litex_name = name[:6] + suffix
100 name = prefix + suffix
101 pad = ['p_' + name, name, name]
102 # SD/MMC
103 elif name.startswith('sd0'):
104 domain = 'SD'
105 if name.startswith('sd0_d'):
106 i = name[5:]
107 name = 'sdcard_data' + i
108 name2 = 'sdcard_data_%%s(%s)' % i
109 pad = ['p_'+name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
110 elif name.startswith('sd0_cmd'):
111 name = 'sdcard_cmd'
112 name2 = 'sdcard_cmd_%s'
113 pad = ['p_'+name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
114 else:
115 name = 'sdcard_' + name[4:]
116 pad = ['p_' + name, name, name]
117 litex_name = orig_name[:4] + "_".join(name.split("_")[1:])
118 # SDRAM
119 elif name.startswith('sdr'):
120 domain = 'SDR'
121 if name == 'sdr_clk':
122 name = 'sdram_clock'
123 pad = ['p_' + name, name, name]
124 elif name.startswith('sdr_ad'):
125 i = name[6:]
126 name = 'sdram_a_' + i
127 name2 = 'sdram_a(%s)' % i
128 pad = ['p_' + name, name2, name2]
129 elif name.startswith('sdr_ba'):
130 i = name[-1]
131 name = 'sdram_ba_' + i
132 name2 = 'sdram_ba(%s)' % i
133 pad = ['p_' + name, name2, name2]
134 elif name.startswith('sdr_dqm'):
135 i = name[-1]
136 name = 'sdram_dm_' + i
137 name2 = 'sdram_dm(%s)' % i
138 pad = ['p_' + name, name2, name2]
139 elif name.startswith('sdr_d'):
140 i = name[5:]
141 name = 'sdram_dq_' + i
142 name2 = 'sdram_dq_%%s(%s)' % i
143 pad = ['p_'+name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
144 elif name == 'sdr_csn0':
145 name = 'sdram_cs_n'
146 pad = ['p_' + name, name, name]
147 elif name[-1] == 'n':
148 name = 'sdram_' + name[4:-1] + '_n'
149 pad = ['p_' + name, name, name]
150 else:
151 name = 'sdram_' + name[4:]
152 pad = ['p_' + name, name, name]
153 litex_name = orig_name[:4] + "_".join(name.split("_")[1:])
154 # UART
155 elif name.startswith('uart'):
156 domain = 'UART'
157 name = 'uart_' + name[6:]
158 pad = ['p_' + name, name, name]
159 # GPIO
160 elif name.startswith('gpio'):
161 gbank = name[4]
162 domain = 'GPIO'
163 i = name[7:]
164 name = 'gpio_' + i
165 name2 = 'gpio_%%s(%s)' % i
166 pad = ['p_' + name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
167 print ("GPIO pad", name, pad)
168 litex_name = "gpio_%s" % gbank + "_".join(name.split("_")[1:])
169 # I2C master-only
170 elif name.startswith('mtwi'):
171 domain = 'MTWI'
172 suffix = name[4:]
173 litex_name = 'mtwi' + suffix
174 name = 'i2c' + suffix
175 if name.startswith('i2c_sda'):
176 name2 = 'i2c_sda_%s'
177 pad = ['p_'+name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
178 print ("I2C pad", name, pad)
179 else:
180 pad = ['p_' + name, name, name]
181 # I2C bi-directional
182 elif name.startswith('twi'):
183 domain = 'TWI'
184 name = 'i2c' + name[3:]
185 name2 = name + '_%s'
186 pad = ['p_'+name, name, name2 % 'o', name2 % 'i', name2 % 'oe']
187 print ("I2C pad", name, pad)
188 # EINT
189 elif name.startswith('eint'):
190 domain = 'EINT'
191 i = name[-1]
192 name = 'eint_%s' % i
193 name2 = 'eint_%s' % i
194 pad = ['p_' + name, name2, name2]
195 # PWM
196 elif name.startswith('pwm'):
197 domain = 'PWM'
198 name = name[:-4]
199 i = name[3:]
200 name2 = 'pwm(%s)' % i
201 pad = ['p_' + name, name2, name2]
202 else:
203 pad = ['p_' + name, name, name]
204 print ("GPIO pad", name, pad)
205
206 if litex_name is None:
207 litex_name = name
208
209 # JTAG domain
210 if name and name.startswith('jtag'):
211 domain = 'JTAG'
212
213 if name and not name.startswith('p_'):
214 if 'power' not in name and 'ground' not in name:
215 name = 'p_' + name
216 if name is not None:
217 padbank[banknum] = name
218 # create domains
219 if domain is not None:
220 if domain not in domains:
221 domains[domain] = []
222 domains[domain].append(name)
223 dl = domain.lower()
224 if domain in psp.clocks and orig_name.startswith(dl):
225 clk = psp.clocks[domain]
226 if clk.lower() in orig_name: # TODO, might over-match
227 clocks[domain] = name
228 # record remap
229 pinmap[orig_name] = name
230 litexmap[litex_name] = name
231
232 # add pad to iopads
233 if domain and pad is not None:
234 # append direction from spec/domain. damn awkward processing
235 # to find it.
236 fn, name = orig_name.split("_")
237 if domain == 'PWM':
238 name = fn[3:]
239 print (psp.byspec)
240 spec = None
241 for k in psp.byspec.keys():
242 if k.startswith(domain):
243 spec = psp.byspec[k]
244 print ("spec found", domain, spec)
245 assert spec is not None
246 found = None
247 for pname in spec:
248 if pname.lower().startswith(name):
249 found = pname
250 print ("found spec", found)
251 assert found is not None
252 # whewwww. add the direction onto the pad spec list
253 dirn = found[-1]
254 if pad[-1] == 'A':
255 pad[-1] += dirn
256 else:
257 pad.append(dirn)
258 iopads.append(pad)
259 elif pad is not None:
260 iopads.append(pad)
261
262 # not connected
263 nc_idx = 0
264 for pl in pads.values():
265 for i in range(len(pl)):
266 if pl[i] == '':
267 name = 'nc_%d' % nc_idx
268 name2 = 'nc(%d)' % nc_idx
269 pl[i] = name
270 pinmap[name] = name
271 iopads.append([name, name2, name2, "-"])
272 nc_idx += 1
273
274 print (p.bankstart)
275 pprint(psp.clocks)
276
277 print()
278 for name, iopads in pads.items():
279 print ("%s pads" % name, iopads)
280
281 # do not want these
282 if 'SYS' in clocks:
283 del clocks['SYS']
284 if 'SYS' in domains:
285 del domains['SYS']
286
287 print ("chip domains (excluding sys-default)")
288 pprint(domains)
289 print ("chip clocks (excluding sys-default)")
290 pprint(clocks)
291 print ("pin spec")
292 pprint(psp.byspec)
293
294 chip = {
295 'pads.instances' : iopads,
296 'pins.specs' : psp.byspec,
297 'pins.map' : pinmap,
298 'litex.map' : litexmap,
299 'chip.domains' : domains,
300 'chip.clocks' : clocks,
301 'chip.n_intpower': n_intpower,
302 'chip.n_extpower': n_extpower,
303 }
304
305 if 'N' in pads:
306 chip['pads.north'] = pads['N']
307 if 'S' in pads:
308 chip['pads.south'] = pads['S']
309 if 'E' in pads:
310 chip['pads.east'] = pads['E']
311 if 'W' in pads:
312 chip['pads.west'] = pads['W']
313 else:
314 for name, iopads in pads.items():
315 chip['pads.side_%s' % name] = iopads
316
317 return pinmap, chip