622feb0bf6e2fd8eb9992ea20cfea25fdf908500
[pinmux.git] / src / bsv / peripheral_gen.py
1 import types
2 from copy import deepcopy
3
4
5 class PBase(object):
6 def __init__(self, name):
7 self.name = name
8
9 def slowifdeclmux(self):
10 return ''
11
12 def slowifinstance(self):
13 return ''
14
15 def slowimport(self):
16 return ''
17
18 def num_axi_regs32(self):
19 return 0
20
21 def slowifdecl(self):
22 return ''
23
24 def axibase(self, name, ifacenum):
25 name = name.upper()
26 return "%(name)s%(ifacenum)dBase" % locals()
27
28 def axiend(self, name, ifacenum):
29 name = name.upper()
30 return "%(name)s%(ifacenum)dEnd" % locals()
31
32 def axi_reg_def(self, start, name, ifacenum):
33 name = name.upper()
34 offs = self.num_axi_regs32() * 4 * 16
35 if offs == 0:
36 return ('', 0)
37 end = start + offs - 1
38 bname = self.axibase(name, ifacenum)
39 bend = self.axiend(name, ifacenum)
40 comment = "%d 32-bit regs" % self.num_axi_regs32()
41 return (" `define %(bname)s 'h%(start)08X\n"
42 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
43 offs)
44
45 def axi_slave_name(self, name, ifacenum):
46 name = name.upper()
47 return "{0}{1}_slave_num".format(name, ifacenum)
48
49 def axi_slave_idx(self, idx, name, ifacenum):
50 name = self.axi_slave_name(name, ifacenum)
51 return ("typedef {0} {1};".format(idx, name), 1)
52
53 def axi_addr_map(self, name, ifacenum):
54 bname = self.axibase(name, ifacenum)
55 bend = self.axiend(name, ifacenum)
56 name = self.axi_slave_name(name, ifacenum)
57 return """\
58 if(addr>=`{0} && addr<=`{1})
59 return tuple2(True,fromInteger(valueOf({2})));
60 else""".format(bname, bend, name)
61
62 def mk_pincon(self, name, count):
63 # TODO: really should be using bsv.interface_decl.Interfaces
64 # pin-naming rules.... logic here is hard-coded to duplicate
65 # it (see Interface.__init__ outen)
66 ret = []
67 for p in self.peripheral.pinspecs:
68 typ = p['type']
69 pname = p['name']
70 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
71 n = name # "{0}{1}".format(self.name, self.mksuffix(name, count))
72 ret.append(" //%s %s" % (n, str(p)))
73 sname = self.peripheral.pname(pname).format(count)
74 ps = "pinmux.peripheral_side.%s" % sname
75 if typ == 'out' or typ == 'inout':
76 ret.append(" rule con_%s%d_%s_out;" % (name, count, pname))
77 fname = self.pinname_out(pname)
78 if not n.startswith('gpio'): # XXX EURGH! horrible hack
79 n_ = "{0}{1}".format(n, count)
80 else:
81 n_ = n
82 if fname:
83 if p.get('outen'):
84 ps_ = ps + '_out'
85 else:
86 ps_ = ps
87 ret.append(" {0}({1}.{2});".format(ps_, n_, fname))
88 fname = None
89 if p.get('outen'):
90 fname = self.pinname_outen(pname)
91 if fname:
92 if isinstance(fname, str):
93 fname = "{0}.{1}".format(n_, fname)
94 fname = self.pinname_tweak(pname, 'outen', fname)
95 ret.append(" {0}_outen({1});".format(ps, fname))
96 ret.append(" endrule")
97 if typ == 'in' or typ == 'inout':
98 fname = self.pinname_in(pname)
99 if fname:
100 if p.get('outen'):
101 ps_ = ps + '_in'
102 else:
103 ps_ = ps
104 ret.append(
105 " rule con_%s%d_%s_in;" %
106 (name, count, pname))
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(" {1}({0});".format(ps_, n_))
111 ret.append(" endrule")
112 return '\n'.join(ret)
113
114 def mk_cellconn(self, *args):
115 return ''
116
117 def mkslow_peripheral(self, size=0):
118 return ''
119
120 def mksuffix(self, name, i):
121 return i
122
123 def __mk_connection(self, con, aname):
124 txt = " mkConnection (slow_fabric.v_to_slaves\n" + \
125 " [fromInteger(valueOf({1}))],\n" + \
126 " {0});"
127
128 print "PBase __mk_connection", self.name, aname
129 if not con:
130 return ''
131 return txt.format(con, aname)
132
133 def mk_connection(self, count, name=None):
134 if name is None:
135 name = self.name
136 print "PBase mk_conn", self.name, count
137 aname = self.axi_slave_name(name, count)
138 #dname = self.mksuffix(name, count)
139 #dname = "{0}{1}".format(name, dname)
140 con = self._mk_connection(name, count).format(count, aname)
141 return self.__mk_connection(con, aname)
142
143 def _mk_connection(self, name=None, count=0):
144 return ''
145
146 def pinname_out(self, pname):
147 return ''
148
149 def pinname_in(self, pname):
150 return ''
151
152 def pinname_outen(self, pname):
153 return ''
154
155 def ifname_tweak(self, pname, typ, txt):
156 return txt
157
158 def pinname_tweak(self, pname, typ, txt):
159 return txt
160
161 def num_irqs(self):
162 return 0
163
164 def mk_plic(self, inum, irq_offs):
165 res = []
166 print "mk_plic", self.name, inum, irq_offs
167 niq = self.num_irqs()
168 if niq == 0:
169 return ('', irq_offs)
170 for idx in range(niq):
171 name = "{0}{1}".format(self.name, self.mksuffix(self.name, inum))
172 plic_obj = self.plic_object(name, idx)
173 print "plic_obj", name, idx, plic_obj
174 plic = mkplic_rule.format(self.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 mkplic_rule = \
180 """
181 rule rl_connect_{0}_to_plic_{2};
182 if({1} == 1'b1) begin
183 ff_gateway_queue[{2}].enq(1);
184 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
185 end
186 endrule
187 """
188
189 class uart(PBase):
190
191 def slowimport(self):
192 return " import Uart_bs :: *;\n" + \
193 " import RS232_modified::*;"
194
195 def slowifdecl(self):
196 return " interface RS232 uart{0}_coe;\n" + \
197 " method Bit#(1) uart{0}_intr;"
198
199 def num_axi_regs32(self):
200 return 8
201
202 def mkslow_peripheral(self, size=0):
203 return " Ifc_Uart_bs uart{0} <- \n" + \
204 " mkUart_bs(clocked_by sp_clock,\n" + \
205 " reset_by uart_reset, sp_clock, sp_reset);"
206
207 def _mk_connection(self, name=None, count=0):
208 return "uart{0}.slave_axi_uart"
209
210 def pinname_out(self, pname):
211 return {'tx': 'coe_rs232.sout'}.get(pname, '')
212
213 def pinname_in(self, pname):
214 return {'rx': 'coe_rs232.sin'}.get(pname, '')
215
216
217 class quart(PBase):
218
219 def slowimport(self):
220 return " import Uart16550 :: *;"
221
222 def slowifdecl(self):
223 return " interface RS232_PHY_Ifc quart{0}_coe;\n" + \
224 " method Bit#(1) quart{0}_intr;"
225
226 def num_axi_regs32(self):
227 return 8
228
229 def mkslow_peripheral(self, size=0):
230 return " Uart16550_AXI4_Lite_Ifc quart{0} <- \n" + \
231 " mkUart16550(clocked_by sp_clock,\n" + \
232 " reset_by uart_reset, sp_clock, sp_reset);"
233
234 def _mk_connection(self, name=None, count=0):
235 return "quart{0}.slave_axi_uart"
236
237 def pinname_out(self, pname):
238 return {'tx' : 'coe_rs232.modem_output_stx',
239 'rts': 'coe_rs232.modem_output_rts',
240 }.get(pname, '')
241
242 def _pinname_in(self, pname):
243 return {'rx': 'coe_rs232.modem_input.srx',
244 'cts': 'coe_rs232.modem_input.cts'
245 }.get(pname, '')
246
247 def mk_pincon(self, name, count):
248 ret = [PBase.mk_pincon(self, name, count)]
249 size = len(self.peripheral.pinspecs)
250 ret.append(eint_pincon_template.format(size))
251 ret.append(" rule con_%s%d_io_in;" % (name, count))
252 ret.append(" {0}{1}.coe_rs232.modem_input(".format(name, count))
253 for idx, pname in enumerate(['rx', 'cts']):
254 sname = self.peripheral.pname(pname).format(count)
255 ps = "pinmux.peripheral_side.%s" % sname
256 ret.append(" {0},".format(ps))
257 ret.append(" 1'b1,1'b0,1'b1")
258 ret.append(" );")
259 ret.append(" endrule")
260
261 return '\n'.join(ret)
262
263
264 class rs232(PBase):
265
266 def slowimport(self):
267 return " import Uart_bs::*;\n" + \
268 " import RS232_modified::*;"
269
270 def slowifdecl(self):
271 return " interface RS232 uart{0}_coe;"
272
273 def num_axi_regs32(self):
274 return 2
275
276 def mkslow_peripheral(self, size=0):
277 return " //Ifc_Uart_bs uart{0} <-" + \
278 " // mkUart_bs(clocked_by uart_clock,\n" + \
279 " // reset_by uart_reset,sp_clock, sp_reset);" +\
280 " Ifc_Uart_bs uart{0} <-" + \
281 " mkUart_bs(clocked_by sp_clock,\n" + \
282 " reset_by sp_reset, sp_clock, sp_reset);"
283
284 def _mk_connection(self, name=None, count=0):
285 return "uart{0}.slave_axi_uart"
286
287 def pinname_out(self, pname):
288 return {'tx': 'coe_rs232.sout'}.get(pname, '')
289
290 def pinname_in(self, pname):
291 return {'rx': 'coe_rs232.sin'}.get(pname, '')
292
293
294 class twi(PBase):
295
296 def slowimport(self):
297 return " import I2C_top :: *;"
298
299 def slowifdecl(self):
300 return " interface I2C_out twi{0}_out;\n" + \
301 " method Bit#(1) twi{0}_isint;"
302
303 def num_irqs(self):
304 return 3
305
306 def num_axi_regs32(self):
307 return 8
308
309 def mkslow_peripheral(self, size=0):
310 return " I2C_IFC twi{0} <- mkI2CController();"
311
312 def _mk_connection(self, name=None, count=0):
313 return "twi{0}.slave_i2c_axi"
314
315 def pinname_out(self, pname):
316 return {'sda': 'out.sda_out',
317 'scl': 'out.scl_out'}.get(pname, '')
318
319 def pinname_in(self, pname):
320 return {'sda': 'out.sda_in',
321 'scl': 'out.scl_in'}.get(pname, '')
322
323 def pinname_outen(self, pname):
324 return {'sda': 'out.sda_out_en',
325 'scl': 'out.scl_out_en'}.get(pname, '')
326
327 def pinname_tweak(self, pname, typ, txt):
328 if typ == 'outen':
329 return "pack({0})".format(txt)
330 return txt
331
332 def plic_object(self, pname, idx):
333 return ["{0}.isint()",
334 "{0}.timerint()",
335 "{0}.isber()"
336 ][idx].format(pname)
337
338
339 class eint(PBase):
340
341 def slowimport(self):
342 size = len(self.peripheral.pinspecs)
343 return " `define NUM_EINTS %d" % size
344
345 def mkslow_peripheral(self, size=0):
346 size = len(self.peripheral.pinspecs)
347 return " Wire#(Bit#(%d)) wr_interrupt <- mkWire();" % size
348
349 def axi_slave_name(self, name, ifacenum):
350 return ''
351
352 def axi_slave_idx(self, idx, name, ifacenum):
353 return ('', 0)
354
355 def axi_addr_map(self, name, ifacenum):
356 return ''
357
358 def ifname_tweak(self, pname, typ, txt):
359 if typ != 'in':
360 return txt
361 print "ifnameweak", pname, typ, txt
362 return "wr_interrupt[{0}] <= ".format(pname)
363
364 def mk_pincon(self, name, count):
365 ret = [PBase.mk_pincon(self, name, count)]
366 size = len(self.peripheral.pinspecs)
367 ret.append(eint_pincon_template.format(size))
368 ret.append(" rule con_%s%d_io_in;" % (name, count))
369 ret.append(" wr_interrupt <= ({")
370 for idx, p in enumerate(self.peripheral.pinspecs):
371 pname = p['name']
372 sname = self.peripheral.pname(pname).format(count)
373 ps = "pinmux.peripheral_side.%s" % sname
374 comma = '' if idx == size - 1 else ','
375 ret.append(" {0}{1}".format(ps, comma))
376 ret.append(" });")
377 ret.append(" endrule")
378
379 return '\n'.join(ret)
380
381
382 eint_pincon_template = '''\
383 // TODO: offset i by the number of eints already used
384 for(Integer i=0;i<{0};i=i+ 1)begin
385 rule connect_int_to_plic(wr_interrupt[i]==1);
386 ff_gateway_queue[i].enq(1);
387 plic.ifc_external_irq[i].irq_frm_gateway(True);
388 endrule
389 end
390 '''
391
392
393 class jtag(PBase):
394
395 def axi_slave_name(self, name, ifacenum):
396 return ''
397
398 def axi_slave_idx(self, idx, name, ifacenum):
399 return ('', 0)
400
401 def axi_addr_map(self, name, ifacenum):
402 return ''
403
404 def slowifdeclmux(self):
405 return " method Action jtag_ms (Bit#(1) in);\n" + \
406 " method Bit#(1) jtag_di;\n" + \
407 " method Action jtag_do (Bit#(1) in);\n" + \
408 " method Action jtag_ck (Bit#(1) in);"
409
410 def slowifinstance(self):
411 return jtag_method_template # bit of a lazy hack this...
412
413 jtag_method_template = """\
414 method Action jtag_ms (Bit#(1) in);
415 pinmux.peripheral_side.jtag_ms(in);
416 endmethod
417 method Bit#(1) jtag_di=pinmux.peripheral_side.jtag_di;
418 method Action jtag_do (Bit#(1) in);
419 pinmux.peripheral_side.jtag_do(in);
420 endmethod
421 method Action jtag_ck (Bit#(1) in);
422 pinmux.peripheral_side.jtag_ck(in);
423 endmethod
424 """
425
426 class sdmmc(PBase):
427
428 def slowimport(self):
429 return " import sdcard_dummy :: *;"
430
431 def slowifdecl(self):
432 return " interface QSPI_out sd{0}_out;\n" + \
433 " method Bit#(1) sd{0}_isint;"
434
435 def num_axi_regs32(self):
436 return 13
437
438 def mkslow_peripheral(self):
439 return " Ifc_sdcard_dummy sd{0} <- mksdcard_dummy();"
440
441 def _mk_connection(self, name=None, count=0):
442 return "sd{0}.slave"
443
444 def pinname_in(self, pname):
445 return "%s_in" % pname
446
447 def pinname_out(self, pname):
448 if pname.startswith('d'):
449 return "%s_out" % pname
450 return pname
451
452 def pinname_outen(self, pname):
453 if pname.startswith('d'):
454 return "%s_outen" % pname
455
456
457 class spi(PBase):
458
459 def slowimport(self):
460 return " import qspi :: *;"
461
462 def slowifdecl(self):
463 return " interface QSPI_out spi{0}_out;\n" + \
464 " method Bit#(1) spi{0}_isint;"
465
466 def num_axi_regs32(self):
467 return 13
468
469 def mkslow_peripheral(self):
470 return " Ifc_qspi spi{0} <- mkqspi();"
471
472 def _mk_connection(self, name=None, count=0):
473 return "spi{0}.slave"
474
475 def pinname_out(self, pname):
476 return {'clk': 'out.clk_o',
477 'nss': 'out.ncs_o',
478 'mosi': 'out.io_o[0]',
479 'miso': 'out.io_o[1]',
480 }.get(pname, '')
481
482 def pinname_outen(self, pname):
483 return {'clk': 1,
484 'nss': 1,
485 'mosi': 'out.io_enable[0]',
486 'miso': 'out.io_enable[1]',
487 }.get(pname, '')
488
489 def mk_pincon(self, name, count):
490 ret = [PBase.mk_pincon(self, name, count)]
491 # special-case for gpio in, store in a temporary vector
492 plen = len(self.peripheral.pinspecs)
493 ret.append(" // XXX NSS and CLK are hard-coded master")
494 ret.append(" // TODO: must add spi slave-mode")
495 ret.append(" // all ins done in one rule from 4-bitfield")
496 ret.append(" rule con_%s%d_io_in;" % (name, count))
497 ret.append(" {0}{1}.out.io_i({{".format(name, count))
498 for idx, pname in enumerate(['mosi', 'miso']):
499 sname = self.peripheral.pname(pname).format(count)
500 ps = "pinmux.peripheral_side.%s_in" % sname
501 ret.append(" {0},".format(ps))
502 ret.append(" 1'b0,1'b0")
503 ret.append(" });")
504 ret.append(" endrule")
505 return '\n'.join(ret)
506
507
508 class qspi(PBase):
509
510 def slowimport(self):
511 return " import qspi :: *;"
512
513 def slowifdecl(self):
514 return " interface QSPI_out qspi{0}_out;\n" + \
515 " method Bit#(1) qspi{0}_isint;"
516
517 def num_axi_regs32(self):
518 return 13
519
520 def mkslow_peripheral(self, size=0):
521 return " Ifc_qspi qspi{0} <- mkqspi();"
522
523 def _mk_connection(self, name=None, count=0):
524 return "qspi{0}.slave"
525
526 def pinname_out(self, pname):
527 return {'ck': 'out.clk_o',
528 'nss': 'out.ncs_o',
529 'io0': 'out.io_o[0]',
530 'io1': 'out.io_o[1]',
531 'io2': 'out.io_o[2]',
532 'io3': 'out.io_o[3]',
533 }.get(pname, '')
534
535 def pinname_outen(self, pname):
536 return {'ck': 1,
537 'nss': 1,
538 'io0': 'out.io_enable[0]',
539 'io1': 'out.io_enable[1]',
540 'io2': 'out.io_enable[2]',
541 'io3': 'out.io_enable[3]',
542 }.get(pname, '')
543
544 def mk_pincon(self, name, count):
545 ret = [PBase.mk_pincon(self, name, count)]
546 # special-case for gpio in, store in a temporary vector
547 plen = len(self.peripheral.pinspecs)
548 ret.append(" // XXX NSS and CLK are hard-coded master")
549 ret.append(" // TODO: must add qspi slave-mode")
550 ret.append(" // all ins done in one rule from 4-bitfield")
551 ret.append(" rule con_%s%d_io_in;" % (name, count))
552 ret.append(" {0}{1}.out.io_i({{".format(name, count))
553 for i, p in enumerate(self.peripheral.pinspecs):
554 typ = p['type']
555 pname = p['name']
556 if not pname.startswith('io'):
557 continue
558 idx = pname[1:]
559 n = name
560 sname = self.peripheral.pname(pname).format(count)
561 ps = "pinmux.peripheral_side.%s_in" % sname
562 comma = '' if i == 5 else ','
563 ret.append(" {0}{1}".format(ps, comma))
564 ret.append(" });")
565 ret.append(" endrule")
566 return '\n'.join(ret)
567
568
569 class pwm(PBase):
570
571 def slowimport(self):
572 return " import pwm::*;"
573
574 def slowifdecl(self):
575 return " interface PWMIO pwm{0}_io;"
576
577 def num_axi_regs32(self):
578 return 4
579
580 def mkslow_peripheral(self, size=0):
581 return " Ifc_PWM_bus pwm{0} <- mkPWM_bus(sp_clock);"
582
583 def _mk_connection(self, name=None, count=0):
584 return "pwm{0}.axi4_slave"
585
586 def pinname_out(self, pname):
587 return {'out': 'pwm_io.pwm_o'}.get(pname, '')
588
589
590 class gpio(PBase):
591
592 def slowimport(self):
593 return " import pinmux::*;\n" + \
594 " import mux::*;\n" + \
595 " import gpio::*;\n"
596
597 def slowifdeclmux(self):
598 size = len(self.peripheral.pinspecs)
599 return " interface GPIO_config#(%d) pad_config{0};" % size
600
601 def num_axi_regs32(self):
602 return 2
603
604 def axi_slave_idx(self, idx, name, ifacenum):
605 """ generates AXI slave number definition, except
606 GPIO also has a muxer per bank
607 """
608 name = name.upper()
609 mname = 'mux' + name[4:]
610 mname = mname.upper()
611 print "AXIslavenum", name, mname
612 (ret, x) = PBase.axi_slave_idx(self, idx, name, ifacenum)
613 (ret2, x) = PBase.axi_slave_idx(self, idx + 1, mname, ifacenum)
614 return ("%s\n%s" % (ret, ret2), 2)
615
616 def mkslow_peripheral(self, size=0):
617 print "gpioslow", self.peripheral, dir(self.peripheral)
618 size = len(self.peripheral.pinspecs)
619 return " MUX#(%d) mux{0} <- mkmux();\n" % size + \
620 " GPIO#(%d) gpio{0} <- mkgpio();" % size
621
622 def mk_connection(self, count):
623 print "GPIO mk_conn", self.name, count
624 res = []
625 dname = self.mksuffix(self.name, count)
626 for i, n in enumerate(['gpio' + dname, 'mux' + dname]):
627 res.append(PBase.mk_connection(self, count, n))
628 return '\n'.join(res)
629
630 def _mk_connection(self, name=None, count=0):
631 n = self.mksuffix(name, count)
632 if name.startswith('gpio'):
633 return "gpio{0}.axi_slave".format(n)
634 if name.startswith('mux'):
635 return "mux{0}.axi_slave".format(n)
636
637 def mksuffix(self, name, i):
638 if name.startswith('mux'):
639 return name[3:]
640 return name[4:]
641
642 def mk_cellconn(self, cellnum, name, count):
643 ret = []
644 bank = self.mksuffix(name, count)
645 txt = " pinmux.mux_lines.cell{0}_mux(mux{1}.mux_config.mux[{2}]);"
646 for p in self.peripheral.pinspecs:
647 ret.append(txt.format(cellnum, bank, p['name'][1:]))
648 cellnum += 1
649 return ("\n".join(ret), cellnum)
650
651 def pinname_out(self, pname):
652 return "func.gpio_out[{0}]".format(pname[1:])
653
654 def pinname_outen(self, pname):
655 return "func.gpio_out_en[{0}]".format(pname[1:])
656
657 def mk_pincon(self, name, count):
658 ret = [PBase.mk_pincon(self, name, count)]
659 # special-case for gpio in, store in a temporary vector
660 plen = len(self.peripheral.pinspecs)
661 ret.append(" rule con_%s%d_in;" % (name, count))
662 ret.append(" Vector#({0},Bit#(1)) temp;".format(plen))
663 for p in self.peripheral.pinspecs:
664 typ = p['type']
665 pname = p['name']
666 idx = pname[1:]
667 n = name
668 sname = self.peripheral.pname(pname).format(count)
669 ps = "pinmux.peripheral_side.%s_in" % sname
670 ret.append(" temp[{0}]={1};".format(idx, ps))
671 ret.append(" {0}.func.gpio_in(temp);".format(name))
672 ret.append(" endrule")
673 return '\n'.join(ret)
674
675
676 axi_slave_declarations = """\
677 typedef 0 SlowMaster;
678 {0}
679 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
680 CLINT_slave_num;
681 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
682 Plic_slave_num;
683 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
684 AxiExp1_slave_num;
685 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
686 """
687
688 pinmux_cellrule = """\
689 rule connect_select_lines_pinmux;
690 {0}
691 endrule
692 """
693
694
695 class CallFn(object):
696 def __init__(self, peripheral, name):
697 self.peripheral = peripheral
698 self.name = name
699
700 def __call__(self, *args):
701 #print "__call__", self.name, self.peripheral.slow, args
702 if not self.peripheral.slow:
703 return ''
704 return getattr(self.peripheral.slow, self.name)(*args[1:])
705
706
707 class PeripheralIface(object):
708 def __init__(self, ifacename):
709 self.slow = None
710 slow = slowfactory.getcls(ifacename)
711 print "Iface", ifacename, slow
712 if slow:
713 self.slow = slow(ifacename)
714 self.slow.peripheral = self
715 for fname in ['slowimport',
716 'slowifinstance', 'slowifdecl', 'slowifdeclmux',
717 'mkslow_peripheral', 'mk_plic',
718 'mk_connection', 'mk_cellconn', 'mk_pincon']:
719 fn = CallFn(self, fname)
720 setattr(self, fname, types.MethodType(fn, self))
721
722 #print "PeripheralIface"
723 #print dir(self)
724
725 def mksuffix(self, name, i):
726 if self.slow is None:
727 return i
728 return self.slow.mksuffix(name, i)
729
730 def axi_reg_def(self, start, count):
731 if not self.slow:
732 return ('', 0)
733 return self.slow.axi_reg_def(start, self.ifacename, count)
734
735 def axi_slave_idx(self, start, count):
736 if not self.slow:
737 return ('', 0)
738 return self.slow.axi_slave_idx(start, self.ifacename, count)
739
740 def axi_addr_map(self, count):
741 if not self.slow:
742 return ''
743 return self.slow.axi_addr_map(self.ifacename, count)
744
745
746 class PeripheralInterfaces(object):
747 def __init__(self):
748 pass
749
750 def slowimport(self, *args):
751 ret = []
752 for (name, count) in self.ifacecount:
753 #print "slowimport", name, self.data[name].slowimport
754 ret.append(self.data[name].slowimport())
755 return '\n'.join(list(filter(None, ret)))
756
757 def slowifinstance(self, *args):
758 ret = []
759 for (name, count) in self.ifacecount:
760 #print "slowimport", name, self.data[name].slowimport
761 ret.append(self.data[name].slowifinstance())
762 return '\n'.join(list(filter(None, ret)))
763
764 def slowifdeclmux(self, *args):
765 ret = []
766 for (name, count) in self.ifacecount:
767 for i in range(count):
768 ret.append(self.data[name].slowifdeclmux().format(i, name))
769 return '\n'.join(list(filter(None, ret)))
770
771 def slowifdecl(self, *args):
772 ret = []
773 for (name, count) in self.ifacecount:
774 for i in range(count):
775 ret.append(self.data[name].slowifdecl().format(i, name))
776 return '\n'.join(list(filter(None, ret)))
777
778 def axi_reg_def(self, *args):
779 ret = []
780 start = 0x00011100 # start of AXI peripherals address
781 for (name, count) in self.ifacecount:
782 for i in range(count):
783 x = self.data[name].axi_reg_def(start, i)
784 #print ("ifc", name, x)
785 (rdef, offs) = x
786 ret.append(rdef)
787 start += offs
788 return '\n'.join(list(filter(None, ret)))
789
790 def axi_slave_idx(self, *args):
791 ret = []
792 start = 0
793 for (name, count) in self.ifacecount:
794 for i in range(count):
795 (rdef, offs) = self.data[name].axi_slave_idx(start, i)
796 #print ("ifc", name, rdef, offs)
797 ret.append(rdef)
798 start += offs
799 ret.append("typedef %d LastGen_slave_num;" % (start - 1))
800 decls = '\n'.join(list(filter(None, ret)))
801 return axi_slave_declarations.format(decls)
802
803 def axi_addr_map(self, *args):
804 ret = []
805 for (name, count) in self.ifacecount:
806 for i in range(count):
807 ret.append(self.data[name].axi_addr_map(i))
808 return '\n'.join(list(filter(None, ret)))
809
810 def mkslow_peripheral(self, *args):
811 ret = []
812 for (name, count) in self.ifacecount:
813 for i in range(count):
814 print "mkslow", name, count
815 x = self.data[name].mkslow_peripheral()
816 print name, count, x
817 suffix = self.data[name].mksuffix(name, i)
818 ret.append(x.format(suffix))
819 return '\n'.join(list(filter(None, ret)))
820
821 def mk_connection(self, *args):
822 ret = []
823 for (name, count) in self.ifacecount:
824 for i in range(count):
825 print "mk_conn", name, i
826 txt = self.data[name].mk_connection(i)
827 if name == 'gpioa':
828 print "txt", txt
829 print self.data[name].mk_connection
830 ret.append(txt)
831 return '\n'.join(list(filter(None, ret)))
832
833 def mk_cellconn(self):
834 ret = []
835 cellcount = 0
836 for (name, count) in self.ifacecount:
837 for i in range(count):
838 res = self.data[name].mk_cellconn(cellcount, name, i)
839 if not res:
840 continue
841 (txt, cellcount) = res
842 ret.append(txt)
843 ret = '\n'.join(list(filter(None, ret)))
844 return pinmux_cellrule.format(ret)
845
846 def mk_pincon(self):
847 ret = []
848 for (name, count) in self.ifacecount:
849 for i in range(count):
850 txt = self.data[name].mk_pincon(name, i)
851 ret.append(txt)
852 return '\n'.join(list(filter(None, ret)))
853
854
855 def mk_plic(self):
856 ret = []
857 irq_offs = 8 # XXX: DMA scovers 0-7?
858 for (name, count) in self.ifacecount:
859 for i in range(count):
860 res = self.data[name].mk_plic(i, irq_offs)
861 if not res:
862 continue
863 (txt, irq_offs) = res
864 ret.append(txt)
865 return '\n'.join(list(filter(None, ret)))
866
867
868 class PFactory(object):
869 def getcls(self, name):
870 for k, v in {'uart': uart,
871 'rs232': rs232,
872 'twi': twi,
873 'quart': quart,
874 'qspi': qspi,
875 'spi': spi,
876 'pwm': pwm,
877 'eint': eint,
878 'sd': sdmmc,
879 'jtag': jtag,
880 'gpio': gpio
881 }.items():
882 if name.startswith(k):
883 return v
884 return None
885
886
887 slowfactory = PFactory()
888
889 if __name__ == '__main__':
890 p = uart('uart')
891 print p.slowimport()
892 print p.slowifdecl()
893 i = PeripheralIface('uart')
894 print i, i.slow
895 i = PeripheralIface('gpioa')
896 print i, i.slow