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