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