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_slave_name(self
, name
, ifacenum
):
50 return "{0}{1}_slave_num".format(name
, ifacenum
)
52 def axi_slave_idx(self
, idx
, name
, ifacenum
):
53 name
= self
.axi_slave_name(name
, ifacenum
)
54 return ("typedef {0} {1};".format(idx
, name
), 1)
56 def axi_addr_map(self
, name
, ifacenum
):
57 bname
= self
.axibase(name
, ifacenum
)
58 bend
= self
.axiend(name
, ifacenum
)
59 name
= self
.axi_slave_name(name
, ifacenum
)
61 if(addr>=`{0} && addr<=`{1})
62 return tuple2(True,fromInteger(valueOf({2})));
63 else""".format(bname
, bend
, name
)
65 def mk_pincon(self
, name
, count
):
66 # TODO: really should be using bsv.interface_decl.Interfaces
67 # pin-naming rules.... logic here is hard-coded to duplicate
68 # it (see Interface.__init__ outen)
70 for p
in self
.peripheral
.pinspecs
:
73 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
74 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
75 ret
.append(" //%s %s" % (n
, str(p
)))
76 sname
= self
.peripheral
.iname().format(count
)
77 sname
= "{0}.{1}".format(sname
, pname
)
78 ps
= "pinmux.peripheral_side.%s" % sname
79 if typ
== 'out' or typ
== 'inout':
80 fname
= self
.pinname_out(pname
)
81 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
82 n_
= "{0}{1}".format(n
, count
)
90 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
91 .format(ps_
, n_
, fname
))
94 fname
= self
.pinname_outen(pname
)
96 if isinstance(fname
, str):
97 fname
= "{0}.{1}".format(n_
, fname
)
98 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
99 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
101 if typ
== 'in' or typ
== 'inout':
102 fname
= self
.pinname_in(pname
)
108 n_
= "{0}{1}".format(n
, count
)
109 n_
= '{0}.{1}'.format(n_
, fname
)
110 n_
= self
.ifname_tweak(pname
, 'in', n_
)
111 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
112 return '\n'.join(ret
)
114 def mk_cellconn(self
, *args
):
117 def mkfast_peripheral(self
, size
=0):
120 def mkslow_peripheral(self
, size
=0):
123 def mksuffix(self
, name
, i
):
126 def __mk_connection(self
, con
, aname
):
127 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
128 " [fromInteger(valueOf({1}))],\n" + \
131 print "PBase __mk_connection", self
.name
, aname
134 return txt
.format(con
, aname
)
136 def mk_connection(self
, count
, name
=None):
139 print "PBase mk_conn", self
.name
, count
140 aname
= self
.axi_slave_name(name
, count
)
141 #dname = self.mksuffix(name, count)
142 #dname = "{0}{1}".format(name, dname)
143 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
144 return self
.__mk
_connection
(con
, aname
)
146 def _mk_connection(self
, name
=None, count
=0):
149 def pinname_out(self
, pname
):
152 def pinname_in(self
, pname
):
155 def pinname_outen(self
, pname
):
158 def ifname_tweak(self
, pname
, typ
, txt
):
161 def pinname_tweak(self
, pname
, typ
, txt
):
167 def mk_plic(self
, inum
, irq_offs
):
169 print "mk_plic", self
.name
, inum
, irq_offs
170 niq
= self
.num_irqs()
172 return ('', irq_offs
)
173 name
= self
.get_iname(inum
)
174 res
.append(" // PLIC rules for {0}".format(name
))
175 for idx
in range(niq
):
176 plic_obj
= self
.plic_object(name
, idx
)
177 print "plic_obj", name
, idx
, plic_obj
178 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
180 irq_offs
+= 1 # increment to next irq
181 return ('\n'.join(res
), irq_offs
)
183 def mk_ext_ifacedef(self
, iname
, inum
):
186 def extifinstance(self
, name
, count
):
187 sname
= self
.peripheral
.iname().format(count
)
188 pname
= self
.get_iname(count
)
189 template
= " interface {0} = pinmux.peripheral_side.{1};"
190 return template
.format(pname
, sname
)
194 rule rl_connect_{0}_to_plic_{2};
195 if({1} == 1'b1) begin
196 ff_gateway_queue[{2}].enq(1);
197 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
203 axi_slave_declarations
= """\
204 typedef 0 SlowMaster;
206 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
208 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
210 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
212 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
215 pinmux_cellrule
= """\
216 rule connect_select_lines_pinmux;
222 class CallFn(object):
223 def __init__(self
, peripheral
, name
):
224 self
.peripheral
= peripheral
227 def __call__(self
, *args
):
228 #print "__call__", self.name, self.peripheral.slow, args
229 if not self
.peripheral
.slow
:
231 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
234 class PeripheralIface(object):
235 def __init__(self
, ifacename
):
237 slow
= slowfactory
.getcls(ifacename
)
238 print "Iface", ifacename
, slow
240 self
.slow
= slow(ifacename
)
241 self
.slow
.peripheral
= self
242 for fname
in ['slowimport',
243 'extifinstance', 'extifdecl',
244 'slowifdecl', 'slowifdeclmux',
247 'mk_plic', 'mk_ext_ifacedef',
248 'mk_connection', 'mk_cellconn', 'mk_pincon']:
249 fn
= CallFn(self
, fname
)
250 setattr(self
, fname
, types
.MethodType(fn
, self
))
252 #print "PeripheralIface"
255 def mksuffix(self
, name
, i
):
256 if self
.slow
is None:
258 return self
.slow
.mksuffix(name
, i
)
260 def axi_reg_def(self
, start
, count
):
263 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
265 def axi_slave_idx(self
, start
, count
):
268 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
)
270 def axi_addr_map(self
, count
):
273 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
276 class PeripheralInterfaces(object):
278 self
.fastbusmode
= False
280 def slowimport(self
, *args
):
282 for (name
, count
) in self
.ifacecount
:
283 #print "slowimport", name, self.data[name].slowimport
284 ret
.append(self
.data
[name
].slowimport())
285 return '\n'.join(list(filter(None, ret
)))
287 def extifinstance(self
, *args
):
289 for (name
, count
) in self
.ifacecount
:
290 for i
in range(count
):
291 iname
= self
.data
[name
].iname().format(i
)
292 if not self
.is_on_fastbus(name
, i
):
294 ret
.append(self
.data
[name
].extifinstance(name
, i
))
295 return '\n'.join(list(filter(None, ret
)))
297 def extifdecl(self
, *args
):
299 for (name
, count
) in self
.ifacecount
:
300 for i
in range(count
):
301 if not self
.is_on_fastbus(name
, i
):
303 ret
.append(self
.data
[name
].extifdecl(name
, i
))
304 return '\n'.join(list(filter(None, ret
)))
306 def slowifdeclmux(self
, *args
):
308 for (name
, count
) in self
.ifacecount
:
309 for i
in range(count
):
310 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
311 return '\n'.join(list(filter(None, ret
)))
313 def slowifdecl(self
, *args
):
315 for (name
, count
) in self
.ifacecount
:
316 for i
in range(count
):
317 if self
.is_on_fastbus(name
, i
):
319 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
320 return '\n'.join(list(filter(None, ret
)))
322 def axi_reg_def(self
, *args
):
324 start
= 0x00011100 # start of AXI peripherals address
325 for (name
, count
) in self
.ifacecount
:
326 for i
in range(count
):
327 if self
.is_on_fastbus(name
, i
):
329 x
= self
.data
[name
].axi_reg_def(start
, i
)
330 #print ("ifc", name, x)
334 return '\n'.join(list(filter(None, ret
)))
336 def axi_slave_idx(self
, *args
):
339 for (name
, count
) in self
.ifacecount
:
340 for i
in range(count
):
341 if self
.is_on_fastbus(name
, i
):
343 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
)
344 #print ("ifc", name, rdef, offs)
347 ret
.append("typedef %d LastGen_slave_num;" % (start
- 1))
348 decls
= '\n'.join(list(filter(None, ret
)))
349 return axi_slave_declarations
.format(decls
)
351 def axi_addr_map(self
, *args
):
353 for (name
, count
) in self
.ifacecount
:
354 for i
in range(count
):
355 if self
.is_on_fastbus(name
, i
):
357 ret
.append(self
.data
[name
].axi_addr_map(i
))
358 return '\n'.join(list(filter(None, ret
)))
360 def mkfast_peripheral(self
, *args
):
362 for (name
, count
) in self
.ifacecount
:
363 for i
in range(count
):
364 if self
.is_on_fastbus(name
, i
):
366 #print "mkfast", name, count
367 x
= self
.data
[name
].mkfast_peripheral()
369 suffix
= self
.data
[name
].mksuffix(name
, i
)
370 ret
.append(x
.format(suffix
))
371 return '\n'.join(list(filter(None, ret
)))
373 def mkslow_peripheral(self
, *args
):
375 for (name
, count
) in self
.ifacecount
:
376 for i
in range(count
):
377 if self
.is_on_fastbus(name
, i
):
379 #print "mkslow", name, count
380 x
= self
.data
[name
].mkslow_peripheral()
382 suffix
= self
.data
[name
].mksuffix(name
, i
)
383 ret
.append(x
.format(suffix
))
384 return '\n'.join(list(filter(None, ret
)))
386 def mk_connection(self
, *args
):
388 for (name
, count
) in self
.ifacecount
:
389 for i
in range(count
):
390 if self
.is_on_fastbus(name
, i
):
392 txt
= self
.data
[name
].mk_connection(i
)
395 print self
.data
[name
].mk_connection
397 return '\n'.join(list(filter(None, ret
)))
399 def mk_cellconn(self
):
402 for (name
, count
) in self
.ifacecount
:
403 for i
in range(count
):
404 if self
.is_on_fastbus(name
, i
):
406 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
409 (txt
, cellcount
) = res
411 ret
= '\n'.join(list(filter(None, ret
)))
412 return pinmux_cellrule
.format(ret
)
416 for (name
, count
) in self
.ifacecount
:
417 for i
in range(count
):
418 if self
.is_on_fastbus(name
, i
):
420 txt
= self
.data
[name
].mk_pincon(name
, i
)
422 return '\n'.join(list(filter(None, ret
)))
424 def mk_ext_ifacedef(self
):
426 for (name
, count
) in self
.ifacecount
:
427 for i
in range(count
):
428 if self
.is_on_fastbus(name
, i
):
430 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
432 return '\n'.join(list(filter(None, ret
)))
436 irq_offs
= 8 # XXX: DMA scovers 0-7?
437 for (name
, count
) in self
.ifacecount
:
438 for i
in range(count
):
439 if self
.is_on_fastbus(name
, i
):
441 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
444 (txt
, irq_offs
) = res
446 self
.num_slow_irqs
= irq_offs
447 return '\n'.join(list(filter(None, ret
)))
449 def mk_sloirqsdef(self
):
450 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
452 def is_on_fastbus(self
, name
, i
):
453 #print "fastbus mode", self.fastbusmode, name, i
454 iname
= self
.data
[name
].iname().format(i
)
456 return iname
not in self
.fastbus
457 return iname
in self
.fastbus
460 class PFactory(object):
461 def getcls(self
, name
):
462 from uart
import uart
463 from quart
import quart
464 from sdmmc
import sdmmc
466 from eint
import eint
467 from rs232
import rs232
469 from eint
import eint
470 from jtag
import jtag
471 from spi
import spi
, mspi
472 from qspi
import qspi
, mqspi
473 from gpio
import gpio
474 from rgbttl
import rgbttl
476 for k
, v
in {'uart': uart
,
491 if name
.startswith(k
):
496 slowfactory
= PFactory()
498 if __name__
== '__main__':
502 i
= PeripheralIface('uart')
504 i
= PeripheralIface('gpioa')