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_fastaddr_map(self
, name
, ifacenum
):
126 return self
.axi_addr_map(name
, ifacenum
, 'fast')
128 def axi_addr_map(self
, name
, ifacenum
, typ
=""):
129 bname
= self
.axibase(name
, ifacenum
)
130 bend
= self
.axiend(name
, ifacenum
)
131 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
133 if(addr>=`{0} && addr<=`{1})
134 return tuple2(True,fromInteger(valueOf({2})));
136 return template
.format(bname
, bend
, name
)
138 def _mk_pincon(self
, name
, count
, ptyp
):
139 # TODO: really should be using bsv.interface_decl.Interfaces
140 # pin-naming rules.... logic here is hard-coded to duplicate
141 # it (see Interface.__init__ outen)
143 for p
in self
.peripheral
.pinspecs
:
146 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
147 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
148 ret
.append("//%s %s" % (n
, str(p
)))
150 sname
= self
.get_iname(count
)
151 sname
= "{0}.{1}".format(sname
, pname
)
152 ps
= "slow_peripherals.%s" % sname
154 sname
= self
.peripheral
.iname().format(count
)
155 sname
= "{0}.{1}".format(sname
, pname
)
156 ps
= "pinmux.peripheral_side.%s" % sname
157 if typ
== 'out' or typ
== 'inout':
158 fname
= self
.pinname_out(pname
)
159 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
160 n_
= "{0}{1}".format(n
, count
)
168 ret
.append("mkConnection({0},\n\t\t\t{1}.{2});"
169 .format(ps_
, n_
, fname
))
172 fname
= self
.pinname_outen(pname
)
174 if isinstance(fname
, str):
175 fname
= "{0}.{1}".format(n_
, fname
)
176 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
177 ret
.append("mkConnection({0}_outen,\n\t\t\t{1});"
179 if typ
== 'in' or typ
== 'inout':
180 fname
= self
.pinname_in(pname
)
186 n_
= "{0}{1}".format(n
, count
)
187 n_
= '{0}.{1}'.format(n_
, fname
)
188 n_
= self
.ifname_tweak(pname
, 'in', n_
)
190 "mkConnection({1},\n\t\t\t{0});".format(
192 return '\n'.join(ret
)
194 def mk_cellconn(self
, *args
):
197 def mkfast_peripheral(self
, size
=0):
200 def mkslow_peripheral(self
, size
=0):
203 def mksuffix(self
, name
, i
):
206 def __mk_connection(self
, con
, aname
, fabricname
):
207 txt
= "mkConnection ({2}.v_to_slaves\n" + \
208 " [fromInteger(valueOf({1}))],\n" + \
211 print "PBase __mk_connection", self
.name
, aname
214 return txt
.format(con
, aname
, fabricname
)
216 def __mk_master_connection(self
, con
, aname
):
217 txt
= "mkConnection (slow_fabric.v_to_slaves\n" + \
218 " [fromInteger(valueOf({1}))],\n" + \
221 print "PBase __mk_connection", self
.name
, aname
224 return txt
.format(con
, aname
)
226 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
229 print "PBase mk_conn", self
.name
, count
230 aname
= self
.axi_slave_name(name
, count
, typ
)
231 #dname = self.mksuffix(name, count)
232 #dname = "{0}{1}".format(name, dname)
233 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
234 return self
.__mk
_connection
(con
, aname
, fabricname
)
236 def _mk_connection(self
, name
=None, count
=0):
239 def pinname_out(self
, pname
):
242 def pinname_in(self
, pname
):
245 def pinname_outen(self
, pname
):
248 def ifname_tweak(self
, pname
, typ
, txt
):
251 def pinname_tweak(self
, pname
, typ
, txt
):
257 def mk_plic(self
, inum
, irq_offs
):
259 print "mk_plic", self
.name
, inum
, irq_offs
260 niq
= self
.num_irqs()
262 return ('', irq_offs
)
263 name
= self
.get_iname(inum
)
264 res
.append("// PLIC rules for {0}".format(name
))
265 for idx
in range(niq
):
266 plic_obj
= self
.plic_object(name
, idx
)
267 print "plic_obj", name
, idx
, plic_obj
268 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
270 irq_offs
+= 1 # increment to next irq
271 return ('\n'.join(res
), irq_offs
)
273 def mk_ext_ifacedef(self
, iname
, inum
):
276 def extfastifinstance(self
, name
, count
):
279 def _extifinstance(self
, name
, count
, suffix
, prefix
, samename
=False,
283 pname
= self
.get_iname(count
)
287 sname
= self
.peripheral
.iname().format(count
)
288 template
= "interface {0}{3} = {2}{1}{4};"
289 return template
.format(pname
, sname
, prefix
, suffix
, ifsuffix
)
291 def extifinstance2(self
, name
, count
):
294 def extifinstance(self
, name
, count
):
295 return self
._extifinstance
(name
, count
, "",
296 "pinmux.peripheral_side.")
300 rule rl_connect_{0}_to_plic_{2};
301 if({1} == 1'b1) begin
302 ff_gateway_queue[{2}].enq(1);
303 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
308 axi_master_declarations
= """\
309 typedef 0 Dmem_master_num;
310 typedef 1 Imem_master_num;
312 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
314 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
316 typedef TAdd#(DMA_master_num,1)
320 axi_fastslave_declarations
= """\
322 typedef TAdd#(LastGen_fastslave_num,1) Sdram_slave_num;
323 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
325 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
327 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
329 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
331 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
333 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
334 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
336 typedef TAdd#(VME_slave_num,1) Num_Fast_Slaves;
339 axi_slave_declarations
= """\
340 typedef 0 SlowMaster;
342 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
344 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
346 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
348 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
351 pinmux_cellrule
= """\
352 rule connect_select_lines_pinmux;
358 class CallFn(object):
359 def __init__(self
, peripheral
, name
):
360 self
.peripheral
= peripheral
363 def __call__(self
, *args
):
364 #print "__call__", self.name, self.peripheral.slow, args
365 if not self
.peripheral
.slow
:
367 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
370 class PeripheralIface(object):
371 def __init__(self
, ifacename
):
373 slow
= slowfactory
.getcls(ifacename
)
374 print "Iface", ifacename
, slow
376 self
.slow
= slow(ifacename
)
377 self
.slow
.peripheral
= self
378 for fname
in ['slowimport',
380 'extifinstance2', 'extifinstance', 'extifdecl',
381 'slowifdecl', 'slowifdeclmux',
384 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
386 'mk_plic', 'mk_ext_ifacedef',
387 'mk_connection', 'mk_cellconn', '_mk_pincon']:
388 fn
= CallFn(self
, fname
)
389 setattr(self
, fname
, types
.MethodType(fn
, self
))
391 #print "PeripheralIface"
394 def mksuffix(self
, name
, i
):
395 if self
.slow
is None:
397 return self
.slow
.mksuffix(name
, i
)
399 def axi_reg_def(self
, start
, count
):
402 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
404 def axi_master_idx(self
, start
, count
, typ
):
405 if not self
.slow
or not self
.slow
.has_axi_master():
407 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
409 def axi_slave_idx(self
, start
, count
, typ
):
412 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
414 def axi_fastaddr_map(self
, count
):
417 return self
.slow
.axi_fastaddr_map(self
.ifacename
, count
)
419 def axi_addr_map(self
, count
):
422 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
425 class PeripheralInterfaces(object):
427 self
.fastbusmode
= False
429 def slowimport(self
, *args
):
431 for (name
, count
) in self
.ifacecount
:
432 #print "slowimport", name, self.data[name].slowimport
433 ret
.append(self
.data
[name
].slowimport())
434 return '\n'.join(li(list(filter(None, ret
)), 4))
436 def extfastifinstance(self
, *args
):
438 for (name
, count
) in self
.ifacecount
:
439 for i
in range(count
):
440 iname
= self
.data
[name
].iname().format(i
)
441 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
442 if self
.is_on_fastbus(name
, i
):
444 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
445 return '\n'.join(li(list(filter(None, ret
)), 8))
447 def extifinstance2(self
, *args
):
449 for (name
, count
) in self
.ifacecount
:
450 for i
in range(count
):
451 iname
= self
.data
[name
].iname().format(i
)
452 ret
.append(self
.data
[name
].extifinstance2(name
, i
))
453 return '\n'.join(li(list(filter(None, ret
)), 8))
455 def extifinstance(self
, *args
):
457 for (name
, count
) in self
.ifacecount
:
458 for i
in range(count
):
459 iname
= self
.data
[name
].iname().format(i
)
460 if not self
.is_on_fastbus(name
, i
):
462 ret
.append(self
.data
[name
].extifinstance(name
, i
))
463 return '\n'.join(li(list(filter(None, ret
)), 8))
465 def extifdecl(self
, *args
):
467 for (name
, count
) in self
.ifacecount
:
468 for i
in range(count
):
469 if not self
.is_on_fastbus(name
, i
):
471 ret
.append(self
.data
[name
].extifdecl(name
, i
))
472 return '\n'.join(li(list(filter(None, ret
)), 8))
474 def slowifdeclmux(self
, *args
):
476 for (name
, count
) in self
.ifacecount
:
477 for i
in range(count
):
478 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
479 return '\n'.join(li(list(filter(None, ret
)), 8))
481 def fastifdecl(self
, *args
):
483 for (name
, count
) in self
.ifacecount
:
484 for i
in range(count
):
485 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
486 if self
.is_on_fastbus(name
, i
):
488 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
489 return '\n'.join(li(list(filter(None, ret
)), 4))
491 def slowifdecl(self
, *args
):
493 for (name
, count
) in self
.ifacecount
:
494 for i
in range(count
):
495 if self
.is_on_fastbus(name
, i
):
497 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
498 return '\n'.join(list(filter(None, ret
)))
500 def axi_fastmem_def(self
, *args
):
501 return self
._axi
_reg
_def
(0x50000000, *args
)
503 def axi_reg_def(self
, *args
):
504 return self
._axi
_reg
_def
(0x00011100, *args
)
506 def _axi_reg_def(self
, start
, *args
):
508 for (name
, count
) in self
.ifacecount
:
509 for i
in range(count
):
510 if self
.is_on_fastbus(name
, i
):
512 x
= self
.data
[name
].axi_reg_def(start
, i
)
513 #print ("ifc", name, x)
517 return '\n'.join(list(filter(None, ret
)))
519 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
521 for (name
, count
) in self
.ifacecount
:
522 for i
in range(count
):
523 if self
.is_on_fastbus(name
, i
):
526 fn
= self
.data
[name
].axi_master_idx
528 fn
= self
.data
[name
].axi_slave_idx
529 (rdef
, offs
) = fn(start
, i
, idxtype
)
530 #print ("ifc", name, rdef, offs)
533 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
534 decls
= '\n'.join(list(filter(None, ret
)))
535 return template
.format(decls
)
537 def axi_slave_idx(self
, *args
):
538 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
541 def axi_fastslave_idx(self
, *args
):
542 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
545 def axi_master_idx(self
, *args
):
546 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
549 def axi_fastslave_idx(self
, *args
):
550 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
553 def axi_fastaddr_map(self
, *args
):
555 for (name
, count
) in self
.ifacecount
:
556 for i
in range(count
):
557 if self
.is_on_fastbus(name
, i
):
559 ret
.append(self
.data
[name
].axi_fastaddr_map(i
))
560 return '\n'.join(li(list(filter(None, ret
)), 8))
562 def axi_addr_map(self
, *args
):
564 for (name
, count
) in self
.ifacecount
:
565 for i
in range(count
):
566 if self
.is_on_fastbus(name
, i
):
568 ret
.append(self
.data
[name
].axi_addr_map(i
))
569 return '\n'.join(li(list(filter(None, ret
)), 8))
571 def mkfast_peripheral(self
, *args
):
573 for (name
, count
) in self
.ifacecount
:
574 for i
in range(count
):
575 if self
.is_on_fastbus(name
, i
):
577 #print "mkfast", name, count
578 x
= self
.data
[name
].mkfast_peripheral()
580 suffix
= self
.data
[name
].mksuffix(name
, i
)
581 ret
.append(x
.format(suffix
))
582 return '\n'.join(li(list(filter(None, ret
)), 8))
584 def mkslow_peripheral(self
, *args
):
586 for (name
, count
) in self
.ifacecount
:
587 for i
in range(count
):
588 if self
.is_on_fastbus(name
, i
):
590 #print "mkslow", name, count
591 x
= self
.data
[name
].mkslow_peripheral()
593 suffix
= self
.data
[name
].mksuffix(name
, i
)
594 ret
.append(x
.format(suffix
))
595 return '\n'.join(li(list(filter(None, ret
)), 8))
597 def mk_fast_connection(self
, *args
):
599 for (name
, count
) in self
.ifacecount
:
600 for i
in range(count
):
601 if self
.is_on_fastbus(name
, i
):
603 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
606 print self
.data
[name
].mk_connection
608 return '\n'.join(li(list(filter(None, ret
)), 12))
610 def mk_connection(self
, *args
):
612 for (name
, count
) in self
.ifacecount
:
613 for i
in range(count
):
614 if self
.is_on_fastbus(name
, i
):
616 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
619 print self
.data
[name
].mk_connection
621 return '\n'.join(li(list(filter(None, ret
)), 8))
623 def mk_cellconn(self
):
626 for (name
, count
) in self
.ifacecount
:
627 for i
in range(count
):
628 if self
.is_on_fastbus(name
, i
):
630 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
633 (txt
, cellcount
) = res
635 ret
= li('\n'.join(list(filter(None, ret
))), 4)
636 return li(pinmux_cellrule
.format(ret
), 4)
639 return self
._mk
_pincon
("slow")
641 def mk_fast_pincon(self
):
642 return self
._mk
_pincon
("fast")
644 def _mk_pincon(self
, typ
):
646 for (name
, count
) in self
.ifacecount
:
647 for i
in range(count
):
648 if self
.is_on_fastbus(name
, i
):
650 txt
= self
.data
[name
]._mk
_pincon
(name
, i
, typ
)
652 return '\n'.join(li(list(filter(None, ret
)), 4))
654 def mk_dma_irq(self
):
662 for (name
, count
) in self
.ifacecount
:
664 for i
in range(count
):
665 if not self
.is_on_fastbus(name
, i
):
667 txt
= self
.data
[name
].mk_dma_sync(name
, i
)
671 txt
= self
.data
[name
].mk_dma_rule(name
, i
)
672 ifacerules
.append(txt
)
673 txt
= self
.data
[name
].mk_dma_connect(name
, i
)
675 ifacerules
= list(filter(None, ifacerules
))
677 txt
= "rule synchronize_%s_interrupts;" % name
680 rules
.append("endrule")
682 cnct
= list(filter(None, cnct
))
684 _cnct
= ["rule rl_connect_interrupt_to_DMA;",
685 " Bit #(%d) lv_interrupt_to_DMA={" % ct
]
688 cnct
= _cnct
+ [spc
+ spcsep
.join(cnct
)]
690 cnct
.append(" dma.interrupt_from_peripherals(\n" +
691 " lv_interrupt_to_DMA);")
692 cnct
.append("endrule;")
694 ret
= list(filter(None, sync
+ rules
+ cnct
))
696 return '\n'.join(ret
)
698 def num_dmachannels(self
):
699 return "`define NUM_DMACHANNELS {0}".format(self
.dma_count
)
701 def mk_ext_ifacedef(self
):
703 for (name
, count
) in self
.ifacecount
:
704 for i
in range(count
):
705 if self
.is_on_fastbus(name
, i
):
707 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
709 return '\n'.join(li(list(filter(None, ret
)), 8))
713 irq_offs
= 8 # XXX: DMA scovers 0-7?
714 for (name
, count
) in self
.ifacecount
:
715 for i
in range(count
):
716 if self
.is_on_fastbus(name
, i
):
718 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
721 (txt
, irq_offs
) = res
723 self
.num_slow_irqs
= irq_offs
724 return '\n'.join(li(list(filter(None, ret
)), 4))
726 def mk_sloirqsdef(self
):
727 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
729 def is_on_fastbus(self
, name
, i
):
730 #print "fastbus mode", self.fastbusmode, name, i
731 iname
= self
.data
[name
].iname().format(i
)
733 return iname
not in self
.fastbus
734 return iname
in self
.fastbus
737 class PFactory(object):
738 def getcls(self
, name
):
739 from uart
import uart
740 from quart
import quart
741 from sdmmc
import sdmmc
743 from eint
import eint
744 from rs232
import rs232
746 from eint
import eint
747 from jtag
import jtag
748 from spi
import spi
, mspi
749 from qspi
import qspi
, mqspi
750 from gpio
import gpio
751 from rgbttl
import rgbttl
752 from flexbus
import flexbus
754 for k
, v
in {'uart': uart
,
770 if name
.startswith(k
):
775 slowfactory
= PFactory()
777 if __name__
== '__main__':
781 i
= PeripheralIface('uart')
783 i
= PeripheralIface('gpioa')