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