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
):
15 def fastifdecl(self
, name
, count
):
18 def slowifdeclmux(self
, name
, count
):
24 def num_axi_regs32(self
):
30 def get_iname(self
, inum
):
31 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
33 def axibase(self
, name
, ifacenum
):
35 return "%(name)s%(ifacenum)dBase" % locals()
37 def axiend(self
, name
, ifacenum
):
39 return "%(name)s%(ifacenum)dEnd" % locals()
41 def axi_reg_def(self
, start
, name
, ifacenum
):
43 offs
= self
.num_axi_regs32() * 4 * 16
46 end
= start
+ offs
- 1
47 bname
= self
.axibase(name
, ifacenum
)
48 bend
= self
.axiend(name
, ifacenum
)
49 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
50 return (" `define %(bname)s 'h%(start)08X\n"
51 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
54 def axi_master_name(self
, name
, ifacenum
, typ
=''):
56 return "{0}{1}_master_num".format(name
, ifacenum
)
58 def axi_slave_name(self
, name
, ifacenum
, typ
=''):
60 return "{0}{1}_{2}slave_num".format(name
, ifacenum
, typ
)
62 def axi_master_idx(self
, idx
, name
, ifacenum
, typ
):
63 name
= self
.axi_master_name(name
, ifacenum
, typ
)
64 return ("typedef {0} {1};".format(idx
, name
), 1)
66 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
67 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
68 return ("typedef {0} {1};".format(idx
, name
), 1)
70 def axi_addr_map(self
, name
, ifacenum
):
71 bname
= self
.axibase(name
, ifacenum
)
72 bend
= self
.axiend(name
, ifacenum
)
73 name
= self
.axi_slave_name(name
, ifacenum
)
75 if(addr>=`{0} && addr<=`{1})
76 return tuple2(True,fromInteger(valueOf({2})));
77 else""".format(bname
, bend
, name
)
79 def mk_pincon(self
, name
, count
):
80 # TODO: really should be using bsv.interface_decl.Interfaces
81 # pin-naming rules.... logic here is hard-coded to duplicate
82 # it (see Interface.__init__ outen)
84 for p
in self
.peripheral
.pinspecs
:
87 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
88 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
89 ret
.append(" //%s %s" % (n
, str(p
)))
90 sname
= self
.peripheral
.iname().format(count
)
91 sname
= "{0}.{1}".format(sname
, pname
)
92 ps
= "pinmux.peripheral_side.%s" % sname
93 if typ
== 'out' or typ
== 'inout':
94 fname
= self
.pinname_out(pname
)
95 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
96 n_
= "{0}{1}".format(n
, count
)
104 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
105 .format(ps_
, n_
, fname
))
108 fname
= self
.pinname_outen(pname
)
110 if isinstance(fname
, str):
111 fname
= "{0}.{1}".format(n_
, fname
)
112 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
113 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
115 if typ
== 'in' or typ
== 'inout':
116 fname
= self
.pinname_in(pname
)
122 n_
= "{0}{1}".format(n
, count
)
123 n_
= '{0}.{1}'.format(n_
, fname
)
124 n_
= self
.ifname_tweak(pname
, 'in', n_
)
125 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
126 return '\n'.join(ret
)
128 def mk_cellconn(self
, *args
):
131 def mkfast_peripheral(self
, size
=0):
134 def mkslow_peripheral(self
, size
=0):
137 def mksuffix(self
, name
, i
):
140 def __mk_connection(self
, con
, aname
, fabricname
):
141 txt
= " mkConnection ({2}.v_to_slaves\n" + \
142 " [fromInteger(valueOf({1}))],\n" + \
145 print "PBase __mk_connection", self
.name
, aname
148 return txt
.format(con
, aname
, fabricname
)
150 def __mk_master_connection(self
, con
, aname
):
151 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
152 " [fromInteger(valueOf({1}))],\n" + \
155 print "PBase __mk_connection", self
.name
, aname
158 return txt
.format(con
, aname
)
160 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
163 print "PBase mk_conn", self
.name
, count
164 aname
= self
.axi_slave_name(name
, count
, typ
)
165 #dname = self.mksuffix(name, count)
166 #dname = "{0}{1}".format(name, dname)
167 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
168 return self
.__mk
_connection
(con
, aname
, fabricname
)
170 def _mk_connection(self
, name
=None, count
=0):
173 def pinname_out(self
, pname
):
176 def pinname_in(self
, pname
):
179 def pinname_outen(self
, pname
):
182 def ifname_tweak(self
, pname
, typ
, txt
):
185 def pinname_tweak(self
, pname
, typ
, txt
):
191 def mk_plic(self
, inum
, irq_offs
):
193 print "mk_plic", self
.name
, inum
, irq_offs
194 niq
= self
.num_irqs()
196 return ('', irq_offs
)
197 name
= self
.get_iname(inum
)
198 res
.append(" // PLIC rules for {0}".format(name
))
199 for idx
in range(niq
):
200 plic_obj
= self
.plic_object(name
, idx
)
201 print "plic_obj", name
, idx
, plic_obj
202 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
204 irq_offs
+= 1 # increment to next irq
205 return ('\n'.join(res
), irq_offs
)
207 def mk_ext_ifacedef(self
, iname
, inum
):
210 def extfastifinstance(self
, name
, count
):
213 def extifinstance(self
, name
, count
):
214 sname
= self
.peripheral
.iname().format(count
)
215 pname
= self
.get_iname(count
)
216 template
= " interface {0} = pinmux.peripheral_side.{1};"
217 return template
.format(pname
, sname
)
221 rule rl_connect_{0}_to_plic_{2};
222 if({1} == 1'b1) begin
223 ff_gateway_queue[{2}].enq(1);
224 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
229 axi_master_declarations
= """\
230 typedef 0 Dmem_master_num;
231 typedef 1 Imem_master_num;
233 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif ) Debug_master_num;
234 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif ) DMA_master_num;
235 typedef TAdd#(DMA_master_num,1) Num_Masters;
238 axi_fastslave_declarations
= """\
240 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
241 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
242 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
243 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
244 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
245 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
246 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
247 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
248 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
249 typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
253 axi_slave_declarations
= """\
254 typedef 0 SlowMaster;
256 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
258 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
260 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
262 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
265 pinmux_cellrule
= """\
266 rule connect_select_lines_pinmux;
272 class CallFn(object):
273 def __init__(self
, peripheral
, name
):
274 self
.peripheral
= peripheral
277 def __call__(self
, *args
):
278 #print "__call__", self.name, self.peripheral.slow, args
279 if not self
.peripheral
.slow
:
281 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
284 class PeripheralIface(object):
285 def __init__(self
, ifacename
):
287 slow
= slowfactory
.getcls(ifacename
)
288 print "Iface", ifacename
, slow
290 self
.slow
= slow(ifacename
)
291 self
.slow
.peripheral
= self
292 for fname
in ['slowimport',
293 'extfastifinstance', 'extifinstance', 'extifdecl',
294 'slowifdecl', 'slowifdeclmux',
298 'mk_plic', 'mk_ext_ifacedef',
299 'mk_connection', 'mk_cellconn', 'mk_pincon']:
300 fn
= CallFn(self
, fname
)
301 setattr(self
, fname
, types
.MethodType(fn
, self
))
303 #print "PeripheralIface"
306 def mksuffix(self
, name
, i
):
307 if self
.slow
is None:
309 return self
.slow
.mksuffix(name
, i
)
311 def axi_reg_def(self
, start
, count
):
314 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
316 def axi_master_idx(self
, start
, count
, typ
):
317 if not self
.slow
or not self
.slow
.has_axi_master():
319 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
321 def axi_slave_idx(self
, start
, count
, typ
):
324 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
326 def axi_addr_map(self
, count
):
329 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
332 class PeripheralInterfaces(object):
334 self
.fastbusmode
= False
336 def slowimport(self
, *args
):
338 for (name
, count
) in self
.ifacecount
:
339 #print "slowimport", name, self.data[name].slowimport
340 ret
.append(self
.data
[name
].slowimport())
341 return '\n'.join(list(filter(None, ret
)))
343 def extfastifinstance(self
, *args
):
345 for (name
, count
) in self
.ifacecount
:
346 for i
in range(count
):
347 iname
= self
.data
[name
].iname().format(i
)
348 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
349 if self
.is_on_fastbus(name
, i
):
351 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
352 return '\n'.join(list(filter(None, ret
)))
354 def extifinstance(self
, *args
):
356 for (name
, count
) in self
.ifacecount
:
357 for i
in range(count
):
358 iname
= self
.data
[name
].iname().format(i
)
359 if not self
.is_on_fastbus(name
, i
):
361 ret
.append(self
.data
[name
].extifinstance(name
, i
))
362 return '\n'.join(list(filter(None, ret
)))
364 def extifdecl(self
, *args
):
366 for (name
, count
) in self
.ifacecount
:
367 for i
in range(count
):
368 if not self
.is_on_fastbus(name
, i
):
370 ret
.append(self
.data
[name
].extifdecl(name
, i
))
371 return '\n'.join(list(filter(None, ret
)))
373 def slowifdeclmux(self
, *args
):
375 for (name
, count
) in self
.ifacecount
:
376 for i
in range(count
):
377 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
378 return '\n'.join(list(filter(None, ret
)))
380 def fastifdecl(self
, *args
):
382 for (name
, count
) in self
.ifacecount
:
383 for i
in range(count
):
384 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
385 if self
.is_on_fastbus(name
, i
):
387 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
388 return '\n'.join(list(filter(None, ret
)))
390 def slowifdecl(self
, *args
):
392 for (name
, count
) in self
.ifacecount
:
393 for i
in range(count
):
394 if self
.is_on_fastbus(name
, i
):
396 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
397 return '\n'.join(list(filter(None, ret
)))
399 def axi_reg_def(self
, *args
):
401 start
= 0x00011100 # start of AXI peripherals address
402 for (name
, count
) in self
.ifacecount
:
403 for i
in range(count
):
404 if self
.is_on_fastbus(name
, i
):
406 x
= self
.data
[name
].axi_reg_def(start
, i
)
407 #print ("ifc", name, x)
411 return '\n'.join(list(filter(None, ret
)))
413 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
415 for (name
, count
) in self
.ifacecount
:
416 for i
in range(count
):
417 if self
.is_on_fastbus(name
, i
):
420 fn
= self
.data
[name
].axi_master_idx
422 fn
= self
.data
[name
].axi_slave_idx
423 (rdef
, offs
) = fn(start
, i
, idxtype
)
424 #print ("ifc", name, rdef, offs)
427 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
428 decls
= '\n'.join(list(filter(None, ret
)))
429 return template
.format(decls
)
431 def axi_slave_idx(self
, *args
):
432 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
435 def axi_fastslave_idx(self
, *args
):
436 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
439 def axi_master_idx(self
, *args
):
440 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
443 def axi_fastslave_idx(self
, *args
):
444 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
447 def axi_addr_map(self
, *args
):
449 for (name
, count
) in self
.ifacecount
:
450 for i
in range(count
):
451 if self
.is_on_fastbus(name
, i
):
453 ret
.append(self
.data
[name
].axi_addr_map(i
))
454 return '\n'.join(list(filter(None, ret
)))
456 def mkfast_peripheral(self
, *args
):
458 for (name
, count
) in self
.ifacecount
:
459 for i
in range(count
):
460 if self
.is_on_fastbus(name
, i
):
462 #print "mkfast", name, count
463 x
= self
.data
[name
].mkfast_peripheral()
465 suffix
= self
.data
[name
].mksuffix(name
, i
)
466 ret
.append(x
.format(suffix
))
467 return '\n'.join(list(filter(None, ret
)))
469 def mkslow_peripheral(self
, *args
):
471 for (name
, count
) in self
.ifacecount
:
472 for i
in range(count
):
473 if self
.is_on_fastbus(name
, i
):
475 #print "mkslow", name, count
476 x
= self
.data
[name
].mkslow_peripheral()
478 suffix
= self
.data
[name
].mksuffix(name
, i
)
479 ret
.append(x
.format(suffix
))
480 return '\n'.join(list(filter(None, ret
)))
482 def mk_fast_connection(self
, *args
):
484 for (name
, count
) in self
.ifacecount
:
485 for i
in range(count
):
486 if self
.is_on_fastbus(name
, i
):
488 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
491 print self
.data
[name
].mk_connection
493 return '\n'.join(list(filter(None, ret
)))
495 def mk_connection(self
, *args
):
497 for (name
, count
) in self
.ifacecount
:
498 for i
in range(count
):
499 if self
.is_on_fastbus(name
, i
):
501 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
504 print self
.data
[name
].mk_connection
506 return '\n'.join(list(filter(None, ret
)))
508 def mk_cellconn(self
):
511 for (name
, count
) in self
.ifacecount
:
512 for i
in range(count
):
513 if self
.is_on_fastbus(name
, i
):
515 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
518 (txt
, cellcount
) = res
520 ret
= '\n'.join(list(filter(None, ret
)))
521 return pinmux_cellrule
.format(ret
)
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_pincon(name
, i
)
531 return '\n'.join(list(filter(None, ret
)))
533 def mk_ext_ifacedef(self
):
535 for (name
, count
) in self
.ifacecount
:
536 for i
in range(count
):
537 if self
.is_on_fastbus(name
, i
):
539 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
541 return '\n'.join(list(filter(None, ret
)))
545 irq_offs
= 8 # XXX: DMA scovers 0-7?
546 for (name
, count
) in self
.ifacecount
:
547 for i
in range(count
):
548 if self
.is_on_fastbus(name
, i
):
550 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
553 (txt
, irq_offs
) = res
555 self
.num_slow_irqs
= irq_offs
556 return '\n'.join(list(filter(None, ret
)))
558 def mk_sloirqsdef(self
):
559 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
561 def is_on_fastbus(self
, name
, i
):
562 #print "fastbus mode", self.fastbusmode, name, i
563 iname
= self
.data
[name
].iname().format(i
)
565 return iname
not in self
.fastbus
566 return iname
in self
.fastbus
569 class PFactory(object):
570 def getcls(self
, name
):
571 from uart
import uart
572 from quart
import quart
573 from sdmmc
import sdmmc
575 from eint
import eint
576 from rs232
import rs232
578 from eint
import eint
579 from jtag
import jtag
580 from spi
import spi
, mspi
581 from qspi
import qspi
, mqspi
582 from gpio
import gpio
583 from rgbttl
import rgbttl
585 for k
, v
in {'uart': uart
,
600 if name
.startswith(k
):
605 slowfactory
= PFactory()
607 if __name__
== '__main__':
611 i
= PeripheralIface('uart')
613 i
= PeripheralIface('gpioa')