7 if isinstance(txt
, str):
12 line
= line
.split('\n')
17 res
.append(indent
+ line
)
24 def __init__(self
, name
):
27 def extifdecl(self
, name
, count
):
28 sname
= self
.get_iname(count
)
29 return "interface PeripheralSide%s %s;" % (name
.upper(), sname
)
31 def has_axi_master(self
):
37 def mk_dma_irq(self
, name
, count
):
38 if not self
.irq_name():
40 sname
= self
.get_iname(count
)
41 return "{0}_interrupt".format(sname
)
43 def mk_dma_rule(self
, name
, count
):
44 irqname
= self
.mk_dma_irq(name
, count
)
47 pirqname
= self
.irq_name().format(count
)
48 template
= " {0}_interrupt.send(\n" + \
49 " slow_peripherals.{1});"
50 return template
.format(irqname
, pirqname
)
52 def get_clock_reset(self
, name
, count
):
53 return "slow_clock,slow_reset"
55 def mk_dma_sync(self
, name
, count
):
56 irqname
= self
.mk_dma_irq(name
, count
)
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
))
64 def mk_dma_connect(self
, name
, count
):
65 irqname
= self
.mk_dma_irq(name
, count
)
68 return "{0}.read".format(irqname
)
70 def fastifdecl(self
, name
, count
):
73 def slowifdeclmux(self
, name
, count
):
79 def num_axi_regs32(self
):
85 def get_iname(self
, inum
):
86 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
88 def axibase(self
, name
, ifacenum
):
90 return "%(name)s%(ifacenum)dBase" % locals()
92 def axiend(self
, name
, ifacenum
):
94 return "%(name)s%(ifacenum)dEnd" % locals()
96 def axi_reg_def(self
, start
, name
, ifacenum
):
98 offs
= self
.num_axi_regs32() * 4 * 16
101 end
= start
+ offs
- 1
102 bname
= self
.axibase(name
, ifacenum
)
103 bend
= self
.axiend(name
, ifacenum
)
104 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
105 return (" `define %(bname)s 'h%(start)08X\n"
106 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
109 def axi_master_name(self
, name
, ifacenum
, typ
=''):
111 return "{0}{1}_master_num".format(name
, ifacenum
)
113 def axi_slave_name(self
, name
, ifacenum
, typ
=''):
115 return "{0}{1}_{2}slave_num".format(name
, ifacenum
, typ
)
117 def axi_master_idx(self
, idx
, name
, ifacenum
, typ
):
118 name
= self
.axi_master_name(name
, ifacenum
, typ
)
119 return ("typedef {0} {1};".format(idx
, name
), 1)
121 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
122 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
123 return ("typedef {0} {1};".format(idx
, name
), 1)
125 def axi_addr_map(self
, name
, ifacenum
):
126 bname
= self
.axibase(name
, ifacenum
)
127 bend
= self
.axiend(name
, ifacenum
)
128 name
= self
.axi_slave_name(name
, ifacenum
)
130 if(addr>=`{0} && addr<=`{1})
131 return tuple2(True,fromInteger(valueOf({2})));
133 return template
.format(bname
, bend
, name
)
135 def mk_pincon(self
, name
, count
):
136 # TODO: really should be using bsv.interface_decl.Interfaces
137 # pin-naming rules.... logic here is hard-coded to duplicate
138 # it (see Interface.__init__ outen)
140 for p
in self
.peripheral
.pinspecs
:
143 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
144 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
145 ret
.append("//%s %s" % (n
, str(p
)))
146 sname
= self
.peripheral
.iname().format(count
)
147 sname
= "{0}.{1}".format(sname
, pname
)
148 ps
= "pinmux.peripheral_side.%s" % sname
149 if typ
== 'out' or typ
== 'inout':
150 fname
= self
.pinname_out(pname
)
151 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
152 n_
= "{0}{1}".format(n
, count
)
160 ret
.append("mkConnection({0},\n\t\t\t{1}.{2});"
161 .format(ps_
, n_
, fname
))
164 fname
= self
.pinname_outen(pname
)
166 if isinstance(fname
, str):
167 fname
= "{0}.{1}".format(n_
, fname
)
168 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
169 ret
.append("mkConnection({0}_outen,\n\t\t\t{1});"
171 if typ
== 'in' or typ
== 'inout':
172 fname
= self
.pinname_in(pname
)
178 n_
= "{0}{1}".format(n
, count
)
179 n_
= '{0}.{1}'.format(n_
, fname
)
180 n_
= self
.ifname_tweak(pname
, 'in', n_
)
182 "mkConnection({1},\n\t\t\t{0});".format(
184 return '\n'.join(ret
)
186 def mk_cellconn(self
, *args
):
189 def mkfast_peripheral(self
, size
=0):
192 def mkslow_peripheral(self
, size
=0):
195 def mksuffix(self
, name
, i
):
198 def __mk_connection(self
, con
, aname
, fabricname
):
199 txt
= "mkConnection ({2}.v_to_slaves\n" + \
200 " [fromInteger(valueOf({1}))],\n" + \
203 print "PBase __mk_connection", self
.name
, aname
206 return txt
.format(con
, aname
, fabricname
)
208 def __mk_master_connection(self
, con
, aname
):
209 txt
= "mkConnection (slow_fabric.v_to_slaves\n" + \
210 " [fromInteger(valueOf({1}))],\n" + \
213 print "PBase __mk_connection", self
.name
, aname
216 return txt
.format(con
, aname
)
218 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
221 print "PBase mk_conn", self
.name
, count
222 aname
= self
.axi_slave_name(name
, count
, typ
)
223 #dname = self.mksuffix(name, count)
224 #dname = "{0}{1}".format(name, dname)
225 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
226 return self
.__mk
_connection
(con
, aname
, fabricname
)
228 def _mk_connection(self
, name
=None, count
=0):
231 def pinname_out(self
, pname
):
234 def pinname_in(self
, pname
):
237 def pinname_outen(self
, pname
):
240 def ifname_tweak(self
, pname
, typ
, txt
):
243 def pinname_tweak(self
, pname
, typ
, txt
):
249 def mk_plic(self
, inum
, irq_offs
):
251 print "mk_plic", self
.name
, inum
, irq_offs
252 niq
= self
.num_irqs()
254 return ('', irq_offs
)
255 name
= self
.get_iname(inum
)
256 res
.append("// PLIC rules for {0}".format(name
))
257 for idx
in range(niq
):
258 plic_obj
= self
.plic_object(name
, idx
)
259 print "plic_obj", name
, idx
, plic_obj
260 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
262 irq_offs
+= 1 # increment to next irq
263 return ('\n'.join(res
), irq_offs
)
265 def mk_ext_ifacedef(self
, iname
, inum
):
268 def extfastifinstance(self
, name
, count
):
271 def _extifinstance(self
, name
, count
, suffix
, prefix
, samename
=False,
275 pname
= self
.get_iname(count
)
279 sname
= self
.peripheral
.iname().format(count
)
280 template
= "interface {0}{3} = {2}{1}{4};"
281 return template
.format(pname
, sname
, prefix
, suffix
, ifsuffix
)
283 def extifinstance2(self
, name
, count
):
286 def extifinstance(self
, name
, count
):
287 return self
._extifinstance
(name
, count
, "",
288 "pinmux.peripheral_side.")
292 rule rl_connect_{0}_to_plic_{2};
293 if({1} == 1'b1) begin
294 ff_gateway_queue[{2}].enq(1);
295 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
300 axi_master_declarations
= """\
301 typedef 0 Dmem_master_num;
302 typedef 1 Imem_master_num;
304 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
306 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
308 typedef TAdd#(DMA_master_num,1)
312 axi_fastslave_declarations
= """\
314 typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
315 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
317 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
319 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
321 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
323 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
325 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
326 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
328 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif )
330 typedef TAdd#(FlexBus_slave_num,1)
335 axi_slave_declarations
= """\
336 typedef 0 SlowMaster;
338 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
340 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
342 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
344 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
347 pinmux_cellrule
= """\
348 rule connect_select_lines_pinmux;
354 class CallFn(object):
355 def __init__(self
, peripheral
, name
):
356 self
.peripheral
= peripheral
359 def __call__(self
, *args
):
360 #print "__call__", self.name, self.peripheral.slow, args
361 if not self
.peripheral
.slow
:
363 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
366 class PeripheralIface(object):
367 def __init__(self
, ifacename
):
369 slow
= slowfactory
.getcls(ifacename
)
370 print "Iface", ifacename
, slow
372 self
.slow
= slow(ifacename
)
373 self
.slow
.peripheral
= self
374 for fname
in ['slowimport',
376 'extifinstance2', 'extifinstance', 'extifdecl',
377 'slowifdecl', 'slowifdeclmux',
380 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
382 'mk_plic', 'mk_ext_ifacedef',
383 'mk_connection', 'mk_cellconn', 'mk_pincon']:
384 fn
= CallFn(self
, fname
)
385 setattr(self
, fname
, types
.MethodType(fn
, self
))
387 #print "PeripheralIface"
390 def mksuffix(self
, name
, i
):
391 if self
.slow
is None:
393 return self
.slow
.mksuffix(name
, i
)
395 def axi_reg_def(self
, start
, count
):
398 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
400 def axi_master_idx(self
, start
, count
, typ
):
401 if not self
.slow
or not self
.slow
.has_axi_master():
403 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
405 def axi_slave_idx(self
, start
, count
, typ
):
408 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
410 def axi_addr_map(self
, count
):
413 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
416 class PeripheralInterfaces(object):
418 self
.fastbusmode
= False
420 def slowimport(self
, *args
):
422 for (name
, count
) in self
.ifacecount
:
423 #print "slowimport", name, self.data[name].slowimport
424 ret
.append(self
.data
[name
].slowimport())
425 return '\n'.join(li(list(filter(None, ret
)), 4))
427 def extfastifinstance(self
, *args
):
429 for (name
, count
) in self
.ifacecount
:
430 for i
in range(count
):
431 iname
= self
.data
[name
].iname().format(i
)
432 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
433 if self
.is_on_fastbus(name
, i
):
435 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
436 return '\n'.join(li(list(filter(None, ret
)), 8))
438 def extifinstance2(self
, *args
):
440 for (name
, count
) in self
.ifacecount
:
441 for i
in range(count
):
442 iname
= self
.data
[name
].iname().format(i
)
443 ret
.append(self
.data
[name
].extifinstance2(name
, i
))
444 return '\n'.join(li(list(filter(None, ret
)), 8))
446 def extifinstance(self
, *args
):
448 for (name
, count
) in self
.ifacecount
:
449 for i
in range(count
):
450 iname
= self
.data
[name
].iname().format(i
)
451 if not self
.is_on_fastbus(name
, i
):
453 ret
.append(self
.data
[name
].extifinstance(name
, i
))
454 return '\n'.join(li(list(filter(None, ret
)), 8))
456 def extifdecl(self
, *args
):
458 for (name
, count
) in self
.ifacecount
:
459 for i
in range(count
):
460 if not self
.is_on_fastbus(name
, i
):
462 ret
.append(self
.data
[name
].extifdecl(name
, i
))
463 return '\n'.join(li(list(filter(None, ret
)), 8))
465 def slowifdeclmux(self
, *args
):
467 for (name
, count
) in self
.ifacecount
:
468 for i
in range(count
):
469 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
470 return '\n'.join(li(list(filter(None, ret
)), 8))
472 def fastifdecl(self
, *args
):
474 for (name
, count
) in self
.ifacecount
:
475 for i
in range(count
):
476 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
477 if self
.is_on_fastbus(name
, i
):
479 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
480 return '\n'.join(li(list(filter(None, ret
)), 4))
482 def slowifdecl(self
, *args
):
484 for (name
, count
) in self
.ifacecount
:
485 for i
in range(count
):
486 if self
.is_on_fastbus(name
, i
):
488 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
489 return '\n'.join(list(filter(None, ret
)))
491 def axi_fastmem_def(self
, *args
):
492 return self
._axi
_reg
_def
(0x50000000, *args
)
494 def axi_reg_def(self
, *args
):
495 return self
._axi
_reg
_def
(0x00011100, *args
)
497 def _axi_reg_def(self
, start
, *args
):
499 for (name
, count
) in self
.ifacecount
:
500 for i
in range(count
):
501 if self
.is_on_fastbus(name
, i
):
503 x
= self
.data
[name
].axi_reg_def(start
, i
)
504 #print ("ifc", name, x)
508 return '\n'.join(list(filter(None, ret
)))
510 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
512 for (name
, count
) in self
.ifacecount
:
513 for i
in range(count
):
514 if self
.is_on_fastbus(name
, i
):
517 fn
= self
.data
[name
].axi_master_idx
519 fn
= self
.data
[name
].axi_slave_idx
520 (rdef
, offs
) = fn(start
, i
, idxtype
)
521 #print ("ifc", name, rdef, offs)
524 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
525 decls
= '\n'.join(list(filter(None, ret
)))
526 return template
.format(decls
)
528 def axi_slave_idx(self
, *args
):
529 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
532 def axi_fastslave_idx(self
, *args
):
533 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
536 def axi_master_idx(self
, *args
):
537 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
540 def axi_fastslave_idx(self
, *args
):
541 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
544 def axi_addr_map(self
, *args
):
546 for (name
, count
) in self
.ifacecount
:
547 for i
in range(count
):
548 if self
.is_on_fastbus(name
, i
):
550 ret
.append(self
.data
[name
].axi_addr_map(i
))
551 return '\n'.join(li(list(filter(None, ret
)), 8))
553 def mkfast_peripheral(self
, *args
):
555 for (name
, count
) in self
.ifacecount
:
556 for i
in range(count
):
557 if self
.is_on_fastbus(name
, i
):
559 #print "mkfast", name, count
560 x
= self
.data
[name
].mkfast_peripheral()
562 suffix
= self
.data
[name
].mksuffix(name
, i
)
563 ret
.append(x
.format(suffix
))
564 return '\n'.join(li(list(filter(None, ret
)), 8))
566 def mkslow_peripheral(self
, *args
):
568 for (name
, count
) in self
.ifacecount
:
569 for i
in range(count
):
570 if self
.is_on_fastbus(name
, i
):
572 #print "mkslow", name, count
573 x
= self
.data
[name
].mkslow_peripheral()
575 suffix
= self
.data
[name
].mksuffix(name
, i
)
576 ret
.append(x
.format(suffix
))
577 return '\n'.join(li(list(filter(None, ret
)), 8))
579 def mk_fast_connection(self
, *args
):
581 for (name
, count
) in self
.ifacecount
:
582 for i
in range(count
):
583 if self
.is_on_fastbus(name
, i
):
585 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
588 print self
.data
[name
].mk_connection
590 return '\n'.join(li(list(filter(None, ret
)), 12))
592 def mk_connection(self
, *args
):
594 for (name
, count
) in self
.ifacecount
:
595 for i
in range(count
):
596 if self
.is_on_fastbus(name
, i
):
598 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
601 print self
.data
[name
].mk_connection
603 return '\n'.join(li(list(filter(None, ret
)), 8))
605 def mk_cellconn(self
):
608 for (name
, count
) in self
.ifacecount
:
609 for i
in range(count
):
610 if self
.is_on_fastbus(name
, i
):
612 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
615 (txt
, cellcount
) = res
617 ret
= li('\n'.join(list(filter(None, ret
))), 4)
618 return li(pinmux_cellrule
.format(ret
), 4)
622 for (name
, count
) in self
.ifacecount
:
623 for i
in range(count
):
624 if self
.is_on_fastbus(name
, i
):
626 txt
= self
.data
[name
].mk_pincon(name
, i
)
628 return '\n'.join(li(list(filter(None, ret
)), 4))
630 def mk_dma_irq(self
):
638 for (name
, count
) in self
.ifacecount
:
640 for i
in range(count
):
641 if not self
.is_on_fastbus(name
, i
):
643 txt
= self
.data
[name
].mk_dma_sync(name
, i
)
647 txt
= self
.data
[name
].mk_dma_rule(name
, i
)
648 ifacerules
.append(txt
)
649 txt
= self
.data
[name
].mk_dma_connect(name
, i
)
651 ifacerules
= list(filter(None, ifacerules
))
653 txt
= "rule synchronize_%s_interrupts;" % name
656 rules
.append("endrule")
658 cnct
= list(filter(None, cnct
))
660 _cnct
= ["rule rl_connect_interrupt_to_DMA;",
661 " Bit #(%d) lv_interrupt_to_DMA={" % ct
]
664 cnct
= _cnct
+ [spc
+ spcsep
.join(cnct
)]
666 cnct
.append(" dma.interrupt_from_peripherals(\n" +
667 " lv_interrupt_to_DMA);")
668 cnct
.append("endrule;")
670 ret
= list(filter(None, sync
+ rules
+ cnct
))
672 return '\n'.join(ret
)
674 def num_dmachannels(self
):
675 return "`define NUM_DMACHANNELS {0}".format(self
.dma_count
)
677 def mk_ext_ifacedef(self
):
679 for (name
, count
) in self
.ifacecount
:
680 for i
in range(count
):
681 if self
.is_on_fastbus(name
, i
):
683 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
685 return '\n'.join(li(list(filter(None, ret
)), 8))
689 irq_offs
= 8 # XXX: DMA scovers 0-7?
690 for (name
, count
) in self
.ifacecount
:
691 for i
in range(count
):
692 if self
.is_on_fastbus(name
, i
):
694 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
697 (txt
, irq_offs
) = res
699 self
.num_slow_irqs
= irq_offs
700 return '\n'.join(li(list(filter(None, ret
)), 4))
702 def mk_sloirqsdef(self
):
703 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
705 def is_on_fastbus(self
, name
, i
):
706 #print "fastbus mode", self.fastbusmode, name, i
707 iname
= self
.data
[name
].iname().format(i
)
709 return iname
not in self
.fastbus
710 return iname
in self
.fastbus
713 class PFactory(object):
714 def getcls(self
, name
):
715 from uart
import uart
716 from quart
import quart
717 from sdmmc
import sdmmc
719 from eint
import eint
720 from rs232
import rs232
722 from eint
import eint
723 from jtag
import jtag
724 from spi
import spi
, mspi
725 from qspi
import qspi
, mqspi
726 from gpio
import gpio
727 from rgbttl
import rgbttl
728 from flexbus
import flexbus
730 for k
, v
in {'uart': uart
,
746 if name
.startswith(k
):
751 slowfactory
= PFactory()
753 if __name__
== '__main__':
757 i
= PeripheralIface('uart')
759 i
= PeripheralIface('gpioa')