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