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