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_num_idx(self
, start
, template
, typ
, getfn
, *args
):
338 for (name
, count
) in self
.ifacecount
:
339 for i
in range(count
):
340 if self
.is_on_fastbus(name
, i
):
342 (rdef
, offs
) = getattr(self
.data
[name
], getfn
)(start
, i
)
343 #print ("ifc", name, rdef, offs)
346 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
347 decls
= '\n'.join(list(filter(None, ret
)))
348 return template
.format(decls
)
350 def axi_slave_idx(self
, *args
):
351 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
352 'axi_slave_idx', *args
)
354 def axi_addr_map(self
, *args
):
356 for (name
, count
) in self
.ifacecount
:
357 for i
in range(count
):
358 if self
.is_on_fastbus(name
, i
):
360 ret
.append(self
.data
[name
].axi_addr_map(i
))
361 return '\n'.join(list(filter(None, ret
)))
363 def mkfast_peripheral(self
, *args
):
365 for (name
, count
) in self
.ifacecount
:
366 for i
in range(count
):
367 if self
.is_on_fastbus(name
, i
):
369 #print "mkfast", name, count
370 x
= self
.data
[name
].mkfast_peripheral()
372 suffix
= self
.data
[name
].mksuffix(name
, i
)
373 ret
.append(x
.format(suffix
))
374 return '\n'.join(list(filter(None, ret
)))
376 def mkslow_peripheral(self
, *args
):
378 for (name
, count
) in self
.ifacecount
:
379 for i
in range(count
):
380 if self
.is_on_fastbus(name
, i
):
382 #print "mkslow", name, count
383 x
= self
.data
[name
].mkslow_peripheral()
385 suffix
= self
.data
[name
].mksuffix(name
, i
)
386 ret
.append(x
.format(suffix
))
387 return '\n'.join(list(filter(None, ret
)))
389 def mk_connection(self
, *args
):
391 for (name
, count
) in self
.ifacecount
:
392 for i
in range(count
):
393 if self
.is_on_fastbus(name
, i
):
395 txt
= self
.data
[name
].mk_connection(i
)
398 print self
.data
[name
].mk_connection
400 return '\n'.join(list(filter(None, ret
)))
402 def mk_cellconn(self
):
405 for (name
, count
) in self
.ifacecount
:
406 for i
in range(count
):
407 if self
.is_on_fastbus(name
, i
):
409 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
412 (txt
, cellcount
) = res
414 ret
= '\n'.join(list(filter(None, ret
)))
415 return pinmux_cellrule
.format(ret
)
419 for (name
, count
) in self
.ifacecount
:
420 for i
in range(count
):
421 if self
.is_on_fastbus(name
, i
):
423 txt
= self
.data
[name
].mk_pincon(name
, i
)
425 return '\n'.join(list(filter(None, ret
)))
427 def mk_ext_ifacedef(self
):
429 for (name
, count
) in self
.ifacecount
:
430 for i
in range(count
):
431 if self
.is_on_fastbus(name
, i
):
433 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
435 return '\n'.join(list(filter(None, ret
)))
439 irq_offs
= 8 # XXX: DMA scovers 0-7?
440 for (name
, count
) in self
.ifacecount
:
441 for i
in range(count
):
442 if self
.is_on_fastbus(name
, i
):
444 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
447 (txt
, irq_offs
) = res
449 self
.num_slow_irqs
= irq_offs
450 return '\n'.join(list(filter(None, ret
)))
452 def mk_sloirqsdef(self
):
453 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
455 def is_on_fastbus(self
, name
, i
):
456 #print "fastbus mode", self.fastbusmode, name, i
457 iname
= self
.data
[name
].iname().format(i
)
459 return iname
not in self
.fastbus
460 return iname
in self
.fastbus
463 class PFactory(object):
464 def getcls(self
, name
):
465 from uart
import uart
466 from quart
import quart
467 from sdmmc
import sdmmc
469 from eint
import eint
470 from rs232
import rs232
472 from eint
import eint
473 from jtag
import jtag
474 from spi
import spi
, mspi
475 from qspi
import qspi
, mqspi
476 from gpio
import gpio
477 from rgbttl
import rgbttl
479 for k
, v
in {'uart': uart
,
494 if name
.startswith(k
):
499 slowfactory
= PFactory()
501 if __name__
== '__main__':
505 i
= PeripheralIface('uart')
507 i
= PeripheralIface('gpioa')