a595dbe23306444b58474dcb8386a4713cf9630c
5 def __init__(self
, name
):
8 def slowifdeclmux(self
, name
, count
):
11 def slowifinstance(self
, name
, count
):
17 def num_axi_regs32(self
):
23 def get_iname(self
, inum
):
24 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
26 def axibase(self
, name
, ifacenum
):
28 return "%(name)s%(ifacenum)dBase" % locals()
30 def axiend(self
, name
, ifacenum
):
32 return "%(name)s%(ifacenum)dEnd" % locals()
34 def axi_reg_def(self
, start
, name
, ifacenum
):
36 offs
= self
.num_axi_regs32() * 4 * 16
39 end
= start
+ offs
- 1
40 bname
= self
.axibase(name
, ifacenum
)
41 bend
= self
.axiend(name
, ifacenum
)
42 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
43 return (" `define %(bname)s 'h%(start)08X\n"
44 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
47 def axi_slave_name(self
, name
, ifacenum
):
49 return "{0}{1}_slave_num".format(name
, ifacenum
)
51 def axi_slave_idx(self
, idx
, name
, ifacenum
):
52 name
= self
.axi_slave_name(name
, ifacenum
)
53 return ("typedef {0} {1};".format(idx
, name
), 1)
55 def axi_addr_map(self
, name
, ifacenum
):
56 bname
= self
.axibase(name
, ifacenum
)
57 bend
= self
.axiend(name
, ifacenum
)
58 name
= self
.axi_slave_name(name
, ifacenum
)
60 if(addr>=`{0} && addr<=`{1})
61 return tuple2(True,fromInteger(valueOf({2})));
62 else""".format(bname
, bend
, name
)
64 def mk_pincon(self
, name
, count
):
65 # TODO: really should be using bsv.interface_decl.Interfaces
66 # pin-naming rules.... logic here is hard-coded to duplicate
67 # it (see Interface.__init__ outen)
69 for p
in self
.peripheral
.pinspecs
:
72 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
73 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
74 ret
.append(" //%s %s" % (n
, str(p
)))
75 sname
= self
.peripheral
.iname().format(count
)
76 sname
= "{0}.{1}".format(sname
, pname
)
77 ps
= "pinmux.peripheral_side.%s" % sname
78 if typ
== 'out' or typ
== 'inout':
79 fname
= self
.pinname_out(pname
)
80 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
81 n_
= "{0}{1}".format(n
, count
)
89 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
90 .format(ps_
, n_
, fname
))
93 fname
= self
.pinname_outen(pname
)
95 if isinstance(fname
, str):
96 fname
= "{0}.{1}".format(n_
, fname
)
97 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
98 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
100 if typ
== 'in' or typ
== 'inout':
101 fname
= self
.pinname_in(pname
)
107 n_
= "{0}{1}".format(n
, count
)
108 n_
= '{0}.{1}'.format(n_
, fname
)
109 n_
= self
.ifname_tweak(pname
, 'in', n_
)
110 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
111 return '\n'.join(ret
)
113 def mk_cellconn(self
, *args
):
116 def mkslow_peripheral(self
, size
=0):
119 def mksuffix(self
, name
, i
):
122 def __mk_connection(self
, con
, aname
):
123 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
124 " [fromInteger(valueOf({1}))],\n" + \
127 print "PBase __mk_connection", self
.name
, aname
130 return txt
.format(con
, aname
)
132 def mk_connection(self
, count
, name
=None):
135 print "PBase mk_conn", self
.name
, count
136 aname
= self
.axi_slave_name(name
, count
)
137 #dname = self.mksuffix(name, count)
138 #dname = "{0}{1}".format(name, dname)
139 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
140 return self
.__mk
_connection
(con
, aname
)
142 def _mk_connection(self
, name
=None, count
=0):
145 def pinname_out(self
, pname
):
148 def pinname_in(self
, pname
):
151 def pinname_outen(self
, pname
):
154 def ifname_tweak(self
, pname
, typ
, txt
):
157 def pinname_tweak(self
, pname
, typ
, txt
):
163 def mk_plic(self
, inum
, irq_offs
):
165 print "mk_plic", self
.name
, inum
, irq_offs
166 niq
= self
.num_irqs()
168 return ('', irq_offs
)
169 name
= self
.get_iname(inum
)
170 res
.append(" // PLIC rules for {0}".format(name
))
171 for idx
in range(niq
):
172 plic_obj
= self
.plic_object(name
, idx
)
173 print "plic_obj", name
, idx
, plic_obj
174 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
176 irq_offs
+= 1 # increment to next irq
177 return ('\n'.join(res
), irq_offs
)
179 def mk_ext_ifacedef(self
, iname
, inum
):
184 rule rl_connect_{0}_to_plic_{2};
185 if({1} == 1'b1) begin
186 ff_gateway_queue[{2}].enq(1);
187 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
193 axi_slave_declarations
= """\
194 typedef 0 SlowMaster;
196 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
198 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
200 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
202 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
205 pinmux_cellrule
= """\
206 rule connect_select_lines_pinmux;
212 class CallFn(object):
213 def __init__(self
, peripheral
, name
):
214 self
.peripheral
= peripheral
217 def __call__(self
, *args
):
218 #print "__call__", self.name, self.peripheral.slow, args
219 if not self
.peripheral
.slow
:
221 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
224 class PeripheralIface(object):
225 def __init__(self
, ifacename
):
227 slow
= slowfactory
.getcls(ifacename
)
228 print "Iface", ifacename
, slow
230 self
.slow
= slow(ifacename
)
231 self
.slow
.peripheral
= self
232 for fname
in ['slowimport',
233 'slowifinstance', 'slowifdecl', 'slowifdeclmux',
234 'mkslow_peripheral', 'mk_plic', 'mk_ext_ifacedef',
235 'mk_connection', 'mk_cellconn', 'mk_pincon']:
236 fn
= CallFn(self
, fname
)
237 setattr(self
, fname
, types
.MethodType(fn
, self
))
239 #print "PeripheralIface"
242 def mksuffix(self
, name
, i
):
243 if self
.slow
is None:
245 return self
.slow
.mksuffix(name
, i
)
247 def axi_reg_def(self
, start
, count
):
250 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
252 def axi_slave_idx(self
, start
, count
):
255 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
)
257 def axi_addr_map(self
, count
):
260 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
263 class PeripheralInterfaces(object):
267 def slowimport(self
, *args
):
269 for (name
, count
) in self
.ifacecount
:
270 #print "slowimport", name, self.data[name].slowimport
271 ret
.append(self
.data
[name
].slowimport())
272 return '\n'.join(list(filter(None, ret
)))
274 def slowifinstance(self
, *args
):
276 for (name
, count
) in self
.ifacecount
:
277 for i
in range(count
):
278 ret
.append(self
.data
[name
].slowifinstance(name
, i
))
279 return '\n'.join(list(filter(None, ret
)))
281 def slowifdeclmux(self
, *args
):
283 for (name
, count
) in self
.ifacecount
:
284 for i
in range(count
):
285 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
286 return '\n'.join(list(filter(None, ret
)))
288 def slowifdecl(self
, *args
):
290 for (name
, count
) in self
.ifacecount
:
291 for i
in range(count
):
292 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
293 return '\n'.join(list(filter(None, ret
)))
295 def axi_reg_def(self
, *args
):
297 start
= 0x00011100 # start of AXI peripherals address
298 for (name
, count
) in self
.ifacecount
:
299 for i
in range(count
):
300 x
= self
.data
[name
].axi_reg_def(start
, i
)
301 #print ("ifc", name, x)
305 return '\n'.join(list(filter(None, ret
)))
307 def axi_slave_idx(self
, *args
):
310 for (name
, count
) in self
.ifacecount
:
311 for i
in range(count
):
312 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
)
313 #print ("ifc", name, rdef, offs)
316 ret
.append("typedef %d LastGen_slave_num;" % (start
- 1))
317 decls
= '\n'.join(list(filter(None, ret
)))
318 return axi_slave_declarations
.format(decls
)
320 def axi_addr_map(self
, *args
):
322 for (name
, count
) in self
.ifacecount
:
323 for i
in range(count
):
324 ret
.append(self
.data
[name
].axi_addr_map(i
))
325 return '\n'.join(list(filter(None, ret
)))
327 def mkslow_peripheral(self
, *args
):
329 for (name
, count
) in self
.ifacecount
:
330 for i
in range(count
):
331 print "mkslow", name
, count
332 x
= self
.data
[name
].mkslow_peripheral()
334 suffix
= self
.data
[name
].mksuffix(name
, i
)
335 ret
.append(x
.format(suffix
))
336 return '\n'.join(list(filter(None, ret
)))
338 def mk_connection(self
, *args
):
340 for (name
, count
) in self
.ifacecount
:
341 for i
in range(count
):
342 print "mk_conn", name
, i
343 txt
= self
.data
[name
].mk_connection(i
)
346 print self
.data
[name
].mk_connection
348 return '\n'.join(list(filter(None, ret
)))
350 def mk_cellconn(self
):
353 for (name
, count
) in self
.ifacecount
:
354 for i
in range(count
):
355 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
358 (txt
, cellcount
) = res
360 ret
= '\n'.join(list(filter(None, ret
)))
361 return pinmux_cellrule
.format(ret
)
365 for (name
, count
) in self
.ifacecount
:
366 for i
in range(count
):
367 txt
= self
.data
[name
].mk_pincon(name
, i
)
369 return '\n'.join(list(filter(None, ret
)))
371 def mk_ext_ifacedef(self
):
373 for (name
, count
) in self
.ifacecount
:
374 for i
in range(count
):
375 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
377 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
407 from spi
import spi
, mspi
408 from qspi
import qspi
, mqspi
409 from gpio
import gpio
410 from rgbttl
import rgbttl
412 for k
, v
in {'uart': uart
,
427 if name
.startswith(k
):
432 slowfactory
= PFactory()
434 if __name__
== '__main__':
438 i
= PeripheralIface('uart')
440 i
= PeripheralIface('gpioa')