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