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