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 CallIfaceFn(object):
654 def __init__(self, ifaces, kls, indent):
659 def __call__(self, ifaces, *args):
661 for (name, count) in self.ifaces.ifacecount:
662 print "CallIfaceFn
", self.kls, self.ifaces
663 print "CallIfaceFn args
", name, count, args
664 ret += list(self.kls(self.ifaces, name, count, *args))
665 return '\n'.join(li(list(filter(None, ret)), self.indent))
668 class PeripheralInterfaces(object):
670 self.fastbusmode = False
672 for (fname, kls, indent) in (
673 ('_mk_connection', MkConnection, 8),
674 ('_mk_pincon', MkPinCon, 4),
675 ('_mk_clk_con', MkClkCon, 8),
676 ('mk_ext_ifacedef', MkExtIface, 8),
678 fn = CallIfaceFn(self, kls, indent)
679 setattr(self, fname, types.MethodType(fn, self))
681 def slowimport(self, *args):
683 for (name, count) in self.ifacecount:
684 #print "slowimport
", name, self.data[name].slowimport
685 ret.append(self.data[name].slowimport())
686 return '\n'.join(li(list(filter(None, ret)), 4))
688 def extfastifinstance(self, *args):
690 for (name, count) in self.ifacecount:
691 for i in range(count):
692 if self.is_on_fastbus(name, i):
694 ret.append(self.data[name].extfastifinstance(name, i))
695 return '\n'.join(li(list(filter(None, ret)), 8))
697 def extifinstance2(self, *args):
699 for (name, count) in self.ifacecount:
700 for i in range(count):
701 ret.append(self.data[name].extifinstance2(name, i))
702 return '\n'.join(li(list(filter(None, ret)), 8))
704 def extifinstance(self, *args):
706 for (name, count) in self.ifacecount:
707 for i in range(count):
708 if not self.is_on_fastbus(name, i):
710 ret.append(self.data[name].extifinstance(name, i))
711 return '\n'.join(li(list(filter(None, ret)), 8))
713 def extifdecl(self, *args):
715 for (name, count) in self.ifacecount:
716 for i in range(count):
717 if not self.is_on_fastbus(name, i):
719 ret.append(self.data[name].extifdecl(name, i))
720 return '\n'.join(li(list(filter(None, ret)), 8))
722 def slowifdeclmux(self, *args):
724 for (name, count) in self.ifacecount:
725 for i in range(count):
726 ret.append(self.data[name].slowifdeclmux(name, i))
727 return '\n'.join(li(list(filter(None, ret)), 8))
729 def fastifdecl(self, *args):
731 for (name, count) in self.ifacecount:
732 for i in range(count):
733 print "fastifdecl
", name, i, self.is_on_fastbus(name, i)
734 if self.is_on_fastbus(name, i):
736 ret.append(self.data[name].fastifdecl(name, i))
737 return '\n'.join(li(list(filter(None, ret)), 4))
739 def slowifdecl(self, *args):
741 for (name, count) in self.ifacecount:
742 for i in range(count):
743 if self.is_on_fastbus(name, i):
745 ret.append(self.data[name].slowifdecl().format(i, name))
746 return '\n'.join(list(filter(None, ret)))
748 def axi_fastmem_def(self, *args):
749 return self._axi_reg_def(0x50000000, *args)
751 def axi_reg_def(self, *args):
752 return self._axi_reg_def(0x00011100, *args)
754 def _axi_reg_def(self, start, *args):
756 for (name, count) in self.ifacecount:
757 for i in range(count):
758 if self.is_on_fastbus(name, i):
760 x = self.data[name].axi_reg_def(start, i)
761 #print ("ifc
", name, x)
765 return '\n'.join(list(filter(None, ret)))
767 def _axi_num_idx(self, start, template, typ, idxtype, *args):
769 for (name, count) in self.ifacecount:
770 for i in range(count):
771 if self.is_on_fastbus(name, i):
774 fn = self.data[name].axi_master_idx
776 fn = self.data[name].axi_slave_idx
777 (rdef, offs) = fn(start, i, idxtype)
778 #print ("ifc
", name, rdef, offs)
781 ret.append("typedef
%d LastGen_
%s_num
;" % (start - 1, typ))
782 decls = '\n'.join(list(filter(None, ret)))
783 return template.format(decls)
785 def axi_slave_idx(self, *args):
786 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
789 def axi_fastslave_idx(self, *args):
790 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
793 def axi_master_idx(self, *args):
794 return self._axi_num_idx(2, axi_master_declarations, 'master',
797 def axi_fastslave_idx(self, *args):
798 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
801 def axi_fastaddr_map(self, *args):
803 for (name, count) in self.ifacecount:
804 for i in range(count):
805 if self.is_on_fastbus(name, i):
807 ret.append(self.data[name].axi_fastaddr_map(i))
808 return '\n'.join(li(list(filter(None, ret)), 8))
810 def axi_addr_map(self, *args):
812 for (name, count) in self.ifacecount:
813 for i in range(count):
814 if self.is_on_fastbus(name, i):
816 ret.append(self.data[name].axi_addr_map(i))
817 return '\n'.join(li(list(filter(None, ret)), 8))
819 def mkfast_peripheral(self, *args):
821 for (name, count) in self.ifacecount:
822 for i in range(count):
823 if self.is_on_fastbus(name, i):
825 #print "mkfast
", name, count
826 x = self.data[name].mkfast_peripheral()
828 suffix = self.data[name].mksuffix(name, i)
829 ret.append(x.format(suffix))
830 return '\n'.join(li(list(filter(None, ret)), 8))
832 def mkslow_peripheral(self, *args):
834 for (name, count) in self.ifacecount:
835 for i in range(count):
836 if self.is_on_fastbus(name, i):
838 #print "mkslow
", name, count
839 x = self.data[name].mkslow_peripheral()
841 suffix = self.data[name].mksuffix(name, i)
842 ret.append(x.format(suffix))
843 return '\n'.join(li(list(filter(None, ret)), 8))
845 def mk_master_connection(self, *args):
846 return self._mk_connection("fabric
", "fast
", True, *args)
848 def mk_fast_connection(self, *args):
849 return self._mk_connection("fabric
", "fast
", False, *args)
851 def mk_connection(self, *args):
852 return self._mk_connection("slow_fabric
", "", False, *args)
854 def mk_cellconn(self):
857 for (name, count) in self.ifacecount:
858 for i in range(count):
859 if self.is_on_fastbus(name, i):
861 res = self.data[name].mk_cellconn(name, i, cellcount)
864 (txt, cellcount) = res
866 ret = li('\n'.join(list(filter(None, ret))), 4)
867 return li(pinmux_cellrule.format(ret), 4)
870 return self._mk_pincon("slow
")
872 def mk_fast_pincon(self):
873 return self._mk_pincon("fast
")
875 def mk_dma_irq(self):
883 for (name, count) in self.ifacecount:
885 for i in range(count):
886 if not self.is_on_fastbus(name, i):
888 txt = self.data[name].mk_dma_sync(name, i)
892 txt = self.data[name].mk_dma_rule(name, i)
893 ifacerules.append(txt)
894 txt = self.data[name].mk_dma_connect(name, i)
896 ifacerules = list(filter(None, ifacerules))
898 txt = "rule synchronize_
%s_interrupts
;" % name
901 rules.append("endrule
")
903 cnct = list(filter(None, cnct))
905 _cnct = ["rule rl_connect_interrupt_to_DMA
;",
906 " Bit
#(%d) lv_interrupt_to_DMA={" % ct]
909 cnct
= _cnct
+ [spc
+ spcsep
.join(cnct
)]
911 cnct
.append(" dma.interrupt_from_peripherals(\n" +
912 " lv_interrupt_to_DMA);")
913 cnct
.append("endrule;")
915 ret
= list(filter(None, sync
+ rules
+ cnct
))
917 return '\n'.join(ret
)
919 def num_dmachannels(self
):
920 return "`define NUM_DMACHANNELS {0}".format(self
.dma_count
)
924 irq_offs
= 8 # XXX: DMA scovers 0-7?
925 for (name
, count
) in self
.ifacecount
:
926 for i
in range(count
):
927 if self
.is_on_fastbus(name
, i
):
929 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
932 (txt
, irq_offs
) = res
934 self
.num_slow_irqs
= irq_offs
935 return '\n'.join(li(list(filter(None, ret
)), 4))
937 def mk_sloirqsdef(self
):
938 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
940 def mk_fastclk_con(self
):
941 return self
._mk
_clk
_con
("fast")
943 def mk_slowclk_con(self
):
944 return self
._mk
_clk
_con
("slow")
946 def is_on_fastbus(self
, name
, i
):
947 #print "fastbus mode", self.fastbusmode, name, i
948 iname
= self
.data
[name
].iname().format(i
)
950 return iname
not in self
.fastbus
951 return iname
in self
.fastbus
954 class IfaceIter(object):
956 def __init__(self
, name
, count
, *args
):
959 self
.maxcount
= count
967 if self
.i
>= self
.maxcount
:
969 if self
.check(self
.name
, self
.i
):
970 #print "iter", self.item
971 #print "item args", self.args
972 res
= self
.item(self
.name
, self
.i
, *self
.args
)
979 return self
.__next
__()
982 class MkConnection(IfaceIter
):
984 def __init__(self
, ifaces
, name
, count
, *args
):
986 IfaceIter
.__init
__(self
, name
, count
, *args
)
988 def check(self
, name
, i
):
989 return not self
.ifaces
.is_on_fastbus(name
, i
)
991 def item(self
, name
, i
, fabric
, typ
, master
):
993 return self
.ifaces
.data
[name
].mk_master_connection(name
,
995 return self
.ifaces
.data
[name
].mk_connection(name
, i
, fabric
, typ
)
998 class MkExtIface(IfaceIter
):
1000 def __init__(self
, ifaces
, name
, count
, *args
):
1001 self
.ifaces
= ifaces
1002 IfaceIter
.__init
__(self
, name
, count
, *args
)
1004 def check(self
, name
, i
):
1005 return not self
.ifaces
.is_on_fastbus(name
, i
)
1007 def item(self
, name
, i
):
1008 return self
.ifaces
.data
[name
].mk_ext_ifacedef(name
, i
)
1011 class MkPinCon(IfaceIter
):
1013 def __init__(self
, ifaces
, name
, count
, *args
):
1014 self
.ifaces
= ifaces
1015 IfaceIter
.__init
__(self
, name
, count
, *args
)
1017 def check(self
, name
, i
):
1018 return not self
.ifaces
.is_on_fastbus(name
, i
)
1020 def item(self
, name
, i
, typ
):
1021 return self
.ifaces
.data
[name
]._mk
_pincon
(name
, i
, typ
)
1024 class MkClkCon(IfaceIter
):
1026 def __init__(self
, ifaces
, name
, count
, *args
):
1027 self
.ifaces
= ifaces
1028 IfaceIter
.__init
__(self
, name
, count
, *args
)
1030 def check(self
, name
, i
):
1031 return not self
.ifaces
.is_on_fastbus(name
, i
)
1033 def item(self
, name
, i
, ctype
):
1034 return self
.ifaces
.data
[name
]._mk
_clk
_con
(name
, i
, ctype
)
1037 class PFactory(object):
1038 def getcls(self
, name
):
1039 from uart
import uart
1040 from quart
import quart
1041 from sdmmc
import sdmmc
1042 from emmc
import emmc
1044 from eint
import eint
1045 from rs232
import rs232
1047 from eint
import eint
1048 from jtag
import jtag
1049 from spi
import spi
, mspi
1050 from qspi
import qspi
, mqspi
1051 from gpio
import gpio
1052 from rgbttl
import rgbttl
1053 from flexbus
import flexbus
1054 from sdram
import sdram
1056 for k
, v
in {'uart': uart
,
1074 if name
.startswith(k
):
1079 slowfactory
= PFactory()
1081 if __name__
== '__main__':
1083 print p
.slowimport()
1084 print p
.slowifdecl()
1085 i
= PeripheralIface('uart')
1087 i
= PeripheralIface('gpioa')