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