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