074a7c66e6e31f4062282c9479cf5a3778fdc068
[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_ = i
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 aname = self.axi_slave_name(idx, name, count, typ)
420 ret.append(self.__mk_connection(con, aname, count, fabricname))
421 return '\n'.join(ret)
422
423 def _mk_connection(self, name=None, count=0):
424 return ''
425
426 def pinname_out(self, pname):
427 return ''
428
429 def pinname_in(self, pname):
430 return ''
431
432 def pinname_outen(self, pname):
433 return ''
434
435 def ifname_tweak(self, pname, typ, txt):
436 return txt
437
438 def pinname_tweak(self, pname, typ, txt):
439 return txt
440
441 def num_irqs(self):
442 return 0
443
444 def mk_plic(self, inum, irq_offs):
445 res = []
446 print "mk_plic", self.name, inum, irq_offs
447 niq = self.num_irqs()
448 if niq == 0:
449 return ('', irq_offs)
450 name = self.get_iname(inum)
451 res.append("// PLIC rules for {0}".format(name))
452 for idx in range(niq):
453 plic_obj = self.plic_object(name, idx)
454 print "plic_obj", name, idx, plic_obj
455 plic = mkplic_rule.format(name, plic_obj, irq_offs)
456 res.append(plic)
457 irq_offs += 1 # increment to next irq
458 return ('\n'.join(res), irq_offs)
459
460 def mk_ext_ifacedef(self, iname, inum):
461 return ''
462
463 def extfastifinstance(self, name, count):
464 return ''
465
466 def _extifinstance(self, name, count, suffix, prefix, samename=False,
467 ifsuffix=None):
468 if ifsuffix is None:
469 ifsuffix = ''
470 pname = self.get_iname(count)
471 if samename:
472 sname = pname
473 else:
474 sname = self.peripheral.iname().format(count)
475 template = "interface {0}{3} = {2}{1}{4};"
476 return template.format(pname, sname, prefix, suffix, ifsuffix)
477
478 def extifinstance2(self, name, count):
479 return ''
480
481 def extifinstance(self, name, count):
482 return self._extifinstance(name, count, "",
483 "pinmux.peripheral_side.")
484
485
486 mkplic_rule = """\
487 rule rl_connect_{0}_to_plic_{2};
488 if({1} == 1'b1) begin
489 ff_gateway_queue[{2}].enq(1);
490 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
491 end
492 endrule
493 """
494
495 axi_master_declarations = """\
496 typedef 0 Dmem_master_num;
497 typedef 1 Imem_master_num;
498 {0}
499 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
500 Debug_master_num;
501 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
502 DMA_master_num;
503 typedef TAdd#(DMA_master_num,1)
504 Num_Masters;
505 """
506
507 axi_fastslave_declarations = """\
508 {0}
509 typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
510 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
511 Sdram_cfg_slave_num;
512 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
513 BootRom_slave_num ;
514 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
515 Debug_slave_num ;
516 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
517 TCM_slave_num;
518 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
519 Dma_slave_num;
520 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
521 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
522 VME_slave_num;
523 typedef TAdd#(VME_slave_num,1) Num_Fast_Slaves;
524 """
525
526 axi_slave_declarations = """\
527 typedef 0 SlowMaster;
528 {0}
529 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
530 CLINT_slave_num;
531 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
532 Plic_slave_num;
533 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
534 AxiExp1_slave_num;
535 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
536 """
537
538 pinmux_cellrule = """\
539 rule connect_select_lines_pinmux;
540 {0}
541 endrule
542 """
543
544
545 class CallFn(object):
546 def __init__(self, peripheral, name):
547 self.peripheral = peripheral
548 self.name = name
549
550 def __call__(self, *args):
551 #print "__call__", self.name, self.peripheral.slow, args
552 if not self.peripheral.slow:
553 return ''
554 return getattr(self.peripheral.slow, self.name)(*args[1:])
555
556
557 class PeripheralIface(object):
558 def __init__(self, ifacename):
559 self.slow = None
560 slow = slowfactory.getcls(ifacename)
561 print "Iface", ifacename, slow
562 if slow:
563 self.slow = slow(ifacename)
564 self.slow.peripheral = self
565 for fname in ['slowimport',
566 'extfastifinstance',
567 'extifinstance2', 'extifinstance', 'extifdecl',
568 'slowifdecl', 'slowifdeclmux',
569 'fastifdecl',
570 'mkslow_peripheral',
571 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
572 'mkfast_peripheral',
573 'mk_plic', 'mk_ext_ifacedef',
574 '_mk_clk_con', 'mk_ext_ifacedef',
575 'mk_connection', 'mk_master_connection',
576 'mk_cellconn', '_mk_pincon']:
577 fn = CallFn(self, fname)
578 setattr(self, fname, types.MethodType(fn, self))
579
580 #print "PeripheralIface"
581 #print dir(self)
582
583 def mksuffix(self, name, i):
584 if self.slow is None:
585 return i
586 return self.slow.mksuffix(name, i)
587
588 def axi_reg_def(self, start, count):
589 if not self.slow:
590 return ('', 0)
591 return self.slow.axi_reg_def(start, self.ifacename, count)
592
593 def axi_master_idx(self, start, count, typ):
594 if not self.slow or not self.slow.has_axi_master():
595 return ('', 0)
596 return self.slow.axi_master_idx(start, self.ifacename, count, typ)
597
598 def axi_slave_idx(self, start, count, typ):
599 if not self.slow:
600 return ('', 0)
601 return self.slow.axi_slave_idx(start, self.ifacename, count, typ)
602
603 def axi_fastaddr_map(self, count):
604 if not self.slow:
605 return ''
606 return self.slow.axi_fastaddr_map(self.ifacename, count)
607
608 def axi_addr_map(self, count):
609 if not self.slow:
610 return ''
611 return self.slow.axi_addr_map(self.ifacename, count)
612
613
614 class PeripheralInterfaces(object):
615 def __init__(self):
616 self.fastbusmode = False
617
618 def slowimport(self, *args):
619 ret = []
620 for (name, count) in self.ifacecount:
621 #print "slowimport", name, self.data[name].slowimport
622 ret.append(self.data[name].slowimport())
623 return '\n'.join(li(list(filter(None, ret)), 4))
624
625 def extfastifinstance(self, *args):
626 ret = []
627 for (name, count) in self.ifacecount:
628 for i in range(count):
629 iname = self.data[name].iname().format(i)
630 print "extfast", iname, self.is_on_fastbus(name, i)
631 if self.is_on_fastbus(name, i):
632 continue
633 ret.append(self.data[name].extfastifinstance(name, i))
634 return '\n'.join(li(list(filter(None, ret)), 8))
635
636 def extifinstance2(self, *args):
637 ret = []
638 for (name, count) in self.ifacecount:
639 for i in range(count):
640 iname = self.data[name].iname().format(i)
641 ret.append(self.data[name].extifinstance2(name, i))
642 return '\n'.join(li(list(filter(None, ret)), 8))
643
644 def extifinstance(self, *args):
645 ret = []
646 for (name, count) in self.ifacecount:
647 for i in range(count):
648 iname = self.data[name].iname().format(i)
649 if not self.is_on_fastbus(name, i):
650 continue
651 ret.append(self.data[name].extifinstance(name, i))
652 return '\n'.join(li(list(filter(None, ret)), 8))
653
654 def extifdecl(self, *args):
655 ret = []
656 for (name, count) in self.ifacecount:
657 for i in range(count):
658 if not self.is_on_fastbus(name, i):
659 continue
660 ret.append(self.data[name].extifdecl(name, i))
661 return '\n'.join(li(list(filter(None, ret)), 8))
662
663 def slowifdeclmux(self, *args):
664 ret = []
665 for (name, count) in self.ifacecount:
666 for i in range(count):
667 ret.append(self.data[name].slowifdeclmux(name, i))
668 return '\n'.join(li(list(filter(None, ret)), 8))
669
670 def fastifdecl(self, *args):
671 ret = []
672 for (name, count) in self.ifacecount:
673 for i in range(count):
674 print "fastifdecl", name, i, self.is_on_fastbus(name, i)
675 if self.is_on_fastbus(name, i):
676 continue
677 ret.append(self.data[name].fastifdecl(name, i))
678 return '\n'.join(li(list(filter(None, ret)), 4))
679
680 def slowifdecl(self, *args):
681 ret = []
682 for (name, count) in self.ifacecount:
683 for i in range(count):
684 if self.is_on_fastbus(name, i):
685 continue
686 ret.append(self.data[name].slowifdecl().format(i, name))
687 return '\n'.join(list(filter(None, ret)))
688
689 def axi_fastmem_def(self, *args):
690 return self._axi_reg_def(0x50000000, *args)
691
692 def axi_reg_def(self, *args):
693 return self._axi_reg_def(0x00011100, *args)
694
695 def _axi_reg_def(self, start, *args):
696 ret = []
697 for (name, count) in self.ifacecount:
698 for i in range(count):
699 if self.is_on_fastbus(name, i):
700 continue
701 x = self.data[name].axi_reg_def(start, i)
702 #print ("ifc", name, x)
703 (rdef, offs) = x
704 ret.append(rdef)
705 start += offs
706 return '\n'.join(list(filter(None, ret)))
707
708 def _axi_num_idx(self, start, template, typ, idxtype, *args):
709 ret = []
710 for (name, count) in self.ifacecount:
711 for i in range(count):
712 if self.is_on_fastbus(name, i):
713 continue
714 if typ == 'master':
715 fn = self.data[name].axi_master_idx
716 else:
717 fn = self.data[name].axi_slave_idx
718 (rdef, offs) = fn(start, i, idxtype)
719 #print ("ifc", name, rdef, offs)
720 ret.append(rdef)
721 start += offs
722 ret.append("typedef %d LastGen_%s_num;" % (start - 1, typ))
723 decls = '\n'.join(list(filter(None, ret)))
724 return template.format(decls)
725
726 def axi_slave_idx(self, *args):
727 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
728 '', *args)
729
730 def axi_fastslave_idx(self, *args):
731 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
732 'fast', *args)
733
734 def axi_master_idx(self, *args):
735 return self._axi_num_idx(2, axi_master_declarations, 'master',
736 'master', *args)
737
738 def axi_fastslave_idx(self, *args):
739 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
740 'fast', *args)
741
742 def axi_fastaddr_map(self, *args):
743 ret = []
744 for (name, count) in self.ifacecount:
745 for i in range(count):
746 if self.is_on_fastbus(name, i):
747 continue
748 ret.append(self.data[name].axi_fastaddr_map(i))
749 return '\n'.join(li(list(filter(None, ret)), 8))
750
751 def axi_addr_map(self, *args):
752 ret = []
753 for (name, count) in self.ifacecount:
754 for i in range(count):
755 if self.is_on_fastbus(name, i):
756 continue
757 ret.append(self.data[name].axi_addr_map(i))
758 return '\n'.join(li(list(filter(None, ret)), 8))
759
760 def mkfast_peripheral(self, *args):
761 ret = []
762 for (name, count) in self.ifacecount:
763 for i in range(count):
764 if self.is_on_fastbus(name, i):
765 continue
766 #print "mkfast", name, count
767 x = self.data[name].mkfast_peripheral()
768 print name, count, x
769 suffix = self.data[name].mksuffix(name, i)
770 ret.append(x.format(suffix))
771 return '\n'.join(li(list(filter(None, ret)), 8))
772
773 def mkslow_peripheral(self, *args):
774 ret = []
775 for (name, count) in self.ifacecount:
776 for i in range(count):
777 if self.is_on_fastbus(name, i):
778 continue
779 #print "mkslow", name, count
780 x = self.data[name].mkslow_peripheral()
781 print name, count, x
782 suffix = self.data[name].mksuffix(name, i)
783 ret.append(x.format(suffix))
784 return '\n'.join(li(list(filter(None, ret)), 8))
785
786 def _mk_connection(self, fabric, typ, indent, master, *args):
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 if master:
793 txt = self.data[name].mk_master_connection(i, fabric, typ)
794 else:
795 txt = self.data[name].mk_connection(i, fabric, typ)
796 if name == 'gpioa':
797 print "txt", txt
798 ret.append(txt)
799 return '\n'.join(li(list(filter(None, ret)), indent))
800
801 def mk_master_connection(self, *args):
802 return self._mk_connection("fabric", "fast", 8, True, *args)
803
804 def mk_fast_connection(self, *args):
805 return self._mk_connection("fabric", "fast", 12, False, *args)
806
807 def mk_connection(self, *args):
808 return self._mk_connection("slow_fabric", "", 8, False, *args)
809
810 def mk_cellconn(self):
811 ret = []
812 cellcount = 0
813 for (name, count) in self.ifacecount:
814 for i in range(count):
815 if self.is_on_fastbus(name, i):
816 continue
817 res = self.data[name].mk_cellconn(cellcount, name, i)
818 if not res:
819 continue
820 (txt, cellcount) = res
821 ret.append(txt)
822 ret = li('\n'.join(list(filter(None, ret))), 4)
823 return li(pinmux_cellrule.format(ret), 4)
824
825 def mk_pincon(self):
826 return self._mk_pincon("slow")
827
828 def mk_fast_pincon(self):
829 return self._mk_pincon("fast")
830
831 def _mk_pincon(self, typ):
832 ret = []
833 for (name, count) in self.ifacecount:
834 for i in range(count):
835 if self.is_on_fastbus(name, i):
836 continue
837 txt = self.data[name]._mk_pincon(name, i, typ)
838 ret.append(txt)
839 return '\n'.join(li(list(filter(None, ret)), 4))
840
841 def mk_dma_irq(self):
842 ret = []
843 sync = []
844 rules = []
845 cnct = []
846
847 self.dma_count = 0
848
849 for (name, count) in self.ifacecount:
850 ifacerules = []
851 for i in range(count):
852 if not self.is_on_fastbus(name, i):
853 continue
854 txt = self.data[name].mk_dma_sync(name, i)
855 if txt:
856 self.dma_count += 1
857 sync.append(txt)
858 txt = self.data[name].mk_dma_rule(name, i)
859 ifacerules.append(txt)
860 txt = self.data[name].mk_dma_connect(name, i)
861 cnct.append(txt)
862 ifacerules = list(filter(None, ifacerules))
863 if ifacerules:
864 txt = "rule synchronize_%s_interrupts;" % name
865 rules.append(txt)
866 rules += ifacerules
867 rules.append("endrule")
868
869 cnct = list(filter(None, cnct))
870 ct = self.dma_count
871 _cnct = ["rule rl_connect_interrupt_to_DMA;",
872 " Bit #(%d) lv_interrupt_to_DMA={" % ct]
873 spc = " "
874 spcsep = ",\n" + spc
875 cnct = _cnct + [spc + spcsep.join(cnct)]
876 cnct.append(" };")
877 cnct.append(" dma.interrupt_from_peripherals(\n" +
878 " lv_interrupt_to_DMA);")
879 cnct.append("endrule;")
880
881 ret = list(filter(None, sync + rules + cnct))
882 ret = li(ret, 15)
883 return '\n'.join(ret)
884
885 def num_dmachannels(self):
886 return "`define NUM_DMACHANNELS {0}".format(self.dma_count)
887
888 def mk_ext_ifacedef(self):
889 ret = []
890 for (name, count) in self.ifacecount:
891 for i in range(count):
892 if self.is_on_fastbus(name, i):
893 continue
894 txt = self.data[name].mk_ext_ifacedef(name, i)
895 ret.append(txt)
896 return '\n'.join(li(list(filter(None, ret)), 8))
897
898 def mk_plic(self):
899 ret = []
900 irq_offs = 8 # XXX: DMA scovers 0-7?
901 for (name, count) in self.ifacecount:
902 for i in range(count):
903 if self.is_on_fastbus(name, i):
904 continue
905 res = self.data[name].mk_plic(i, irq_offs)
906 if not res:
907 continue
908 (txt, irq_offs) = res
909 ret.append(txt)
910 self.num_slow_irqs = irq_offs
911 return '\n'.join(li(list(filter(None, ret)), 4))
912
913 def mk_sloirqsdef(self):
914 return " `define NUM_SLOW_IRQS {0}".format(self.num_slow_irqs)
915
916 def mk_fastclk_con(self):
917 return self._mk_clk_con("fast")
918
919 def mk_slowclk_con(self):
920 return self._mk_clk_con("slow")
921
922 def _mk_clk_con(self, ctype):
923 ret = []
924 for (name, count) in self.ifacecount:
925 for i in range(count):
926 if self.is_on_fastbus(name, i):
927 continue
928 txt = self.data[name]._mk_clk_con(name, i, ctype)
929 ret.append(txt)
930 return '\n'.join(li(list(filter(None, ret)), 8))
931
932 def is_on_fastbus(self, name, i):
933 #print "fastbus mode", self.fastbusmode, name, i
934 iname = self.data[name].iname().format(i)
935 if self.fastbusmode:
936 return iname not in self.fastbus
937 return iname in self.fastbus
938
939
940 class PFactory(object):
941 def getcls(self, name):
942 from uart import uart
943 from quart import quart
944 from sdmmc import sdmmc
945 from pwm import pwm
946 from eint import eint
947 from rs232 import rs232
948 from twi import twi
949 from eint import eint
950 from jtag import jtag
951 from spi import spi, mspi
952 from qspi import qspi, mqspi
953 from gpio import gpio
954 from rgbttl import rgbttl
955 from flexbus import flexbus
956 from sdram import sdram
957
958 for k, v in {'uart': uart,
959 'rs232': rs232,
960 'twi': twi,
961 'sdr': sdram,
962 'quart': quart,
963 'mqspi': mqspi,
964 'mspi': mspi,
965 'qspi': qspi,
966 'spi': spi,
967 'pwm': pwm,
968 'eint': eint,
969 'mmc': sdmmc,
970 'jtag': jtag,
971 'lcd': rgbttl,
972 'fb': flexbus,
973 'gpio': gpio
974 }.items():
975 if name.startswith(k):
976 return v
977 return None
978
979
980 slowfactory = PFactory()
981
982 if __name__ == '__main__':
983 p = uart('uart')
984 print p.slowimport()
985 print p.slowifdecl()
986 i = PeripheralIface('uart')
987 print i, i.slow
988 i = PeripheralIface('gpioa')
989 print i, i.slow