horrible clock-sync hack
[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}_interrupt.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_actual_connection(self, ctype, name, count, typ,
200 pname, ps, n, fname):
201 ret = []
202 if ctype == 'out':
203 ret.append("mkConnection({0},\n\t\t\t{1}.{2});"
204 .format(ps, n, fname))
205 elif ctype == 'outen':
206 ret.append("mkConnection({0}_outen,\n\t\t\t{1});"
207 .format(ps, fname))
208 elif ctype == 'in':
209 ck = self.get_clock_reset(name, count)
210 if ck == PBase.get_clock_reset(self, name, count):
211 ret.append("mkConnection({1},\n\t\t\t{0});".format(
212 ps, n))
213 else:
214 n2 = "{0}{1}".format(name, count)
215 sync = '{0}_{1}_sync'.format(n2, pname)
216 ret.append("mkConnection({1}.put,\n\t\t\t{0});".format(
217 ps, sync))
218 ret.append("mkConnection({1},\n\t\t\t{0}.get);".format(
219 sync, n))
220 return ret
221
222 def mk_clk_con(self, name, count):
223 ret = []
224 ck = self.get_clock_reset(name, count)
225 if ck == PBase.get_clock_reset(self, name, count):
226 return ''
227 spc = "sp_clock, sp_reset"
228 template = """\
229 Ifc_sync#({0}) {1}_sync <-mksyncconnection(
230 {2}, {3});"""
231 for p in self.peripheral.pinspecs:
232 typ = p['type']
233 pname = p['name']
234 n = name
235 if typ == 'in' or typ == 'inout':
236 #fname = self.pinname_in(pname)
237 n_ = "{0}{1}".format(n, count)
238 n_ = '{0}_{1}'.format(n_, pname)
239 #n_ = self.ifname_tweak(pname, 'in', n_)
240 ret.append(template.format("Bit#(1)", n_, spc, ck))
241 return '\n'.join(ret)
242
243
244 def mk_cellconn(self, *args):
245 return ''
246
247 def mkfast_peripheral(self, size=0):
248 return ''
249
250 def mkslow_peripheral(self, size=0):
251 return ''
252
253 def mksuffix(self, name, i):
254 return i
255
256 def __mk_connection(self, con, aname, fabricname):
257 txt = "mkConnection ({2}.v_to_slaves\n" + \
258 " [fromInteger(valueOf({1}))],\n" + \
259 " {0});"
260
261 print "PBase __mk_connection", self.name, aname
262 if not con:
263 return ''
264 return txt.format(con, aname, fabricname)
265
266 def __mk_master_connection(self, con, aname):
267 txt = "mkConnection (slow_fabric.v_to_slaves\n" + \
268 " [fromInteger(valueOf({1}))],\n" + \
269 " {0});"
270
271 print "PBase __mk_connection", self.name, aname
272 if not con:
273 return ''
274 return txt.format(con, aname)
275
276 def mk_connection(self, count, fabricname, typ, name=None):
277 if name is None:
278 name = self.name
279 print "PBase mk_conn", self.name, count
280 aname = self.axi_slave_name(name, count, typ)
281 #dname = self.mksuffix(name, count)
282 #dname = "{0}{1}".format(name, dname)
283 con = self._mk_connection(name, count).format(count, aname)
284 return self.__mk_connection(con, aname, fabricname)
285
286 def _mk_connection(self, name=None, count=0):
287 return ''
288
289 def pinname_out(self, pname):
290 return ''
291
292 def pinname_in(self, pname):
293 return ''
294
295 def pinname_outen(self, pname):
296 return ''
297
298 def ifname_tweak(self, pname, typ, txt):
299 return txt
300
301 def pinname_tweak(self, pname, typ, txt):
302 return txt
303
304 def num_irqs(self):
305 return 0
306
307 def mk_plic(self, inum, irq_offs):
308 res = []
309 print "mk_plic", self.name, inum, irq_offs
310 niq = self.num_irqs()
311 if niq == 0:
312 return ('', irq_offs)
313 name = self.get_iname(inum)
314 res.append("// PLIC rules for {0}".format(name))
315 for idx in range(niq):
316 plic_obj = self.plic_object(name, idx)
317 print "plic_obj", name, idx, plic_obj
318 plic = mkplic_rule.format(name, plic_obj, irq_offs)
319 res.append(plic)
320 irq_offs += 1 # increment to next irq
321 return ('\n'.join(res), irq_offs)
322
323 def mk_ext_ifacedef(self, iname, inum):
324 return ''
325
326 def extfastifinstance(self, name, count):
327 return ''
328
329 def _extifinstance(self, name, count, suffix, prefix, samename=False,
330 ifsuffix=None):
331 if ifsuffix is None:
332 ifsuffix = ''
333 pname = self.get_iname(count)
334 if samename:
335 sname = pname
336 else:
337 sname = self.peripheral.iname().format(count)
338 template = "interface {0}{3} = {2}{1}{4};"
339 return template.format(pname, sname, prefix, suffix, ifsuffix)
340
341 def extifinstance2(self, name, count):
342 return ''
343
344 def extifinstance(self, name, count):
345 return self._extifinstance(name, count, "",
346 "pinmux.peripheral_side.")
347
348
349 mkplic_rule = """\
350 rule rl_connect_{0}_to_plic_{2};
351 if({1} == 1'b1) begin
352 ff_gateway_queue[{2}].enq(1);
353 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
354 end
355 endrule
356 """
357
358 axi_master_declarations = """\
359 typedef 0 Dmem_master_num;
360 typedef 1 Imem_master_num;
361 {0}
362 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
363 Debug_master_num;
364 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
365 DMA_master_num;
366 typedef TAdd#(DMA_master_num,1)
367 Num_Masters;
368 """
369
370 axi_fastslave_declarations = """\
371 {0}
372 typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
373 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
374 Sdram_cfg_slave_num;
375 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
376 BootRom_slave_num ;
377 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
378 Debug_slave_num ;
379 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
380 TCM_slave_num;
381 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
382 Dma_slave_num;
383 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
384 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
385 VME_slave_num;
386 typedef TAdd#(VME_slave_num,1) Num_Fast_Slaves;
387 """
388
389 axi_slave_declarations = """\
390 typedef 0 SlowMaster;
391 {0}
392 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
393 CLINT_slave_num;
394 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
395 Plic_slave_num;
396 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
397 AxiExp1_slave_num;
398 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
399 """
400
401 pinmux_cellrule = """\
402 rule connect_select_lines_pinmux;
403 {0}
404 endrule
405 """
406
407
408 class CallFn(object):
409 def __init__(self, peripheral, name):
410 self.peripheral = peripheral
411 self.name = name
412
413 def __call__(self, *args):
414 #print "__call__", self.name, self.peripheral.slow, args
415 if not self.peripheral.slow:
416 return ''
417 return getattr(self.peripheral.slow, self.name)(*args[1:])
418
419
420 class PeripheralIface(object):
421 def __init__(self, ifacename):
422 self.slow = None
423 slow = slowfactory.getcls(ifacename)
424 print "Iface", ifacename, slow
425 if slow:
426 self.slow = slow(ifacename)
427 self.slow.peripheral = self
428 for fname in ['slowimport',
429 'extfastifinstance',
430 'extifinstance2', 'extifinstance', 'extifdecl',
431 'slowifdecl', 'slowifdeclmux',
432 'fastifdecl',
433 'mkslow_peripheral',
434 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
435 'mkfast_peripheral',
436 'mk_plic', 'mk_ext_ifacedef',
437 'mk_clk_con', 'mk_ext_ifacedef',
438 'mk_connection', 'mk_cellconn', '_mk_pincon']:
439 fn = CallFn(self, fname)
440 setattr(self, fname, types.MethodType(fn, self))
441
442 #print "PeripheralIface"
443 #print dir(self)
444
445 def mksuffix(self, name, i):
446 if self.slow is None:
447 return i
448 return self.slow.mksuffix(name, i)
449
450 def axi_reg_def(self, start, count):
451 if not self.slow:
452 return ('', 0)
453 return self.slow.axi_reg_def(start, self.ifacename, count)
454
455 def axi_master_idx(self, start, count, typ):
456 if not self.slow or not self.slow.has_axi_master():
457 return ('', 0)
458 return self.slow.axi_master_idx(start, self.ifacename, count, typ)
459
460 def axi_slave_idx(self, start, count, typ):
461 if not self.slow:
462 return ('', 0)
463 return self.slow.axi_slave_idx(start, self.ifacename, count, typ)
464
465 def axi_fastaddr_map(self, count):
466 if not self.slow:
467 return ''
468 return self.slow.axi_fastaddr_map(self.ifacename, count)
469
470 def axi_addr_map(self, count):
471 if not self.slow:
472 return ''
473 return self.slow.axi_addr_map(self.ifacename, count)
474
475
476 class PeripheralInterfaces(object):
477 def __init__(self):
478 self.fastbusmode = False
479
480 def slowimport(self, *args):
481 ret = []
482 for (name, count) in self.ifacecount:
483 #print "slowimport", name, self.data[name].slowimport
484 ret.append(self.data[name].slowimport())
485 return '\n'.join(li(list(filter(None, ret)), 4))
486
487 def extfastifinstance(self, *args):
488 ret = []
489 for (name, count) in self.ifacecount:
490 for i in range(count):
491 iname = self.data[name].iname().format(i)
492 print "extfast", iname, self.is_on_fastbus(name, i)
493 if self.is_on_fastbus(name, i):
494 continue
495 ret.append(self.data[name].extfastifinstance(name, i))
496 return '\n'.join(li(list(filter(None, ret)), 8))
497
498 def extifinstance2(self, *args):
499 ret = []
500 for (name, count) in self.ifacecount:
501 for i in range(count):
502 iname = self.data[name].iname().format(i)
503 ret.append(self.data[name].extifinstance2(name, i))
504 return '\n'.join(li(list(filter(None, ret)), 8))
505
506 def extifinstance(self, *args):
507 ret = []
508 for (name, count) in self.ifacecount:
509 for i in range(count):
510 iname = self.data[name].iname().format(i)
511 if not self.is_on_fastbus(name, i):
512 continue
513 ret.append(self.data[name].extifinstance(name, i))
514 return '\n'.join(li(list(filter(None, ret)), 8))
515
516 def extifdecl(self, *args):
517 ret = []
518 for (name, count) in self.ifacecount:
519 for i in range(count):
520 if not self.is_on_fastbus(name, i):
521 continue
522 ret.append(self.data[name].extifdecl(name, i))
523 return '\n'.join(li(list(filter(None, ret)), 8))
524
525 def slowifdeclmux(self, *args):
526 ret = []
527 for (name, count) in self.ifacecount:
528 for i in range(count):
529 ret.append(self.data[name].slowifdeclmux(name, i))
530 return '\n'.join(li(list(filter(None, ret)), 8))
531
532 def fastifdecl(self, *args):
533 ret = []
534 for (name, count) in self.ifacecount:
535 for i in range(count):
536 print "fastifdecl", name, i, self.is_on_fastbus(name, i)
537 if self.is_on_fastbus(name, i):
538 continue
539 ret.append(self.data[name].fastifdecl(name, i))
540 return '\n'.join(li(list(filter(None, ret)), 4))
541
542 def slowifdecl(self, *args):
543 ret = []
544 for (name, count) in self.ifacecount:
545 for i in range(count):
546 if self.is_on_fastbus(name, i):
547 continue
548 ret.append(self.data[name].slowifdecl().format(i, name))
549 return '\n'.join(list(filter(None, ret)))
550
551 def axi_fastmem_def(self, *args):
552 return self._axi_reg_def(0x50000000, *args)
553
554 def axi_reg_def(self, *args):
555 return self._axi_reg_def(0x00011100, *args)
556
557 def _axi_reg_def(self, start, *args):
558 ret = []
559 for (name, count) in self.ifacecount:
560 for i in range(count):
561 if self.is_on_fastbus(name, i):
562 continue
563 x = self.data[name].axi_reg_def(start, i)
564 #print ("ifc", name, x)
565 (rdef, offs) = x
566 ret.append(rdef)
567 start += offs
568 return '\n'.join(list(filter(None, ret)))
569
570 def _axi_num_idx(self, start, template, typ, idxtype, *args):
571 ret = []
572 for (name, count) in self.ifacecount:
573 for i in range(count):
574 if self.is_on_fastbus(name, i):
575 continue
576 if typ == 'master':
577 fn = self.data[name].axi_master_idx
578 else:
579 fn = self.data[name].axi_slave_idx
580 (rdef, offs) = fn(start, i, idxtype)
581 #print ("ifc", name, rdef, offs)
582 ret.append(rdef)
583 start += offs
584 ret.append("typedef %d LastGen_%s_num;" % (start - 1, typ))
585 decls = '\n'.join(list(filter(None, ret)))
586 return template.format(decls)
587
588 def axi_slave_idx(self, *args):
589 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
590 '', *args)
591
592 def axi_fastslave_idx(self, *args):
593 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
594 'fast', *args)
595
596 def axi_master_idx(self, *args):
597 return self._axi_num_idx(2, axi_master_declarations, 'master',
598 'master', *args)
599
600 def axi_fastslave_idx(self, *args):
601 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
602 'fast', *args)
603
604 def axi_fastaddr_map(self, *args):
605 ret = []
606 for (name, count) in self.ifacecount:
607 for i in range(count):
608 if self.is_on_fastbus(name, i):
609 continue
610 ret.append(self.data[name].axi_fastaddr_map(i))
611 return '\n'.join(li(list(filter(None, ret)), 8))
612
613 def axi_addr_map(self, *args):
614 ret = []
615 for (name, count) in self.ifacecount:
616 for i in range(count):
617 if self.is_on_fastbus(name, i):
618 continue
619 ret.append(self.data[name].axi_addr_map(i))
620 return '\n'.join(li(list(filter(None, ret)), 8))
621
622 def mkfast_peripheral(self, *args):
623 ret = []
624 for (name, count) in self.ifacecount:
625 for i in range(count):
626 if self.is_on_fastbus(name, i):
627 continue
628 #print "mkfast", name, count
629 x = self.data[name].mkfast_peripheral()
630 print name, count, x
631 suffix = self.data[name].mksuffix(name, i)
632 ret.append(x.format(suffix))
633 return '\n'.join(li(list(filter(None, ret)), 8))
634
635 def mkslow_peripheral(self, *args):
636 ret = []
637 for (name, count) in self.ifacecount:
638 for i in range(count):
639 if self.is_on_fastbus(name, i):
640 continue
641 #print "mkslow", name, count
642 x = self.data[name].mkslow_peripheral()
643 print name, count, x
644 suffix = self.data[name].mksuffix(name, i)
645 ret.append(x.format(suffix))
646 return '\n'.join(li(list(filter(None, ret)), 8))
647
648 def mk_fast_connection(self, *args):
649 ret = []
650 for (name, count) in self.ifacecount:
651 for i in range(count):
652 if self.is_on_fastbus(name, i):
653 continue
654 txt = self.data[name].mk_connection(i, "fabric", "fast")
655 if name == 'gpioa':
656 print "txt", txt
657 print self.data[name].mk_connection
658 ret.append(txt)
659 return '\n'.join(li(list(filter(None, ret)), 12))
660
661 def mk_connection(self, *args):
662 ret = []
663 for (name, count) in self.ifacecount:
664 for i in range(count):
665 if self.is_on_fastbus(name, i):
666 continue
667 txt = self.data[name].mk_connection(i, "slow_fabric", "")
668 if name == 'gpioa':
669 print "txt", txt
670 print self.data[name].mk_connection
671 ret.append(txt)
672 return '\n'.join(li(list(filter(None, ret)), 8))
673
674 def mk_cellconn(self):
675 ret = []
676 cellcount = 0
677 for (name, count) in self.ifacecount:
678 for i in range(count):
679 if self.is_on_fastbus(name, i):
680 continue
681 res = self.data[name].mk_cellconn(cellcount, name, i)
682 if not res:
683 continue
684 (txt, cellcount) = res
685 ret.append(txt)
686 ret = li('\n'.join(list(filter(None, ret))), 4)
687 return li(pinmux_cellrule.format(ret), 4)
688
689 def mk_pincon(self):
690 return self._mk_pincon("slow")
691
692 def mk_fast_pincon(self):
693 return self._mk_pincon("fast")
694
695 def _mk_pincon(self, typ):
696 ret = []
697 for (name, count) in self.ifacecount:
698 for i in range(count):
699 if self.is_on_fastbus(name, i):
700 continue
701 txt = self.data[name]._mk_pincon(name, i, typ)
702 ret.append(txt)
703 return '\n'.join(li(list(filter(None, ret)), 4))
704
705 def mk_dma_irq(self):
706 ret = []
707 sync = []
708 rules = []
709 cnct = []
710
711 self.dma_count = 0
712
713 for (name, count) in self.ifacecount:
714 ifacerules = []
715 for i in range(count):
716 if not self.is_on_fastbus(name, i):
717 continue
718 txt = self.data[name].mk_dma_sync(name, i)
719 if txt:
720 self.dma_count += 1
721 sync.append(txt)
722 txt = self.data[name].mk_dma_rule(name, i)
723 ifacerules.append(txt)
724 txt = self.data[name].mk_dma_connect(name, i)
725 cnct.append(txt)
726 ifacerules = list(filter(None, ifacerules))
727 if ifacerules:
728 txt = "rule synchronize_%s_interrupts;" % name
729 rules.append(txt)
730 rules += ifacerules
731 rules.append("endrule")
732
733 cnct = list(filter(None, cnct))
734 ct = self.dma_count
735 _cnct = ["rule rl_connect_interrupt_to_DMA;",
736 " Bit #(%d) lv_interrupt_to_DMA={" % ct]
737 spc = " "
738 spcsep = ",\n" + spc
739 cnct = _cnct + [spc + spcsep.join(cnct)]
740 cnct.append(" };")
741 cnct.append(" dma.interrupt_from_peripherals(\n" +
742 " lv_interrupt_to_DMA);")
743 cnct.append("endrule;")
744
745 ret = list(filter(None, sync + rules + cnct))
746 ret = li(ret, 15)
747 return '\n'.join(ret)
748
749 def num_dmachannels(self):
750 return "`define NUM_DMACHANNELS {0}".format(self.dma_count)
751
752 def mk_ext_ifacedef(self):
753 ret = []
754 for (name, count) in self.ifacecount:
755 for i in range(count):
756 if self.is_on_fastbus(name, i):
757 continue
758 txt = self.data[name].mk_ext_ifacedef(name, i)
759 ret.append(txt)
760 return '\n'.join(li(list(filter(None, ret)), 8))
761
762 def mk_plic(self):
763 ret = []
764 irq_offs = 8 # XXX: DMA scovers 0-7?
765 for (name, count) in self.ifacecount:
766 for i in range(count):
767 if self.is_on_fastbus(name, i):
768 continue
769 res = self.data[name].mk_plic(i, irq_offs)
770 if not res:
771 continue
772 (txt, irq_offs) = res
773 ret.append(txt)
774 self.num_slow_irqs = irq_offs
775 return '\n'.join(li(list(filter(None, ret)), 4))
776
777 def mk_sloirqsdef(self):
778 return " `define NUM_SLOW_IRQS {0}".format(self.num_slow_irqs)
779
780 def mk_clk_con(self):
781 ret = []
782 for (name, count) in self.ifacecount:
783 for i in range(count):
784 if self.is_on_fastbus(name, i):
785 continue
786 txt = self.data[name].mk_clk_con(name, i)
787 ret.append(txt)
788 return '\n'.join(li(list(filter(None, ret)), 8))
789
790 def is_on_fastbus(self, name, i):
791 #print "fastbus mode", self.fastbusmode, name, i
792 iname = self.data[name].iname().format(i)
793 if self.fastbusmode:
794 return iname not in self.fastbus
795 return iname in self.fastbus
796
797
798 class PFactory(object):
799 def getcls(self, name):
800 from uart import uart
801 from quart import quart
802 from sdmmc import sdmmc
803 from pwm import pwm
804 from eint import eint
805 from rs232 import rs232
806 from twi import twi
807 from eint import eint
808 from jtag import jtag
809 from spi import spi, mspi
810 from qspi import qspi, mqspi
811 from gpio import gpio
812 from rgbttl import rgbttl
813 from flexbus import flexbus
814
815 for k, v in {'uart': uart,
816 'rs232': rs232,
817 'twi': twi,
818 'quart': quart,
819 'mqspi': mqspi,
820 'mspi': mspi,
821 'qspi': qspi,
822 'spi': spi,
823 'pwm': pwm,
824 'eint': eint,
825 'sd': sdmmc,
826 'jtag': jtag,
827 'lcd': rgbttl,
828 'fb': flexbus,
829 'gpio': gpio
830 }.items():
831 if name.startswith(k):
832 return v
833 return None
834
835
836 slowfactory = PFactory()
837
838 if __name__ == '__main__':
839 p = uart('uart')
840 print p.slowimport()
841 print p.slowifdecl()
842 i = PeripheralIface('uart')
843 print i, i.slow
844 i = PeripheralIface('gpioa')
845 print i, i.slow