0d4384b1c25752a2a107164354b67698df37098b
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_slave_name(self
, name
, ifacenum
):
50 return "{0}{1}_slave_num".format(name
, ifacenum
)
52 def axi_slave_idx(self
, idx
, name
, ifacenum
):
53 name
= self
.axi_slave_name(name
, ifacenum
)
54 return ("typedef {0} {1};".format(idx
, name
), 1)
56 def axi_addr_map(self
, name
, ifacenum
):
57 bname
= self
.axibase(name
, ifacenum
)
58 bend
= self
.axiend(name
, ifacenum
)
59 name
= self
.axi_slave_name(name
, ifacenum
)
61 if(addr>=`{0} && addr<=`{1})
62 return tuple2(True,fromInteger(valueOf({2})));
63 else""".format(bname
, bend
, name
)
65 def mk_pincon(self
, name
, count
):
66 # TODO: really should be using bsv.interface_decl.Interfaces
67 # pin-naming rules.... logic here is hard-coded to duplicate
68 # it (see Interface.__init__ outen)
70 for p
in self
.peripheral
.pinspecs
:
73 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
74 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
75 ret
.append(" //%s %s" % (n
, str(p
)))
76 sname
= self
.peripheral
.iname().format(count
)
77 sname
= "{0}.{1}".format(sname
, pname
)
78 ps
= "pinmux.peripheral_side.%s" % sname
79 if typ
== 'out' or typ
== 'inout':
80 fname
= self
.pinname_out(pname
)
81 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
82 n_
= "{0}{1}".format(n
, count
)
90 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
91 .format(ps_
, n_
, fname
))
94 fname
= self
.pinname_outen(pname
)
96 if isinstance(fname
, str):
97 fname
= "{0}.{1}".format(n_
, fname
)
98 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
99 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
101 if typ
== 'in' or typ
== 'inout':
102 fname
= self
.pinname_in(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(" mkConnection({1}, {0});".format(ps_
, n_
))
112 return '\n'.join(ret
)
114 def mk_cellconn(self
, *args
):
117 def mkslow_peripheral(self
, size
=0):
120 def mksuffix(self
, name
, i
):
123 def __mk_connection(self
, con
, aname
):
124 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
125 " [fromInteger(valueOf({1}))],\n" + \
128 print "PBase __mk_connection", self
.name
, aname
131 return txt
.format(con
, aname
)
133 def mk_connection(self
, count
, name
=None):
136 print "PBase mk_conn", self
.name
, count
137 aname
= self
.axi_slave_name(name
, count
)
138 #dname = self.mksuffix(name, count)
139 #dname = "{0}{1}".format(name, dname)
140 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
141 return self
.__mk
_connection
(con
, aname
)
143 def _mk_connection(self
, name
=None, count
=0):
146 def pinname_out(self
, pname
):
149 def pinname_in(self
, pname
):
152 def pinname_outen(self
, pname
):
155 def ifname_tweak(self
, pname
, typ
, txt
):
158 def pinname_tweak(self
, pname
, typ
, txt
):
164 def mk_plic(self
, inum
, irq_offs
):
166 print "mk_plic", self
.name
, inum
, irq_offs
167 niq
= self
.num_irqs()
169 return ('', irq_offs
)
170 name
= self
.get_iname(inum
)
171 res
.append(" // PLIC rules for {0}".format(name
))
172 for idx
in range(niq
):
173 plic_obj
= self
.plic_object(name
, idx
)
174 print "plic_obj", name
, idx
, plic_obj
175 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
177 irq_offs
+= 1 # increment to next irq
178 return ('\n'.join(res
), irq_offs
)
180 def mk_ext_ifacedef(self
, iname
, inum
):
183 def extifinstance(self
, name
, count
):
184 sname
= self
.peripheral
.iname().format(count
)
185 pname
= self
.get_iname(count
)
186 template
= " interface {0} = pinmux.peripheral_side.{1};"
187 return template
.format(pname
, sname
)
191 rule rl_connect_{0}_to_plic_{2};
192 if({1} == 1'b1) begin
193 ff_gateway_queue[{2}].enq(1);
194 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
200 axi_slave_declarations
= """\
201 typedef 0 SlowMaster;
203 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
205 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
207 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
209 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
212 pinmux_cellrule
= """\
213 rule connect_select_lines_pinmux;
219 class CallFn(object):
220 def __init__(self
, peripheral
, name
):
221 self
.peripheral
= peripheral
224 def __call__(self
, *args
):
225 #print "__call__", self.name, self.peripheral.slow, args
226 if not self
.peripheral
.slow
:
228 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
231 class PeripheralIface(object):
232 def __init__(self
, ifacename
):
234 slow
= slowfactory
.getcls(ifacename
)
235 print "Iface", ifacename
, slow
237 self
.slow
= slow(ifacename
)
238 self
.slow
.peripheral
= self
239 for fname
in ['slowimport',
240 'extifinstance', 'extifdecl',
241 'slowifdecl', 'slowifdeclmux',
242 'mkslow_peripheral', 'mk_plic', 'mk_ext_ifacedef',
243 'mk_connection', 'mk_cellconn', 'mk_pincon']:
244 fn
= CallFn(self
, fname
)
245 setattr(self
, fname
, types
.MethodType(fn
, self
))
247 #print "PeripheralIface"
250 def mksuffix(self
, name
, i
):
251 if self
.slow
is None:
253 return self
.slow
.mksuffix(name
, i
)
255 def axi_reg_def(self
, start
, count
):
258 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
260 def axi_slave_idx(self
, start
, count
):
263 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
)
265 def axi_addr_map(self
, count
):
268 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
271 class PeripheralInterfaces(object):
275 def slowimport(self
, *args
):
277 for (name
, count
) in self
.ifacecount
:
278 #print "slowimport", name, self.data[name].slowimport
279 ret
.append(self
.data
[name
].slowimport())
280 return '\n'.join(list(filter(None, ret
)))
282 def extifinstance(self
, *args
):
284 for (name
, count
) in self
.ifacecount
:
285 for i
in range(count
):
286 iname
= self
.data
[name
].iname().format(i
)
287 if not self
.is_on_fastbus(name
, i
):
289 ret
.append(self
.data
[name
].extifinstance(name
, i
))
290 return '\n'.join(list(filter(None, ret
)))
292 def extifdecl(self
, *args
):
294 for (name
, count
) in self
.ifacecount
:
295 for i
in range(count
):
296 if not self
.is_on_fastbus(name
, i
):
298 ret
.append(self
.data
[name
].extifdecl(name
, i
))
299 return '\n'.join(list(filter(None, ret
)))
301 def slowifdeclmux(self
, *args
):
303 for (name
, count
) in self
.ifacecount
:
304 for i
in range(count
):
305 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
306 return '\n'.join(list(filter(None, ret
)))
308 def slowifdecl(self
, *args
):
310 for (name
, count
) in self
.ifacecount
:
311 for i
in range(count
):
312 if self
.is_on_fastbus(name
, i
):
314 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
315 return '\n'.join(list(filter(None, ret
)))
317 def axi_reg_def(self
, *args
):
319 start
= 0x00011100 # start of AXI peripherals address
320 for (name
, count
) in self
.ifacecount
:
321 for i
in range(count
):
322 if self
.is_on_fastbus(name
, i
):
324 x
= self
.data
[name
].axi_reg_def(start
, i
)
325 #print ("ifc", name, x)
329 return '\n'.join(list(filter(None, ret
)))
331 def axi_slave_idx(self
, *args
):
334 for (name
, count
) in self
.ifacecount
:
335 for i
in range(count
):
336 if self
.is_on_fastbus(name
, i
):
338 (rdef
, offs
) = self
.data
[name
].axi_slave_idx(start
, i
)
339 #print ("ifc", name, rdef, offs)
342 ret
.append("typedef %d LastGen_slave_num;" % (start
- 1))
343 decls
= '\n'.join(list(filter(None, ret
)))
344 return axi_slave_declarations
.format(decls
)
346 def axi_addr_map(self
, *args
):
348 for (name
, count
) in self
.ifacecount
:
349 for i
in range(count
):
350 if self
.is_on_fastbus(name
, i
):
352 ret
.append(self
.data
[name
].axi_addr_map(i
))
353 return '\n'.join(list(filter(None, ret
)))
355 def mkslow_peripheral(self
, *args
):
357 for (name
, count
) in self
.ifacecount
:
358 for i
in range(count
):
359 if self
.is_on_fastbus(name
, i
):
361 print "mkslow", name
, count
362 x
= self
.data
[name
].mkslow_peripheral()
364 suffix
= self
.data
[name
].mksuffix(name
, i
)
365 ret
.append(x
.format(suffix
))
366 return '\n'.join(list(filter(None, ret
)))
368 def mk_connection(self
, *args
):
370 for (name
, count
) in self
.ifacecount
:
371 for i
in range(count
):
372 if self
.is_on_fastbus(name
, i
):
374 txt
= self
.data
[name
].mk_connection(i
)
377 print self
.data
[name
].mk_connection
379 return '\n'.join(list(filter(None, ret
)))
381 def mk_cellconn(self
):
384 for (name
, count
) in self
.ifacecount
:
385 for i
in range(count
):
386 if self
.is_on_fastbus(name
, i
):
388 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
391 (txt
, cellcount
) = res
393 ret
= '\n'.join(list(filter(None, ret
)))
394 return pinmux_cellrule
.format(ret
)
398 for (name
, count
) in self
.ifacecount
:
399 for i
in range(count
):
400 if self
.is_on_fastbus(name
, i
):
402 txt
= self
.data
[name
].mk_pincon(name
, i
)
404 return '\n'.join(list(filter(None, ret
)))
406 def mk_ext_ifacedef(self
):
408 for (name
, count
) in self
.ifacecount
:
409 for i
in range(count
):
410 if self
.is_on_fastbus(name
, i
):
412 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
414 return '\n'.join(list(filter(None, ret
)))
418 irq_offs
= 8 # XXX: DMA scovers 0-7?
419 for (name
, count
) in self
.ifacecount
:
420 for i
in range(count
):
421 if self
.is_on_fastbus(name
, i
):
423 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
426 (txt
, irq_offs
) = res
428 self
.num_slow_irqs
= irq_offs
429 return '\n'.join(list(filter(None, ret
)))
431 def mk_sloirqsdef(self
):
432 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
434 def is_on_fastbus(self
, name
, i
):
435 iname
= self
.data
[name
].iname().format(i
)
436 return iname
in self
.fastbus
439 class PFactory(object):
440 def getcls(self
, name
):
441 from uart
import uart
442 from quart
import quart
443 from sdmmc
import sdmmc
445 from eint
import eint
446 from rs232
import rs232
448 from eint
import eint
449 from jtag
import jtag
450 from spi
import spi
, mspi
451 from qspi
import qspi
, mqspi
452 from gpio
import gpio
453 from rgbttl
import rgbttl
455 for k
, v
in {'uart': uart
,
470 if name
.startswith(k
):
475 slowfactory
= PFactory()
477 if __name__
== '__main__':
481 i
= PeripheralIface('uart')
483 i
= PeripheralIface('gpioa')