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