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})));
132 return template
.format(bname
, bend
, name
)
134 def mk_pincon(self
, name
, count
):
135 # TODO: really should be using bsv.interface_decl.Interfaces
136 # pin-naming rules.... logic here is hard-coded to duplicate
137 # it (see Interface.__init__ outen)
139 for p
in self
.peripheral
.pinspecs
:
142 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
143 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
144 ret
.append("//%s %s" % (n
, str(p
)))
145 sname
= self
.peripheral
.iname().format(count
)
146 sname
= "{0}.{1}".format(sname
, pname
)
147 ps
= "pinmux.peripheral_side.%s" % sname
148 if typ
== 'out' or typ
== 'inout':
149 fname
= self
.pinname_out(pname
)
150 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
151 n_
= "{0}{1}".format(n
, count
)
159 ret
.append("mkConnection({0},\n\t\t\t{1}.{2});"
160 .format(ps_
, n_
, fname
))
163 fname
= self
.pinname_outen(pname
)
165 if isinstance(fname
, str):
166 fname
= "{0}.{1}".format(n_
, fname
)
167 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
168 ret
.append("mkConnection({0}_outen,\n\t\t\t{1});"
170 if typ
== 'in' or typ
== 'inout':
171 fname
= self
.pinname_in(pname
)
177 n_
= "{0}{1}".format(n
, count
)
178 n_
= '{0}.{1}'.format(n_
, fname
)
179 n_
= self
.ifname_tweak(pname
, 'in', n_
)
180 ret
.append("mkConnection({1}, {0});".format(ps_
, n_
))
181 return '\n'.join(ret
)
183 def mk_cellconn(self
, *args
):
186 def mkfast_peripheral(self
, size
=0):
189 def mkslow_peripheral(self
, size
=0):
192 def mksuffix(self
, name
, i
):
195 def __mk_connection(self
, con
, aname
, fabricname
):
196 txt
= "mkConnection ({2}.v_to_slaves\n" + \
197 " [fromInteger(valueOf({1}))],\n" + \
200 print "PBase __mk_connection", self
.name
, aname
203 return txt
.format(con
, aname
, fabricname
)
205 def __mk_master_connection(self
, con
, aname
):
206 txt
= "mkConnection (slow_fabric.v_to_slaves\n" + \
207 " [fromInteger(valueOf({1}))],\n" + \
210 print "PBase __mk_connection", self
.name
, aname
213 return txt
.format(con
, aname
)
215 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
218 print "PBase mk_conn", self
.name
, count
219 aname
= self
.axi_slave_name(name
, count
, typ
)
220 #dname = self.mksuffix(name, count)
221 #dname = "{0}{1}".format(name, dname)
222 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
223 return self
.__mk
_connection
(con
, aname
, fabricname
)
225 def _mk_connection(self
, name
=None, count
=0):
228 def pinname_out(self
, pname
):
231 def pinname_in(self
, pname
):
234 def pinname_outen(self
, pname
):
237 def ifname_tweak(self
, pname
, typ
, txt
):
240 def pinname_tweak(self
, pname
, typ
, txt
):
246 def mk_plic(self
, inum
, irq_offs
):
248 print "mk_plic", self
.name
, inum
, irq_offs
249 niq
= self
.num_irqs()
251 return ('', irq_offs
)
252 name
= self
.get_iname(inum
)
253 res
.append("// PLIC rules for {0}".format(name
))
254 for idx
in range(niq
):
255 plic_obj
= self
.plic_object(name
, idx
)
256 print "plic_obj", name
, idx
, plic_obj
257 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
259 irq_offs
+= 1 # increment to next irq
260 return ('\n'.join(res
), irq_offs
)
262 def mk_ext_ifacedef(self
, iname
, inum
):
265 def extfastifinstance(self
, name
, count
):
268 def _extifinstance(self
, name
, count
, suffix
, prefix
, samename
=False):
269 pname
= self
.get_iname(count
)
273 sname
= self
.peripheral
.iname().format(count
)
274 template
= "interface {0}{3} = {2}{1};"
275 return template
.format(pname
, sname
, prefix
, suffix
)
277 def extifinstance2(self
, name
, count
):
280 def extifinstance(self
, name
, count
):
281 return self
._extifinstance
(name
, count
, "",
282 "pinmux.peripheral_side.")
286 rule rl_connect_{0}_to_plic_{2};
287 if({1} == 1'b1) begin
288 ff_gateway_queue[{2}].enq(1);
289 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
294 axi_master_declarations
= """\
295 typedef 0 Dmem_master_num;
296 typedef 1 Imem_master_num;
298 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
300 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
302 typedef TAdd#(DMA_master_num,1)
306 axi_fastslave_declarations
= """\
308 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
309 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
311 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
313 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
315 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
317 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
319 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
320 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
322 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif )
324 typedef TAdd#(FlexBus_slave_num,1)
329 axi_slave_declarations
= """\
330 typedef 0 SlowMaster;
332 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
334 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
336 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
338 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
341 pinmux_cellrule
= """\
342 rule connect_select_lines_pinmux;
348 class CallFn(object):
349 def __init__(self
, peripheral
, name
):
350 self
.peripheral
= peripheral
353 def __call__(self
, *args
):
354 #print "__call__", self.name, self.peripheral.slow, args
355 if not self
.peripheral
.slow
:
357 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
360 class PeripheralIface(object):
361 def __init__(self
, ifacename
):
363 slow
= slowfactory
.getcls(ifacename
)
364 print "Iface", ifacename
, slow
366 self
.slow
= slow(ifacename
)
367 self
.slow
.peripheral
= self
368 for fname
in ['slowimport',
370 'extifinstance2', 'extifinstance', 'extifdecl',
371 'slowifdecl', 'slowifdeclmux',
374 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
376 'mk_plic', 'mk_ext_ifacedef',
377 'mk_connection', 'mk_cellconn', 'mk_pincon']:
378 fn
= CallFn(self
, fname
)
379 setattr(self
, fname
, types
.MethodType(fn
, self
))
381 #print "PeripheralIface"
384 def mksuffix(self
, name
, i
):
385 if self
.slow
is None:
387 return self
.slow
.mksuffix(name
, i
)
389 def axi_reg_def(self
, start
, count
):
392 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
394 def axi_master_idx(self
, start
, count
, typ
):
395 if not self
.slow
or not self
.slow
.has_axi_master():
397 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
399 def axi_slave_idx(self
, start
, count
, typ
):
402 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
404 def axi_addr_map(self
, count
):
407 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
410 class PeripheralInterfaces(object):
412 self
.fastbusmode
= False
414 def slowimport(self
, *args
):
416 for (name
, count
) in self
.ifacecount
:
417 #print "slowimport", name, self.data[name].slowimport
418 ret
.append(self
.data
[name
].slowimport())
419 return '\n'.join(li(list(filter(None, ret
)), 4))
421 def extfastifinstance(self
, *args
):
423 for (name
, count
) in self
.ifacecount
:
424 for i
in range(count
):
425 iname
= self
.data
[name
].iname().format(i
)
426 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
427 if self
.is_on_fastbus(name
, i
):
429 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
430 return '\n'.join(li(list(filter(None, ret
)), 8))
432 def extifinstance2(self
, *args
):
434 for (name
, count
) in self
.ifacecount
:
435 for i
in range(count
):
436 iname
= self
.data
[name
].iname().format(i
)
437 ret
.append(self
.data
[name
].extifinstance2(name
, i
))
438 return '\n'.join(li(list(filter(None, ret
)), 8))
440 def extifinstance(self
, *args
):
442 for (name
, count
) in self
.ifacecount
:
443 for i
in range(count
):
444 iname
= self
.data
[name
].iname().format(i
)
445 if not self
.is_on_fastbus(name
, i
):
447 ret
.append(self
.data
[name
].extifinstance(name
, i
))
448 return '\n'.join(li(list(filter(None, ret
)), 8))
450 def extifdecl(self
, *args
):
452 for (name
, count
) in self
.ifacecount
:
453 for i
in range(count
):
454 if not self
.is_on_fastbus(name
, i
):
456 ret
.append(self
.data
[name
].extifdecl(name
, i
))
457 return '\n'.join(li(list(filter(None, ret
)), 8))
459 def slowifdeclmux(self
, *args
):
461 for (name
, count
) in self
.ifacecount
:
462 for i
in range(count
):
463 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
464 return '\n'.join(li(list(filter(None, ret
)), 8))
466 def fastifdecl(self
, *args
):
468 for (name
, count
) in self
.ifacecount
:
469 for i
in range(count
):
470 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
471 if self
.is_on_fastbus(name
, i
):
473 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
474 return '\n'.join(li(list(filter(None, ret
)), 4))
476 def slowifdecl(self
, *args
):
478 for (name
, count
) in self
.ifacecount
:
479 for i
in range(count
):
480 if self
.is_on_fastbus(name
, i
):
482 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
483 return '\n'.join(list(filter(None, ret
)))
485 def axi_reg_def(self
, *args
):
487 start
= 0x00011100 # start of AXI peripherals address
488 for (name
, count
) in self
.ifacecount
:
489 for i
in range(count
):
490 if self
.is_on_fastbus(name
, i
):
492 x
= self
.data
[name
].axi_reg_def(start
, i
)
493 #print ("ifc", name, x)
497 return '\n'.join(list(filter(None, ret
)))
499 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
501 for (name
, count
) in self
.ifacecount
:
502 for i
in range(count
):
503 if self
.is_on_fastbus(name
, i
):
506 fn
= self
.data
[name
].axi_master_idx
508 fn
= self
.data
[name
].axi_slave_idx
509 (rdef
, offs
) = fn(start
, i
, idxtype
)
510 #print ("ifc", name, rdef, offs)
513 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
514 decls
= '\n'.join(list(filter(None, ret
)))
515 return template
.format(decls
)
517 def axi_slave_idx(self
, *args
):
518 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
521 def axi_fastslave_idx(self
, *args
):
522 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
525 def axi_master_idx(self
, *args
):
526 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
529 def axi_fastslave_idx(self
, *args
):
530 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
533 def axi_addr_map(self
, *args
):
535 for (name
, count
) in self
.ifacecount
:
536 for i
in range(count
):
537 if self
.is_on_fastbus(name
, i
):
539 ret
.append(self
.data
[name
].axi_addr_map(i
))
540 return '\n'.join(li(list(filter(None, ret
)), 8))
542 def mkfast_peripheral(self
, *args
):
544 for (name
, count
) in self
.ifacecount
:
545 for i
in range(count
):
546 if self
.is_on_fastbus(name
, i
):
548 #print "mkfast", name, count
549 x
= self
.data
[name
].mkfast_peripheral()
551 suffix
= self
.data
[name
].mksuffix(name
, i
)
552 ret
.append(x
.format(suffix
))
553 return '\n'.join(li(list(filter(None, ret
)), 8))
555 def mkslow_peripheral(self
, *args
):
557 for (name
, count
) in self
.ifacecount
:
558 for i
in range(count
):
559 if self
.is_on_fastbus(name
, i
):
561 #print "mkslow", name, count
562 x
= self
.data
[name
].mkslow_peripheral()
564 suffix
= self
.data
[name
].mksuffix(name
, i
)
565 ret
.append(x
.format(suffix
))
566 return '\n'.join(li(list(filter(None, ret
)), 8))
568 def mk_fast_connection(self
, *args
):
570 for (name
, count
) in self
.ifacecount
:
571 for i
in range(count
):
572 if self
.is_on_fastbus(name
, i
):
574 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
577 print self
.data
[name
].mk_connection
579 return '\n'.join(li(list(filter(None, ret
)), 4))
581 def mk_connection(self
, *args
):
583 for (name
, count
) in self
.ifacecount
:
584 for i
in range(count
):
585 if self
.is_on_fastbus(name
, i
):
587 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
590 print self
.data
[name
].mk_connection
592 return '\n'.join(li(list(filter(None, ret
)), 8))
594 def mk_cellconn(self
):
597 for (name
, count
) in self
.ifacecount
:
598 for i
in range(count
):
599 if self
.is_on_fastbus(name
, i
):
601 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
604 (txt
, cellcount
) = res
606 ret
= li('\n'.join(list(filter(None, ret
))), 4)
607 return li(pinmux_cellrule
.format(ret
), 4)
611 for (name
, count
) in self
.ifacecount
:
612 for i
in range(count
):
613 if self
.is_on_fastbus(name
, i
):
615 txt
= self
.data
[name
].mk_pincon(name
, i
)
617 return '\n'.join(li(list(filter(None, ret
)), 4))
619 def mk_dma_irq(self
):
627 for (name
, count
) in self
.ifacecount
:
629 for i
in range(count
):
630 if not self
.is_on_fastbus(name
, i
):
632 txt
= self
.data
[name
].mk_dma_sync(name
, i
)
636 txt
= self
.data
[name
].mk_dma_rule(name
, i
)
637 ifacerules
.append(txt
)
638 txt
= self
.data
[name
].mk_dma_connect(name
, i
)
640 ifacerules
= list(filter(None, ifacerules
))
642 txt
= "rule synchronize_%s_interrupts;" % name
645 rules
.append("endrule")
647 cnct
= list(filter(None, cnct
))
649 _cnct
= ["rule rl_connect_interrupt_to_DMA;",
650 " Bit #(%d) lv_interrupt_to_DMA={" % ct
]
653 cnct
= _cnct
+ [spc
+ spcsep
.join(cnct
)]
655 cnct
.append(" dma.interrupt_from_peripherals(\n" + \
656 " lv_interrupt_to_DMA);")
657 cnct
.append("endrule;")
659 ret
= list(filter(None, sync
+ rules
+ cnct
))
661 return '\n'.join(ret
)
663 def num_dmachannels(self
):
664 return "`define NUM_DMACHANNELS {0}".format(self
.dma_count
)
666 def mk_ext_ifacedef(self
):
668 for (name
, count
) in self
.ifacecount
:
669 for i
in range(count
):
670 if self
.is_on_fastbus(name
, i
):
672 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
674 return '\n'.join(li(list(filter(None, ret
)), 8))
678 irq_offs
= 8 # XXX: DMA scovers 0-7?
679 for (name
, count
) in self
.ifacecount
:
680 for i
in range(count
):
681 if self
.is_on_fastbus(name
, i
):
683 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
686 (txt
, irq_offs
) = res
688 self
.num_slow_irqs
= irq_offs
689 return '\n'.join(li(list(filter(None, ret
)), 4))
691 def mk_sloirqsdef(self
):
692 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
694 def is_on_fastbus(self
, name
, i
):
695 #print "fastbus mode", self.fastbusmode, name, i
696 iname
= self
.data
[name
].iname().format(i
)
698 return iname
not in self
.fastbus
699 return iname
in self
.fastbus
702 class PFactory(object):
703 def getcls(self
, name
):
704 from uart
import uart
705 from quart
import quart
706 from sdmmc
import sdmmc
708 from eint
import eint
709 from rs232
import rs232
711 from eint
import eint
712 from jtag
import jtag
713 from spi
import spi
, mspi
714 from qspi
import qspi
, mqspi
715 from gpio
import gpio
716 from rgbttl
import rgbttl
718 for k
, v
in {'uart': uart
,
733 if name
.startswith(k
):
738 slowfactory
= PFactory()
740 if __name__
== '__main__':
744 i
= PeripheralIface('uart')
746 i
= PeripheralIface('gpioa')