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_
)
181 ret
.append("mkConnection({1},\n\t\t\t{0});".format(ps_
, n_
))
182 return '\n'.join(ret
)
184 def mk_cellconn(self
, *args
):
187 def mkfast_peripheral(self
, size
=0):
190 def mkslow_peripheral(self
, size
=0):
193 def mksuffix(self
, name
, i
):
196 def __mk_connection(self
, con
, aname
, fabricname
):
197 txt
= "mkConnection ({2}.v_to_slaves\n" + \
198 " [fromInteger(valueOf({1}))],\n" + \
201 print "PBase __mk_connection", self
.name
, aname
204 return txt
.format(con
, aname
, fabricname
)
206 def __mk_master_connection(self
, con
, aname
):
207 txt
= "mkConnection (slow_fabric.v_to_slaves\n" + \
208 " [fromInteger(valueOf({1}))],\n" + \
211 print "PBase __mk_connection", self
.name
, aname
214 return txt
.format(con
, aname
)
216 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
219 print "PBase mk_conn", self
.name
, count
220 aname
= self
.axi_slave_name(name
, count
, typ
)
221 #dname = self.mksuffix(name, count)
222 #dname = "{0}{1}".format(name, dname)
223 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
224 return self
.__mk
_connection
(con
, aname
, fabricname
)
226 def _mk_connection(self
, name
=None, count
=0):
229 def pinname_out(self
, pname
):
232 def pinname_in(self
, pname
):
235 def pinname_outen(self
, pname
):
238 def ifname_tweak(self
, pname
, typ
, txt
):
241 def pinname_tweak(self
, pname
, typ
, txt
):
247 def mk_plic(self
, inum
, irq_offs
):
249 print "mk_plic", self
.name
, inum
, irq_offs
250 niq
= self
.num_irqs()
252 return ('', irq_offs
)
253 name
= self
.get_iname(inum
)
254 res
.append("// PLIC rules for {0}".format(name
))
255 for idx
in range(niq
):
256 plic_obj
= self
.plic_object(name
, idx
)
257 print "plic_obj", name
, idx
, plic_obj
258 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
260 irq_offs
+= 1 # increment to next irq
261 return ('\n'.join(res
), irq_offs
)
263 def mk_ext_ifacedef(self
, iname
, inum
):
266 def extfastifinstance(self
, name
, count
):
269 def _extifinstance(self
, name
, count
, suffix
, prefix
, samename
=False,
273 pname
= self
.get_iname(count
)
277 sname
= self
.peripheral
.iname().format(count
)
278 template
= "interface {0}{3} = {2}{1}{4};"
279 return template
.format(pname
, sname
, prefix
, suffix
, ifsuffix
)
281 def extifinstance2(self
, name
, count
):
284 def extifinstance(self
, name
, count
):
285 return self
._extifinstance
(name
, count
, "",
286 "pinmux.peripheral_side.")
290 rule rl_connect_{0}_to_plic_{2};
291 if({1} == 1'b1) begin
292 ff_gateway_queue[{2}].enq(1);
293 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
298 axi_master_declarations
= """\
299 typedef 0 Dmem_master_num;
300 typedef 1 Imem_master_num;
302 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
304 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
306 typedef TAdd#(DMA_master_num,1)
310 axi_fastslave_declarations
= """\
312 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
313 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
315 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
317 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
319 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
321 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
323 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
324 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
326 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif )
328 typedef TAdd#(FlexBus_slave_num,1)
333 axi_slave_declarations
= """\
334 typedef 0 SlowMaster;
336 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
338 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
340 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
342 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
345 pinmux_cellrule
= """\
346 rule connect_select_lines_pinmux;
352 class CallFn(object):
353 def __init__(self
, peripheral
, name
):
354 self
.peripheral
= peripheral
357 def __call__(self
, *args
):
358 #print "__call__", self.name, self.peripheral.slow, args
359 if not self
.peripheral
.slow
:
361 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
364 class PeripheralIface(object):
365 def __init__(self
, ifacename
):
367 slow
= slowfactory
.getcls(ifacename
)
368 print "Iface", ifacename
, slow
370 self
.slow
= slow(ifacename
)
371 self
.slow
.peripheral
= self
372 for fname
in ['slowimport',
374 'extifinstance2', 'extifinstance', 'extifdecl',
375 'slowifdecl', 'slowifdeclmux',
378 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
380 'mk_plic', 'mk_ext_ifacedef',
381 'mk_connection', 'mk_cellconn', 'mk_pincon']:
382 fn
= CallFn(self
, fname
)
383 setattr(self
, fname
, types
.MethodType(fn
, self
))
385 #print "PeripheralIface"
388 def mksuffix(self
, name
, i
):
389 if self
.slow
is None:
391 return self
.slow
.mksuffix(name
, i
)
393 def axi_reg_def(self
, start
, count
):
396 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
398 def axi_master_idx(self
, start
, count
, typ
):
399 if not self
.slow
or not self
.slow
.has_axi_master():
401 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
403 def axi_slave_idx(self
, start
, count
, typ
):
406 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
408 def axi_addr_map(self
, count
):
411 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
414 class PeripheralInterfaces(object):
416 self
.fastbusmode
= False
418 def slowimport(self
, *args
):
420 for (name
, count
) in self
.ifacecount
:
421 #print "slowimport", name, self.data[name].slowimport
422 ret
.append(self
.data
[name
].slowimport())
423 return '\n'.join(li(list(filter(None, ret
)), 4))
425 def extfastifinstance(self
, *args
):
427 for (name
, count
) in self
.ifacecount
:
428 for i
in range(count
):
429 iname
= self
.data
[name
].iname().format(i
)
430 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
431 if self
.is_on_fastbus(name
, i
):
433 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
434 return '\n'.join(li(list(filter(None, ret
)), 8))
436 def extifinstance2(self
, *args
):
438 for (name
, count
) in self
.ifacecount
:
439 for i
in range(count
):
440 iname
= self
.data
[name
].iname().format(i
)
441 ret
.append(self
.data
[name
].extifinstance2(name
, i
))
442 return '\n'.join(li(list(filter(None, ret
)), 8))
444 def extifinstance(self
, *args
):
446 for (name
, count
) in self
.ifacecount
:
447 for i
in range(count
):
448 iname
= self
.data
[name
].iname().format(i
)
449 if not self
.is_on_fastbus(name
, i
):
451 ret
.append(self
.data
[name
].extifinstance(name
, i
))
452 return '\n'.join(li(list(filter(None, ret
)), 8))
454 def extifdecl(self
, *args
):
456 for (name
, count
) in self
.ifacecount
:
457 for i
in range(count
):
458 if not self
.is_on_fastbus(name
, i
):
460 ret
.append(self
.data
[name
].extifdecl(name
, i
))
461 return '\n'.join(li(list(filter(None, ret
)), 8))
463 def slowifdeclmux(self
, *args
):
465 for (name
, count
) in self
.ifacecount
:
466 for i
in range(count
):
467 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
468 return '\n'.join(li(list(filter(None, ret
)), 8))
470 def fastifdecl(self
, *args
):
472 for (name
, count
) in self
.ifacecount
:
473 for i
in range(count
):
474 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
475 if self
.is_on_fastbus(name
, i
):
477 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
478 return '\n'.join(li(list(filter(None, ret
)), 4))
480 def slowifdecl(self
, *args
):
482 for (name
, count
) in self
.ifacecount
:
483 for i
in range(count
):
484 if self
.is_on_fastbus(name
, i
):
486 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
487 return '\n'.join(list(filter(None, ret
)))
489 def axi_reg_def(self
, *args
):
491 start
= 0x00011100 # start of AXI peripherals address
492 for (name
, count
) in self
.ifacecount
:
493 for i
in range(count
):
494 if self
.is_on_fastbus(name
, i
):
496 x
= self
.data
[name
].axi_reg_def(start
, i
)
497 #print ("ifc", name, x)
501 return '\n'.join(list(filter(None, ret
)))
503 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
505 for (name
, count
) in self
.ifacecount
:
506 for i
in range(count
):
507 if self
.is_on_fastbus(name
, i
):
510 fn
= self
.data
[name
].axi_master_idx
512 fn
= self
.data
[name
].axi_slave_idx
513 (rdef
, offs
) = fn(start
, i
, idxtype
)
514 #print ("ifc", name, rdef, offs)
517 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
518 decls
= '\n'.join(list(filter(None, ret
)))
519 return template
.format(decls
)
521 def axi_slave_idx(self
, *args
):
522 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
525 def axi_fastslave_idx(self
, *args
):
526 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
529 def axi_master_idx(self
, *args
):
530 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
533 def axi_fastslave_idx(self
, *args
):
534 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
537 def axi_addr_map(self
, *args
):
539 for (name
, count
) in self
.ifacecount
:
540 for i
in range(count
):
541 if self
.is_on_fastbus(name
, i
):
543 ret
.append(self
.data
[name
].axi_addr_map(i
))
544 return '\n'.join(li(list(filter(None, ret
)), 8))
546 def mkfast_peripheral(self
, *args
):
548 for (name
, count
) in self
.ifacecount
:
549 for i
in range(count
):
550 if self
.is_on_fastbus(name
, i
):
552 #print "mkfast", name, count
553 x
= self
.data
[name
].mkfast_peripheral()
555 suffix
= self
.data
[name
].mksuffix(name
, i
)
556 ret
.append(x
.format(suffix
))
557 return '\n'.join(li(list(filter(None, ret
)), 8))
559 def mkslow_peripheral(self
, *args
):
561 for (name
, count
) in self
.ifacecount
:
562 for i
in range(count
):
563 if self
.is_on_fastbus(name
, i
):
565 #print "mkslow", name, count
566 x
= self
.data
[name
].mkslow_peripheral()
568 suffix
= self
.data
[name
].mksuffix(name
, i
)
569 ret
.append(x
.format(suffix
))
570 return '\n'.join(li(list(filter(None, ret
)), 8))
572 def mk_fast_connection(self
, *args
):
574 for (name
, count
) in self
.ifacecount
:
575 for i
in range(count
):
576 if self
.is_on_fastbus(name
, i
):
578 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
581 print self
.data
[name
].mk_connection
583 return '\n'.join(li(list(filter(None, ret
)), 12))
585 def mk_connection(self
, *args
):
587 for (name
, count
) in self
.ifacecount
:
588 for i
in range(count
):
589 if self
.is_on_fastbus(name
, i
):
591 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
594 print self
.data
[name
].mk_connection
596 return '\n'.join(li(list(filter(None, ret
)), 8))
598 def mk_cellconn(self
):
601 for (name
, count
) in self
.ifacecount
:
602 for i
in range(count
):
603 if self
.is_on_fastbus(name
, i
):
605 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
608 (txt
, cellcount
) = res
610 ret
= li('\n'.join(list(filter(None, ret
))), 4)
611 return li(pinmux_cellrule
.format(ret
), 4)
615 for (name
, count
) in self
.ifacecount
:
616 for i
in range(count
):
617 if self
.is_on_fastbus(name
, i
):
619 txt
= self
.data
[name
].mk_pincon(name
, i
)
621 return '\n'.join(li(list(filter(None, ret
)), 4))
623 def mk_dma_irq(self
):
631 for (name
, count
) in self
.ifacecount
:
633 for i
in range(count
):
634 if not self
.is_on_fastbus(name
, i
):
636 txt
= self
.data
[name
].mk_dma_sync(name
, i
)
640 txt
= self
.data
[name
].mk_dma_rule(name
, i
)
641 ifacerules
.append(txt
)
642 txt
= self
.data
[name
].mk_dma_connect(name
, i
)
644 ifacerules
= list(filter(None, ifacerules
))
646 txt
= "rule synchronize_%s_interrupts;" % name
649 rules
.append("endrule")
651 cnct
= list(filter(None, cnct
))
653 _cnct
= ["rule rl_connect_interrupt_to_DMA;",
654 " Bit #(%d) lv_interrupt_to_DMA={" % ct
]
657 cnct
= _cnct
+ [spc
+ spcsep
.join(cnct
)]
659 cnct
.append(" dma.interrupt_from_peripherals(\n" +
660 " lv_interrupt_to_DMA);")
661 cnct
.append("endrule;")
663 ret
= list(filter(None, sync
+ rules
+ cnct
))
665 return '\n'.join(ret
)
667 def num_dmachannels(self
):
668 return "`define NUM_DMACHANNELS {0}".format(self
.dma_count
)
670 def mk_ext_ifacedef(self
):
672 for (name
, count
) in self
.ifacecount
:
673 for i
in range(count
):
674 if self
.is_on_fastbus(name
, i
):
676 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
678 return '\n'.join(li(list(filter(None, ret
)), 8))
682 irq_offs
= 8 # XXX: DMA scovers 0-7?
683 for (name
, count
) in self
.ifacecount
:
684 for i
in range(count
):
685 if self
.is_on_fastbus(name
, i
):
687 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
690 (txt
, irq_offs
) = res
692 self
.num_slow_irqs
= irq_offs
693 return '\n'.join(li(list(filter(None, ret
)), 4))
695 def mk_sloirqsdef(self
):
696 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
698 def is_on_fastbus(self
, name
, i
):
699 #print "fastbus mode", self.fastbusmode, name, i
700 iname
= self
.data
[name
].iname().format(i
)
702 return iname
not in self
.fastbus
703 return iname
in self
.fastbus
706 class PFactory(object):
707 def getcls(self
, name
):
708 from uart
import uart
709 from quart
import quart
710 from sdmmc
import sdmmc
712 from eint
import eint
713 from rs232
import rs232
715 from eint
import eint
716 from jtag
import jtag
717 from spi
import spi
, mspi
718 from qspi
import qspi
, mqspi
719 from gpio
import gpio
720 from rgbttl
import rgbttl
721 from flexbus
import flexbus
723 for k
, v
in {'uart': uart
,
739 if name
.startswith(k
):
744 slowfactory
= PFactory()
746 if __name__
== '__main__':
750 i
= PeripheralIface('uart')
752 i
= PeripheralIface('gpioa')