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