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