6 if isinstance(txt
, str):
11 line
= line
.split('\n')
16 res
.append(indent
+ line
)
23 def __init__(self
, name
):
26 def extifdecl(self
, name
, count
):
27 sname
= self
.get_iname(count
)
28 return "interface PeripheralSide%s %s;" % (name
.upper(), sname
)
30 def has_axi_master(self
):
36 def mk_dma_irq(self
, name
, count
):
37 if not self
.irq_name():
39 sname
= self
.get_iname(count
)
40 return "{0}_interrupt".format(sname
)
42 def mk_dma_rule(self
, name
, count
):
43 irqname
= self
.mk_dma_irq(name
, count
)
46 pirqname
= self
.irq_name().format(count
)
47 template
= " {0}_interrupt.send(\n" + \
48 " slow_peripherals.{1});"
49 return template
.format(irqname
, pirqname
)
51 def get_clock_reset(self
, name
, count
):
52 return "slow_clock,slow_reset"
54 def mk_dma_sync(self
, name
, count
):
55 irqname
= self
.mk_dma_irq(name
, count
)
58 sname
= self
.peripheral
.iname().format(count
)
59 template
= "SyncBitIfc#(Bit#(1)) {0} <-\n" + \
60 " <-mkSyncBitToCC({1});"
61 return template
.format(irqname
, self
.get_clock_reset(name
, count
))
63 def mk_dma_connect(self
, name
, count
):
64 irqname
= self
.mk_dma_irq(name
, count
)
67 return "{0}.read".format(irqname
)
69 def fastifdecl(self
, name
, count
):
72 def slowifdeclmux(self
, name
, count
):
78 def num_axi_regs32(self
):
84 def get_iname(self
, inum
):
85 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
87 def axibase(self
, name
, ifacenum
):
89 return "%(name)s%(ifacenum)dBase" % locals()
91 def axiend(self
, name
, ifacenum
):
93 return "%(name)s%(ifacenum)dEnd" % locals()
95 def axi_reg_def(self
, start
, name
, ifacenum
):
97 offs
= self
.num_axi_regs32() * 4 * 16
100 end
= start
+ offs
- 1
101 bname
= self
.axibase(name
, ifacenum
)
102 bend
= self
.axiend(name
, ifacenum
)
103 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
104 return (" `define %(bname)s 'h%(start)08X\n"
105 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
108 def axi_master_name(self
, name
, ifacenum
, typ
=''):
110 return "{0}{1}_master_num".format(name
, ifacenum
)
112 def axi_slave_name(self
, name
, ifacenum
, typ
=''):
114 return "{0}{1}_{2}slave_num".format(name
, ifacenum
, typ
)
116 def axi_master_idx(self
, idx
, name
, ifacenum
, typ
):
117 name
= self
.axi_master_name(name
, ifacenum
, typ
)
118 return ("typedef {0} {1};".format(idx
, name
), 1)
120 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
121 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
122 return ("typedef {0} {1};".format(idx
, name
), 1)
124 def axi_addr_map(self
, name
, ifacenum
):
125 bname
= self
.axibase(name
, ifacenum
)
126 bend
= self
.axiend(name
, ifacenum
)
127 name
= self
.axi_slave_name(name
, ifacenum
)
129 if(addr>=`{0} && addr<=`{1})
130 return tuple2(True,fromInteger(valueOf({2})));
131 else""".format(bname
, bend
, name
)
133 def mk_pincon(self
, name
, count
):
134 # TODO: really should be using bsv.interface_decl.Interfaces
135 # pin-naming rules.... logic here is hard-coded to duplicate
136 # it (see Interface.__init__ outen)
138 for p
in self
.peripheral
.pinspecs
:
141 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
142 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
143 ret
.append(" //%s %s" % (n
, str(p
)))
144 sname
= self
.peripheral
.iname().format(count
)
145 sname
= "{0}.{1}".format(sname
, pname
)
146 ps
= "pinmux.peripheral_side.%s" % sname
147 if typ
== 'out' or typ
== 'inout':
148 fname
= self
.pinname_out(pname
)
149 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
150 n_
= "{0}{1}".format(n
, count
)
158 ret
.append("mkConnection({0},\n\t\t\t{1}.{2});"
159 .format(ps_
, n_
, fname
))
162 fname
= self
.pinname_outen(pname
)
164 if isinstance(fname
, str):
165 fname
= "{0}.{1}".format(n_
, fname
)
166 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
167 ret
.append("mkConnection({0}_outen,\n\t\t\t{1});"
169 if typ
== 'in' or typ
== 'inout':
170 fname
= self
.pinname_in(pname
)
176 n_
= "{0}{1}".format(n
, count
)
177 n_
= '{0}.{1}'.format(n_
, fname
)
178 n_
= self
.ifname_tweak(pname
, 'in', n_
)
179 ret
.append("mkConnection({1}, {0});".format(ps_
, n_
))
180 return '\n'.join(li(ret
, 6))
182 def mk_cellconn(self
, *args
):
185 def mkfast_peripheral(self
, size
=0):
188 def mkslow_peripheral(self
, size
=0):
191 def mksuffix(self
, name
, i
):
194 def __mk_connection(self
, con
, aname
, fabricname
):
195 txt
= "mkConnection ({2}.v_to_slaves\n" + \
196 " [fromInteger(valueOf({1}))],\n" + \
199 print "PBase __mk_connection", self
.name
, aname
202 return li(txt
.format(con
, aname
, fabricname
), 8)
204 def __mk_master_connection(self
, con
, aname
):
205 txt
= "mkConnection (slow_fabric.v_to_slaves\n" + \
206 " [fromInteger(valueOf({1}))],\n" + \
209 print "PBase __mk_connection", self
.name
, aname
212 return li(txt
.format(con
, aname
), 8)
214 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
217 print "PBase mk_conn", self
.name
, count
218 aname
= self
.axi_slave_name(name
, count
, typ
)
219 #dname = self.mksuffix(name, count)
220 #dname = "{0}{1}".format(name, dname)
221 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
222 return self
.__mk
_connection
(con
, aname
, fabricname
)
224 def _mk_connection(self
, name
=None, count
=0):
227 def pinname_out(self
, pname
):
230 def pinname_in(self
, pname
):
233 def pinname_outen(self
, pname
):
236 def ifname_tweak(self
, pname
, typ
, txt
):
239 def pinname_tweak(self
, pname
, typ
, txt
):
245 def mk_plic(self
, inum
, irq_offs
):
247 print "mk_plic", self
.name
, inum
, irq_offs
248 niq
= self
.num_irqs()
250 return ('', irq_offs
)
251 name
= self
.get_iname(inum
)
252 res
.append("// PLIC rules for {0}".format(name
))
253 for idx
in range(niq
):
254 plic_obj
= self
.plic_object(name
, idx
)
255 print "plic_obj", name
, idx
, plic_obj
256 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
258 irq_offs
+= 1 # increment to next irq
259 return ('\n'.join(li(res
, 5)), irq_offs
)
261 def mk_ext_ifacedef(self
, iname
, inum
):
264 def extfastifinstance(self
, name
, count
):
267 def _extifinstance(self
, name
, count
, suffix
, prefix
, samename
=False):
268 pname
= self
.get_iname(count
)
272 sname
= self
.peripheral
.iname().format(count
)
273 template
= " interface {0}{3} = {2}{1};"
274 return template
.format(pname
, sname
, prefix
, suffix
)
276 def extifinstance2(self
, name
, count
):
279 def extifinstance(self
, name
, count
):
280 return self
._extifinstance
(name
, count
, "",
281 "pinmux.peripheral_side.")
285 rule rl_connect_{0}_to_plic_{2};
286 if({1} == 1'b1) begin
287 ff_gateway_queue[{2}].enq(1);
288 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
293 axi_master_declarations
= """\
294 typedef 0 Dmem_master_num;
295 typedef 1 Imem_master_num;
297 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
299 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
301 typedef TAdd#(DMA_master_num,1)
305 axi_fastslave_declarations
= """\
307 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
308 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
310 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
312 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
314 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
316 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
318 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
319 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
321 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif )
323 typedef TAdd#(FlexBus_slave_num,1)
328 axi_slave_declarations
= """\
329 typedef 0 SlowMaster;
331 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
333 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
335 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
337 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
340 pinmux_cellrule
= """\
341 rule connect_select_lines_pinmux;
347 class CallFn(object):
348 def __init__(self
, peripheral
, name
):
349 self
.peripheral
= peripheral
352 def __call__(self
, *args
):
353 #print "__call__", self.name, self.peripheral.slow, args
354 if not self
.peripheral
.slow
:
356 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
359 class PeripheralIface(object):
360 def __init__(self
, ifacename
):
362 slow
= slowfactory
.getcls(ifacename
)
363 print "Iface", ifacename
, slow
365 self
.slow
= slow(ifacename
)
366 self
.slow
.peripheral
= self
367 for fname
in ['slowimport',
369 'extifinstance2', 'extifinstance', 'extifdecl',
370 'slowifdecl', 'slowifdeclmux',
373 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
375 'mk_plic', 'mk_ext_ifacedef',
376 'mk_connection', 'mk_cellconn', 'mk_pincon']:
377 fn
= CallFn(self
, fname
)
378 setattr(self
, fname
, types
.MethodType(fn
, self
))
380 #print "PeripheralIface"
383 def mksuffix(self
, name
, i
):
384 if self
.slow
is None:
386 return self
.slow
.mksuffix(name
, i
)
388 def axi_reg_def(self
, start
, count
):
391 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
393 def axi_master_idx(self
, start
, count
, typ
):
394 if not self
.slow
or not self
.slow
.has_axi_master():
396 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
398 def axi_slave_idx(self
, start
, count
, typ
):
401 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
403 def axi_addr_map(self
, count
):
406 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
409 class PeripheralInterfaces(object):
411 self
.fastbusmode
= False
413 def slowimport(self
, *args
):
415 for (name
, count
) in self
.ifacecount
:
416 #print "slowimport", name, self.data[name].slowimport
417 ret
.append(self
.data
[name
].slowimport())
418 return '\n'.join(list(filter(None, ret
)))
420 def extfastifinstance(self
, *args
):
422 for (name
, count
) in self
.ifacecount
:
423 for i
in range(count
):
424 iname
= self
.data
[name
].iname().format(i
)
425 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
426 if self
.is_on_fastbus(name
, i
):
428 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
429 return '\n'.join(list(filter(None, ret
)))
431 def extifinstance2(self
, *args
):
433 for (name
, count
) in self
.ifacecount
:
434 for i
in range(count
):
435 iname
= self
.data
[name
].iname().format(i
)
436 ret
.append(self
.data
[name
].extifinstance2(name
, i
))
437 return '\n'.join(list(filter(None, ret
)))
439 def extifinstance(self
, *args
):
441 for (name
, count
) in self
.ifacecount
:
442 for i
in range(count
):
443 iname
= self
.data
[name
].iname().format(i
)
444 if not self
.is_on_fastbus(name
, i
):
446 ret
.append(self
.data
[name
].extifinstance(name
, i
))
447 return '\n'.join(list(filter(None, ret
)))
449 def extifdecl(self
, *args
):
451 for (name
, count
) in self
.ifacecount
:
452 for i
in range(count
):
453 if not self
.is_on_fastbus(name
, i
):
455 ret
.append(self
.data
[name
].extifdecl(name
, i
))
456 return '\n'.join(li(list(filter(None, ret
)), 8))
458 def slowifdeclmux(self
, *args
):
460 for (name
, count
) in self
.ifacecount
:
461 for i
in range(count
):
462 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
463 return '\n'.join(list(filter(None, ret
)))
465 def fastifdecl(self
, *args
):
467 for (name
, count
) in self
.ifacecount
:
468 for i
in range(count
):
469 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
470 if self
.is_on_fastbus(name
, i
):
472 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
473 return '\n'.join(list(filter(None, ret
)))
475 def slowifdecl(self
, *args
):
477 for (name
, count
) in self
.ifacecount
:
478 for i
in range(count
):
479 if self
.is_on_fastbus(name
, i
):
481 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
482 return '\n'.join(list(filter(None, ret
)))
484 def axi_reg_def(self
, *args
):
486 start
= 0x00011100 # start of AXI peripherals address
487 for (name
, count
) in self
.ifacecount
:
488 for i
in range(count
):
489 if self
.is_on_fastbus(name
, i
):
491 x
= self
.data
[name
].axi_reg_def(start
, i
)
492 #print ("ifc", name, x)
496 return '\n'.join(list(filter(None, ret
)))
498 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
500 for (name
, count
) in self
.ifacecount
:
501 for i
in range(count
):
502 if self
.is_on_fastbus(name
, i
):
505 fn
= self
.data
[name
].axi_master_idx
507 fn
= self
.data
[name
].axi_slave_idx
508 (rdef
, offs
) = fn(start
, i
, idxtype
)
509 #print ("ifc", name, rdef, offs)
512 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
513 decls
= '\n'.join(list(filter(None, ret
)))
514 return template
.format(decls
)
516 def axi_slave_idx(self
, *args
):
517 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
520 def axi_fastslave_idx(self
, *args
):
521 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
524 def axi_master_idx(self
, *args
):
525 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
528 def axi_fastslave_idx(self
, *args
):
529 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
532 def axi_addr_map(self
, *args
):
534 for (name
, count
) in self
.ifacecount
:
535 for i
in range(count
):
536 if self
.is_on_fastbus(name
, i
):
538 ret
.append(self
.data
[name
].axi_addr_map(i
))
539 return '\n'.join(list(filter(None, ret
)))
541 def mkfast_peripheral(self
, *args
):
543 for (name
, count
) in self
.ifacecount
:
544 for i
in range(count
):
545 if self
.is_on_fastbus(name
, i
):
547 #print "mkfast", name, count
548 x
= self
.data
[name
].mkfast_peripheral()
550 suffix
= self
.data
[name
].mksuffix(name
, i
)
551 ret
.append(x
.format(suffix
))
552 return '\n'.join(list(filter(None, ret
)))
554 def mkslow_peripheral(self
, *args
):
556 for (name
, count
) in self
.ifacecount
:
557 for i
in range(count
):
558 if self
.is_on_fastbus(name
, i
):
560 #print "mkslow", name, count
561 x
= self
.data
[name
].mkslow_peripheral()
563 suffix
= self
.data
[name
].mksuffix(name
, i
)
564 ret
.append(x
.format(suffix
))
565 return '\n'.join(list(filter(None, ret
)))
567 def mk_fast_connection(self
, *args
):
569 for (name
, count
) in self
.ifacecount
:
570 for i
in range(count
):
571 if self
.is_on_fastbus(name
, i
):
573 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
576 print self
.data
[name
].mk_connection
578 return '\n'.join(list(filter(None, ret
)))
580 def mk_connection(self
, *args
):
582 for (name
, count
) in self
.ifacecount
:
583 for i
in range(count
):
584 if self
.is_on_fastbus(name
, i
):
586 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
589 print self
.data
[name
].mk_connection
591 return '\n'.join(list(filter(None, ret
)))
593 def mk_cellconn(self
):
596 for (name
, count
) in self
.ifacecount
:
597 for i
in range(count
):
598 if self
.is_on_fastbus(name
, i
):
600 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
603 (txt
, cellcount
) = res
605 ret
= '\n'.join(list(filter(None, ret
)))
606 return pinmux_cellrule
.format(ret
)
610 for (name
, count
) in self
.ifacecount
:
611 for i
in range(count
):
612 if self
.is_on_fastbus(name
, i
):
614 txt
= self
.data
[name
].mk_pincon(name
, i
)
616 return '\n'.join(list(filter(None, ret
)))
618 def mk_dma_irq(self
):
626 for (name
, count
) in self
.ifacecount
:
628 for i
in range(count
):
629 if not self
.is_on_fastbus(name
, i
):
631 txt
= self
.data
[name
].mk_dma_sync(name
, i
)
635 txt
= self
.data
[name
].mk_dma_rule(name
, i
)
636 ifacerules
.append(txt
)
637 txt
= self
.data
[name
].mk_dma_connect(name
, i
)
639 ifacerules
= list(filter(None, ifacerules
))
641 txt
= "rule synchronize_%s_interrupts;" % name
644 rules
.append("endrule")
646 cnct
= list(filter(None, cnct
))
648 _cnct
= ["rule rl_connect_interrupt_to_DMA;",
649 " Bit #(%d) lv_interrupt_to_DMA={" % ct
]
652 cnct
= _cnct
+ [spc
+ spcsep
.join(cnct
)]
654 cnct
.append(" dma.interrupt_from_peripherals(\n" + \
655 " lv_interrupt_to_DMA);")
656 cnct
.append("endrule;")
658 ret
= list(filter(None, sync
+ rules
+ cnct
))
660 return '\n'.join(ret
)
662 def num_dmachannels(self
):
663 return "`define NUM_DMACHANNELS {0}".format(self
.dma_count
)
665 def mk_ext_ifacedef(self
):
667 for (name
, count
) in self
.ifacecount
:
668 for i
in range(count
):
669 if self
.is_on_fastbus(name
, i
):
671 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
673 return '\n'.join(list(filter(None, ret
)))
677 irq_offs
= 8 # XXX: DMA scovers 0-7?
678 for (name
, count
) in self
.ifacecount
:
679 for i
in range(count
):
680 if self
.is_on_fastbus(name
, i
):
682 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
685 (txt
, irq_offs
) = res
687 self
.num_slow_irqs
= irq_offs
688 return '\n'.join(list(filter(None, ret
)))
690 def mk_sloirqsdef(self
):
691 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
693 def is_on_fastbus(self
, name
, i
):
694 #print "fastbus mode", self.fastbusmode, name, i
695 iname
= self
.data
[name
].iname().format(i
)
697 return iname
not in self
.fastbus
698 return iname
in self
.fastbus
701 class PFactory(object):
702 def getcls(self
, name
):
703 from uart
import uart
704 from quart
import quart
705 from sdmmc
import sdmmc
707 from eint
import eint
708 from rs232
import rs232
710 from eint
import eint
711 from jtag
import jtag
712 from spi
import spi
, mspi
713 from qspi
import qspi
, mqspi
714 from gpio
import gpio
715 from rgbttl
import rgbttl
717 for k
, v
in {'uart': uart
,
732 if name
.startswith(k
):
737 slowfactory
= PFactory()
739 if __name__
== '__main__':
743 i
= PeripheralIface('uart')
745 i
= PeripheralIface('gpioa')