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