add pin renaming for vector connections
[pinmux.git] / src / bsv / peripheral_gen / base.py
1 import types
2
3
4 def li(txt, indent):
5 indent = ' ' * indent
6 istxt = False
7 if isinstance(txt, str):
8 istxt = True
9 txt = txt.split('\n')
10 res = []
11 for line in txt:
12 line = line.split('\n')
13 res += line
14 txt = res
15 res = []
16 for line in txt:
17 res.append(indent + line)
18 if istxt:
19 res = '\n'.join(res)
20 return res
21
22
23 class PBase(object):
24 def __init__(self, name):
25 self.name = name
26
27 def extifdecl(self, name, count):
28 sname = self.get_iname(count)
29 return "interface PeripheralSide%s %s;" % (name.upper(), sname)
30
31 def has_axi_master(self):
32 return False
33
34 def irq_name(self):
35 return ""
36
37 def mk_dma_irq(self, name, count):
38 if not self.irq_name():
39 return ''
40 sname = self.get_iname(count)
41 return "{0}_interrupt".format(sname)
42
43 def mk_dma_rule(self, name, count):
44 irqname = self.mk_dma_irq(name, count)
45 if not irqname:
46 return ''
47 pirqname = self.irq_name().format(count)
48 template = " {0}.send(\n" + \
49 " slow_peripherals.{1});"
50 return template.format(irqname, pirqname)
51
52 def get_clock_reset(self, name, count):
53 return "slow_clock,slow_reset"
54
55 def mk_dma_sync(self, name, count):
56 irqname = self.mk_dma_irq(name, count)
57 if not irqname:
58 return ''
59 sname = self.peripheral.iname().format(count)
60 template = "SyncBitIfc#(Bit#(1)) {0} <-\n" + \
61 " <-mkSyncBitToCC({1});"
62 return template.format(irqname, self.get_clock_reset(name, count))
63
64 def mk_dma_connect(self, name, count):
65 irqname = self.mk_dma_irq(name, count)
66 if not irqname:
67 return ''
68 return "{0}.read".format(irqname)
69
70 def fastifdecl(self, name, count):
71 return ''
72
73 def slowifdeclmux(self, name, count):
74 return ''
75
76 def slowimport(self):
77 return ''
78
79 def num_axi_regs32(self):
80 return 0
81
82 def slowifdecl(self):
83 return ''
84
85 def get_iname(self, inum):
86 return "{0}{1}".format(self.name, self.mksuffix(self.name, inum))
87
88 def axibase(self, name, ifacenum):
89 name = name.upper()
90 return "%(name)s%(ifacenum)dBase" % locals()
91
92 def axiend(self, name, ifacenum):
93 name = name.upper()
94 return "%(name)s%(ifacenum)dEnd" % locals()
95
96 def axi_reg_def(self, start, name, ifacenum):
97 name = name.upper()
98 offs = self.num_axi_regs32() * 4 * 16
99 if offs == 0:
100 return ('', 0)
101 end = start + offs - 1
102 bname = self.axibase(name, ifacenum)
103 bend = self.axiend(name, ifacenum)
104 comment = "%d 32-bit regs" % self.num_axi_regs32()
105 return (" `define %(bname)s 'h%(start)08X\n"
106 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
107 offs)
108
109 def axi_master_name(self, name, ifacenum, typ=''):
110 name = name.upper()
111 return "{0}{1}_master_num".format(name, ifacenum)
112
113 def axi_slave_name(self, name, ifacenum, typ=''):
114 name = name.upper()
115 return "{0}{1}_{2}slave_num".format(name, ifacenum, typ)
116
117 def axi_master_idx(self, idx, name, ifacenum, typ):
118 name = self.axi_master_name(name, ifacenum, typ)
119 return ("typedef {0} {1};".format(idx, name), 1)
120
121 def axi_slave_idx(self, idx, name, ifacenum, typ):
122 name = self.axi_slave_name(name, ifacenum, typ)
123 return ("typedef {0} {1};".format(idx, name), 1)
124
125 def axi_fastaddr_map(self, name, ifacenum):
126 return self.axi_addr_map(name, ifacenum, 'fast')
127
128 def axi_addr_map(self, name, ifacenum, typ=""):
129 bname = self.axibase(name, ifacenum)
130 bend = self.axiend(name, ifacenum)
131 name = self.axi_slave_name(name, ifacenum, typ)
132 template = """\
133 if(addr>=`{0} && addr<=`{1})
134 return tuple2(True,fromInteger(valueOf({2})));
135 else"""
136 return template.format(bname, bend, name)
137
138 def _mk_pincon(self, name, count, ptyp):
139 # TODO: really should be using bsv.interface_decl.Interfaces
140 # pin-naming rules.... logic here is hard-coded to duplicate
141 # it (see Interface.__init__ outen)
142 ret = []
143 for p in self.peripheral.pinspecs:
144 typ = p['type']
145 pname = p['name']
146 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
147 n = name # "{0}{1}".format(self.name, self.mksuffix(name, count))
148 ret.append("//%s %s" % (n, str(p)))
149 if ptyp == 'fast':
150 sname = self.get_iname(count)
151 sname = "{0}.{1}".format(sname, pname)
152 ps = "slow_peripherals.%s" % sname
153 else:
154 sname = self.peripheral.iname().format(count)
155 sname = "{0}.{1}".format(sname, pname)
156 ps = "pinmux.peripheral_side.%s" % sname
157 if typ == 'out' or typ == 'inout':
158 fname = self.pinname_out(pname)
159 if not n.startswith('gpio'): # XXX EURGH! horrible hack
160 n_ = "{0}{1}".format(n, count)
161 else:
162 n_ = n
163 if fname:
164 if p.get('outen'):
165 ps_ = ps + '_out'
166 else:
167 ps_ = ps
168 cn = self._mk_actual_connection('out', name,
169 count, typ,
170 pname, ps_, n_, fname)
171 ret += cn
172 fname = None
173 if p.get('outen'):
174 fname = self.pinname_outen(pname)
175 if fname:
176 if isinstance(fname, str):
177 fname = "{0}.{1}".format(n_, fname)
178 fname = self.pinname_tweak(pname, 'outen', fname)
179 cn = self._mk_actual_connection('outen', name,
180 count, typ,
181 pname, ps, n, fname)
182 ret += cn
183 if typ == 'in' or typ == 'inout':
184 fname = self.pinname_in(pname)
185 if fname:
186 if p.get('outen'):
187 ps_ = ps + '_in'
188 else:
189 ps_ = ps
190 n_ = "{0}{1}".format(n, count)
191 n_ = '{0}.{1}'.format(n_, fname)
192 n_ = self.ifname_tweak(pname, 'in', n_)
193 cn = self._mk_actual_connection('in', name,
194 count, typ,
195 pname, ps_, n_, fname)
196 ret += cn
197 return '\n'.join(ret)
198
199 def _mk_vpincon(self, name, count, ptyp, typ, pname, stype=None):
200 if stype is None:
201 stype = pname
202 ret = []
203 if ptyp == 'fast':
204 sname = self.get_iname(count)
205 ps = "slow_peripherals.%s" % sname
206 else:
207 sname = self.peripheral.iname().format(count)
208 ps = "pinmux.peripheral_side.%s" % sname
209 n = self.get_iname(count)
210 ps_ = "{0}.{1}".format(ps, pname)
211 ret += self._mk_actual_connection(typ, name, count, typ,
212 pname, ps_, n, stype)
213 return '\n'.join(ret)
214
215 def _mk_actual_connection(self, ctype, name, count, typ,
216 pname, ps, n, fname):
217 ret = []
218 ck = self.get_clock_reset(name, count)
219 if ctype == 'out':
220 if ck == PBase.get_clock_reset(self, name, count):
221 ret.append("mkConnection({0},\n\t\t\t{1}.{2});"
222 .format(ps, n, fname))
223 else:
224 n2 = "{0}{1}".format(name, count)
225 sync = '{0}_{1}_sync'.format(n2, pname)
226 ret.append("mkConnection({0},\n\t\t\t{1}.get);"
227 .format(ps, sync))
228 ret.append("mkConnection({0}.put,\n\t\t\t{1}.{2});"
229 .format(sync, n, fname))
230 elif ctype == 'outen':
231 ret.append("mkConnection({0}_outen,\n\t\t\t{1});"
232 .format(ps, fname))
233 elif ctype == 'in':
234 if ck == PBase.get_clock_reset(self, name, count):
235 ret.append("mkConnection({1},\n\t\t\t{0});".format(
236 ps, n))
237 else:
238 n2 = "{0}{1}".format(name, count)
239 sync = '{0}_{1}_sync'.format(n2, pname)
240 ret.append("mkConnection({1}.put,\n\t\t\t{0});".format(
241 ps, sync))
242 ret.append("mkConnection({1},\n\t\t\t{0}.get);".format(
243 sync, n))
244 return ret
245
246
247 def _mk_clk_con(self, name, count, ctype):
248 ret = []
249 ck = self.get_clock_reset(name, count)
250 if ck == PBase.get_clock_reset(self, name, count):
251 return ''
252 if ctype == 'slow':
253 spc = "sp_clock, sp_reset"
254 else:
255 spc = ck
256 ck = "core_clock, core_reset"
257 template = """\
258 Ifc_sync#({0}) {1}_sync <-mksyncconnection(
259 {2}, {3});"""
260 for p in self.peripheral.pinspecs:
261 typ = p['type']
262 pname = p['name']
263 n = name
264 if typ == 'out' or typ == 'inout':
265 fname = self.pinname_out(pname)
266 if not fname:
267 continue
268 if not n.startswith('gpio'): # XXX EURGH! horrible hack
269 n_ = "{0}{1}".format(n, count)
270 else:
271 n_ = n
272 n_ = '{0}_{1}'.format(n_, pname)
273 ret.append(template.format("Bit#(1)", n_, ck, spc))
274 if typ == 'in' or typ == 'inout':
275 fname = self.pinname_in(pname)
276 if not fname:
277 continue
278 #fname = self.pinname_in(pname)
279 n_ = "{0}{1}".format(n, count)
280 n_ = '{0}_{1}'.format(n_, pname)
281 #n_ = self.ifname_tweak(pname, 'in', n_)
282 ret.append(template.format("Bit#(1)", n_, spc, ck))
283 return '\n'.join(ret)
284
285 def _mk_clk_vcon(self, name, count, ctype, typ, pname, bitspec):
286 ck = self.get_clock_reset(name, count)
287 if ck == PBase.get_clock_reset(self, name, count):
288 return ''
289 if ctype == 'slow':
290 spc = "sp_clock, sp_reset"
291 else:
292 spc = ck
293 ck = "core_clock, core_reset"
294 template = """\
295 Ifc_sync#({0}) {1}_sync <-mksyncconnection(
296 {2}, {3});"""
297
298 n_ = "{0}{1}".format(name, count)
299 n_ = '{0}_{1}'.format(n_, pname)
300 return template.format(bitspec, n_, ck, spc)
301
302
303 def mk_cellconn(self, *args):
304 return ''
305
306 def mkfast_peripheral(self, size=0):
307 return ''
308
309 def mkslow_peripheral(self, size=0):
310 return ''
311
312 def mksuffix(self, name, i):
313 return i
314
315 def __mk_connection(self, con, aname, fabricname):
316 txt = "mkConnection ({2}.v_to_slaves\n" + \
317 " [fromInteger(valueOf({1}))],\n" + \
318 " {0});"
319
320 print "PBase __mk_connection", self.name, aname
321 if not con:
322 return ''
323 return txt.format(con, aname, fabricname)
324
325 def __mk_master_connection(self, con, aname):
326 txt = "mkConnection (slow_fabric.v_to_slaves\n" + \
327 " [fromInteger(valueOf({1}))],\n" + \
328 " {0});"
329
330 print "PBase __mk_connection", self.name, aname
331 if not con:
332 return ''
333 return txt.format(con, aname)
334
335 def mk_connection(self, count, fabricname, typ, name=None):
336 if name is None:
337 name = self.name
338 print "PBase mk_conn", self.name, count
339 aname = self.axi_slave_name(name, count, typ)
340 #dname = self.mksuffix(name, count)
341 #dname = "{0}{1}".format(name, dname)
342 con = self._mk_connection(name, count).format(count, aname)
343 return self.__mk_connection(con, aname, fabricname)
344
345 def _mk_connection(self, name=None, count=0):
346 return ''
347
348 def pinname_out(self, pname):
349 return ''
350
351 def pinname_in(self, pname):
352 return ''
353
354 def pinname_outen(self, pname):
355 return ''
356
357 def ifname_tweak(self, pname, typ, txt):
358 return txt
359
360 def pinname_tweak(self, pname, typ, txt):
361 return txt
362
363 def num_irqs(self):
364 return 0
365
366 def mk_plic(self, inum, irq_offs):
367 res = []
368 print "mk_plic", self.name, inum, irq_offs
369 niq = self.num_irqs()
370 if niq == 0:
371 return ('', irq_offs)
372 name = self.get_iname(inum)
373 res.append("// PLIC rules for {0}".format(name))
374 for idx in range(niq):
375 plic_obj = self.plic_object(name, idx)
376 print "plic_obj", name, idx, plic_obj
377 plic = mkplic_rule.format(name, plic_obj, irq_offs)
378 res.append(plic)
379 irq_offs += 1 # increment to next irq
380 return ('\n'.join(res), irq_offs)
381
382 def mk_ext_ifacedef(self, iname, inum):
383 return ''
384
385 def extfastifinstance(self, name, count):
386 return ''
387
388 def _extifinstance(self, name, count, suffix, prefix, samename=False,
389 ifsuffix=None):
390 if ifsuffix is None:
391 ifsuffix = ''
392 pname = self.get_iname(count)
393 if samename:
394 sname = pname
395 else:
396 sname = self.peripheral.iname().format(count)
397 template = "interface {0}{3} = {2}{1}{4};"
398 return template.format(pname, sname, prefix, suffix, ifsuffix)
399
400 def extifinstance2(self, name, count):
401 return ''
402
403 def extifinstance(self, name, count):
404 return self._extifinstance(name, count, "",
405 "pinmux.peripheral_side.")
406
407
408 mkplic_rule = """\
409 rule rl_connect_{0}_to_plic_{2};
410 if({1} == 1'b1) begin
411 ff_gateway_queue[{2}].enq(1);
412 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
413 end
414 endrule
415 """
416
417 axi_master_declarations = """\
418 typedef 0 Dmem_master_num;
419 typedef 1 Imem_master_num;
420 {0}
421 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
422 Debug_master_num;
423 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
424 DMA_master_num;
425 typedef TAdd#(DMA_master_num,1)
426 Num_Masters;
427 """
428
429 axi_fastslave_declarations = """\
430 {0}
431 typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
432 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
433 Sdram_cfg_slave_num;
434 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
435 BootRom_slave_num ;
436 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
437 Debug_slave_num ;
438 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
439 TCM_slave_num;
440 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
441 Dma_slave_num;
442 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
443 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
444 VME_slave_num;
445 typedef TAdd#(VME_slave_num,1) Num_Fast_Slaves;
446 """
447
448 axi_slave_declarations = """\
449 typedef 0 SlowMaster;
450 {0}
451 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
452 CLINT_slave_num;
453 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
454 Plic_slave_num;
455 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
456 AxiExp1_slave_num;
457 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
458 """
459
460 pinmux_cellrule = """\
461 rule connect_select_lines_pinmux;
462 {0}
463 endrule
464 """
465
466
467 class CallFn(object):
468 def __init__(self, peripheral, name):
469 self.peripheral = peripheral
470 self.name = name
471
472 def __call__(self, *args):
473 #print "__call__", self.name, self.peripheral.slow, args
474 if not self.peripheral.slow:
475 return ''
476 return getattr(self.peripheral.slow, self.name)(*args[1:])
477
478
479 class PeripheralIface(object):
480 def __init__(self, ifacename):
481 self.slow = None
482 slow = slowfactory.getcls(ifacename)
483 print "Iface", ifacename, slow
484 if slow:
485 self.slow = slow(ifacename)
486 self.slow.peripheral = self
487 for fname in ['slowimport',
488 'extfastifinstance',
489 'extifinstance2', 'extifinstance', 'extifdecl',
490 'slowifdecl', 'slowifdeclmux',
491 'fastifdecl',
492 'mkslow_peripheral',
493 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
494 'mkfast_peripheral',
495 'mk_plic', 'mk_ext_ifacedef',
496 '_mk_clk_con', 'mk_ext_ifacedef',
497 'mk_connection', 'mk_cellconn', '_mk_pincon']:
498 fn = CallFn(self, fname)
499 setattr(self, fname, types.MethodType(fn, self))
500
501 #print "PeripheralIface"
502 #print dir(self)
503
504 def mksuffix(self, name, i):
505 if self.slow is None:
506 return i
507 return self.slow.mksuffix(name, i)
508
509 def axi_reg_def(self, start, count):
510 if not self.slow:
511 return ('', 0)
512 return self.slow.axi_reg_def(start, self.ifacename, count)
513
514 def axi_master_idx(self, start, count, typ):
515 if not self.slow or not self.slow.has_axi_master():
516 return ('', 0)
517 return self.slow.axi_master_idx(start, self.ifacename, count, typ)
518
519 def axi_slave_idx(self, start, count, typ):
520 if not self.slow:
521 return ('', 0)
522 return self.slow.axi_slave_idx(start, self.ifacename, count, typ)
523
524 def axi_fastaddr_map(self, count):
525 if not self.slow:
526 return ''
527 return self.slow.axi_fastaddr_map(self.ifacename, count)
528
529 def axi_addr_map(self, count):
530 if not self.slow:
531 return ''
532 return self.slow.axi_addr_map(self.ifacename, count)
533
534
535 class PeripheralInterfaces(object):
536 def __init__(self):
537 self.fastbusmode = False
538
539 def slowimport(self, *args):
540 ret = []
541 for (name, count) in self.ifacecount:
542 #print "slowimport", name, self.data[name].slowimport
543 ret.append(self.data[name].slowimport())
544 return '\n'.join(li(list(filter(None, ret)), 4))
545
546 def extfastifinstance(self, *args):
547 ret = []
548 for (name, count) in self.ifacecount:
549 for i in range(count):
550 iname = self.data[name].iname().format(i)
551 print "extfast", iname, self.is_on_fastbus(name, i)
552 if self.is_on_fastbus(name, i):
553 continue
554 ret.append(self.data[name].extfastifinstance(name, i))
555 return '\n'.join(li(list(filter(None, ret)), 8))
556
557 def extifinstance2(self, *args):
558 ret = []
559 for (name, count) in self.ifacecount:
560 for i in range(count):
561 iname = self.data[name].iname().format(i)
562 ret.append(self.data[name].extifinstance2(name, i))
563 return '\n'.join(li(list(filter(None, ret)), 8))
564
565 def extifinstance(self, *args):
566 ret = []
567 for (name, count) in self.ifacecount:
568 for i in range(count):
569 iname = self.data[name].iname().format(i)
570 if not self.is_on_fastbus(name, i):
571 continue
572 ret.append(self.data[name].extifinstance(name, i))
573 return '\n'.join(li(list(filter(None, ret)), 8))
574
575 def extifdecl(self, *args):
576 ret = []
577 for (name, count) in self.ifacecount:
578 for i in range(count):
579 if not self.is_on_fastbus(name, i):
580 continue
581 ret.append(self.data[name].extifdecl(name, i))
582 return '\n'.join(li(list(filter(None, ret)), 8))
583
584 def slowifdeclmux(self, *args):
585 ret = []
586 for (name, count) in self.ifacecount:
587 for i in range(count):
588 ret.append(self.data[name].slowifdeclmux(name, i))
589 return '\n'.join(li(list(filter(None, ret)), 8))
590
591 def fastifdecl(self, *args):
592 ret = []
593 for (name, count) in self.ifacecount:
594 for i in range(count):
595 print "fastifdecl", name, i, self.is_on_fastbus(name, i)
596 if self.is_on_fastbus(name, i):
597 continue
598 ret.append(self.data[name].fastifdecl(name, i))
599 return '\n'.join(li(list(filter(None, ret)), 4))
600
601 def slowifdecl(self, *args):
602 ret = []
603 for (name, count) in self.ifacecount:
604 for i in range(count):
605 if self.is_on_fastbus(name, i):
606 continue
607 ret.append(self.data[name].slowifdecl().format(i, name))
608 return '\n'.join(list(filter(None, ret)))
609
610 def axi_fastmem_def(self, *args):
611 return self._axi_reg_def(0x50000000, *args)
612
613 def axi_reg_def(self, *args):
614 return self._axi_reg_def(0x00011100, *args)
615
616 def _axi_reg_def(self, start, *args):
617 ret = []
618 for (name, count) in self.ifacecount:
619 for i in range(count):
620 if self.is_on_fastbus(name, i):
621 continue
622 x = self.data[name].axi_reg_def(start, i)
623 #print ("ifc", name, x)
624 (rdef, offs) = x
625 ret.append(rdef)
626 start += offs
627 return '\n'.join(list(filter(None, ret)))
628
629 def _axi_num_idx(self, start, template, typ, idxtype, *args):
630 ret = []
631 for (name, count) in self.ifacecount:
632 for i in range(count):
633 if self.is_on_fastbus(name, i):
634 continue
635 if typ == 'master':
636 fn = self.data[name].axi_master_idx
637 else:
638 fn = self.data[name].axi_slave_idx
639 (rdef, offs) = fn(start, i, idxtype)
640 #print ("ifc", name, rdef, offs)
641 ret.append(rdef)
642 start += offs
643 ret.append("typedef %d LastGen_%s_num;" % (start - 1, typ))
644 decls = '\n'.join(list(filter(None, ret)))
645 return template.format(decls)
646
647 def axi_slave_idx(self, *args):
648 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
649 '', *args)
650
651 def axi_fastslave_idx(self, *args):
652 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
653 'fast', *args)
654
655 def axi_master_idx(self, *args):
656 return self._axi_num_idx(2, axi_master_declarations, 'master',
657 'master', *args)
658
659 def axi_fastslave_idx(self, *args):
660 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
661 'fast', *args)
662
663 def axi_fastaddr_map(self, *args):
664 ret = []
665 for (name, count) in self.ifacecount:
666 for i in range(count):
667 if self.is_on_fastbus(name, i):
668 continue
669 ret.append(self.data[name].axi_fastaddr_map(i))
670 return '\n'.join(li(list(filter(None, ret)), 8))
671
672 def axi_addr_map(self, *args):
673 ret = []
674 for (name, count) in self.ifacecount:
675 for i in range(count):
676 if self.is_on_fastbus(name, i):
677 continue
678 ret.append(self.data[name].axi_addr_map(i))
679 return '\n'.join(li(list(filter(None, ret)), 8))
680
681 def mkfast_peripheral(self, *args):
682 ret = []
683 for (name, count) in self.ifacecount:
684 for i in range(count):
685 if self.is_on_fastbus(name, i):
686 continue
687 #print "mkfast", name, count
688 x = self.data[name].mkfast_peripheral()
689 print name, count, x
690 suffix = self.data[name].mksuffix(name, i)
691 ret.append(x.format(suffix))
692 return '\n'.join(li(list(filter(None, ret)), 8))
693
694 def mkslow_peripheral(self, *args):
695 ret = []
696 for (name, count) in self.ifacecount:
697 for i in range(count):
698 if self.is_on_fastbus(name, i):
699 continue
700 #print "mkslow", name, count
701 x = self.data[name].mkslow_peripheral()
702 print name, count, x
703 suffix = self.data[name].mksuffix(name, i)
704 ret.append(x.format(suffix))
705 return '\n'.join(li(list(filter(None, ret)), 8))
706
707 def mk_fast_connection(self, *args):
708 ret = []
709 for (name, count) in self.ifacecount:
710 for i in range(count):
711 if self.is_on_fastbus(name, i):
712 continue
713 txt = self.data[name].mk_connection(i, "fabric", "fast")
714 if name == 'gpioa':
715 print "txt", txt
716 print self.data[name].mk_connection
717 ret.append(txt)
718 return '\n'.join(li(list(filter(None, ret)), 12))
719
720 def mk_connection(self, *args):
721 ret = []
722 for (name, count) in self.ifacecount:
723 for i in range(count):
724 if self.is_on_fastbus(name, i):
725 continue
726 txt = self.data[name].mk_connection(i, "slow_fabric", "")
727 if name == 'gpioa':
728 print "txt", txt
729 print self.data[name].mk_connection
730 ret.append(txt)
731 return '\n'.join(li(list(filter(None, ret)), 8))
732
733 def mk_cellconn(self):
734 ret = []
735 cellcount = 0
736 for (name, count) in self.ifacecount:
737 for i in range(count):
738 if self.is_on_fastbus(name, i):
739 continue
740 res = self.data[name].mk_cellconn(cellcount, name, i)
741 if not res:
742 continue
743 (txt, cellcount) = res
744 ret.append(txt)
745 ret = li('\n'.join(list(filter(None, ret))), 4)
746 return li(pinmux_cellrule.format(ret), 4)
747
748 def mk_pincon(self):
749 return self._mk_pincon("slow")
750
751 def mk_fast_pincon(self):
752 return self._mk_pincon("fast")
753
754 def _mk_pincon(self, typ):
755 ret = []
756 for (name, count) in self.ifacecount:
757 for i in range(count):
758 if self.is_on_fastbus(name, i):
759 continue
760 txt = self.data[name]._mk_pincon(name, i, typ)
761 ret.append(txt)
762 return '\n'.join(li(list(filter(None, ret)), 4))
763
764 def mk_dma_irq(self):
765 ret = []
766 sync = []
767 rules = []
768 cnct = []
769
770 self.dma_count = 0
771
772 for (name, count) in self.ifacecount:
773 ifacerules = []
774 for i in range(count):
775 if not self.is_on_fastbus(name, i):
776 continue
777 txt = self.data[name].mk_dma_sync(name, i)
778 if txt:
779 self.dma_count += 1
780 sync.append(txt)
781 txt = self.data[name].mk_dma_rule(name, i)
782 ifacerules.append(txt)
783 txt = self.data[name].mk_dma_connect(name, i)
784 cnct.append(txt)
785 ifacerules = list(filter(None, ifacerules))
786 if ifacerules:
787 txt = "rule synchronize_%s_interrupts;" % name
788 rules.append(txt)
789 rules += ifacerules
790 rules.append("endrule")
791
792 cnct = list(filter(None, cnct))
793 ct = self.dma_count
794 _cnct = ["rule rl_connect_interrupt_to_DMA;",
795 " Bit #(%d) lv_interrupt_to_DMA={" % ct]
796 spc = " "
797 spcsep = ",\n" + spc
798 cnct = _cnct + [spc + spcsep.join(cnct)]
799 cnct.append(" };")
800 cnct.append(" dma.interrupt_from_peripherals(\n" +
801 " lv_interrupt_to_DMA);")
802 cnct.append("endrule;")
803
804 ret = list(filter(None, sync + rules + cnct))
805 ret = li(ret, 15)
806 return '\n'.join(ret)
807
808 def num_dmachannels(self):
809 return "`define NUM_DMACHANNELS {0}".format(self.dma_count)
810
811 def mk_ext_ifacedef(self):
812 ret = []
813 for (name, count) in self.ifacecount:
814 for i in range(count):
815 if self.is_on_fastbus(name, i):
816 continue
817 txt = self.data[name].mk_ext_ifacedef(name, i)
818 ret.append(txt)
819 return '\n'.join(li(list(filter(None, ret)), 8))
820
821 def mk_plic(self):
822 ret = []
823 irq_offs = 8 # XXX: DMA scovers 0-7?
824 for (name, count) in self.ifacecount:
825 for i in range(count):
826 if self.is_on_fastbus(name, i):
827 continue
828 res = self.data[name].mk_plic(i, irq_offs)
829 if not res:
830 continue
831 (txt, irq_offs) = res
832 ret.append(txt)
833 self.num_slow_irqs = irq_offs
834 return '\n'.join(li(list(filter(None, ret)), 4))
835
836 def mk_sloirqsdef(self):
837 return " `define NUM_SLOW_IRQS {0}".format(self.num_slow_irqs)
838
839 def mk_fastclk_con(self):
840 return self._mk_clk_con("fast")
841
842 def mk_slowclk_con(self):
843 return self._mk_clk_con("slow")
844
845 def _mk_clk_con(self, ctype):
846 ret = []
847 for (name, count) in self.ifacecount:
848 for i in range(count):
849 if self.is_on_fastbus(name, i):
850 continue
851 txt = self.data[name]._mk_clk_con(name, i, ctype)
852 ret.append(txt)
853 return '\n'.join(li(list(filter(None, ret)), 8))
854
855 def is_on_fastbus(self, name, i):
856 #print "fastbus mode", self.fastbusmode, name, i
857 iname = self.data[name].iname().format(i)
858 if self.fastbusmode:
859 return iname not in self.fastbus
860 return iname in self.fastbus
861
862
863 class PFactory(object):
864 def getcls(self, name):
865 from uart import uart
866 from quart import quart
867 from sdmmc import sdmmc
868 from pwm import pwm
869 from eint import eint
870 from rs232 import rs232
871 from twi import twi
872 from eint import eint
873 from jtag import jtag
874 from spi import spi, mspi
875 from qspi import qspi, mqspi
876 from gpio import gpio
877 from rgbttl import rgbttl
878 from flexbus import flexbus
879
880 for k, v in {'uart': uart,
881 'rs232': rs232,
882 'twi': twi,
883 'quart': quart,
884 'mqspi': mqspi,
885 'mspi': mspi,
886 'qspi': qspi,
887 'spi': spi,
888 'pwm': pwm,
889 'eint': eint,
890 'sd': sdmmc,
891 'jtag': jtag,
892 'lcd': rgbttl,
893 'fb': flexbus,
894 'gpio': gpio
895 }.items():
896 if name.startswith(k):
897 return v
898 return None
899
900
901 slowfactory = PFactory()
902
903 if __name__ == '__main__':
904 p = uart('uart')
905 print p.slowimport()
906 print p.slowifdecl()
907 i = PeripheralIface('uart')
908 print i, i.slow
909 i = PeripheralIface('gpioa')
910 print i, i.slow