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