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