4 def __init__(self
, name
):
7 def slowifdeclmux(self
):
10 def slowifinstance(self
):
16 def num_axi_regs32(self
):
22 def get_iname(self
, inum
):
23 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
25 def axibase(self
, name
, ifacenum
):
27 return "%(name)s%(ifacenum)dBase" % locals()
29 def axiend(self
, name
, ifacenum
):
31 return "%(name)s%(ifacenum)dEnd" % locals()
33 def axi_reg_def(self
, start
, name
, ifacenum
):
35 offs
= self
.num_axi_regs32() * 4 * 16
38 end
= start
+ offs
- 1
39 bname
= self
.axibase(name
, ifacenum
)
40 bend
= self
.axiend(name
, ifacenum
)
41 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
42 return (" `define %(bname)s 'h%(start)08X\n"
43 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
46 def axi_slave_name(self
, name
, ifacenum
):
48 return "{0}{1}_slave_num".format(name
, ifacenum
)
50 def axi_slave_idx(self
, idx
, name
, ifacenum
):
51 name
= self
.axi_slave_name(name
, ifacenum
)
52 return ("typedef {0} {1};".format(idx
, name
), 1)
54 def axi_addr_map(self
, name
, ifacenum
):
55 bname
= self
.axibase(name
, ifacenum
)
56 bend
= self
.axiend(name
, ifacenum
)
57 name
= self
.axi_slave_name(name
, ifacenum
)
59 if(addr>=`{0} && addr<=`{1})
60 return tuple2(True,fromInteger(valueOf({2})));
61 else""".format(bname
, bend
, name
)
63 def mk_pincon(self
, name
, count
):
64 # TODO: really should be using bsv.interface_decl.Interfaces
65 # pin-naming rules.... logic here is hard-coded to duplicate
66 # it (see Interface.__init__ outen)
68 for p
in self
.peripheral
.pinspecs
:
71 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
72 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
73 ret
.append(" //%s %s" % (n
, str(p
)))
74 sname
= self
.peripheral
.pname(pname
).format(count
)
75 ps
= "pinmux.peripheral_side.%s" % sname
76 if typ
== 'out' or typ
== 'inout':
77 ret
.append(" rule con_%s%d_%s_out;" % (name
, count
, pname
))
78 fname
= self
.pinname_out(pname
)
79 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
80 n_
= "{0}{1}".format(n
, count
)
88 ret
.append(" {0}({1}.{2});".format(ps_
, n_
, fname
))
91 fname
= self
.pinname_outen(pname
)
93 if isinstance(fname
, str):
94 fname
= "{0}.{1}".format(n_
, fname
)
95 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
96 ret
.append(" {0}_outen({1});".format(ps
, fname
))
97 ret
.append(" endrule")
98 if typ
== 'in' or typ
== 'inout':
99 fname
= self
.pinname_in(pname
)
106 " rule con_%s%d_%s_in;" %
107 (name
, count
, 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(" {1}({0});".format(ps_
, n_
))
112 ret
.append(" endrule")
113 return '\n'.join(ret
)
115 def mk_cellconn(self
, *args
):
118 def mkslow_peripheral(self
, size
=0):
121 def mksuffix(self
, name
, i
):
124 def __mk_connection(self
, con
, aname
):
125 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
126 " [fromInteger(valueOf({1}))],\n" + \
129 print "PBase __mk_connection", self
.name
, aname
132 return txt
.format(con
, aname
)
134 def mk_connection(self
, count
, name
=None):
137 print "PBase mk_conn", self
.name
, count
138 aname
= self
.axi_slave_name(name
, count
)
139 #dname = self.mksuffix(name, count)
140 #dname = "{0}{1}".format(name, dname)
141 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
142 return self
.__mk
_connection
(con
, aname
)
144 def _mk_connection(self
, name
=None, count
=0):
147 def pinname_out(self
, pname
):
150 def pinname_in(self
, pname
):
153 def pinname_outen(self
, pname
):
156 def ifname_tweak(self
, pname
, typ
, txt
):
159 def pinname_tweak(self
, pname
, typ
, txt
):
165 def mk_plic(self
, inum
, irq_offs
):
167 print "mk_plic", self
.name
, inum
, irq_offs
168 niq
= self
.num_irqs()
170 return ('', irq_offs
)
171 name
= self
.get_iname(inum
)
172 res
.append(" // PLIC rules for {0}".format(name
))
173 for idx
in range(niq
):
174 plic_obj
= self
.plic_object(name
, idx
)
175 print "plic_obj", name
, idx
, plic_obj
176 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
178 irq_offs
+= 1 # increment to next irq
179 return ('\n'.join(res
), irq_offs
)
181 def mk_ext_ifacedef(self
, iname
, inum
):
186 rule rl_connect_{0}_to_plic_{2};
187 if({1} == 1'b1) begin
188 ff_gateway_queue[{2}].enq(1);
189 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
195 axi_slave_declarations
= """\
196 typedef 0 SlowMaster;
198 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
200 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
202 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
204 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
207 pinmux_cellrule
= """\
208 rule connect_select_lines_pinmux;
214 class CallFn(object):
215 def __init__(self
, peripheral
, name
):
216 self
.peripheral
= peripheral
219 def __call__(self
, *args
):
220 #print "__call__", self.name, self.peripheral.slow, args
221 if not self
.peripheral
.slow
:
223 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
226 class PeripheralIface(object):
227 def __init__(self
, ifacename
):
229 slow
= slowfactory
.getcls(ifacename
)
230 print "Iface", ifacename
, slow
232 self
.slow
= slow(ifacename
)
233 self
.slow
.peripheral
= self
234 for fname
in ['slowimport',
235 'slowifinstance', 'slowifdecl', 'slowifdeclmux',
236 'mkslow_peripheral', 'mk_plic', 'mk_ext_ifacedef',
237 'mk_connection', 'mk_cellconn', 'mk_pincon']:
238 fn
= CallFn(self
, fname
)
239 setattr(self
, fname
, types
.MethodType(fn
, self
))
241 #print "PeripheralIface"
244 def mksuffix(self
, name
, i
):
245 if self
.slow
is None:
247 return self
.slow
.mksuffix(name
, i
)
249 def axi_reg_def(self
, start
, count
):
252 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
254 def axi_slave_idx(self
, start
, count
):
257 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
)
259 def axi_addr_map(self
, count
):
262 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
265 class PeripheralInterfaces(object):
269 def slowimport(self
, *args
):
271 for (name
, count
) in self
.ifacecount
:
272 #print "slowimport", name, self.data[name].slowimport
273 ret
.append(self
.data
[name
].slowimport())
274 return '\n'.join(list(filter(None, ret
)))
276 def slowifinstance(self
, *args
):
278 for (name
, count
) in self
.ifacecount
:
279 #print "slowimport", name, self.data[name].slowimport
280 ret
.append(self
.data
[name
].slowifinstance())
281 return '\n'.join(list(filter(None, ret
)))
283 def slowifdeclmux(self
, *args
):
285 for (name
, count
) in self
.ifacecount
:
286 for i
in range(count
):
287 ret
.append(self
.data
[name
].slowifdeclmux().format(i
, name
))
288 return '\n'.join(list(filter(None, ret
)))
290 def slowifdecl(self
, *args
):
292 for (name
, count
) in self
.ifacecount
:
293 for i
in range(count
):
294 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
295 return '\n'.join(list(filter(None, ret
)))
297 def axi_reg_def(self
, *args
):
299 start
= 0x00011100 # start of AXI peripherals address
300 for (name
, count
) in self
.ifacecount
:
301 for i
in range(count
):
302 x
= self
.data
[name
].axi_reg_def(start
, i
)
303 #print ("ifc", name, x)
307 return '\n'.join(list(filter(None, ret
)))
309 def axi_slave_idx(self
, *args
):
312 for (name
, count
) in self
.ifacecount
:
313 for i
in range(count
):
314 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
)
315 #print ("ifc", name, rdef, offs)
318 ret
.append("typedef %d LastGen_slave_num;" % (start
- 1))
319 decls
= '\n'.join(list(filter(None, ret
)))
320 return axi_slave_declarations
.format(decls
)
322 def axi_addr_map(self
, *args
):
324 for (name
, count
) in self
.ifacecount
:
325 for i
in range(count
):
326 ret
.append(self
.data
[name
].axi_addr_map(i
))
327 return '\n'.join(list(filter(None, ret
)))
329 def mkslow_peripheral(self
, *args
):
331 for (name
, count
) in self
.ifacecount
:
332 for i
in range(count
):
333 print "mkslow", name
, count
334 x
= self
.data
[name
].mkslow_peripheral()
336 suffix
= self
.data
[name
].mksuffix(name
, i
)
337 ret
.append(x
.format(suffix
))
338 return '\n'.join(list(filter(None, ret
)))
340 def mk_connection(self
, *args
):
342 for (name
, count
) in self
.ifacecount
:
343 for i
in range(count
):
344 print "mk_conn", name
, i
345 txt
= self
.data
[name
].mk_connection(i
)
348 print self
.data
[name
].mk_connection
350 return '\n'.join(list(filter(None, ret
)))
352 def mk_cellconn(self
):
355 for (name
, count
) in self
.ifacecount
:
356 for i
in range(count
):
357 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
360 (txt
, cellcount
) = res
362 ret
= '\n'.join(list(filter(None, ret
)))
363 return pinmux_cellrule
.format(ret
)
367 for (name
, count
) in self
.ifacecount
:
368 for i
in range(count
):
369 txt
= self
.data
[name
].mk_pincon(name
, i
)
371 return '\n'.join(list(filter(None, ret
)))
373 def mk_ext_ifacedef(self
):
375 for (name
, count
) in self
.ifacecount
:
376 for i
in range(count
):
377 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
379 return '\n'.join(list(filter(None, ret
)))
384 irq_offs
= 8 # XXX: DMA scovers 0-7?
385 for (name
, count
) in self
.ifacecount
:
386 for i
in range(count
):
387 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
390 (txt
, irq_offs
) = res
392 self
.num_slow_irqs
= irq_offs
393 return '\n'.join(list(filter(None, ret
)))
395 def mk_sloirqsdef(self
):
396 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
399 class PFactory(object):
400 def getcls(self
, name
):
401 from uart
import uart
402 from quart
import quart
403 from sdmmc
import sdmmc
405 from eint
import eint
406 from rs232
import rs232
408 from eint
import eint
409 from jtag
import jtag
411 from qspi
import qspi
412 from gpio
import gpio
413 from rgbttl
import rgbttl
415 for k
, v
in {'uart': uart
,
428 if name
.startswith(k
):
432 slowfactory
= PFactory()
434 if __name__
== '__main__':
438 i
= PeripheralIface('uart')
440 i
= PeripheralIface('gpioa')