44602380823b47b9a21d0fa123a971b4e9048d0d
[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 iname = self.data[name].iname().format(i)
671 print "extfast", iname, self.is_on_fastbus(name, i)
672 if self.is_on_fastbus(name, i):
673 continue
674 ret.append(self.data[name].extfastifinstance(name, i))
675 return '\n'.join(li(list(filter(None, ret)), 8))
676
677 def extifinstance2(self, *args):
678 ret = []
679 for (name, count) in self.ifacecount:
680 for i in range(count):
681 iname = self.data[name].iname().format(i)
682 ret.append(self.data[name].extifinstance2(name, i))
683 return '\n'.join(li(list(filter(None, ret)), 8))
684
685 def extifinstance(self, *args):
686 ret = []
687 for (name, count) in self.ifacecount:
688 for i in range(count):
689 iname = self.data[name].iname().format(i)
690 if not self.is_on_fastbus(name, i):
691 continue
692 ret.append(self.data[name].extifinstance(name, i))
693 return '\n'.join(li(list(filter(None, ret)), 8))
694
695 def extifdecl(self, *args):
696 ret = []
697 for (name, count) in self.ifacecount:
698 for i in range(count):
699 if not self.is_on_fastbus(name, i):
700 continue
701 ret.append(self.data[name].extifdecl(name, i))
702 return '\n'.join(li(list(filter(None, ret)), 8))
703
704 def slowifdeclmux(self, *args):
705 ret = []
706 for (name, count) in self.ifacecount:
707 for i in range(count):
708 ret.append(self.data[name].slowifdeclmux(name, i))
709 return '\n'.join(li(list(filter(None, ret)), 8))
710
711 def fastifdecl(self, *args):
712 ret = []
713 for (name, count) in self.ifacecount:
714 for i in range(count):
715 print "fastifdecl", name, i, self.is_on_fastbus(name, i)
716 if self.is_on_fastbus(name, i):
717 continue
718 ret.append(self.data[name].fastifdecl(name, i))
719 return '\n'.join(li(list(filter(None, ret)), 4))
720
721 def slowifdecl(self, *args):
722 ret = []
723 for (name, count) in self.ifacecount:
724 for i in range(count):
725 if self.is_on_fastbus(name, i):
726 continue
727 ret.append(self.data[name].slowifdecl().format(i, name))
728 return '\n'.join(list(filter(None, ret)))
729
730 def axi_fastmem_def(self, *args):
731 return self._axi_reg_def(0x50000000, *args)
732
733 def axi_reg_def(self, *args):
734 return self._axi_reg_def(0x00011100, *args)
735
736 def _axi_reg_def(self, start, *args):
737 ret = []
738 for (name, count) in self.ifacecount:
739 for i in range(count):
740 if self.is_on_fastbus(name, i):
741 continue
742 x = self.data[name].axi_reg_def(start, i)
743 #print ("ifc", name, x)
744 (rdef, offs) = x
745 ret.append(rdef)
746 start += offs
747 return '\n'.join(list(filter(None, ret)))
748
749 def _axi_num_idx(self, start, template, typ, idxtype, *args):
750 ret = []
751 for (name, count) in self.ifacecount:
752 for i in range(count):
753 if self.is_on_fastbus(name, i):
754 continue
755 if typ == 'master':
756 fn = self.data[name].axi_master_idx
757 else:
758 fn = self.data[name].axi_slave_idx
759 (rdef, offs) = fn(start, i, idxtype)
760 #print ("ifc", name, rdef, offs)
761 ret.append(rdef)
762 start += offs
763 ret.append("typedef %d LastGen_%s_num;" % (start - 1, typ))
764 decls = '\n'.join(list(filter(None, ret)))
765 return template.format(decls)
766
767 def axi_slave_idx(self, *args):
768 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
769 '', *args)
770
771 def axi_fastslave_idx(self, *args):
772 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
773 'fast', *args)
774
775 def axi_master_idx(self, *args):
776 return self._axi_num_idx(2, axi_master_declarations, 'master',
777 'master', *args)
778
779 def axi_fastslave_idx(self, *args):
780 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
781 'fast', *args)
782
783 def axi_fastaddr_map(self, *args):
784 ret = []
785 for (name, count) in self.ifacecount:
786 for i in range(count):
787 if self.is_on_fastbus(name, i):
788 continue
789 ret.append(self.data[name].axi_fastaddr_map(i))
790 return '\n'.join(li(list(filter(None, ret)), 8))
791
792 def axi_addr_map(self, *args):
793 ret = []
794 for (name, count) in self.ifacecount:
795 for i in range(count):
796 if self.is_on_fastbus(name, i):
797 continue
798 ret.append(self.data[name].axi_addr_map(i))
799 return '\n'.join(li(list(filter(None, ret)), 8))
800
801 def mkfast_peripheral(self, *args):
802 ret = []
803 for (name, count) in self.ifacecount:
804 for i in range(count):
805 if self.is_on_fastbus(name, i):
806 continue
807 #print "mkfast", name, count
808 x = self.data[name].mkfast_peripheral()
809 print name, count, x
810 suffix = self.data[name].mksuffix(name, i)
811 ret.append(x.format(suffix))
812 return '\n'.join(li(list(filter(None, ret)), 8))
813
814 def mkslow_peripheral(self, *args):
815 ret = []
816 for (name, count) in self.ifacecount:
817 for i in range(count):
818 if self.is_on_fastbus(name, i):
819 continue
820 #print "mkslow", name, count
821 x = self.data[name].mkslow_peripheral()
822 print name, count, x
823 suffix = self.data[name].mksuffix(name, i)
824 ret.append(x.format(suffix))
825 return '\n'.join(li(list(filter(None, ret)), 8))
826
827 def _mk_connection(self, fabric, typ, indent, master, *args):
828 ret = []
829 for (name, count) in self.ifacecount:
830 for i in range(count):
831 if self.is_on_fastbus(name, i):
832 continue
833 if master:
834 txt = self.data[name].mk_master_connection(i, fabric, typ)
835 else:
836 txt = self.data[name].mk_connection(i, fabric, typ)
837 if name == 'gpioa':
838 print "txt", txt
839 ret.append(txt)
840 return '\n'.join(li(list(filter(None, ret)), indent))
841
842 def mk_master_connection(self, *args):
843 return self._mk_connection("fabric", "fast", 8, True, *args)
844
845 def mk_fast_connection(self, *args):
846 return self._mk_connection("fabric", "fast", 12, False, *args)
847
848 def mk_connection(self, *args):
849 return self._mk_connection("slow_fabric", "", 8, False, *args)
850
851 def mk_cellconn(self):
852 ret = []
853 cellcount = 0
854 for (name, count) in self.ifacecount:
855 for i in range(count):
856 if self.is_on_fastbus(name, i):
857 continue
858 res = self.data[name].mk_cellconn(cellcount, name, i)
859 if not res:
860 continue
861 (txt, cellcount) = res
862 ret.append(txt)
863 ret = li('\n'.join(list(filter(None, ret))), 4)
864 return li(pinmux_cellrule.format(ret), 4)
865
866 def mk_pincon(self):
867 return self._mk_pincon("slow")
868
869 def mk_fast_pincon(self):
870 return self._mk_pincon("fast")
871
872 def _mk_pincon(self, typ):
873 ret = []
874 for (name, count) in self.ifacecount:
875 for i in range(count):
876 if self.is_on_fastbus(name, i):
877 continue
878 txt = self.data[name]._mk_pincon(name, i, typ)
879 ret.append(txt)
880 return '\n'.join(li(list(filter(None, ret)), 4))
881
882 def mk_dma_irq(self):
883 ret = []
884 sync = []
885 rules = []
886 cnct = []
887
888 self.dma_count = 0
889
890 for (name, count) in self.ifacecount:
891 ifacerules = []
892 for i in range(count):
893 if not self.is_on_fastbus(name, i):
894 continue
895 txt = self.data[name].mk_dma_sync(name, i)
896 if txt:
897 self.dma_count += 1
898 sync.append(txt)
899 txt = self.data[name].mk_dma_rule(name, i)
900 ifacerules.append(txt)
901 txt = self.data[name].mk_dma_connect(name, i)
902 cnct.append(txt)
903 ifacerules = list(filter(None, ifacerules))
904 if ifacerules:
905 txt = "rule synchronize_%s_interrupts;" % name
906 rules.append(txt)
907 rules += ifacerules
908 rules.append("endrule")
909
910 cnct = list(filter(None, cnct))
911 ct = self.dma_count
912 _cnct = ["rule rl_connect_interrupt_to_DMA;",
913 " Bit #(%d) lv_interrupt_to_DMA={" % ct]
914 spc = " "
915 spcsep = ",\n" + spc
916 cnct = _cnct + [spc + spcsep.join(cnct)]
917 cnct.append(" };")
918 cnct.append(" dma.interrupt_from_peripherals(\n" +
919 " lv_interrupt_to_DMA);")
920 cnct.append("endrule;")
921
922 ret = list(filter(None, sync + rules + cnct))
923 ret = li(ret, 15)
924 return '\n'.join(ret)
925
926 def num_dmachannels(self):
927 return "`define NUM_DMACHANNELS {0}".format(self.dma_count)
928
929 def mk_ext_ifacedef(self):
930 ret = []
931 for (name, count) in self.ifacecount:
932 for i in range(count):
933 if self.is_on_fastbus(name, i):
934 continue
935 txt = self.data[name].mk_ext_ifacedef(name, i)
936 ret.append(txt)
937 return '\n'.join(li(list(filter(None, ret)), 8))
938
939 def mk_plic(self):
940 ret = []
941 irq_offs = 8 # XXX: DMA scovers 0-7?
942 for (name, count) in self.ifacecount:
943 for i in range(count):
944 if self.is_on_fastbus(name, i):
945 continue
946 res = self.data[name].mk_plic(i, irq_offs)
947 if not res:
948 continue
949 (txt, irq_offs) = res
950 ret.append(txt)
951 self.num_slow_irqs = irq_offs
952 return '\n'.join(li(list(filter(None, ret)), 4))
953
954 def mk_sloirqsdef(self):
955 return " `define NUM_SLOW_IRQS {0}".format(self.num_slow_irqs)
956
957 def mk_fastclk_con(self):
958 return self._mk_clk_con("fast")
959
960 def mk_slowclk_con(self):
961 return self._mk_clk_con("slow")
962
963 def _mk_clk_con(self, ctype):
964 ret = []
965 for (name, count) in self.ifacecount:
966 for i in range(count):
967 if self.is_on_fastbus(name, i):
968 continue
969 txt = self.data[name]._mk_clk_con(name, i, ctype)
970 ret.append(txt)
971 return '\n'.join(li(list(filter(None, ret)), 8))
972
973 def is_on_fastbus(self, name, i):
974 #print "fastbus mode", self.fastbusmode, name, i
975 iname = self.data[name].iname().format(i)
976 if self.fastbusmode:
977 return iname not in self.fastbus
978 return iname in self.fastbus
979
980
981 class PFactory(object):
982 def getcls(self, name):
983 from uart import uart
984 from quart import quart
985 from sdmmc import sdmmc
986 from emmc import emmc
987 from pwm import pwm
988 from eint import eint
989 from rs232 import rs232
990 from twi import twi
991 from eint import eint
992 from jtag import jtag
993 from spi import spi, mspi
994 from qspi import qspi, mqspi
995 from gpio import gpio
996 from rgbttl import rgbttl
997 from flexbus import flexbus
998 from sdram import sdram
999
1000 for k, v in {'uart': uart,
1001 'rs232': rs232,
1002 'twi': twi,
1003 'sdr': sdram,
1004 'quart': quart,
1005 'mqspi': mqspi,
1006 'mspi': mspi,
1007 'qspi': qspi,
1008 'spi': spi,
1009 'pwm': pwm,
1010 'eint': eint,
1011 'mmc': sdmmc,
1012 'emmc': emmc,
1013 'jtag': jtag,
1014 'lcd': rgbttl,
1015 'fb': flexbus,
1016 'gpio': gpio
1017 }.items():
1018 if name.startswith(k):
1019 return v
1020 return None
1021
1022
1023 slowfactory = PFactory()
1024
1025 if __name__ == '__main__':
1026 p = uart('uart')
1027 print p.slowimport()
1028 print p.slowifdecl()
1029 i = PeripheralIface('uart')
1030 print i, i.slow
1031 i = PeripheralIface('gpioa')
1032 print i, i.slow