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