5 def __init__(self
, name
):
8 def extifdecl(self
, name
, count
):
9 sname
= self
.get_iname(count
)
10 return " interface PeripheralSide%s %s;" % (name
.upper(), sname
)
12 def has_axi_master(self
):
18 def mk_dma_irq(self
, name
, count
):
19 if not self
.irq_name():
21 sname
= self
.get_iname(count
)
22 return "{0}_interrupt".format(sname
)
24 def mk_dma_rule(self
, name
, count
):
25 irqname
= self
.mk_dma_irq(name
, count
)
28 pirqname
= self
.irq_name().format(count
)
29 template
= " {0}_interrupt.send(\n" + \
30 " slow_peripherals.{1});"
31 return template
.format(irqname
, pirqname
)
33 def get_clock_reset(self
, name
, count
):
34 return "slow_clock,slow_reset"
36 def mk_dma_sync(self
, name
, count
):
37 irqname
= self
.mk_dma_irq(name
, count
)
40 sname
= self
.peripheral
.iname().format(count
)
41 template
= " SyncBitIfc#(Bit#(1)) {0} <-\n" + \
42 " <-mkSyncBitToCC({1});"
43 return template
.format(irqname
, self
.get_clock_reset(name
, count
))
45 def mk_dma_connect(self
, name
, count
):
48 def fastifdecl(self
, name
, count
):
51 def slowifdeclmux(self
, name
, count
):
57 def num_axi_regs32(self
):
63 def get_iname(self
, inum
):
64 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
66 def axibase(self
, name
, ifacenum
):
68 return "%(name)s%(ifacenum)dBase" % locals()
70 def axiend(self
, name
, ifacenum
):
72 return "%(name)s%(ifacenum)dEnd" % locals()
74 def axi_reg_def(self
, start
, name
, ifacenum
):
76 offs
= self
.num_axi_regs32() * 4 * 16
79 end
= start
+ offs
- 1
80 bname
= self
.axibase(name
, ifacenum
)
81 bend
= self
.axiend(name
, ifacenum
)
82 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
83 return (" `define %(bname)s 'h%(start)08X\n"
84 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
87 def axi_master_name(self
, name
, ifacenum
, typ
=''):
89 return "{0}{1}_master_num".format(name
, ifacenum
)
91 def axi_slave_name(self
, name
, ifacenum
, typ
=''):
93 return "{0}{1}_{2}slave_num".format(name
, ifacenum
, typ
)
95 def axi_master_idx(self
, idx
, name
, ifacenum
, typ
):
96 name
= self
.axi_master_name(name
, ifacenum
, typ
)
97 return ("typedef {0} {1};".format(idx
, name
), 1)
99 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
100 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
101 return ("typedef {0} {1};".format(idx
, name
), 1)
103 def axi_addr_map(self
, name
, ifacenum
):
104 bname
= self
.axibase(name
, ifacenum
)
105 bend
= self
.axiend(name
, ifacenum
)
106 name
= self
.axi_slave_name(name
, ifacenum
)
108 if(addr>=`{0} && addr<=`{1})
109 return tuple2(True,fromInteger(valueOf({2})));
110 else""".format(bname
, bend
, name
)
112 def mk_pincon(self
, name
, count
):
113 # TODO: really should be using bsv.interface_decl.Interfaces
114 # pin-naming rules.... logic here is hard-coded to duplicate
115 # it (see Interface.__init__ outen)
117 for p
in self
.peripheral
.pinspecs
:
120 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
121 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
122 ret
.append(" //%s %s" % (n
, str(p
)))
123 sname
= self
.peripheral
.iname().format(count
)
124 sname
= "{0}.{1}".format(sname
, pname
)
125 ps
= "pinmux.peripheral_side.%s" % sname
126 if typ
== 'out' or typ
== 'inout':
127 fname
= self
.pinname_out(pname
)
128 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
129 n_
= "{0}{1}".format(n
, count
)
137 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
138 .format(ps_
, n_
, fname
))
141 fname
= self
.pinname_outen(pname
)
143 if isinstance(fname
, str):
144 fname
= "{0}.{1}".format(n_
, fname
)
145 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
146 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
148 if typ
== 'in' or typ
== 'inout':
149 fname
= self
.pinname_in(pname
)
155 n_
= "{0}{1}".format(n
, count
)
156 n_
= '{0}.{1}'.format(n_
, fname
)
157 n_
= self
.ifname_tweak(pname
, 'in', n_
)
158 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
159 return '\n'.join(ret
)
161 def mk_cellconn(self
, *args
):
164 def mkfast_peripheral(self
, size
=0):
167 def mkslow_peripheral(self
, size
=0):
170 def mksuffix(self
, name
, i
):
173 def __mk_connection(self
, con
, aname
, fabricname
):
174 txt
= " mkConnection ({2}.v_to_slaves\n" + \
175 " [fromInteger(valueOf({1}))],\n" + \
178 print "PBase __mk_connection", self
.name
, aname
181 return txt
.format(con
, aname
, fabricname
)
183 def __mk_master_connection(self
, con
, aname
):
184 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
185 " [fromInteger(valueOf({1}))],\n" + \
188 print "PBase __mk_connection", self
.name
, aname
191 return txt
.format(con
, aname
)
193 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
196 print "PBase mk_conn", self
.name
, count
197 aname
= self
.axi_slave_name(name
, count
, typ
)
198 #dname = self.mksuffix(name, count)
199 #dname = "{0}{1}".format(name, dname)
200 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
201 return self
.__mk
_connection
(con
, aname
, fabricname
)
203 def _mk_connection(self
, name
=None, count
=0):
206 def pinname_out(self
, pname
):
209 def pinname_in(self
, pname
):
212 def pinname_outen(self
, pname
):
215 def ifname_tweak(self
, pname
, typ
, txt
):
218 def pinname_tweak(self
, pname
, typ
, txt
):
224 def mk_plic(self
, inum
, irq_offs
):
226 print "mk_plic", self
.name
, inum
, irq_offs
227 niq
= self
.num_irqs()
229 return ('', irq_offs
)
230 name
= self
.get_iname(inum
)
231 res
.append(" // PLIC rules for {0}".format(name
))
232 for idx
in range(niq
):
233 plic_obj
= self
.plic_object(name
, idx
)
234 print "plic_obj", name
, idx
, plic_obj
235 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
237 irq_offs
+= 1 # increment to next irq
238 return ('\n'.join(res
), irq_offs
)
240 def mk_ext_ifacedef(self
, iname
, inum
):
243 def extfastifinstance(self
, name
, count
):
246 def _extifinstance(self
, name
, count
, suffix
, prefix
, samename
=False):
247 pname
= self
.get_iname(count
)
251 sname
= self
.peripheral
.iname().format(count
)
252 template
= " interface {0}{3} = {2}{1};"
253 return template
.format(pname
, sname
, prefix
, suffix
)
255 def extifinstance(self
, name
, count
):
256 return self
._extifinstance
(name
, count
, "",
257 "pinmux.peripheral_side.")
261 rule rl_connect_{0}_to_plic_{2};
262 if({1} == 1'b1) begin
263 ff_gateway_queue[{2}].enq(1);
264 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
269 axi_master_declarations
= """\
270 typedef 0 Dmem_master_num;
271 typedef 1 Imem_master_num;
273 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif ) Debug_master_num;
274 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif ) DMA_master_num;
275 typedef TAdd#(DMA_master_num,1) Num_Masters;
278 axi_fastslave_declarations
= """\
280 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
281 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
282 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
283 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
284 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
285 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
286 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
287 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
288 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
289 typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
293 axi_slave_declarations
= """\
294 typedef 0 SlowMaster;
296 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
298 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
300 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
302 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
305 pinmux_cellrule
= """\
306 rule connect_select_lines_pinmux;
312 class CallFn(object):
313 def __init__(self
, peripheral
, name
):
314 self
.peripheral
= peripheral
317 def __call__(self
, *args
):
318 #print "__call__", self.name, self.peripheral.slow, args
319 if not self
.peripheral
.slow
:
321 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
324 class PeripheralIface(object):
325 def __init__(self
, ifacename
):
327 slow
= slowfactory
.getcls(ifacename
)
328 print "Iface", ifacename
, slow
330 self
.slow
= slow(ifacename
)
331 self
.slow
.peripheral
= self
332 for fname
in ['slowimport',
333 'extfastifinstance', 'extifinstance', 'extifdecl',
334 'slowifdecl', 'slowifdeclmux',
337 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
339 'mk_plic', 'mk_ext_ifacedef',
340 'mk_connection', 'mk_cellconn', 'mk_pincon']:
341 fn
= CallFn(self
, fname
)
342 setattr(self
, fname
, types
.MethodType(fn
, self
))
344 #print "PeripheralIface"
347 def mksuffix(self
, name
, i
):
348 if self
.slow
is None:
350 return self
.slow
.mksuffix(name
, i
)
352 def axi_reg_def(self
, start
, count
):
355 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
357 def axi_master_idx(self
, start
, count
, typ
):
358 if not self
.slow
or not self
.slow
.has_axi_master():
360 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
362 def axi_slave_idx(self
, start
, count
, typ
):
365 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
367 def axi_addr_map(self
, count
):
370 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
373 class PeripheralInterfaces(object):
375 self
.fastbusmode
= False
377 def slowimport(self
, *args
):
379 for (name
, count
) in self
.ifacecount
:
380 #print "slowimport", name, self.data[name].slowimport
381 ret
.append(self
.data
[name
].slowimport())
382 return '\n'.join(list(filter(None, ret
)))
384 def extfastifinstance(self
, *args
):
386 for (name
, count
) in self
.ifacecount
:
387 for i
in range(count
):
388 iname
= self
.data
[name
].iname().format(i
)
389 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
390 if self
.is_on_fastbus(name
, i
):
392 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
393 return '\n'.join(list(filter(None, ret
)))
395 def extifinstance(self
, *args
):
397 for (name
, count
) in self
.ifacecount
:
398 for i
in range(count
):
399 iname
= self
.data
[name
].iname().format(i
)
400 if not self
.is_on_fastbus(name
, i
):
402 ret
.append(self
.data
[name
].extifinstance(name
, i
))
403 return '\n'.join(list(filter(None, ret
)))
405 def extifdecl(self
, *args
):
407 for (name
, count
) in self
.ifacecount
:
408 for i
in range(count
):
409 if not self
.is_on_fastbus(name
, i
):
411 ret
.append(self
.data
[name
].extifdecl(name
, i
))
412 return '\n'.join(list(filter(None, ret
)))
414 def slowifdeclmux(self
, *args
):
416 for (name
, count
) in self
.ifacecount
:
417 for i
in range(count
):
418 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
419 return '\n'.join(list(filter(None, ret
)))
421 def fastifdecl(self
, *args
):
423 for (name
, count
) in self
.ifacecount
:
424 for i
in range(count
):
425 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
426 if self
.is_on_fastbus(name
, i
):
428 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
429 return '\n'.join(list(filter(None, ret
)))
431 def slowifdecl(self
, *args
):
433 for (name
, count
) in self
.ifacecount
:
434 for i
in range(count
):
435 if self
.is_on_fastbus(name
, i
):
437 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
438 return '\n'.join(list(filter(None, ret
)))
440 def axi_reg_def(self
, *args
):
442 start
= 0x00011100 # start of AXI peripherals address
443 for (name
, count
) in self
.ifacecount
:
444 for i
in range(count
):
445 if self
.is_on_fastbus(name
, i
):
447 x
= self
.data
[name
].axi_reg_def(start
, i
)
448 #print ("ifc", name, x)
452 return '\n'.join(list(filter(None, ret
)))
454 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
456 for (name
, count
) in self
.ifacecount
:
457 for i
in range(count
):
458 if self
.is_on_fastbus(name
, i
):
461 fn
= self
.data
[name
].axi_master_idx
463 fn
= self
.data
[name
].axi_slave_idx
464 (rdef
, offs
) = fn(start
, i
, idxtype
)
465 #print ("ifc", name, rdef, offs)
468 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
469 decls
= '\n'.join(list(filter(None, ret
)))
470 return template
.format(decls
)
472 def axi_slave_idx(self
, *args
):
473 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
476 def axi_fastslave_idx(self
, *args
):
477 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
480 def axi_master_idx(self
, *args
):
481 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
484 def axi_fastslave_idx(self
, *args
):
485 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
488 def axi_addr_map(self
, *args
):
490 for (name
, count
) in self
.ifacecount
:
491 for i
in range(count
):
492 if self
.is_on_fastbus(name
, i
):
494 ret
.append(self
.data
[name
].axi_addr_map(i
))
495 return '\n'.join(list(filter(None, ret
)))
497 def mkfast_peripheral(self
, *args
):
499 for (name
, count
) in self
.ifacecount
:
500 for i
in range(count
):
501 if self
.is_on_fastbus(name
, i
):
503 #print "mkfast", name, count
504 x
= self
.data
[name
].mkfast_peripheral()
506 suffix
= self
.data
[name
].mksuffix(name
, i
)
507 ret
.append(x
.format(suffix
))
508 return '\n'.join(list(filter(None, ret
)))
510 def mkslow_peripheral(self
, *args
):
512 for (name
, count
) in self
.ifacecount
:
513 for i
in range(count
):
514 if self
.is_on_fastbus(name
, i
):
516 #print "mkslow", name, count
517 x
= self
.data
[name
].mkslow_peripheral()
519 suffix
= self
.data
[name
].mksuffix(name
, i
)
520 ret
.append(x
.format(suffix
))
521 return '\n'.join(list(filter(None, ret
)))
523 def mk_fast_connection(self
, *args
):
525 for (name
, count
) in self
.ifacecount
:
526 for i
in range(count
):
527 if self
.is_on_fastbus(name
, i
):
529 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
532 print self
.data
[name
].mk_connection
534 return '\n'.join(list(filter(None, ret
)))
536 def mk_connection(self
, *args
):
538 for (name
, count
) in self
.ifacecount
:
539 for i
in range(count
):
540 if self
.is_on_fastbus(name
, i
):
542 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
545 print self
.data
[name
].mk_connection
547 return '\n'.join(list(filter(None, ret
)))
549 def mk_cellconn(self
):
552 for (name
, count
) in self
.ifacecount
:
553 for i
in range(count
):
554 if self
.is_on_fastbus(name
, i
):
556 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
559 (txt
, cellcount
) = res
561 ret
= '\n'.join(list(filter(None, ret
)))
562 return pinmux_cellrule
.format(ret
)
566 for (name
, count
) in self
.ifacecount
:
567 for i
in range(count
):
568 if self
.is_on_fastbus(name
, i
):
570 txt
= self
.data
[name
].mk_pincon(name
, i
)
572 return '\n'.join(list(filter(None, ret
)))
574 def mk_dma_irq(self
):
582 for (name
, count
) in self
.ifacecount
:
584 for i
in range(count
):
585 if not self
.is_on_fastbus(name
, i
):
587 txt
= self
.data
[name
].mk_dma_sync(name
, i
)
591 txt
= self
.data
[name
].mk_dma_rule(name
, i
)
592 ifacerules
.append(txt
)
593 txt
= self
.data
[name
].mk_dma_connect(name
, i
)
595 ifacerules
= list(filter(None, ifacerules
))
597 txt
= " rule synchronize_%s_interrupts;" % name
600 rules
.append(" endrule")
603 _cnct
= [" rule rl_connect_interrupt_to_DMA;",
604 " Bit #(%d) lv_interrupt_to_DMA={" % ct
]
607 cnct
.append(" dma.interrupt_from_peripherals(\n" + \
608 " lv_interrupt_to_DMA);")
609 cnct
.append(" endrule;")
611 return '\n'.join(list(filter(None, sync
+ rules
+ cnct
)))
613 def mk_ext_ifacedef(self
):
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_ext_ifacedef(name
, i
)
621 return '\n'.join(list(filter(None, ret
)))
625 irq_offs
= 8 # XXX: DMA scovers 0-7?
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_plic(i
, irq_offs
)
633 (txt
, irq_offs
) = res
635 self
.num_slow_irqs
= irq_offs
636 return '\n'.join(list(filter(None, ret
)))
638 def mk_sloirqsdef(self
):
639 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
641 def is_on_fastbus(self
, name
, i
):
642 #print "fastbus mode", self.fastbusmode, name, i
643 iname
= self
.data
[name
].iname().format(i
)
645 return iname
not in self
.fastbus
646 return iname
in self
.fastbus
649 class PFactory(object):
650 def getcls(self
, name
):
651 from uart
import uart
652 from quart
import quart
653 from sdmmc
import sdmmc
655 from eint
import eint
656 from rs232
import rs232
658 from eint
import eint
659 from jtag
import jtag
660 from spi
import spi
, mspi
661 from qspi
import qspi
, mqspi
662 from gpio
import gpio
663 from rgbttl
import rgbttl
665 for k
, v
in {'uart': uart
,
680 if name
.startswith(k
):
685 slowfactory
= PFactory()
687 if __name__
== '__main__':
691 i
= PeripheralIface('uart')
693 i
= PeripheralIface('gpioa')