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
.iname().format(count
)
75 sname
= "{0}.{1}".format(sname
, pname
)
76 ps
= "pinmux.peripheral_side.%s" % sname
77 if typ
== 'out' or typ
== 'inout':
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(" mkConnection({0},\n\t\t\t{1}.{2});" \
89 .format(ps_
, n_
, fname
))
92 fname
= self
.pinname_outen(pname
)
94 if isinstance(fname
, str):
95 fname
= "{0}.{1}".format(n_
, fname
)
96 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
97 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"\
99 if typ
== 'in' or typ
== 'inout':
100 fname
= self
.pinname_in(pname
)
106 n_
= "{0}{1}".format(n
, count
)
107 n_
= '{0}.{1}'.format(n_
, fname
)
108 n_
= self
.ifname_tweak(pname
, 'in', n_
)
109 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
110 return '\n'.join(ret
)
112 def mk_cellconn(self
, *args
):
115 def mkslow_peripheral(self
, size
=0):
118 def mksuffix(self
, name
, i
):
121 def __mk_connection(self
, con
, aname
):
122 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
123 " [fromInteger(valueOf({1}))],\n" + \
126 print "PBase __mk_connection", self
.name
, aname
129 return txt
.format(con
, aname
)
131 def mk_connection(self
, count
, name
=None):
134 print "PBase mk_conn", self
.name
, count
135 aname
= self
.axi_slave_name(name
, count
)
136 #dname = self.mksuffix(name, count)
137 #dname = "{0}{1}".format(name, dname)
138 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
139 return self
.__mk
_connection
(con
, aname
)
141 def _mk_connection(self
, name
=None, count
=0):
144 def pinname_out(self
, pname
):
147 def pinname_in(self
, pname
):
150 def pinname_outen(self
, pname
):
153 def ifname_tweak(self
, pname
, typ
, txt
):
156 def pinname_tweak(self
, pname
, typ
, txt
):
162 def mk_plic(self
, inum
, irq_offs
):
164 print "mk_plic", self
.name
, inum
, irq_offs
165 niq
= self
.num_irqs()
167 return ('', irq_offs
)
168 name
= self
.get_iname(inum
)
169 res
.append(" // PLIC rules for {0}".format(name
))
170 for idx
in range(niq
):
171 plic_obj
= self
.plic_object(name
, idx
)
172 print "plic_obj", name
, idx
, plic_obj
173 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
175 irq_offs
+= 1 # increment to next irq
176 return ('\n'.join(res
), irq_offs
)
178 def mk_ext_ifacedef(self
, iname
, inum
):
183 rule rl_connect_{0}_to_plic_{2};
184 if({1} == 1'b1) begin
185 ff_gateway_queue[{2}].enq(1);
186 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
192 axi_slave_declarations
= """\
193 typedef 0 SlowMaster;
195 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
197 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
199 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
201 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
204 pinmux_cellrule
= """\
205 rule connect_select_lines_pinmux;
211 class CallFn(object):
212 def __init__(self
, peripheral
, name
):
213 self
.peripheral
= peripheral
216 def __call__(self
, *args
):
217 #print "__call__", self.name, self.peripheral.slow, args
218 if not self
.peripheral
.slow
:
220 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
223 class PeripheralIface(object):
224 def __init__(self
, ifacename
):
226 slow
= slowfactory
.getcls(ifacename
)
227 print "Iface", ifacename
, slow
229 self
.slow
= slow(ifacename
)
230 self
.slow
.peripheral
= self
231 for fname
in ['slowimport',
232 'slowifinstance', 'slowifdecl', 'slowifdeclmux',
233 'mkslow_peripheral', 'mk_plic', 'mk_ext_ifacedef',
234 'mk_connection', 'mk_cellconn', 'mk_pincon']:
235 fn
= CallFn(self
, fname
)
236 setattr(self
, fname
, types
.MethodType(fn
, self
))
238 #print "PeripheralIface"
241 def mksuffix(self
, name
, i
):
242 if self
.slow
is None:
244 return self
.slow
.mksuffix(name
, i
)
246 def axi_reg_def(self
, start
, count
):
249 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
251 def axi_slave_idx(self
, start
, count
):
254 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
)
256 def axi_addr_map(self
, count
):
259 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
262 class PeripheralInterfaces(object):
266 def slowimport(self
, *args
):
268 for (name
, count
) in self
.ifacecount
:
269 #print "slowimport", name, self.data[name].slowimport
270 ret
.append(self
.data
[name
].slowimport())
271 return '\n'.join(list(filter(None, ret
)))
273 def slowifinstance(self
, *args
):
275 for (name
, count
) in self
.ifacecount
:
276 #print "slowimport", name, self.data[name].slowimport
277 ret
.append(self
.data
[name
].slowifinstance())
278 return '\n'.join(list(filter(None, ret
)))
280 def slowifdeclmux(self
, *args
):
282 for (name
, count
) in self
.ifacecount
:
283 for i
in range(count
):
284 ret
.append(self
.data
[name
].slowifdeclmux().format(i
, name
))
285 return '\n'.join(list(filter(None, ret
)))
287 def slowifdecl(self
, *args
):
289 for (name
, count
) in self
.ifacecount
:
290 for i
in range(count
):
291 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
292 return '\n'.join(list(filter(None, ret
)))
294 def axi_reg_def(self
, *args
):
296 start
= 0x00011100 # start of AXI peripherals address
297 for (name
, count
) in self
.ifacecount
:
298 for i
in range(count
):
299 x
= self
.data
[name
].axi_reg_def(start
, i
)
300 #print ("ifc", name, x)
304 return '\n'.join(list(filter(None, ret
)))
306 def axi_slave_idx(self
, *args
):
309 for (name
, count
) in self
.ifacecount
:
310 for i
in range(count
):
311 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
)
312 #print ("ifc", name, rdef, offs)
315 ret
.append("typedef %d LastGen_slave_num;" % (start
- 1))
316 decls
= '\n'.join(list(filter(None, ret
)))
317 return axi_slave_declarations
.format(decls
)
319 def axi_addr_map(self
, *args
):
321 for (name
, count
) in self
.ifacecount
:
322 for i
in range(count
):
323 ret
.append(self
.data
[name
].axi_addr_map(i
))
324 return '\n'.join(list(filter(None, ret
)))
326 def mkslow_peripheral(self
, *args
):
328 for (name
, count
) in self
.ifacecount
:
329 for i
in range(count
):
330 print "mkslow", name
, count
331 x
= self
.data
[name
].mkslow_peripheral()
333 suffix
= self
.data
[name
].mksuffix(name
, i
)
334 ret
.append(x
.format(suffix
))
335 return '\n'.join(list(filter(None, ret
)))
337 def mk_connection(self
, *args
):
339 for (name
, count
) in self
.ifacecount
:
340 for i
in range(count
):
341 print "mk_conn", name
, i
342 txt
= self
.data
[name
].mk_connection(i
)
345 print self
.data
[name
].mk_connection
347 return '\n'.join(list(filter(None, ret
)))
349 def mk_cellconn(self
):
352 for (name
, count
) in self
.ifacecount
:
353 for i
in range(count
):
354 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
357 (txt
, cellcount
) = res
359 ret
= '\n'.join(list(filter(None, ret
)))
360 return pinmux_cellrule
.format(ret
)
364 for (name
, count
) in self
.ifacecount
:
365 for i
in range(count
):
366 txt
= self
.data
[name
].mk_pincon(name
, i
)
368 return '\n'.join(list(filter(None, ret
)))
370 def mk_ext_ifacedef(self
):
372 for (name
, count
) in self
.ifacecount
:
373 for i
in range(count
):
374 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
376 return '\n'.join(list(filter(None, ret
)))
381 irq_offs
= 8 # XXX: DMA scovers 0-7?
382 for (name
, count
) in self
.ifacecount
:
383 for i
in range(count
):
384 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
387 (txt
, irq_offs
) = res
389 self
.num_slow_irqs
= irq_offs
390 return '\n'.join(list(filter(None, ret
)))
392 def mk_sloirqsdef(self
):
393 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
396 class PFactory(object):
397 def getcls(self
, name
):
398 from uart
import uart
399 from quart
import quart
400 from sdmmc
import sdmmc
402 from eint
import eint
403 from rs232
import rs232
405 from eint
import eint
406 from jtag
import jtag
408 from qspi
import qspi
409 from gpio
import gpio
410 from rgbttl
import rgbttl
412 for k
, v
in {'uart': uart
,
425 if name
.startswith(k
):
429 slowfactory
= PFactory()
431 if __name__
== '__main__':
435 i
= PeripheralIface('uart')
437 i
= PeripheralIface('gpioa')