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 has_axi_master(self
):
15 def slowifdeclmux(self
, name
, count
):
21 def num_axi_regs32(self
):
27 def get_iname(self
, inum
):
28 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
30 def axibase(self
, name
, ifacenum
):
32 return "%(name)s%(ifacenum)dBase" % locals()
34 def axiend(self
, name
, ifacenum
):
36 return "%(name)s%(ifacenum)dEnd" % locals()
38 def axi_reg_def(self
, start
, name
, ifacenum
):
40 offs
= self
.num_axi_regs32() * 4 * 16
43 end
= start
+ offs
- 1
44 bname
= self
.axibase(name
, ifacenum
)
45 bend
= self
.axiend(name
, ifacenum
)
46 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
47 return (" `define %(bname)s 'h%(start)08X\n"
48 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
51 def axi_master_name(self
, name
, ifacenum
, typ
=''):
53 return "{0}{1}_master_num".format(name
, ifacenum
)
55 def axi_slave_name(self
, name
, ifacenum
, typ
=''):
57 return "{0}{1}_{2}slave_num".format(name
, ifacenum
, typ
)
59 def axi_master_idx(self
, idx
, name
, ifacenum
, typ
):
60 name
= self
.axi_master_name(name
, ifacenum
, typ
)
61 return ("typedef {0} {1};".format(idx
, name
), 1)
63 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
64 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
65 return ("typedef {0} {1};".format(idx
, name
), 1)
67 def axi_addr_map(self
, name
, ifacenum
):
68 bname
= self
.axibase(name
, ifacenum
)
69 bend
= self
.axiend(name
, ifacenum
)
70 name
= self
.axi_slave_name(name
, ifacenum
)
72 if(addr>=`{0} && addr<=`{1})
73 return tuple2(True,fromInteger(valueOf({2})));
74 else""".format(bname
, bend
, name
)
76 def mk_pincon(self
, name
, count
):
77 # TODO: really should be using bsv.interface_decl.Interfaces
78 # pin-naming rules.... logic here is hard-coded to duplicate
79 # it (see Interface.__init__ outen)
81 for p
in self
.peripheral
.pinspecs
:
84 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
85 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
86 ret
.append(" //%s %s" % (n
, str(p
)))
87 sname
= self
.peripheral
.iname().format(count
)
88 sname
= "{0}.{1}".format(sname
, pname
)
89 ps
= "pinmux.peripheral_side.%s" % sname
90 if typ
== 'out' or typ
== 'inout':
91 fname
= self
.pinname_out(pname
)
92 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
93 n_
= "{0}{1}".format(n
, count
)
101 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
102 .format(ps_
, n_
, fname
))
105 fname
= self
.pinname_outen(pname
)
107 if isinstance(fname
, str):
108 fname
= "{0}.{1}".format(n_
, fname
)
109 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
110 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
112 if typ
== 'in' or typ
== 'inout':
113 fname
= self
.pinname_in(pname
)
119 n_
= "{0}{1}".format(n
, count
)
120 n_
= '{0}.{1}'.format(n_
, fname
)
121 n_
= self
.ifname_tweak(pname
, 'in', n_
)
122 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
123 return '\n'.join(ret
)
125 def mk_cellconn(self
, *args
):
128 def mkfast_peripheral(self
, size
=0):
131 def mkslow_peripheral(self
, size
=0):
134 def mksuffix(self
, name
, i
):
137 def __mk_connection(self
, con
, aname
, fabricname
):
138 txt
= " mkConnection ({2}.v_to_slaves\n" + \
139 " [fromInteger(valueOf({1}))],\n" + \
142 print "PBase __mk_connection", self
.name
, aname
145 return txt
.format(con
, aname
, fabricname
)
147 def __mk_master_connection(self
, con
, aname
):
148 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
149 " [fromInteger(valueOf({1}))],\n" + \
152 print "PBase __mk_connection", self
.name
, aname
155 return txt
.format(con
, aname
)
157 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
160 print "PBase mk_conn", self
.name
, count
161 aname
= self
.axi_slave_name(name
, count
, typ
)
162 #dname = self.mksuffix(name, count)
163 #dname = "{0}{1}".format(name, dname)
164 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
165 return self
.__mk
_connection
(con
, aname
, fabricname
)
167 def _mk_connection(self
, name
=None, count
=0):
170 def pinname_out(self
, pname
):
173 def pinname_in(self
, pname
):
176 def pinname_outen(self
, pname
):
179 def ifname_tweak(self
, pname
, typ
, txt
):
182 def pinname_tweak(self
, pname
, typ
, txt
):
188 def mk_plic(self
, inum
, irq_offs
):
190 print "mk_plic", self
.name
, inum
, irq_offs
191 niq
= self
.num_irqs()
193 return ('', irq_offs
)
194 name
= self
.get_iname(inum
)
195 res
.append(" // PLIC rules for {0}".format(name
))
196 for idx
in range(niq
):
197 plic_obj
= self
.plic_object(name
, idx
)
198 print "plic_obj", name
, idx
, plic_obj
199 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
201 irq_offs
+= 1 # increment to next irq
202 return ('\n'.join(res
), irq_offs
)
204 def mk_ext_ifacedef(self
, iname
, inum
):
207 def extifinstance(self
, name
, count
):
208 sname
= self
.peripheral
.iname().format(count
)
209 pname
= self
.get_iname(count
)
210 template
= " interface {0} = pinmux.peripheral_side.{1};"
211 return template
.format(pname
, sname
)
215 rule rl_connect_{0}_to_plic_{2};
216 if({1} == 1'b1) begin
217 ff_gateway_queue[{2}].enq(1);
218 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
223 axi_master_declarations
= """\
224 typedef 0 Dmem_master_num;
225 typedef 1 Imem_master_num;
227 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif ) Debug_master_num;
228 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif ) DMA_master_num;
229 typedef TAdd#(DMA_master_num,1) Num_Masters;
232 axi_fastslave_declarations
= """\
234 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
235 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
236 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
237 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
238 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
239 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
240 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
241 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
242 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
243 typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
247 axi_slave_declarations
= """\
248 typedef 0 SlowMaster;
250 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
252 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
254 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
256 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
259 pinmux_cellrule
= """\
260 rule connect_select_lines_pinmux;
266 class CallFn(object):
267 def __init__(self
, peripheral
, name
):
268 self
.peripheral
= peripheral
271 def __call__(self
, *args
):
272 #print "__call__", self.name, self.peripheral.slow, args
273 if not self
.peripheral
.slow
:
275 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
278 class PeripheralIface(object):
279 def __init__(self
, ifacename
):
281 slow
= slowfactory
.getcls(ifacename
)
282 print "Iface", ifacename
, slow
284 self
.slow
= slow(ifacename
)
285 self
.slow
.peripheral
= self
286 for fname
in ['slowimport',
287 'extifinstance', 'extifdecl',
288 'slowifdecl', 'slowifdeclmux',
291 'mk_plic', 'mk_ext_ifacedef',
292 'mk_connection', 'mk_cellconn', 'mk_pincon']:
293 fn
= CallFn(self
, fname
)
294 setattr(self
, fname
, types
.MethodType(fn
, self
))
296 #print "PeripheralIface"
299 def mksuffix(self
, name
, i
):
300 if self
.slow
is None:
302 return self
.slow
.mksuffix(name
, i
)
304 def axi_reg_def(self
, start
, count
):
307 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
309 def axi_master_idx(self
, start
, count
, typ
):
310 if not self
.slow
or not self
.slow
.has_axi_master():
312 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
314 def axi_slave_idx(self
, start
, count
, typ
):
317 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
319 def axi_addr_map(self
, count
):
322 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
325 class PeripheralInterfaces(object):
327 self
.fastbusmode
= False
329 def slowimport(self
, *args
):
331 for (name
, count
) in self
.ifacecount
:
332 #print "slowimport", name, self.data[name].slowimport
333 ret
.append(self
.data
[name
].slowimport())
334 return '\n'.join(list(filter(None, ret
)))
336 def extifinstance(self
, *args
):
338 for (name
, count
) in self
.ifacecount
:
339 for i
in range(count
):
340 iname
= self
.data
[name
].iname().format(i
)
341 if not self
.is_on_fastbus(name
, i
):
343 ret
.append(self
.data
[name
].extifinstance(name
, i
))
344 return '\n'.join(list(filter(None, ret
)))
346 def extifdecl(self
, *args
):
348 for (name
, count
) in self
.ifacecount
:
349 for i
in range(count
):
350 if not self
.is_on_fastbus(name
, i
):
352 ret
.append(self
.data
[name
].extifdecl(name
, i
))
353 return '\n'.join(list(filter(None, ret
)))
355 def slowifdeclmux(self
, *args
):
357 for (name
, count
) in self
.ifacecount
:
358 for i
in range(count
):
359 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
360 return '\n'.join(list(filter(None, ret
)))
362 def slowifdecl(self
, *args
):
364 for (name
, count
) in self
.ifacecount
:
365 for i
in range(count
):
366 if self
.is_on_fastbus(name
, i
):
368 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
369 return '\n'.join(list(filter(None, ret
)))
371 def axi_reg_def(self
, *args
):
373 start
= 0x00011100 # start of AXI peripherals address
374 for (name
, count
) in self
.ifacecount
:
375 for i
in range(count
):
376 if self
.is_on_fastbus(name
, i
):
378 x
= self
.data
[name
].axi_reg_def(start
, i
)
379 #print ("ifc", name, x)
383 return '\n'.join(list(filter(None, ret
)))
385 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
387 for (name
, count
) in self
.ifacecount
:
388 for i
in range(count
):
389 if self
.is_on_fastbus(name
, i
):
392 fn
= self
.data
[name
].axi_master_idx
394 fn
= self
.data
[name
].axi_slave_idx
395 (rdef
, offs
) = fn(start
, i
, idxtype
)
396 #print ("ifc", name, rdef, offs)
399 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
400 decls
= '\n'.join(list(filter(None, ret
)))
401 return template
.format(decls
)
403 def axi_slave_idx(self
, *args
):
404 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
407 def axi_fastslave_idx(self
, *args
):
408 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
411 def axi_master_idx(self
, *args
):
412 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
415 def axi_fastslave_idx(self
, *args
):
416 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
419 def axi_addr_map(self
, *args
):
421 for (name
, count
) in self
.ifacecount
:
422 for i
in range(count
):
423 if self
.is_on_fastbus(name
, i
):
425 ret
.append(self
.data
[name
].axi_addr_map(i
))
426 return '\n'.join(list(filter(None, ret
)))
428 def mkfast_peripheral(self
, *args
):
430 for (name
, count
) in self
.ifacecount
:
431 for i
in range(count
):
432 if self
.is_on_fastbus(name
, i
):
434 #print "mkfast", name, count
435 x
= self
.data
[name
].mkfast_peripheral()
437 suffix
= self
.data
[name
].mksuffix(name
, i
)
438 ret
.append(x
.format(suffix
))
439 return '\n'.join(list(filter(None, ret
)))
441 def mkslow_peripheral(self
, *args
):
443 for (name
, count
) in self
.ifacecount
:
444 for i
in range(count
):
445 if self
.is_on_fastbus(name
, i
):
447 #print "mkslow", name, count
448 x
= self
.data
[name
].mkslow_peripheral()
450 suffix
= self
.data
[name
].mksuffix(name
, i
)
451 ret
.append(x
.format(suffix
))
452 return '\n'.join(list(filter(None, ret
)))
454 def mk_fast_connection(self
, *args
):
456 for (name
, count
) in self
.ifacecount
:
457 for i
in range(count
):
458 if self
.is_on_fastbus(name
, i
):
460 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
463 print self
.data
[name
].mk_connection
465 return '\n'.join(list(filter(None, ret
)))
467 def mk_connection(self
, *args
):
469 for (name
, count
) in self
.ifacecount
:
470 for i
in range(count
):
471 if self
.is_on_fastbus(name
, i
):
473 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
476 print self
.data
[name
].mk_connection
478 return '\n'.join(list(filter(None, ret
)))
480 def mk_cellconn(self
):
483 for (name
, count
) in self
.ifacecount
:
484 for i
in range(count
):
485 if self
.is_on_fastbus(name
, i
):
487 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
490 (txt
, cellcount
) = res
492 ret
= '\n'.join(list(filter(None, ret
)))
493 return pinmux_cellrule
.format(ret
)
497 for (name
, count
) in self
.ifacecount
:
498 for i
in range(count
):
499 if self
.is_on_fastbus(name
, i
):
501 txt
= self
.data
[name
].mk_pincon(name
, i
)
503 return '\n'.join(list(filter(None, ret
)))
505 def mk_ext_ifacedef(self
):
507 for (name
, count
) in self
.ifacecount
:
508 for i
in range(count
):
509 if self
.is_on_fastbus(name
, i
):
511 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
513 return '\n'.join(list(filter(None, ret
)))
517 irq_offs
= 8 # XXX: DMA scovers 0-7?
518 for (name
, count
) in self
.ifacecount
:
519 for i
in range(count
):
520 if self
.is_on_fastbus(name
, i
):
522 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
525 (txt
, irq_offs
) = res
527 self
.num_slow_irqs
= irq_offs
528 return '\n'.join(list(filter(None, ret
)))
530 def mk_sloirqsdef(self
):
531 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
533 def is_on_fastbus(self
, name
, i
):
534 #print "fastbus mode", self.fastbusmode, name, i
535 iname
= self
.data
[name
].iname().format(i
)
537 return iname
not in self
.fastbus
538 return iname
in self
.fastbus
541 class PFactory(object):
542 def getcls(self
, name
):
543 from uart
import uart
544 from quart
import quart
545 from sdmmc
import sdmmc
547 from eint
import eint
548 from rs232
import rs232
550 from eint
import eint
551 from jtag
import jtag
552 from spi
import spi
, mspi
553 from qspi
import qspi
, mqspi
554 from gpio
import gpio
555 from rgbttl
import rgbttl
557 for k
, v
in {'uart': uart
,
572 if name
.startswith(k
):
577 slowfactory
= PFactory()
579 if __name__
== '__main__':
583 i
= PeripheralIface('uart')
585 i
= PeripheralIface('gpioa')