5 def __init__(self
, name
):
8 def slowifdeclmux(self
, name
, count
):
14 def num_axi_regs32(self
):
20 def get_iname(self
, inum
):
21 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
23 def axibase(self
, name
, ifacenum
):
25 return "%(name)s%(ifacenum)dBase" % locals()
27 def axiend(self
, name
, ifacenum
):
29 return "%(name)s%(ifacenum)dEnd" % locals()
31 def axi_reg_def(self
, start
, name
, ifacenum
):
33 offs
= self
.num_axi_regs32() * 4 * 16
36 end
= start
+ offs
- 1
37 bname
= self
.axibase(name
, ifacenum
)
38 bend
= self
.axiend(name
, ifacenum
)
39 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
40 return (" `define %(bname)s 'h%(start)08X\n"
41 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
44 def axi_slave_name(self
, name
, ifacenum
):
46 return "{0}{1}_slave_num".format(name
, ifacenum
)
48 def axi_slave_idx(self
, idx
, name
, ifacenum
):
49 name
= self
.axi_slave_name(name
, ifacenum
)
50 return ("typedef {0} {1};".format(idx
, name
), 1)
52 def axi_addr_map(self
, name
, ifacenum
):
53 bname
= self
.axibase(name
, ifacenum
)
54 bend
= self
.axiend(name
, ifacenum
)
55 name
= self
.axi_slave_name(name
, ifacenum
)
57 if(addr>=`{0} && addr<=`{1})
58 return tuple2(True,fromInteger(valueOf({2})));
59 else""".format(bname
, bend
, name
)
61 def mk_pincon(self
, name
, count
):
62 # TODO: really should be using bsv.interface_decl.Interfaces
63 # pin-naming rules.... logic here is hard-coded to duplicate
64 # it (see Interface.__init__ outen)
66 for p
in self
.peripheral
.pinspecs
:
69 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
70 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
71 ret
.append(" //%s %s" % (n
, str(p
)))
72 sname
= self
.peripheral
.iname().format(count
)
73 sname
= "{0}.{1}".format(sname
, pname
)
74 ps
= "pinmux.peripheral_side.%s" % sname
75 if typ
== 'out' or typ
== 'inout':
76 fname
= self
.pinname_out(pname
)
77 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
78 n_
= "{0}{1}".format(n
, count
)
86 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
87 .format(ps_
, n_
, fname
))
90 fname
= self
.pinname_outen(pname
)
92 if isinstance(fname
, str):
93 fname
= "{0}.{1}".format(n_
, fname
)
94 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
95 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
97 if typ
== 'in' or typ
== 'inout':
98 fname
= self
.pinname_in(pname
)
104 n_
= "{0}{1}".format(n
, count
)
105 n_
= '{0}.{1}'.format(n_
, fname
)
106 n_
= self
.ifname_tweak(pname
, 'in', n_
)
107 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
108 return '\n'.join(ret
)
110 def mk_cellconn(self
, *args
):
113 def mkslow_peripheral(self
, size
=0):
116 def mksuffix(self
, name
, i
):
119 def __mk_connection(self
, con
, aname
):
120 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
121 " [fromInteger(valueOf({1}))],\n" + \
124 print "PBase __mk_connection", self
.name
, aname
127 return txt
.format(con
, aname
)
129 def mk_connection(self
, count
, name
=None):
132 print "PBase mk_conn", self
.name
, count
133 aname
= self
.axi_slave_name(name
, count
)
134 #dname = self.mksuffix(name, count)
135 #dname = "{0}{1}".format(name, dname)
136 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
137 return self
.__mk
_connection
(con
, aname
)
139 def _mk_connection(self
, name
=None, count
=0):
142 def pinname_out(self
, pname
):
145 def pinname_in(self
, pname
):
148 def pinname_outen(self
, pname
):
151 def ifname_tweak(self
, pname
, typ
, txt
):
154 def pinname_tweak(self
, pname
, typ
, txt
):
160 def mk_plic(self
, inum
, irq_offs
):
162 print "mk_plic", self
.name
, inum
, irq_offs
163 niq
= self
.num_irqs()
165 return ('', irq_offs
)
166 name
= self
.get_iname(inum
)
167 res
.append(" // PLIC rules for {0}".format(name
))
168 for idx
in range(niq
):
169 plic_obj
= self
.plic_object(name
, idx
)
170 print "plic_obj", name
, idx
, plic_obj
171 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
173 irq_offs
+= 1 # increment to next irq
174 return ('\n'.join(res
), irq_offs
)
176 def mk_ext_ifacedef(self
, iname
, inum
):
179 def extifinstance(self
, name
, count
):
180 sname
= self
.peripheral
.iname().format(count
)
181 pname
= self
.get_iname(count
)
182 template
= " interface {0} = pinmux.peripheral_side.{1};"
183 return template
.format(pname
, sname
)
188 rule rl_connect_{0}_to_plic_{2};
189 if({1} == 1'b1) begin
190 ff_gateway_queue[{2}].enq(1);
191 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
197 axi_slave_declarations
= """\
198 typedef 0 SlowMaster;
200 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
202 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
204 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
206 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
209 pinmux_cellrule
= """\
210 rule connect_select_lines_pinmux;
216 class CallFn(object):
217 def __init__(self
, peripheral
, name
):
218 self
.peripheral
= peripheral
221 def __call__(self
, *args
):
222 #print "__call__", self.name, self.peripheral.slow, args
223 if not self
.peripheral
.slow
:
225 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
228 class PeripheralIface(object):
229 def __init__(self
, ifacename
):
231 slow
= slowfactory
.getcls(ifacename
)
232 print "Iface", ifacename
, slow
234 self
.slow
= slow(ifacename
)
235 self
.slow
.peripheral
= self
236 for fname
in ['slowimport',
237 'extifinstance', 'slowifdecl', 'slowifdeclmux',
238 'mkslow_peripheral', 'mk_plic', 'mk_ext_ifacedef',
239 'mk_connection', 'mk_cellconn', 'mk_pincon']:
240 fn
= CallFn(self
, fname
)
241 setattr(self
, fname
, types
.MethodType(fn
, self
))
243 #print "PeripheralIface"
246 def mksuffix(self
, name
, i
):
247 if self
.slow
is None:
249 return self
.slow
.mksuffix(name
, i
)
251 def axi_reg_def(self
, start
, count
):
254 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
256 def axi_slave_idx(self
, start
, count
):
259 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
)
261 def axi_addr_map(self
, count
):
264 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
267 class PeripheralInterfaces(object):
271 def slowimport(self
, *args
):
273 for (name
, count
) in self
.ifacecount
:
274 #print "slowimport", name, self.data[name].slowimport
275 ret
.append(self
.data
[name
].slowimport())
276 return '\n'.join(list(filter(None, ret
)))
278 def extifinstance(self
, *args
):
280 for (name
, count
) in self
.ifacecount
:
281 for i
in range(count
):
282 ret
.append(self
.data
[name
].extifinstance(name
, i
))
283 return '\n'.join(list(filter(None, ret
)))
285 def slowifdeclmux(self
, *args
):
287 for (name
, count
) in self
.ifacecount
:
288 for i
in range(count
):
289 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
290 return '\n'.join(list(filter(None, ret
)))
292 def slowifdecl(self
, *args
):
294 for (name
, count
) in self
.ifacecount
:
295 for i
in range(count
):
296 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
297 return '\n'.join(list(filter(None, ret
)))
299 def axi_reg_def(self
, *args
):
301 start
= 0x00011100 # start of AXI peripherals address
302 for (name
, count
) in self
.ifacecount
:
303 for i
in range(count
):
304 x
= self
.data
[name
].axi_reg_def(start
, i
)
305 #print ("ifc", name, x)
309 return '\n'.join(list(filter(None, ret
)))
311 def axi_slave_idx(self
, *args
):
314 for (name
, count
) in self
.ifacecount
:
315 for i
in range(count
):
316 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
)
317 #print ("ifc", name, rdef, offs)
320 ret
.append("typedef %d LastGen_slave_num;" % (start
- 1))
321 decls
= '\n'.join(list(filter(None, ret
)))
322 return axi_slave_declarations
.format(decls
)
324 def axi_addr_map(self
, *args
):
326 for (name
, count
) in self
.ifacecount
:
327 for i
in range(count
):
328 ret
.append(self
.data
[name
].axi_addr_map(i
))
329 return '\n'.join(list(filter(None, ret
)))
331 def mkslow_peripheral(self
, *args
):
333 for (name
, count
) in self
.ifacecount
:
334 for i
in range(count
):
335 print "mkslow", name
, count
336 x
= self
.data
[name
].mkslow_peripheral()
338 suffix
= self
.data
[name
].mksuffix(name
, i
)
339 ret
.append(x
.format(suffix
))
340 return '\n'.join(list(filter(None, ret
)))
342 def mk_connection(self
, *args
):
344 for (name
, count
) in self
.ifacecount
:
345 for i
in range(count
):
346 print "mk_conn", name
, i
347 txt
= self
.data
[name
].mk_connection(i
)
350 print self
.data
[name
].mk_connection
352 return '\n'.join(list(filter(None, ret
)))
354 def mk_cellconn(self
):
357 for (name
, count
) in self
.ifacecount
:
358 for i
in range(count
):
359 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
362 (txt
, cellcount
) = res
364 ret
= '\n'.join(list(filter(None, ret
)))
365 return pinmux_cellrule
.format(ret
)
369 for (name
, count
) in self
.ifacecount
:
370 for i
in range(count
):
371 txt
= self
.data
[name
].mk_pincon(name
, i
)
373 return '\n'.join(list(filter(None, ret
)))
375 def mk_ext_ifacedef(self
):
377 for (name
, count
) in self
.ifacecount
:
378 for i
in range(count
):
379 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
381 return '\n'.join(list(filter(None, ret
)))
385 irq_offs
= 8 # XXX: DMA scovers 0-7?
386 for (name
, count
) in self
.ifacecount
:
387 for i
in range(count
):
388 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
391 (txt
, irq_offs
) = res
393 self
.num_slow_irqs
= irq_offs
394 return '\n'.join(list(filter(None, ret
)))
396 def mk_sloirqsdef(self
):
397 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
400 class PFactory(object):
401 def getcls(self
, name
):
402 from uart
import uart
403 from quart
import quart
404 from sdmmc
import sdmmc
406 from eint
import eint
407 from rs232
import rs232
409 from eint
import eint
410 from jtag
import jtag
411 from spi
import spi
, mspi
412 from qspi
import qspi
, mqspi
413 from gpio
import gpio
414 from rgbttl
import rgbttl
416 for k
, v
in {'uart': uart
,
431 if name
.startswith(k
):
436 slowfactory
= PFactory()
438 if __name__
== '__main__':
442 i
= PeripheralIface('uart')
444 i
= PeripheralIface('gpioa')