remove redundant calls
[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, count, fabricname, typ, name=None):
435 if not self.has_axi_master():
436 return ''
437 if name is None:
438 name = self.name
439 print "PBase mk_master_conn", self.name, count
440 aname = self.axi_master_name(name, count, typ)
441 ret = []
442 connections = self._mk_connection(name, count, True)
443 if not isinstance(connections, list):
444 connections = [connections]
445 for con in connections:
446 ret.append(self.__mk_master_connection(con, aname, count,
447 fabricname))
448 return '\n'.join(ret)
449
450 def mk_connection(self, count, fabricname, typ, name=None):
451 if name is None:
452 name = self.name
453 print "PBase mk_conn", self.name, count
454 ret = []
455 connections = self._mk_connection(name, count)
456 if not isinstance(connections, list):
457 connections = [connections]
458 for (idx, con) in enumerate(connections):
459 cfg = self.get_mmap_cfg_name(idx)
460 aname = self.axi_slave_name(cfg, name, count, typ)
461 ret.append(self.__mk_connection(con, aname, count, fabricname))
462 return '\n'.join(ret)
463
464 def _mk_connection(self, name=None, count=0):
465 return ''
466
467 def pinname_out(self, pname):
468 return ''
469
470 def pinname_in(self, pname):
471 return ''
472
473 def pinname_outen(self, pname):
474 return ''
475
476 def ifname_tweak(self, pname, typ, txt):
477 return txt
478
479 def pinname_tweak(self, pname, typ, txt):
480 return txt
481
482 def num_irqs(self):
483 return 0
484
485 def mk_plic(self, inum, irq_offs):
486 res = []
487 print "mk_plic", self.name, inum, irq_offs
488 niq = self.num_irqs()
489 if niq == 0:
490 return ('', irq_offs)
491 name = self.get_iname(inum)
492 res.append("// PLIC rules for {0}".format(name))
493 for idx in range(niq):
494 plic_obj = self.plic_object(name, idx)
495 print "plic_obj", name, idx, plic_obj
496 plic = mkplic_rule.format(name, plic_obj, irq_offs)
497 res.append(plic)
498 irq_offs += 1 # increment to next irq
499 return ('\n'.join(res), irq_offs)
500
501 def mk_ext_ifacedef(self, iname, inum):
502 return ''
503
504 def extfastifinstance(self, name, count):
505 return ''
506
507 def _extifinstance(self, name, count, suffix, prefix, samename=False,
508 ifsuffix=None):
509 if ifsuffix is None:
510 ifsuffix = ''
511 pname = self.get_iname(count)
512 if samename:
513 sname = pname
514 else:
515 sname = self.peripheral.iname().format(count)
516 template = "interface {0}{3} = {2}{1}{4};"
517 return template.format(pname, sname, prefix, suffix, ifsuffix)
518
519 def extifinstance2(self, name, count):
520 return ''
521
522 def extifinstance(self, name, count):
523 return self._extifinstance(name, count, "",
524 "pinmux.peripheral_side.")
525
526
527 mkplic_rule = """\
528 rule rl_connect_{0}_to_plic_{2};
529 if({1} == 1'b1) begin
530 ff_gateway_queue[{2}].enq(1);
531 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
532 end
533 endrule
534 """
535
536 axi_master_declarations = """\
537 typedef 0 Dmem_master_num;
538 typedef 1 Imem_master_num;
539 {0}
540 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
541 Debug_master_num;
542 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
543 DMA_master_num;
544 typedef TAdd#(DMA_master_num,1)
545 Num_Masters;
546 """
547
548 axi_fastslave_declarations = """\
549 {0}
550 typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
551 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
552 Sdram_cfg_slave_num;
553 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
554 BootRom_slave_num ;
555 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
556 Debug_slave_num ;
557 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
558 TCM_slave_num;
559 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
560 Dma_slave_num;
561 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
562 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
563 VME_slave_num;
564 typedef TAdd#(VME_slave_num,1) Num_Fast_Slaves;
565 """
566
567 axi_slave_declarations = """\
568 typedef 0 SlowMaster;
569 {0}
570 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
571 CLINT_slave_num;
572 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
573 Plic_slave_num;
574 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
575 AxiExp1_slave_num;
576 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
577 """
578
579 pinmux_cellrule = """\
580 rule connect_select_lines_pinmux;
581 {0}
582 endrule
583 """
584
585
586 class CallFn(object):
587 def __init__(self, peripheral, name):
588 self.peripheral = peripheral
589 self.name = name
590
591 def __call__(self, *args):
592 #print "__call__", self.name, self.peripheral.slow, args
593 if not self.peripheral.slow:
594 return ''
595 return getattr(self.peripheral.slow, self.name)(*args[1:])
596
597
598 class PeripheralIface(object):
599 def __init__(self, ifacename):
600 self.slow = None
601 slow = slowfactory.getcls(ifacename)
602 print "Iface", ifacename, slow
603 if slow:
604 self.slow = slow(ifacename)
605 self.slow.peripheral = self
606 for fname in ['slowimport',
607 'extfastifinstance',
608 'extifinstance2', 'extifinstance', 'extifdecl',
609 'slowifdecl', 'slowifdeclmux',
610 'fastifdecl',
611 'mkslow_peripheral',
612 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
613 'mkfast_peripheral',
614 'mk_plic', 'mk_ext_ifacedef',
615 '_mk_clk_con', 'mk_ext_ifacedef',
616 'mk_connection', 'mk_master_connection',
617 'mk_cellconn', '_mk_pincon']:
618 fn = CallFn(self, fname)
619 setattr(self, fname, types.MethodType(fn, self))
620
621 #print "PeripheralIface"
622 #print dir(self)
623
624 def mksuffix(self, name, i):
625 if self.slow is None:
626 return i
627 return self.slow.mksuffix(name, i)
628
629 def axi_reg_def(self, start, count):
630 if not self.slow:
631 return ('', 0)
632 return self.slow.axi_reg_def(start, self.ifacename, count)
633
634 def axi_master_idx(self, start, count, typ):
635 if not self.slow or not self.slow.has_axi_master():
636 return ('', 0)
637 return self.slow.axi_master_idx(start, self.ifacename, count, typ)
638
639 def axi_slave_idx(self, start, count, typ):
640 if not self.slow:
641 return ('', 0)
642 return self.slow.axi_slave_idx(start, self.ifacename, count, typ)
643
644 def axi_fastaddr_map(self, count):
645 if not self.slow:
646 return ''
647 return self.slow.axi_fastaddr_map(self.ifacename, count)
648
649 def axi_addr_map(self, count):
650 if not self.slow:
651 return ''
652 return self.slow.axi_addr_map(self.ifacename, count)
653
654
655 class PeripheralInterfaces(object):
656 def __init__(self):
657 self.fastbusmode = False
658
659 def slowimport(self, *args):
660 ret = []
661 for (name, count) in self.ifacecount:
662 #print "slowimport", name, self.data[name].slowimport
663 ret.append(self.data[name].slowimport())
664 return '\n'.join(li(list(filter(None, ret)), 4))
665
666 def extfastifinstance(self, *args):
667 ret = []
668 for (name, count) in self.ifacecount:
669 for i in range(count):
670 if self.is_on_fastbus(name, i):
671 continue
672 ret.append(self.data[name].extfastifinstance(name, i))
673 return '\n'.join(li(list(filter(None, ret)), 8))
674
675 def extifinstance2(self, *args):
676 ret = []
677 for (name, count) in self.ifacecount:
678 for i in range(count):
679 ret.append(self.data[name].extifinstance2(name, i))
680 return '\n'.join(li(list(filter(None, ret)), 8))
681
682 def extifinstance(self, *args):
683 ret = []
684 for (name, count) in self.ifacecount:
685 for i in range(count):
686 if not self.is_on_fastbus(name, i):
687 continue
688 ret.append(self.data[name].extifinstance(name, i))
689 return '\n'.join(li(list(filter(None, ret)), 8))
690
691 def extifdecl(self, *args):
692 ret = []
693 for (name, count) in self.ifacecount:
694 for i in range(count):
695 if not self.is_on_fastbus(name, i):
696 continue
697 ret.append(self.data[name].extifdecl(name, i))
698 return '\n'.join(li(list(filter(None, ret)), 8))
699
700 def slowifdeclmux(self, *args):
701 ret = []
702 for (name, count) in self.ifacecount:
703 for i in range(count):
704 ret.append(self.data[name].slowifdeclmux(name, i))
705 return '\n'.join(li(list(filter(None, ret)), 8))
706
707 def fastifdecl(self, *args):
708 ret = []
709 for (name, count) in self.ifacecount:
710 for i in range(count):
711 print "fastifdecl", name, i, self.is_on_fastbus(name, i)
712 if self.is_on_fastbus(name, i):
713 continue
714 ret.append(self.data[name].fastifdecl(name, i))
715 return '\n'.join(li(list(filter(None, ret)), 4))
716
717 def slowifdecl(self, *args):
718 ret = []
719 for (name, count) in self.ifacecount:
720 for i in range(count):
721 if self.is_on_fastbus(name, i):
722 continue
723 ret.append(self.data[name].slowifdecl().format(i, name))
724 return '\n'.join(list(filter(None, ret)))
725
726 def axi_fastmem_def(self, *args):
727 return self._axi_reg_def(0x50000000, *args)
728
729 def axi_reg_def(self, *args):
730 return self._axi_reg_def(0x00011100, *args)
731
732 def _axi_reg_def(self, start, *args):
733 ret = []
734 for (name, count) in self.ifacecount:
735 for i in range(count):
736 if self.is_on_fastbus(name, i):
737 continue
738 x = self.data[name].axi_reg_def(start, i)
739 #print ("ifc", name, x)
740 (rdef, offs) = x
741 ret.append(rdef)
742 start += offs
743 return '\n'.join(list(filter(None, ret)))
744
745 def _axi_num_idx(self, start, template, typ, idxtype, *args):
746 ret = []
747 for (name, count) in self.ifacecount:
748 for i in range(count):
749 if self.is_on_fastbus(name, i):
750 continue
751 if typ == 'master':
752 fn = self.data[name].axi_master_idx
753 else:
754 fn = self.data[name].axi_slave_idx
755 (rdef, offs) = fn(start, i, idxtype)
756 #print ("ifc", name, rdef, offs)
757 ret.append(rdef)
758 start += offs
759 ret.append("typedef %d LastGen_%s_num;" % (start - 1, typ))
760 decls = '\n'.join(list(filter(None, ret)))
761 return template.format(decls)
762
763 def axi_slave_idx(self, *args):
764 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
765 '', *args)
766
767 def axi_fastslave_idx(self, *args):
768 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
769 'fast', *args)
770
771 def axi_master_idx(self, *args):
772 return self._axi_num_idx(2, axi_master_declarations, 'master',
773 'master', *args)
774
775 def axi_fastslave_idx(self, *args):
776 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
777 'fast', *args)
778
779 def axi_fastaddr_map(self, *args):
780 ret = []
781 for (name, count) in self.ifacecount:
782 for i in range(count):
783 if self.is_on_fastbus(name, i):
784 continue
785 ret.append(self.data[name].axi_fastaddr_map(i))
786 return '\n'.join(li(list(filter(None, ret)), 8))
787
788 def axi_addr_map(self, *args):
789 ret = []
790 for (name, count) in self.ifacecount:
791 for i in range(count):
792 if self.is_on_fastbus(name, i):
793 continue
794 ret.append(self.data[name].axi_addr_map(i))
795 return '\n'.join(li(list(filter(None, ret)), 8))
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_connection(self, fabric, typ, indent, master, *args):
824 ret = []
825 for (name, count) in self.ifacecount:
826 for i in range(count):
827 if self.is_on_fastbus(name, i):
828 continue
829 if master:
830 txt = self.data[name].mk_master_connection(i, fabric, typ)
831 else:
832 txt = self.data[name].mk_connection(i, fabric, typ)
833 if name == 'gpioa':
834 print "txt", txt
835 ret.append(txt)
836 return '\n'.join(li(list(filter(None, ret)), indent))
837
838 def mk_master_connection(self, *args):
839 return self._mk_connection("fabric", "fast", 8, True, *args)
840
841 def mk_fast_connection(self, *args):
842 return self._mk_connection("fabric", "fast", 12, False, *args)
843
844 def mk_connection(self, *args):
845 return self._mk_connection("slow_fabric", "", 8, False, *args)
846
847 def mk_cellconn(self):
848 ret = []
849 cellcount = 0
850 for (name, count) in self.ifacecount:
851 for i in range(count):
852 if self.is_on_fastbus(name, i):
853 continue
854 res = self.data[name].mk_cellconn(cellcount, name, i)
855 if not res:
856 continue
857 (txt, cellcount) = res
858 ret.append(txt)
859 ret = li('\n'.join(list(filter(None, ret))), 4)
860 return li(pinmux_cellrule.format(ret), 4)
861
862 def mk_pincon(self):
863 return self._mk_pincon("slow")
864
865 def mk_fast_pincon(self):
866 return self._mk_pincon("fast")
867
868 def _mk_pincon(self, typ):
869 ret = []
870 for (name, count) in self.ifacecount:
871 for i in range(count):
872 if self.is_on_fastbus(name, i):
873 continue
874 txt = self.data[name]._mk_pincon(name, i, typ)
875 ret.append(txt)
876 return '\n'.join(li(list(filter(None, ret)), 4))
877
878 def mk_dma_irq(self):
879 ret = []
880 sync = []
881 rules = []
882 cnct = []
883
884 self.dma_count = 0
885
886 for (name, count) in self.ifacecount:
887 ifacerules = []
888 for i in range(count):
889 if not self.is_on_fastbus(name, i):
890 continue
891 txt = self.data[name].mk_dma_sync(name, i)
892 if txt:
893 self.dma_count += 1
894 sync.append(txt)
895 txt = self.data[name].mk_dma_rule(name, i)
896 ifacerules.append(txt)
897 txt = self.data[name].mk_dma_connect(name, i)
898 cnct.append(txt)
899 ifacerules = list(filter(None, ifacerules))
900 if ifacerules:
901 txt = "rule synchronize_%s_interrupts;" % name
902 rules.append(txt)
903 rules += ifacerules
904 rules.append("endrule")
905
906 cnct = list(filter(None, cnct))
907 ct = self.dma_count
908 _cnct = ["rule rl_connect_interrupt_to_DMA;",
909 " Bit #(%d) lv_interrupt_to_DMA={" % ct]
910 spc = " "
911 spcsep = ",\n" + spc
912 cnct = _cnct + [spc + spcsep.join(cnct)]
913 cnct.append(" };")
914 cnct.append(" dma.interrupt_from_peripherals(\n" +
915 " lv_interrupt_to_DMA);")
916 cnct.append("endrule;")
917
918 ret = list(filter(None, sync + rules + cnct))
919 ret = li(ret, 15)
920 return '\n'.join(ret)
921
922 def num_dmachannels(self):
923 return "`define NUM_DMACHANNELS {0}".format(self.dma_count)
924
925 def mk_ext_ifacedef(self):
926 ret = []
927 for (name, count) in self.ifacecount:
928 for i in range(count):
929 if self.is_on_fastbus(name, i):
930 continue
931 txt = self.data[name].mk_ext_ifacedef(name, i)
932 ret.append(txt)
933 return '\n'.join(li(list(filter(None, ret)), 8))
934
935 def mk_plic(self):
936 ret = []
937 irq_offs = 8 # XXX: DMA scovers 0-7?
938 for (name, count) in self.ifacecount:
939 for i in range(count):
940 if self.is_on_fastbus(name, i):
941 continue
942 res = self.data[name].mk_plic(i, irq_offs)
943 if not res:
944 continue
945 (txt, irq_offs) = res
946 ret.append(txt)
947 self.num_slow_irqs = irq_offs
948 return '\n'.join(li(list(filter(None, ret)), 4))
949
950 def mk_sloirqsdef(self):
951 return " `define NUM_SLOW_IRQS {0}".format(self.num_slow_irqs)
952
953 def mk_fastclk_con(self):
954 return self._mk_clk_con("fast")
955
956 def mk_slowclk_con(self):
957 return self._mk_clk_con("slow")
958
959 def _mk_clk_con(self, ctype):
960 ret = []
961 for (name, count) in self.ifacecount:
962 for i in range(count):
963 if self.is_on_fastbus(name, i):
964 continue
965 txt = self.data[name]._mk_clk_con(name, i, ctype)
966 ret.append(txt)
967 return '\n'.join(li(list(filter(None, ret)), 8))
968
969 def is_on_fastbus(self, name, i):
970 #print "fastbus mode", self.fastbusmode, name, i
971 iname = self.data[name].iname().format(i)
972 if self.fastbusmode:
973 return iname not in self.fastbus
974 return iname in self.fastbus
975
976
977 class PFactory(object):
978 def getcls(self, name):
979 from uart import uart
980 from quart import quart
981 from sdmmc import sdmmc
982 from emmc import emmc
983 from pwm import pwm
984 from eint import eint
985 from rs232 import rs232
986 from twi import twi
987 from eint import eint
988 from jtag import jtag
989 from spi import spi, mspi
990 from qspi import qspi, mqspi
991 from gpio import gpio
992 from rgbttl import rgbttl
993 from flexbus import flexbus
994 from sdram import sdram
995
996 for k, v in {'uart': uart,
997 'rs232': rs232,
998 'twi': twi,
999 'sdr': sdram,
1000 'quart': quart,
1001 'mqspi': mqspi,
1002 'mspi': mspi,
1003 'qspi': qspi,
1004 'spi': spi,
1005 'pwm': pwm,
1006 'eint': eint,
1007 'mmc': sdmmc,
1008 'emmc': emmc,
1009 'jtag': jtag,
1010 'lcd': rgbttl,
1011 'fb': flexbus,
1012 'gpio': gpio
1013 }.items():
1014 if name.startswith(k):
1015 return v
1016 return None
1017
1018
1019 slowfactory = PFactory()
1020
1021 if __name__ == '__main__':
1022 p = uart('uart')
1023 print p.slowimport()
1024 print p.slowifdecl()
1025 i = PeripheralIface('uart')
1026 print i, i.slow
1027 i = PeripheralIface('gpioa')
1028 print i, i.slow