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 slowifdeclmux(self
, name
, count
):
18 def num_axi_regs32(self
):
24 def get_iname(self
, inum
):
25 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
27 def axibase(self
, name
, ifacenum
):
29 return "%(name)s%(ifacenum)dBase" % locals()
31 def axiend(self
, name
, ifacenum
):
33 return "%(name)s%(ifacenum)dEnd" % locals()
35 def axi_reg_def(self
, start
, name
, ifacenum
):
37 offs
= self
.num_axi_regs32() * 4 * 16
40 end
= start
+ offs
- 1
41 bname
= self
.axibase(name
, ifacenum
)
42 bend
= self
.axiend(name
, ifacenum
)
43 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
44 return (" `define %(bname)s 'h%(start)08X\n"
45 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
48 def axi_master_name(self
, name
, ifacenum
):
50 return "{0}{1}_laster_num".format(name
, ifacenum
)
52 def axi_slave_name(self
, name
, ifacenum
, typ
=''):
54 return "{0}{1}_{2}slave_num".format(name
, ifacenum
, typ
)
56 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
57 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
58 return ("typedef {0} {1};".format(idx
, name
), 1)
60 def axi_addr_map(self
, name
, ifacenum
):
61 bname
= self
.axibase(name
, ifacenum
)
62 bend
= self
.axiend(name
, ifacenum
)
63 name
= self
.axi_slave_name(name
, ifacenum
)
65 if(addr>=`{0} && addr<=`{1})
66 return tuple2(True,fromInteger(valueOf({2})));
67 else""".format(bname
, bend
, name
)
69 def mk_pincon(self
, name
, count
):
70 # TODO: really should be using bsv.interface_decl.Interfaces
71 # pin-naming rules.... logic here is hard-coded to duplicate
72 # it (see Interface.__init__ outen)
74 for p
in self
.peripheral
.pinspecs
:
77 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
78 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
79 ret
.append(" //%s %s" % (n
, str(p
)))
80 sname
= self
.peripheral
.iname().format(count
)
81 sname
= "{0}.{1}".format(sname
, pname
)
82 ps
= "pinmux.peripheral_side.%s" % sname
83 if typ
== 'out' or typ
== 'inout':
84 fname
= self
.pinname_out(pname
)
85 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
86 n_
= "{0}{1}".format(n
, count
)
94 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
95 .format(ps_
, n_
, fname
))
98 fname
= self
.pinname_outen(pname
)
100 if isinstance(fname
, str):
101 fname
= "{0}.{1}".format(n_
, fname
)
102 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
103 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
105 if typ
== 'in' or typ
== 'inout':
106 fname
= self
.pinname_in(pname
)
112 n_
= "{0}{1}".format(n
, count
)
113 n_
= '{0}.{1}'.format(n_
, fname
)
114 n_
= self
.ifname_tweak(pname
, 'in', n_
)
115 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
116 return '\n'.join(ret
)
118 def mk_cellconn(self
, *args
):
121 def mkfast_peripheral(self
, size
=0):
124 def mkslow_peripheral(self
, size
=0):
127 def mksuffix(self
, name
, i
):
130 def __mk_connection(self
, con
, aname
):
131 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
132 " [fromInteger(valueOf({1}))],\n" + \
135 print "PBase __mk_connection", self
.name
, aname
138 return txt
.format(con
, aname
)
140 def mk_connection(self
, count
, name
=None):
143 print "PBase mk_conn", self
.name
, count
144 aname
= self
.axi_slave_name(name
, count
)
145 #dname = self.mksuffix(name, count)
146 #dname = "{0}{1}".format(name, dname)
147 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
148 return self
.__mk
_connection
(con
, aname
)
150 def _mk_connection(self
, name
=None, count
=0):
153 def pinname_out(self
, pname
):
156 def pinname_in(self
, pname
):
159 def pinname_outen(self
, pname
):
162 def ifname_tweak(self
, pname
, typ
, txt
):
165 def pinname_tweak(self
, pname
, typ
, txt
):
171 def mk_plic(self
, inum
, irq_offs
):
173 print "mk_plic", self
.name
, inum
, irq_offs
174 niq
= self
.num_irqs()
176 return ('', irq_offs
)
177 name
= self
.get_iname(inum
)
178 res
.append(" // PLIC rules for {0}".format(name
))
179 for idx
in range(niq
):
180 plic_obj
= self
.plic_object(name
, idx
)
181 print "plic_obj", name
, idx
, plic_obj
182 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
184 irq_offs
+= 1 # increment to next irq
185 return ('\n'.join(res
), irq_offs
)
187 def mk_ext_ifacedef(self
, iname
, inum
):
190 def extifinstance(self
, name
, count
):
191 sname
= self
.peripheral
.iname().format(count
)
192 pname
= self
.get_iname(count
)
193 template
= " interface {0} = pinmux.peripheral_side.{1};"
194 return template
.format(pname
, sname
)
198 rule rl_connect_{0}_to_plic_{2};
199 if({1} == 1'b1) begin
200 ff_gateway_queue[{2}].enq(1);
201 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
207 axi_fastslave_declarations
= """\
209 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
210 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
211 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
212 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
213 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
214 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
215 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
216 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
217 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
218 typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
222 axi_slave_declarations
= """\
223 typedef 0 SlowMaster;
225 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
227 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
229 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
231 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
234 pinmux_cellrule
= """\
235 rule connect_select_lines_pinmux;
241 class CallFn(object):
242 def __init__(self
, peripheral
, name
):
243 self
.peripheral
= peripheral
246 def __call__(self
, *args
):
247 #print "__call__", self.name, self.peripheral.slow, args
248 if not self
.peripheral
.slow
:
250 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
253 class PeripheralIface(object):
254 def __init__(self
, ifacename
):
256 slow
= slowfactory
.getcls(ifacename
)
257 print "Iface", ifacename
, slow
259 self
.slow
= slow(ifacename
)
260 self
.slow
.peripheral
= self
261 for fname
in ['slowimport',
262 'extifinstance', 'extifdecl',
263 'slowifdecl', 'slowifdeclmux',
266 'mk_plic', 'mk_ext_ifacedef',
267 'mk_connection', 'mk_cellconn', 'mk_pincon']:
268 fn
= CallFn(self
, fname
)
269 setattr(self
, fname
, types
.MethodType(fn
, self
))
271 #print "PeripheralIface"
274 def mksuffix(self
, name
, i
):
275 if self
.slow
is None:
277 return self
.slow
.mksuffix(name
, i
)
279 def axi_reg_def(self
, start
, count
):
282 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
284 def axi_slave_idx(self
, start
, count
, typ
):
287 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
289 def axi_addr_map(self
, count
):
292 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
295 class PeripheralInterfaces(object):
297 self
.fastbusmode
= False
299 def slowimport(self
, *args
):
301 for (name
, count
) in self
.ifacecount
:
302 #print "slowimport", name, self.data[name].slowimport
303 ret
.append(self
.data
[name
].slowimport())
304 return '\n'.join(list(filter(None, ret
)))
306 def extifinstance(self
, *args
):
308 for (name
, count
) in self
.ifacecount
:
309 for i
in range(count
):
310 iname
= self
.data
[name
].iname().format(i
)
311 if not self
.is_on_fastbus(name
, i
):
313 ret
.append(self
.data
[name
].extifinstance(name
, i
))
314 return '\n'.join(list(filter(None, ret
)))
316 def extifdecl(self
, *args
):
318 for (name
, count
) in self
.ifacecount
:
319 for i
in range(count
):
320 if not self
.is_on_fastbus(name
, i
):
322 ret
.append(self
.data
[name
].extifdecl(name
, i
))
323 return '\n'.join(list(filter(None, ret
)))
325 def slowifdeclmux(self
, *args
):
327 for (name
, count
) in self
.ifacecount
:
328 for i
in range(count
):
329 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
330 return '\n'.join(list(filter(None, ret
)))
332 def slowifdecl(self
, *args
):
334 for (name
, count
) in self
.ifacecount
:
335 for i
in range(count
):
336 if self
.is_on_fastbus(name
, i
):
338 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
339 return '\n'.join(list(filter(None, ret
)))
341 def axi_reg_def(self
, *args
):
343 start
= 0x00011100 # start of AXI peripherals address
344 for (name
, count
) in self
.ifacecount
:
345 for i
in range(count
):
346 if self
.is_on_fastbus(name
, i
):
348 x
= self
.data
[name
].axi_reg_def(start
, i
)
349 #print ("ifc", name, x)
353 return '\n'.join(list(filter(None, ret
)))
355 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
357 for (name
, count
) in self
.ifacecount
:
358 for i
in range(count
):
359 if self
.is_on_fastbus(name
, i
):
361 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
, idxtype
)
362 #print ("ifc", name, rdef, offs)
365 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
366 decls
= '\n'.join(list(filter(None, ret
)))
367 return template
.format(decls
)
369 def axi_slave_idx(self
, *args
):
370 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
373 def axi_fastslave_idx(self
, *args
):
374 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
377 def axi_addr_map(self
, *args
):
379 for (name
, count
) in self
.ifacecount
:
380 for i
in range(count
):
381 if self
.is_on_fastbus(name
, i
):
383 ret
.append(self
.data
[name
].axi_addr_map(i
))
384 return '\n'.join(list(filter(None, ret
)))
386 def mkfast_peripheral(self
, *args
):
388 for (name
, count
) in self
.ifacecount
:
389 for i
in range(count
):
390 if self
.is_on_fastbus(name
, i
):
392 #print "mkfast", name, count
393 x
= self
.data
[name
].mkfast_peripheral()
395 suffix
= self
.data
[name
].mksuffix(name
, i
)
396 ret
.append(x
.format(suffix
))
397 return '\n'.join(list(filter(None, ret
)))
399 def mkslow_peripheral(self
, *args
):
401 for (name
, count
) in self
.ifacecount
:
402 for i
in range(count
):
403 if self
.is_on_fastbus(name
, i
):
405 #print "mkslow", name, count
406 x
= self
.data
[name
].mkslow_peripheral()
408 suffix
= self
.data
[name
].mksuffix(name
, i
)
409 ret
.append(x
.format(suffix
))
410 return '\n'.join(list(filter(None, ret
)))
412 def mk_connection(self
, *args
):
414 for (name
, count
) in self
.ifacecount
:
415 for i
in range(count
):
416 if self
.is_on_fastbus(name
, i
):
418 txt
= self
.data
[name
].mk_connection(i
)
421 print self
.data
[name
].mk_connection
423 return '\n'.join(list(filter(None, ret
)))
425 def mk_cellconn(self
):
428 for (name
, count
) in self
.ifacecount
:
429 for i
in range(count
):
430 if self
.is_on_fastbus(name
, i
):
432 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
435 (txt
, cellcount
) = res
437 ret
= '\n'.join(list(filter(None, ret
)))
438 return pinmux_cellrule
.format(ret
)
442 for (name
, count
) in self
.ifacecount
:
443 for i
in range(count
):
444 if self
.is_on_fastbus(name
, i
):
446 txt
= self
.data
[name
].mk_pincon(name
, i
)
448 return '\n'.join(list(filter(None, ret
)))
450 def mk_ext_ifacedef(self
):
452 for (name
, count
) in self
.ifacecount
:
453 for i
in range(count
):
454 if self
.is_on_fastbus(name
, i
):
456 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
458 return '\n'.join(list(filter(None, ret
)))
462 irq_offs
= 8 # XXX: DMA scovers 0-7?
463 for (name
, count
) in self
.ifacecount
:
464 for i
in range(count
):
465 if self
.is_on_fastbus(name
, i
):
467 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
470 (txt
, irq_offs
) = res
472 self
.num_slow_irqs
= irq_offs
473 return '\n'.join(list(filter(None, ret
)))
475 def mk_sloirqsdef(self
):
476 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
478 def is_on_fastbus(self
, name
, i
):
479 #print "fastbus mode", self.fastbusmode, name, i
480 iname
= self
.data
[name
].iname().format(i
)
482 return iname
not in self
.fastbus
483 return iname
in self
.fastbus
486 class PFactory(object):
487 def getcls(self
, name
):
488 from uart
import uart
489 from quart
import quart
490 from sdmmc
import sdmmc
492 from eint
import eint
493 from rs232
import rs232
495 from eint
import eint
496 from jtag
import jtag
497 from spi
import spi
, mspi
498 from qspi
import qspi
, mqspi
499 from gpio
import gpio
500 from rgbttl
import rgbttl
502 for k
, v
in {'uart': uart
,
517 if name
.startswith(k
):
522 slowfactory
= PFactory()
524 if __name__
== '__main__':
528 i
= PeripheralIface('uart')
530 i
= PeripheralIface('gpioa')