pep8 cleanup
[pinmux.git] / src / bsv / peripheral_gen / base.py
1 import types
2
3
4 class PBase(object):
5 def __init__(self, name):
6 self.name = name
7
8 def slowifdeclmux(self):
9 return ''
10
11 def slowifinstance(self):
12 return ''
13
14 def slowimport(self):
15 return ''
16
17 def num_axi_regs32(self):
18 return 0
19
20 def slowifdecl(self):
21 return ''
22
23 def get_iname(self, inum):
24 return "{0}{1}".format(self.name, self.mksuffix(self.name, inum))
25
26 def axibase(self, name, ifacenum):
27 name = name.upper()
28 return "%(name)s%(ifacenum)dBase" % locals()
29
30 def axiend(self, name, ifacenum):
31 name = name.upper()
32 return "%(name)s%(ifacenum)dEnd" % locals()
33
34 def axi_reg_def(self, start, name, ifacenum):
35 name = name.upper()
36 offs = self.num_axi_regs32() * 4 * 16
37 if offs == 0:
38 return ('', 0)
39 end = start + offs - 1
40 bname = self.axibase(name, ifacenum)
41 bend = self.axiend(name, ifacenum)
42 comment = "%d 32-bit regs" % self.num_axi_regs32()
43 return (" `define %(bname)s 'h%(start)08X\n"
44 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
45 offs)
46
47 def axi_slave_name(self, name, ifacenum):
48 name = name.upper()
49 return "{0}{1}_slave_num".format(name, ifacenum)
50
51 def axi_slave_idx(self, idx, name, ifacenum):
52 name = self.axi_slave_name(name, ifacenum)
53 return ("typedef {0} {1};".format(idx, name), 1)
54
55 def axi_addr_map(self, name, ifacenum):
56 bname = self.axibase(name, ifacenum)
57 bend = self.axiend(name, ifacenum)
58 name = self.axi_slave_name(name, ifacenum)
59 return """\
60 if(addr>=`{0} && addr<=`{1})
61 return tuple2(True,fromInteger(valueOf({2})));
62 else""".format(bname, bend, name)
63
64 def mk_pincon(self, name, count):
65 # TODO: really should be using bsv.interface_decl.Interfaces
66 # pin-naming rules.... logic here is hard-coded to duplicate
67 # it (see Interface.__init__ outen)
68 ret = []
69 for p in self.peripheral.pinspecs:
70 typ = p['type']
71 pname = p['name']
72 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
73 n = name # "{0}{1}".format(self.name, self.mksuffix(name, count))
74 ret.append(" //%s %s" % (n, str(p)))
75 sname = self.peripheral.iname().format(count)
76 sname = "{0}.{1}".format(sname, pname)
77 ps = "pinmux.peripheral_side.%s" % sname
78 if typ == 'out' or typ == 'inout':
79 fname = self.pinname_out(pname)
80 if not n.startswith('gpio'): # XXX EURGH! horrible hack
81 n_ = "{0}{1}".format(n, count)
82 else:
83 n_ = n
84 if fname:
85 if p.get('outen'):
86 ps_ = ps + '_out'
87 else:
88 ps_ = ps
89 ret.append(" mkConnection({0},\n\t\t\t{1}.{2});"
90 .format(ps_, n_, fname))
91 fname = None
92 if p.get('outen'):
93 fname = self.pinname_outen(pname)
94 if fname:
95 if isinstance(fname, str):
96 fname = "{0}.{1}".format(n_, fname)
97 fname = self.pinname_tweak(pname, 'outen', fname)
98 ret.append(" mkConnection({0}_outen,\n\t\t\t{1});"
99 .format(ps, fname))
100 if typ == 'in' or typ == 'inout':
101 fname = self.pinname_in(pname)
102 if fname:
103 if p.get('outen'):
104 ps_ = ps + '_in'
105 else:
106 ps_ = ps
107 n_ = "{0}{1}".format(n, count)
108 n_ = '{0}.{1}'.format(n_, fname)
109 n_ = self.ifname_tweak(pname, 'in', n_)
110 ret.append(" mkConnection({1}, {0});".format(ps_, n_))
111 return '\n'.join(ret)
112
113 def mk_cellconn(self, *args):
114 return ''
115
116 def mkslow_peripheral(self, size=0):
117 return ''
118
119 def mksuffix(self, name, i):
120 return i
121
122 def __mk_connection(self, con, aname):
123 txt = " mkConnection (slow_fabric.v_to_slaves\n" + \
124 " [fromInteger(valueOf({1}))],\n" + \
125 " {0});"
126
127 print "PBase __mk_connection", self.name, aname
128 if not con:
129 return ''
130 return txt.format(con, aname)
131
132 def mk_connection(self, count, name=None):
133 if name is None:
134 name = self.name
135 print "PBase mk_conn", self.name, count
136 aname = self.axi_slave_name(name, count)
137 #dname = self.mksuffix(name, count)
138 #dname = "{0}{1}".format(name, dname)
139 con = self._mk_connection(name, count).format(count, aname)
140 return self.__mk_connection(con, aname)
141
142 def _mk_connection(self, name=None, count=0):
143 return ''
144
145 def pinname_out(self, pname):
146 return ''
147
148 def pinname_in(self, pname):
149 return ''
150
151 def pinname_outen(self, pname):
152 return ''
153
154 def ifname_tweak(self, pname, typ, txt):
155 return txt
156
157 def pinname_tweak(self, pname, typ, txt):
158 return txt
159
160 def num_irqs(self):
161 return 0
162
163 def mk_plic(self, inum, irq_offs):
164 res = []
165 print "mk_plic", self.name, inum, irq_offs
166 niq = self.num_irqs()
167 if niq == 0:
168 return ('', irq_offs)
169 name = self.get_iname(inum)
170 res.append(" // PLIC rules for {0}".format(name))
171 for idx in range(niq):
172 plic_obj = self.plic_object(name, idx)
173 print "plic_obj", name, idx, plic_obj
174 plic = mkplic_rule.format(name, plic_obj, irq_offs)
175 res.append(plic)
176 irq_offs += 1 # increment to next irq
177 return ('\n'.join(res), irq_offs)
178
179 def mk_ext_ifacedef(self, iname, inum):
180 return ''
181
182
183 mkplic_rule = """\
184 rule rl_connect_{0}_to_plic_{2};
185 if({1} == 1'b1) begin
186 ff_gateway_queue[{2}].enq(1);
187 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
188 end
189 endrule
190 """
191
192
193 axi_slave_declarations = """\
194 typedef 0 SlowMaster;
195 {0}
196 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
197 CLINT_slave_num;
198 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
199 Plic_slave_num;
200 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
201 AxiExp1_slave_num;
202 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
203 """
204
205 pinmux_cellrule = """\
206 rule connect_select_lines_pinmux;
207 {0}
208 endrule
209 """
210
211
212 class CallFn(object):
213 def __init__(self, peripheral, name):
214 self.peripheral = peripheral
215 self.name = name
216
217 def __call__(self, *args):
218 #print "__call__", self.name, self.peripheral.slow, args
219 if not self.peripheral.slow:
220 return ''
221 return getattr(self.peripheral.slow, self.name)(*args[1:])
222
223
224 class PeripheralIface(object):
225 def __init__(self, ifacename):
226 self.slow = None
227 slow = slowfactory.getcls(ifacename)
228 print "Iface", ifacename, slow
229 if slow:
230 self.slow = slow(ifacename)
231 self.slow.peripheral = self
232 for fname in ['slowimport',
233 'slowifinstance', 'slowifdecl', 'slowifdeclmux',
234 'mkslow_peripheral', 'mk_plic', 'mk_ext_ifacedef',
235 'mk_connection', 'mk_cellconn', 'mk_pincon']:
236 fn = CallFn(self, fname)
237 setattr(self, fname, types.MethodType(fn, self))
238
239 #print "PeripheralIface"
240 #print dir(self)
241
242 def mksuffix(self, name, i):
243 if self.slow is None:
244 return i
245 return self.slow.mksuffix(name, i)
246
247 def axi_reg_def(self, start, count):
248 if not self.slow:
249 return ('', 0)
250 return self.slow.axi_reg_def(start, self.ifacename, count)
251
252 def axi_slave_idx(self, start, count):
253 if not self.slow:
254 return ('', 0)
255 return self.slow.axi_slave_idx(start, self.ifacename, count)
256
257 def axi_addr_map(self, count):
258 if not self.slow:
259 return ''
260 return self.slow.axi_addr_map(self.ifacename, count)
261
262
263 class PeripheralInterfaces(object):
264 def __init__(self):
265 pass
266
267 def slowimport(self, *args):
268 ret = []
269 for (name, count) in self.ifacecount:
270 #print "slowimport", name, self.data[name].slowimport
271 ret.append(self.data[name].slowimport())
272 return '\n'.join(list(filter(None, ret)))
273
274 def slowifinstance(self, *args):
275 ret = []
276 for (name, count) in self.ifacecount:
277 #print "slowimport", name, self.data[name].slowimport
278 ret.append(self.data[name].slowifinstance())
279 return '\n'.join(list(filter(None, ret)))
280
281 def slowifdeclmux(self, *args):
282 ret = []
283 for (name, count) in self.ifacecount:
284 for i in range(count):
285 ret.append(self.data[name].slowifdeclmux().format(i, name))
286 return '\n'.join(list(filter(None, ret)))
287
288 def slowifdecl(self, *args):
289 ret = []
290 for (name, count) in self.ifacecount:
291 for i in range(count):
292 ret.append(self.data[name].slowifdecl().format(i, name))
293 return '\n'.join(list(filter(None, ret)))
294
295 def axi_reg_def(self, *args):
296 ret = []
297 start = 0x00011100 # start of AXI peripherals address
298 for (name, count) in self.ifacecount:
299 for i in range(count):
300 x = self.data[name].axi_reg_def(start, i)
301 #print ("ifc", name, x)
302 (rdef, offs) = x
303 ret.append(rdef)
304 start += offs
305 return '\n'.join(list(filter(None, ret)))
306
307 def axi_slave_idx(self, *args):
308 ret = []
309 start = 0
310 for (name, count) in self.ifacecount:
311 for i in range(count):
312 (rdef, offs) = self.data[name].axi_slave_idx(start, i)
313 #print ("ifc", name, rdef, offs)
314 ret.append(rdef)
315 start += offs
316 ret.append("typedef %d LastGen_slave_num;" % (start - 1))
317 decls = '\n'.join(list(filter(None, ret)))
318 return axi_slave_declarations.format(decls)
319
320 def axi_addr_map(self, *args):
321 ret = []
322 for (name, count) in self.ifacecount:
323 for i in range(count):
324 ret.append(self.data[name].axi_addr_map(i))
325 return '\n'.join(list(filter(None, ret)))
326
327 def mkslow_peripheral(self, *args):
328 ret = []
329 for (name, count) in self.ifacecount:
330 for i in range(count):
331 print "mkslow", name, count
332 x = self.data[name].mkslow_peripheral()
333 print name, count, x
334 suffix = self.data[name].mksuffix(name, i)
335 ret.append(x.format(suffix))
336 return '\n'.join(list(filter(None, ret)))
337
338 def mk_connection(self, *args):
339 ret = []
340 for (name, count) in self.ifacecount:
341 for i in range(count):
342 print "mk_conn", name, i
343 txt = self.data[name].mk_connection(i)
344 if name == 'gpioa':
345 print "txt", txt
346 print self.data[name].mk_connection
347 ret.append(txt)
348 return '\n'.join(list(filter(None, ret)))
349
350 def mk_cellconn(self):
351 ret = []
352 cellcount = 0
353 for (name, count) in self.ifacecount:
354 for i in range(count):
355 res = self.data[name].mk_cellconn(cellcount, name, i)
356 if not res:
357 continue
358 (txt, cellcount) = res
359 ret.append(txt)
360 ret = '\n'.join(list(filter(None, ret)))
361 return pinmux_cellrule.format(ret)
362
363 def mk_pincon(self):
364 ret = []
365 for (name, count) in self.ifacecount:
366 for i in range(count):
367 txt = self.data[name].mk_pincon(name, i)
368 ret.append(txt)
369 return '\n'.join(list(filter(None, ret)))
370
371 def mk_ext_ifacedef(self):
372 ret = []
373 for (name, count) in self.ifacecount:
374 for i in range(count):
375 txt = self.data[name].mk_ext_ifacedef(name, i)
376 ret.append(txt)
377 return '\n'.join(list(filter(None, ret)))
378
379 def mk_plic(self):
380 ret = []
381 irq_offs = 8 # XXX: DMA scovers 0-7?
382 for (name, count) in self.ifacecount:
383 for i in range(count):
384 res = self.data[name].mk_plic(i, irq_offs)
385 if not res:
386 continue
387 (txt, irq_offs) = res
388 ret.append(txt)
389 self.num_slow_irqs = irq_offs
390 return '\n'.join(list(filter(None, ret)))
391
392 def mk_sloirqsdef(self):
393 return " `define NUM_SLOW_IRQS {0}".format(self.num_slow_irqs)
394
395
396 class PFactory(object):
397 def getcls(self, name):
398 from uart import uart
399 from quart import quart
400 from sdmmc import sdmmc
401 from pwm import pwm
402 from eint import eint
403 from rs232 import rs232
404 from twi import twi
405 from eint import eint
406 from jtag import jtag
407 from spi import spi
408 from qspi import qspi
409 from gpio import gpio
410 from rgbttl import rgbttl
411
412 for k, v in {'uart': uart,
413 'rs232': rs232,
414 'twi': twi,
415 'quart': quart,
416 'qspi': qspi,
417 'spi': spi,
418 'pwm': pwm,
419 'eint': eint,
420 'sd': sdmmc,
421 'jtag': jtag,
422 'lcd': rgbttl,
423 'gpio': gpio
424 }.items():
425 if name.startswith(k):
426 return v
427 return None
428
429
430 slowfactory = PFactory()
431
432 if __name__ == '__main__':
433 p = uart('uart')
434 print p.slowimport()
435 print p.slowifdecl()
436 i = PeripheralIface('uart')
437 print i, i.slow
438 i = PeripheralIface('gpioa')
439 print i, i.slow