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