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_slave_declarations
= """\
208 typedef 0 SlowMaster;
210 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
212 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
214 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
216 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
219 pinmux_cellrule
= """\
220 rule connect_select_lines_pinmux;
226 class CallFn(object):
227 def __init__(self
, peripheral
, name
):
228 self
.peripheral
= peripheral
231 def __call__(self
, *args
):
232 #print "__call__", self.name, self.peripheral.slow, args
233 if not self
.peripheral
.slow
:
235 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
238 class PeripheralIface(object):
239 def __init__(self
, ifacename
):
241 slow
= slowfactory
.getcls(ifacename
)
242 print "Iface", ifacename
, slow
244 self
.slow
= slow(ifacename
)
245 self
.slow
.peripheral
= self
246 for fname
in ['slowimport',
247 'extifinstance', 'extifdecl',
248 'slowifdecl', 'slowifdeclmux',
251 'mk_plic', 'mk_ext_ifacedef',
252 'mk_connection', 'mk_cellconn', 'mk_pincon']:
253 fn
= CallFn(self
, fname
)
254 setattr(self
, fname
, types
.MethodType(fn
, self
))
256 #print "PeripheralIface"
259 def mksuffix(self
, name
, i
):
260 if self
.slow
is None:
262 return self
.slow
.mksuffix(name
, i
)
264 def axi_reg_def(self
, start
, count
):
267 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
269 def axi_slave_idx(self
, start
, count
, typ
):
272 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
274 def axi_addr_map(self
, count
):
277 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
280 class PeripheralInterfaces(object):
282 self
.fastbusmode
= False
284 def slowimport(self
, *args
):
286 for (name
, count
) in self
.ifacecount
:
287 #print "slowimport", name, self.data[name].slowimport
288 ret
.append(self
.data
[name
].slowimport())
289 return '\n'.join(list(filter(None, ret
)))
291 def extifinstance(self
, *args
):
293 for (name
, count
) in self
.ifacecount
:
294 for i
in range(count
):
295 iname
= self
.data
[name
].iname().format(i
)
296 if not self
.is_on_fastbus(name
, i
):
298 ret
.append(self
.data
[name
].extifinstance(name
, i
))
299 return '\n'.join(list(filter(None, ret
)))
301 def extifdecl(self
, *args
):
303 for (name
, count
) in self
.ifacecount
:
304 for i
in range(count
):
305 if not self
.is_on_fastbus(name
, i
):
307 ret
.append(self
.data
[name
].extifdecl(name
, i
))
308 return '\n'.join(list(filter(None, ret
)))
310 def slowifdeclmux(self
, *args
):
312 for (name
, count
) in self
.ifacecount
:
313 for i
in range(count
):
314 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
315 return '\n'.join(list(filter(None, ret
)))
317 def slowifdecl(self
, *args
):
319 for (name
, count
) in self
.ifacecount
:
320 for i
in range(count
):
321 if self
.is_on_fastbus(name
, i
):
323 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
324 return '\n'.join(list(filter(None, ret
)))
326 def axi_reg_def(self
, *args
):
328 start
= 0x00011100 # start of AXI peripherals address
329 for (name
, count
) in self
.ifacecount
:
330 for i
in range(count
):
331 if self
.is_on_fastbus(name
, i
):
333 x
= self
.data
[name
].axi_reg_def(start
, i
)
334 #print ("ifc", name, x)
338 return '\n'.join(list(filter(None, ret
)))
340 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
342 for (name
, count
) in self
.ifacecount
:
343 for i
in range(count
):
344 if self
.is_on_fastbus(name
, i
):
346 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
, idxtype
)
347 #print ("ifc", name, rdef, offs)
350 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
351 decls
= '\n'.join(list(filter(None, ret
)))
352 return template
.format(decls
)
354 def axi_slave_idx(self
, *args
):
355 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
358 def axi_fastslave_idx(self
, *args
):
359 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
362 def axi_addr_map(self
, *args
):
364 for (name
, count
) in self
.ifacecount
:
365 for i
in range(count
):
366 if self
.is_on_fastbus(name
, i
):
368 ret
.append(self
.data
[name
].axi_addr_map(i
))
369 return '\n'.join(list(filter(None, ret
)))
371 def mkfast_peripheral(self
, *args
):
373 for (name
, count
) in self
.ifacecount
:
374 for i
in range(count
):
375 if self
.is_on_fastbus(name
, i
):
377 #print "mkfast", name, count
378 x
= self
.data
[name
].mkfast_peripheral()
380 suffix
= self
.data
[name
].mksuffix(name
, i
)
381 ret
.append(x
.format(suffix
))
382 return '\n'.join(list(filter(None, ret
)))
384 def mkslow_peripheral(self
, *args
):
386 for (name
, count
) in self
.ifacecount
:
387 for i
in range(count
):
388 if self
.is_on_fastbus(name
, i
):
390 #print "mkslow", name, count
391 x
= self
.data
[name
].mkslow_peripheral()
393 suffix
= self
.data
[name
].mksuffix(name
, i
)
394 ret
.append(x
.format(suffix
))
395 return '\n'.join(list(filter(None, ret
)))
397 def mk_connection(self
, *args
):
399 for (name
, count
) in self
.ifacecount
:
400 for i
in range(count
):
401 if self
.is_on_fastbus(name
, i
):
403 txt
= self
.data
[name
].mk_connection(i
)
406 print self
.data
[name
].mk_connection
408 return '\n'.join(list(filter(None, ret
)))
410 def mk_cellconn(self
):
413 for (name
, count
) in self
.ifacecount
:
414 for i
in range(count
):
415 if self
.is_on_fastbus(name
, i
):
417 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
420 (txt
, cellcount
) = res
422 ret
= '\n'.join(list(filter(None, ret
)))
423 return pinmux_cellrule
.format(ret
)
427 for (name
, count
) in self
.ifacecount
:
428 for i
in range(count
):
429 if self
.is_on_fastbus(name
, i
):
431 txt
= self
.data
[name
].mk_pincon(name
, i
)
433 return '\n'.join(list(filter(None, ret
)))
435 def mk_ext_ifacedef(self
):
437 for (name
, count
) in self
.ifacecount
:
438 for i
in range(count
):
439 if self
.is_on_fastbus(name
, i
):
441 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
443 return '\n'.join(list(filter(None, ret
)))
447 irq_offs
= 8 # XXX: DMA scovers 0-7?
448 for (name
, count
) in self
.ifacecount
:
449 for i
in range(count
):
450 if self
.is_on_fastbus(name
, i
):
452 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
455 (txt
, irq_offs
) = res
457 self
.num_slow_irqs
= irq_offs
458 return '\n'.join(list(filter(None, ret
)))
460 def mk_sloirqsdef(self
):
461 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
463 def is_on_fastbus(self
, name
, i
):
464 #print "fastbus mode", self.fastbusmode, name, i
465 iname
= self
.data
[name
].iname().format(i
)
467 return iname
not in self
.fastbus
468 return iname
in self
.fastbus
471 class PFactory(object):
472 def getcls(self
, name
):
473 from uart
import uart
474 from quart
import quart
475 from sdmmc
import sdmmc
477 from eint
import eint
478 from rs232
import rs232
480 from eint
import eint
481 from jtag
import jtag
482 from spi
import spi
, mspi
483 from qspi
import qspi
, mqspi
484 from gpio
import gpio
485 from rgbttl
import rgbttl
487 for k
, v
in {'uart': uart
,
502 if name
.startswith(k
):
507 slowfactory
= PFactory()
509 if __name__
== '__main__':
513 i
= PeripheralIface('uart')
515 i
= PeripheralIface('gpioa')