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