7 if isinstance(txt
, str):
12 line
= line
.split('\n')
17 res
.append(indent
+ line
)
23 class MMapConfig(object):
25 def get_mmap_configs(self
):
27 for cfg
in self
.peripheral
.configs
:
28 res
.append(cfg
.get('mmap', None))
29 # XXX HACK! assume all configs same for each peripheral!
32 def map_to_idx(self
, cfg
, idx
):
33 if isinstance(idx
, int):
35 for (i
, c
) in enumerate(cfg
):
38 assert "config name %s not found" % s
40 def get_mmap_cfg_start(self
, idx
):
41 cfg
= self
.get_mmap_configs()
43 nregs
= self
.num_axi_regs32()
44 if isinstance(nregs
, int) or len(nregs
) == 1:
47 idx
= self
.map_to_idx(cfg
, idx
)
50 def get_mmap_cfg_name(self
, idx
):
51 cfg
= self
.get_mmap_configs()
53 nregs
= self
.num_axi_regs32()
54 if isinstance(nregs
, int) or len(nregs
) == 1:
59 def num_axi_regs32cfg(self
):
60 cfg
= self
.get_mmap_configs()
62 return self
.num_axi_regs32()
69 class PBase(MMapConfig
):
70 def __init__(self
, name
):
72 MMapConfig
.__init
__(self
)
74 def extifdecl(self
, name
, count
):
75 sname
= self
.get_iname(count
)
76 return "interface PeripheralSide%s %s;" % (name
.upper(), sname
)
78 def has_axi_master(self
):
84 def mk_dma_irq(self
, name
, count
):
85 if not self
.irq_name():
87 sname
= self
.get_iname(count
)
88 return "{0}_interrupt".format(sname
)
90 def mk_dma_rule(self
, name
, count
):
91 irqname
= self
.mk_dma_irq(name
, count
)
94 pirqname
= self
.irq_name().format(count
)
95 template
= " {0}.send(\n" + \
96 " slow_peripherals.{1});"
97 return template
.format(irqname
, pirqname
)
99 def get_clock_reset(self
, name
, count
):
100 return "slow_clock,slow_reset"
102 def mk_dma_sync(self
, name
, count
):
103 irqname
= self
.mk_dma_irq(name
, count
)
106 sname
= self
.peripheral
.iname().format(count
)
107 template
= "SyncBitIfc#(Bit#(1)) {0} <-\n" + \
108 " <-mkSyncBitToCC({1});"
109 return template
.format(irqname
, self
.get_clock_reset(name
, count
))
111 def mk_dma_connect(self
, name
, count
):
112 irqname
= self
.mk_dma_irq(name
, count
)
115 return "{0}.read".format(irqname
)
117 def fastifdecl(self
, name
, count
):
120 def slowifdeclmux(self
, name
, count
):
123 def slowimport(self
):
126 def num_axi_regs32(self
):
129 def slowifdecl(self
):
132 def get_iname(self
, inum
):
133 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
135 def axibase(self
, name
, ifacenum
, idx
):
137 return "%(name)s%(ifacenum)d%(idx)sBase" % locals()
139 def axiend(self
, name
, ifacenum
, idx
):
141 return "%(name)s%(ifacenum)d%(idx)sEnd" % locals()
143 def _axi_reg_def(self
, idx
, numregs
, start
, name
, ifacenum
):
145 offs
= numregs
* 4 * 16
148 cfgstart
= self
.get_mmap_cfg_start(idx
)
151 end
= start
+ offs
- 1
152 offs
= 0 # don't do contiguous addressing
154 end
= start
+ offs
- 1
155 bname
= self
.axibase(name
, ifacenum
, idx
)
156 bend
= self
.axiend(name
, ifacenum
, idx
)
157 comment
= "%d 32-bit regs" % numregs
158 return ("`define %(bname)s 'h%(start)08X\n"
159 "`define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
162 def axi_reg_def(self
, start
, name
, ifacenum
):
163 offs
= self
.num_axi_regs32cfg()
166 if not isinstance(offs
, list):
171 for (idx
, nregs
) in enumerate(offs
):
172 cfg
= self
.get_mmap_cfg_name(idx
)
173 (txt
, off
) = self
._axi
_reg
_def
(cfg
, nregs
, start
, name
, ifacenum
)
177 return ('\n'.join(res
), offstotal
)
179 def axi_master_name(self
, name
, ifacenum
, typ
=''):
181 return "{0}{1}_master_num".format(name
, ifacenum
)
183 def axi_slave_name(self
, idx
, name
, ifacenum
, typ
=''):
185 return "{0}{1}{3}_{2}slave_num".format(name
, ifacenum
, typ
, idx
)
187 def axi_master_idx(self
, idx
, name
, ifacenum
, typ
):
188 name
= self
.axi_master_name(name
, ifacenum
, typ
)
189 return ("typedef {0} {1};".format(idx
, name
), 1)
191 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
192 offs
= self
.num_axi_regs32()
195 if not isinstance(offs
, list):
198 for (i
, nregs
) in enumerate(offs
):
199 cfg
= self
.get_mmap_cfg_name(i
)
200 name_
= self
.axi_slave_name(cfg
, name
, ifacenum
, typ
)
201 res
.append("typedef {0} {1};".format(idx
+ i
, name_
))
202 return ('\n'.join(res
), len(offs
))
204 def axi_fastaddr_map(self
, name
, ifacenum
):
205 return self
.axi_addr_map(name
, ifacenum
, 'fast')
207 def _axi_addr_map(self
, idx
, name
, ifacenum
, typ
=""):
208 bname
= self
.axibase(name
, ifacenum
, idx
)
209 bend
= self
.axiend(name
, ifacenum
, idx
)
210 name
= self
.axi_slave_name(idx
, name
, ifacenum
, typ
)
212 if(addr>=`{0} && addr<=`{1})
213 return tuple2(True,fromInteger(valueOf({2})));
215 return template
.format(bname
, bend
, name
)
217 def axi_addr_map(self
, name
, ifacenum
, typ
=""):
218 offs
= self
.num_axi_regs32()
221 if not isinstance(offs
, list):
224 for (idx
, nregs
) in enumerate(offs
):
225 cfg
= self
.get_mmap_cfg_name(idx
)
226 res
.append(self
._axi
_addr
_map
(cfg
, name
, ifacenum
, typ
))
227 return '\n'.join(res
)
229 def _mk_pincon(self
, name
, count
, ptyp
):
230 # TODO: really should be using bsv.interface_decl.Interfaces
231 # pin-naming rules.... logic here is hard-coded to duplicate
232 # it (see Interface.__init__ outen)
234 for p
in self
.peripheral
.pinspecs
:
237 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
238 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
239 ret
.append("//%s %s" % (n
, str(p
)))
241 sname
= self
.get_iname(count
)
242 sname
= "{0}.{1}".format(sname
, pname
)
243 ps
= "slow_peripherals.%s" % sname
245 sname
= self
.peripheral
.iname().format(count
)
246 sname
= "{0}.{1}".format(sname
, pname
)
247 ps
= "pinmux.peripheral_side.%s" % sname
248 if typ
== 'out' or typ
== 'inout':
249 fname
= self
.pinname_out(pname
)
250 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
251 n_
= "{0}{1}".format(n
, count
)
259 cn
= self
._mk
_actual
_connection
('out', name
,
261 pname
, ps_
, n_
, fname
)
265 fname
= self
.pinname_outen(pname
)
267 if isinstance(fname
, str):
268 fname
= "{0}.{1}".format(n_
, fname
)
269 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
270 cn
= self
._mk
_actual
_connection
('outen', name
,
274 if typ
== 'in' or typ
== 'inout':
275 fname
= self
.pinname_in(pname
)
281 n_
= "{0}{1}".format(n
, count
)
282 n_
= '{0}.{1}'.format(n_
, fname
)
283 n_
= self
.ifname_tweak(pname
, 'in', n_
)
284 cn
= self
._mk
_actual
_connection
('in', name
,
286 pname
, ps_
, n_
, fname
)
288 return '\n'.join(ret
)
290 def _mk_vpincon(self
, name
, count
, ptyp
, typ
, pname
, stype
=None):
294 ret
.append("//%s %s %s %s %s" % (name
, ptyp
, typ
, pname
, stype
))
296 sname
= self
.get_iname(count
)
297 ps
= "slow_peripherals.%s" % sname
299 sname
= self
.peripheral
.iname().format(count
)
300 ps
= "pinmux.peripheral_side.%s" % sname
301 n
= self
.get_iname(count
)
303 n
= "{0}.{1}".format(n
, stype
)
304 ps_
= "{0}.{1}".format(ps
, pname
)
305 ret
+= self
._mk
_actual
_connection
(typ
, name
, count
, typ
,
306 pname
, ps_
, n
, stype
)
307 return '\n'.join(ret
)
309 def _mk_actual_connection(self
, ctype
, name
, count
, typ
,
310 pname
, ps
, n
, fname
):
312 ck
= self
.get_clock_reset(name
, count
)
314 if ck
== PBase
.get_clock_reset(self
, name
, count
):
315 ret
.append("mkConnection({0},\n\t\t\t{1}.{2});"
316 .format(ps
, n
, fname
))
318 n2
= "{0}{1}".format(name
, count
)
319 sync
= '{0}_{1}_sync'.format(n2
, pname
)
320 ret
.append("mkConnection({0},\n\t\t\t{1}.get);"
322 ret
.append("mkConnection({0}.put,\n\t\t\t{1}.{2});"
323 .format(sync
, n
, fname
))
324 elif ctype
== 'outen':
325 ret
.append("mkConnection({0}_outen,\n\t\t\t{1});"
328 if ck
== PBase
.get_clock_reset(self
, name
, count
):
329 ret
.append("mkConnection({1},\n\t\t\t{0});".format(
332 n2
= "{0}{1}".format(name
, count
)
333 sync
= '{0}_{1}_sync'.format(n2
, pname
)
334 ret
.append("mkConnection({1}.put,\n\t\t\t{0});".format(
336 ret
.append("mkConnection({1},\n\t\t\t{0}.get);".format(
340 def _mk_clk_con(self
, name
, count
, ctype
):
342 ck
= self
.get_clock_reset(name
, count
)
343 if ck
== PBase
.get_clock_reset(self
, name
, count
):
346 spc
= self
.get_clk_spc(ctype
)
349 ck
= self
.get_clk_spc(ctype
)
350 template
= "Ifc_sync#({0}) {1}_sync <-mksyncconnection(\n" + \
352 for p
in self
.peripheral
.pinspecs
:
356 if typ
== 'out' or typ
== 'inout':
357 fname
= self
.pinname_out(pname
)
360 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
361 n_
= "{0}{1}".format(n
, count
)
364 n_
= '{0}_{1}'.format(n_
, pname
)
365 ret
.append(template
.format("Bit#(1)", n_
, ck
, spc
))
366 if typ
== 'in' or typ
== 'inout':
367 fname
= self
.pinname_in(pname
)
370 #fname = self.pinname_in(pname)
371 n_
= "{0}{1}".format(n
, count
)
372 n_
= '{0}_{1}'.format(n_
, pname
)
373 #n_ = self.ifname_tweak(pname, 'in', n_)
374 ret
.append(template
.format("Bit#(1)", n_
, spc
, ck
))
375 return '\n'.join(ret
)
377 def get_clk_spc(self
, ctype
):
379 return "sp_clock, sp_reset"
381 return "core_clock, core_reset"
383 def _mk_clk_vcon(self
, name
, count
, ctype
, typ
, pname
, bitspec
):
384 ck
= self
.get_clock_reset(name
, count
)
385 if ck
== PBase
.get_clock_reset(self
, name
, count
):
388 spc
= self
.get_clk_spc(ctype
)
391 ck
= self
.get_clk_spc(ctype
)
392 template
= "Ifc_sync#({0}) {1}_sync <-mksyncconnection(\n" + \
395 n_ = "{0}{1}
".format(name, count)
396 n_ = '{0}_{1}'.format(n_, pname)
397 if typ == 'in' or typ == 'inout':
399 return template.format(bitspec, n_, ck, spc)
401 def mk_cellconn(self, *args):
404 def mkfast_peripheral(self, size=0):
407 def mkslow_peripheral(self, size=0):
410 def mksuffix(self, name, i):
413 def __mk_connection(self, con, aname, count, fabricname):
414 txt = "mkConnection ({2}
.v_to_slaves
\n" + \
415 " [fromInteger(valueOf({1}
))],\n" + \
418 print "PBase __mk_connection
", self.name, aname
421 con = con.format(count, aname)
422 return txt.format(con, aname, fabricname)
424 def __mk_master_connection(self, con, aname, count, fabricname):
425 txt = "mkConnection ({0}
, {2}
.v_from_masters
\n" + \
426 " [fromInteger(valueOf({1}
))]);\n"
428 print "PBase __mk_master_connection
", self.name, aname
431 con = con.format(count, aname)
432 return txt.format(con, aname, fabricname)
434 def mk_master_connection(self, name, count, fabricname, typ):
435 if not self.has_axi_master():
437 print "PBase mk_master_conn
", self.name, count
438 aname = self.axi_master_name(name, count, typ)
440 connections = self._mk_connection(name, count, True)
441 if not isinstance(connections, list):
442 connections = [connections]
443 for con in connections:
444 ret.append(self.__mk_master_connection(con, aname, count,
446 return '\n'.join(ret)
448 def mk_connection(self, name, count, fabricname, typ, name_override=None):
449 if name_override: # needed for GPIO
451 print "PBase mk_conn
", name, count
453 connections = self._mk_connection(name, count)
454 if not isinstance(connections, list):
455 connections = [connections]
456 for (idx, con) in enumerate(connections):
457 cfg = self.get_mmap_cfg_name(idx)
458 aname = self.axi_slave_name(cfg, name, count, typ)
459 ret.append(self.__mk_connection(con, aname, count, fabricname))
460 return '\n'.join(ret)
462 def _mk_connection(self, name=None, count=0):
465 def pinname_out(self, pname):
468 def pinname_in(self, pname):
471 def pinname_outen(self, pname):
474 def ifname_tweak(self, pname, typ, txt):
477 def pinname_tweak(self, pname, typ, txt):
483 def mk_plic(self, inum, irq_offs):
485 print "mk_plic
", self.name, inum, irq_offs
486 niq = self.num_irqs()
488 return ('', irq_offs)
489 name = self.get_iname(inum)
490 res.append("// PLIC rules
for {0}
".format(name))
491 for idx in range(niq):
492 plic_obj = self.plic_object(name, idx)
493 print "plic_obj
", name, idx, plic_obj
494 plic = mkplic_rule.format(name, plic_obj, irq_offs)
496 irq_offs += 1 # increment to next irq
497 return ('\n'.join(res), irq_offs)
499 def mk_ext_ifacedef(self, iname, inum):
502 def extfastifinstance(self, name, count):
505 def _extifinstance(self, name, count, suffix, prefix, samename=False,
509 pname = self.get_iname(count)
513 sname = self.peripheral.iname().format(count)
514 template = "interface {0}{3}
= {2}{1}{4}
;"
515 return template.format(pname, sname, prefix, suffix, ifsuffix)
517 def extifinstance2(self, name, count):
520 def extifinstance(self, name, count):
521 return self._extifinstance(name, count, "",
522 "pinmux
.peripheral_side
.")
526 rule rl_connect_{0}_to_plic_{2};
527 if({1} == 1'b1) begin
528 ff_gateway_queue[{2}].enq(1);
529 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
534 axi_master_declarations = """\
535 typedef 0 Dmem_master_num;
536 typedef 1 Imem_master_num;
538 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
540 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
542 typedef TAdd#(DMA_master_num,1)
546 axi_fastslave_declarations = """\
548 typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
549 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
551 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
553 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
555 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
557 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
559 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
560 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
562 typedef TAdd#(VME_slave_num,1) Num_Fast_Slaves;
565 axi_slave_declarations = """\
566 typedef 0 SlowMaster;
568 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
570 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
572 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
574 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
577 pinmux_cellrule = """\
578 rule connect_select_lines_pinmux;
584 class CallFn(object):
585 def __init__(self, peripheral, name):
586 self.peripheral = peripheral
589 def __call__(self, *args):
590 #print "__call__
", self.name, self.peripheral.slow, args
591 if not self.peripheral.slow:
593 return getattr(self.peripheral.slow, self.name)(*args[1:])
596 class PeripheralIface(object):
597 def __init__(self, ifacename):
599 slow = slowfactory.getcls(ifacename)
600 print "Iface
", ifacename, slow
602 self.slow = slow(ifacename)
603 self.slow.peripheral = self
604 for fname in ['slowimport',
606 'extifinstance2', 'extifinstance', 'extifdecl',
607 'slowifdecl', 'slowifdeclmux',
610 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
612 'mk_plic', 'mk_ext_ifacedef',
613 '_mk_clk_con', 'mk_ext_ifacedef',
614 'mk_connection', 'mk_master_connection',
615 'mk_cellconn', '_mk_pincon']:
616 fn = CallFn(self, fname)
617 setattr(self, fname, types.MethodType(fn, self))
619 #print "PeripheralIface
"
622 def mksuffix(self, name, i):
623 if self.slow is None:
625 return self.slow.mksuffix(name, i)
627 def axi_reg_def(self, start, count):
630 return self.slow.axi_reg_def(start, self.ifacename, count)
632 def axi_master_idx(self, start, count, typ):
633 if not self.slow or not self.slow.has_axi_master():
635 return self.slow.axi_master_idx(start, self.ifacename, count, typ)
637 def axi_slave_idx(self, start, count, typ):
640 return self.slow.axi_slave_idx(start, self.ifacename, count, typ)
642 def axi_fastaddr_map(self, count):
645 return self.slow.axi_fastaddr_map(self.ifacename, count)
647 def axi_addr_map(self, count):
650 return self.slow.axi_addr_map(self.ifacename, count)
653 class PeripheralInterfaces(object):
655 self.fastbusmode = False
657 def slowimport(self, *args):
659 for (name, count) in self.ifacecount:
660 #print "slowimport
", name, self.data[name].slowimport
661 ret.append(self.data[name].slowimport())
662 return '\n'.join(li(list(filter(None, ret)), 4))
664 def extfastifinstance(self, *args):
666 for (name, count) in self.ifacecount:
667 for i in range(count):
668 if self.is_on_fastbus(name, i):
670 ret.append(self.data[name].extfastifinstance(name, i))
671 return '\n'.join(li(list(filter(None, ret)), 8))
673 def extifinstance2(self, *args):
675 for (name, count) in self.ifacecount:
676 for i in range(count):
677 ret.append(self.data[name].extifinstance2(name, i))
678 return '\n'.join(li(list(filter(None, ret)), 8))
680 def extifinstance(self, *args):
682 for (name, count) in self.ifacecount:
683 for i in range(count):
684 if not self.is_on_fastbus(name, i):
686 ret.append(self.data[name].extifinstance(name, i))
687 return '\n'.join(li(list(filter(None, ret)), 8))
689 def extifdecl(self, *args):
691 for (name, count) in self.ifacecount:
692 for i in range(count):
693 if not self.is_on_fastbus(name, i):
695 ret.append(self.data[name].extifdecl(name, i))
696 return '\n'.join(li(list(filter(None, ret)), 8))
698 def slowifdeclmux(self, *args):
700 for (name, count) in self.ifacecount:
701 for i in range(count):
702 ret.append(self.data[name].slowifdeclmux(name, i))
703 return '\n'.join(li(list(filter(None, ret)), 8))
705 def fastifdecl(self, *args):
707 for (name, count) in self.ifacecount:
708 for i in range(count):
709 print "fastifdecl
", name, i, self.is_on_fastbus(name, i)
710 if self.is_on_fastbus(name, i):
712 ret.append(self.data[name].fastifdecl(name, i))
713 return '\n'.join(li(list(filter(None, ret)), 4))
715 def slowifdecl(self, *args):
717 for (name, count) in self.ifacecount:
718 for i in range(count):
719 if self.is_on_fastbus(name, i):
721 ret.append(self.data[name].slowifdecl().format(i, name))
722 return '\n'.join(list(filter(None, ret)))
724 def axi_fastmem_def(self, *args):
725 return self._axi_reg_def(0x50000000, *args)
727 def axi_reg_def(self, *args):
728 return self._axi_reg_def(0x00011100, *args)
730 def _axi_reg_def(self, start, *args):
732 for (name, count) in self.ifacecount:
733 for i in range(count):
734 if self.is_on_fastbus(name, i):
736 x = self.data[name].axi_reg_def(start, i)
737 #print ("ifc
", name, x)
741 return '\n'.join(list(filter(None, ret)))
743 def _axi_num_idx(self, start, template, typ, idxtype, *args):
745 for (name, count) in self.ifacecount:
746 for i in range(count):
747 if self.is_on_fastbus(name, i):
750 fn = self.data[name].axi_master_idx
752 fn = self.data[name].axi_slave_idx
753 (rdef, offs) = fn(start, i, idxtype)
754 #print ("ifc
", name, rdef, offs)
757 ret.append("typedef
%d LastGen_
%s_num
;" % (start - 1, typ))
758 decls = '\n'.join(list(filter(None, ret)))
759 return template.format(decls)
761 def axi_slave_idx(self, *args):
762 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
765 def axi_fastslave_idx(self, *args):
766 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
769 def axi_master_idx(self, *args):
770 return self._axi_num_idx(2, axi_master_declarations, 'master',
773 def axi_fastslave_idx(self, *args):
774 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
777 def axi_fastaddr_map(self, *args):
779 for (name, count) in self.ifacecount:
780 for i in range(count):
781 if self.is_on_fastbus(name, i):
783 ret.append(self.data[name].axi_fastaddr_map(i))
784 return '\n'.join(li(list(filter(None, ret)), 8))
786 def axi_addr_map(self, *args):
788 for (name, count) in self.ifacecount:
789 for i in range(count):
790 if self.is_on_fastbus(name, i):
792 ret.append(self.data[name].axi_addr_map(i))
793 return '\n'.join(li(list(filter(None, ret)), 8))
795 def mkfast_peripheral(self, *args):
797 for (name, count) in self.ifacecount:
798 for i in range(count):
799 if self.is_on_fastbus(name, i):
801 #print "mkfast
", name, count
802 x = self.data[name].mkfast_peripheral()
804 suffix = self.data[name].mksuffix(name, i)
805 ret.append(x.format(suffix))
806 return '\n'.join(li(list(filter(None, ret)), 8))
808 def mkslow_peripheral(self, *args):
810 for (name, count) in self.ifacecount:
811 for i in range(count):
812 if self.is_on_fastbus(name, i):
814 #print "mkslow
", name, count
815 x = self.data[name].mkslow_peripheral()
817 suffix = self.data[name].mksuffix(name, i)
818 ret.append(x.format(suffix))
819 return '\n'.join(li(list(filter(None, ret)), 8))
821 def _mk_connection(self, fabric, typ, indent, master, *args):
823 for (name, count) in self.ifacecount:
824 ret += list(MkConnection(self, name, count,
825 fabric, typ, master, *args))
826 return '\n'.join(li(list(filter(None, ret)), indent))
828 def mk_master_connection(self, *args):
829 return self._mk_connection("fabric
", "fast
", 8, True, *args)
831 def mk_fast_connection(self, *args):
832 return self._mk_connection("fabric
", "fast
", 12, False, *args)
834 def mk_connection(self, *args):
835 return self._mk_connection("slow_fabric
", "", 8, False, *args)
837 def mk_cellconn(self):
840 for (name, count) in self.ifacecount:
841 for i in range(count):
842 if self.is_on_fastbus(name, i):
844 res = self.data[name].mk_cellconn(name, i, cellcount)
847 (txt, cellcount) = res
849 ret = li('\n'.join(list(filter(None, ret))), 4)
850 return li(pinmux_cellrule.format(ret), 4)
853 return self._mk_pincon("slow
")
855 def mk_fast_pincon(self):
856 return self._mk_pincon("fast
")
858 def _mk_pincon(self, typ):
860 for (name, count) in self.ifacecount:
861 ret += list(MkPinCon(self, name, count, typ))
862 return '\n'.join(li(list(ret), 4))
864 def mk_dma_irq(self):
872 for (name, count) in self.ifacecount:
874 for i in range(count):
875 if not self.is_on_fastbus(name, i):
877 txt = self.data[name].mk_dma_sync(name, i)
881 txt = self.data[name].mk_dma_rule(name, i)
882 ifacerules.append(txt)
883 txt = self.data[name].mk_dma_connect(name, i)
885 ifacerules = list(filter(None, ifacerules))
887 txt = "rule synchronize_
%s_interrupts
;" % name
890 rules.append("endrule
")
892 cnct = list(filter(None, cnct))
894 _cnct = ["rule rl_connect_interrupt_to_DMA
;",
895 " Bit
#(%d) lv_interrupt_to_DMA={" % ct]
898 cnct
= _cnct
+ [spc
+ spcsep
.join(cnct
)]
900 cnct
.append(" dma.interrupt_from_peripherals(\n" +
901 " lv_interrupt_to_DMA);")
902 cnct
.append("endrule;")
904 ret
= list(filter(None, sync
+ rules
+ cnct
))
906 return '\n'.join(ret
)
908 def num_dmachannels(self
):
909 return "`define NUM_DMACHANNELS {0}".format(self
.dma_count
)
911 def mk_ext_ifacedef(self
):
913 for (name
, count
) in self
.ifacecount
:
914 ret
+= list(MkExtIface(self
, name
, count
))
915 return '\n'.join(li(list(filter(None, ret
)), 8))
919 irq_offs
= 8 # XXX: DMA scovers 0-7?
920 for (name
, count
) in self
.ifacecount
:
921 for i
in range(count
):
922 if self
.is_on_fastbus(name
, i
):
924 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
927 (txt
, irq_offs
) = res
929 self
.num_slow_irqs
= irq_offs
930 return '\n'.join(li(list(filter(None, ret
)), 4))
932 def mk_sloirqsdef(self
):
933 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
935 def mk_fastclk_con(self
):
936 return self
._mk
_clk
_con
("fast")
938 def mk_slowclk_con(self
):
939 return self
._mk
_clk
_con
("slow")
941 def _mk_clk_con(self
, ctype
):
943 for (name
, count
) in self
.ifacecount
:
944 ret
+= list(MkClkCon(self
, name
, count
, ctype
))
945 return '\n'.join(li(list(filter(None, ret
)), 8))
947 def is_on_fastbus(self
, name
, i
):
948 #print "fastbus mode", self.fastbusmode, name, i
949 iname
= self
.data
[name
].iname().format(i
)
951 return iname
not in self
.fastbus
952 return iname
in self
.fastbus
955 class IfaceIter(object):
957 def __init__(self
, name
, count
, *args
):
960 self
.maxcount
= count
968 if self
.i
>= self
.maxcount
:
970 if self
.check(self
.name
, self
.i
):
971 #print self.item, self.args
972 res
= self
.item(self
.name
, self
.i
, *self
.args
)
979 return self
.__next
__()
981 class MkConnection(IfaceIter
):
983 def __init__(self
, ifaces
, name
, count
, *args
):
985 IfaceIter
.__init
__(self
, name
, count
, *args
)
987 def check(self
, name
, i
):
988 return not self
.ifaces
.is_on_fastbus(name
, i
)
990 def item(self
, name
, i
, fabric
, typ
, master
):
992 return self
.ifaces
.data
[name
].mk_master_connection(name
,
994 return self
.ifaces
.data
[name
].mk_connection(name
, i
, fabric
, typ
)
996 class MkExtIface(IfaceIter
):
998 def __init__(self
, ifaces
, name
, count
, *args
):
1000 IfaceIter
.__init
__(self
, name
, count
, *args
)
1002 def check(self
, name
, i
):
1003 return not self
.ifaces
.is_on_fastbus(name
, i
)
1005 def item(self
, name
, i
):
1006 return self
.ifaces
.data
[name
].mk_ext_ifacedef(name
, i
)
1009 class MkPinCon(IfaceIter
):
1011 def __init__(self
, ifaces
, name
, count
, *args
):
1012 self
.ifaces
= ifaces
1013 IfaceIter
.__init
__(self
, name
, count
, *args
)
1015 def check(self
, name
, i
):
1016 return not self
.ifaces
.is_on_fastbus(name
, i
)
1018 def item(self
, name
, i
, typ
):
1019 return self
.ifaces
.data
[name
]._mk
_pincon
(name
, i
, typ
)
1022 class MkClkCon(IfaceIter
):
1024 def __init__(self
, ifaces
, name
, count
, *args
):
1025 self
.ifaces
= ifaces
1026 IfaceIter
.__init
__(self
, name
, count
, *args
)
1028 def check(self
, name
, i
):
1029 return not self
.ifaces
.is_on_fastbus(name
, i
)
1031 def item(self
, name
, i
, ctype
):
1032 return self
.ifaces
.data
[name
]._mk
_clk
_con
(name
, i
, ctype
)
1035 class PFactory(object):
1036 def getcls(self
, name
):
1037 from uart
import uart
1038 from quart
import quart
1039 from sdmmc
import sdmmc
1040 from emmc
import emmc
1042 from eint
import eint
1043 from rs232
import rs232
1045 from eint
import eint
1046 from jtag
import jtag
1047 from spi
import spi
, mspi
1048 from qspi
import qspi
, mqspi
1049 from gpio
import gpio
1050 from rgbttl
import rgbttl
1051 from flexbus
import flexbus
1052 from sdram
import sdram
1054 for k
, v
in {'uart': uart
,
1072 if name
.startswith(k
):
1077 slowfactory
= PFactory()
1079 if __name__
== '__main__':
1081 print p
.slowimport()
1082 print p
.slowifdecl()
1083 i
= PeripheralIface('uart')
1085 i
= PeripheralIface('gpioa')