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