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 fastifdecl(self
, name
, count
):
18 def slowifdeclmux(self
, name
, count
):
24 def num_axi_regs32(self
):
30 def get_iname(self
, inum
):
31 return "{0}{1}".format(self
.name
, self
.mksuffix(self
.name
, inum
))
33 def axibase(self
, name
, ifacenum
):
35 return "%(name)s%(ifacenum)dBase" % locals()
37 def axiend(self
, name
, ifacenum
):
39 return "%(name)s%(ifacenum)dEnd" % locals()
41 def axi_reg_def(self
, start
, name
, ifacenum
):
43 offs
= self
.num_axi_regs32() * 4 * 16
46 end
= start
+ offs
- 1
47 bname
= self
.axibase(name
, ifacenum
)
48 bend
= self
.axiend(name
, ifacenum
)
49 comment
= "%d 32-bit regs" % self
.num_axi_regs32()
50 return (" `define %(bname)s 'h%(start)08X\n"
51 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
54 def axi_master_name(self
, name
, ifacenum
, typ
=''):
56 return "{0}{1}_master_num".format(name
, ifacenum
)
58 def axi_slave_name(self
, name
, ifacenum
, typ
=''):
60 return "{0}{1}_{2}slave_num".format(name
, ifacenum
, typ
)
62 def axi_master_idx(self
, idx
, name
, ifacenum
, typ
):
63 name
= self
.axi_master_name(name
, ifacenum
, typ
)
64 return ("typedef {0} {1};".format(idx
, name
), 1)
66 def axi_slave_idx(self
, idx
, name
, ifacenum
, typ
):
67 name
= self
.axi_slave_name(name
, ifacenum
, typ
)
68 return ("typedef {0} {1};".format(idx
, name
), 1)
70 def axi_addr_map(self
, name
, ifacenum
):
71 bname
= self
.axibase(name
, ifacenum
)
72 bend
= self
.axiend(name
, ifacenum
)
73 name
= self
.axi_slave_name(name
, ifacenum
)
75 if(addr>=`{0} && addr<=`{1})
76 return tuple2(True,fromInteger(valueOf({2})));
77 else""".format(bname
, bend
, name
)
79 def mk_pincon(self
, name
, count
):
80 # TODO: really should be using bsv.interface_decl.Interfaces
81 # pin-naming rules.... logic here is hard-coded to duplicate
82 # it (see Interface.__init__ outen)
84 for p
in self
.peripheral
.pinspecs
:
87 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
88 n
= name
# "{0}{1}".format(self.name, self.mksuffix(name, count))
89 ret
.append(" //%s %s" % (n
, str(p
)))
90 sname
= self
.peripheral
.iname().format(count
)
91 sname
= "{0}.{1}".format(sname
, pname
)
92 ps
= "pinmux.peripheral_side.%s" % sname
93 if typ
== 'out' or typ
== 'inout':
94 fname
= self
.pinname_out(pname
)
95 if not n
.startswith('gpio'): # XXX EURGH! horrible hack
96 n_
= "{0}{1}".format(n
, count
)
104 ret
.append(" mkConnection({0},\n\t\t\t{1}.{2});"
105 .format(ps_
, n_
, fname
))
108 fname
= self
.pinname_outen(pname
)
110 if isinstance(fname
, str):
111 fname
= "{0}.{1}".format(n_
, fname
)
112 fname
= self
.pinname_tweak(pname
, 'outen', fname
)
113 ret
.append(" mkConnection({0}_outen,\n\t\t\t{1});"
115 if typ
== 'in' or typ
== 'inout':
116 fname
= self
.pinname_in(pname
)
122 n_
= "{0}{1}".format(n
, count
)
123 n_
= '{0}.{1}'.format(n_
, fname
)
124 n_
= self
.ifname_tweak(pname
, 'in', n_
)
125 ret
.append(" mkConnection({1}, {0});".format(ps_
, n_
))
126 return '\n'.join(ret
)
128 def mk_cellconn(self
, *args
):
131 def mkfast_peripheral(self
, size
=0):
134 def mkslow_peripheral(self
, size
=0):
137 def mksuffix(self
, name
, i
):
140 def __mk_connection(self
, con
, aname
, fabricname
):
141 txt
= " mkConnection ({2}.v_to_slaves\n" + \
142 " [fromInteger(valueOf({1}))],\n" + \
145 print "PBase __mk_connection", self
.name
, aname
148 return txt
.format(con
, aname
, fabricname
)
150 def __mk_master_connection(self
, con
, aname
):
151 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
152 " [fromInteger(valueOf({1}))],\n" + \
155 print "PBase __mk_connection", self
.name
, aname
158 return txt
.format(con
, aname
)
160 def mk_connection(self
, count
, fabricname
, typ
, name
=None):
163 print "PBase mk_conn", self
.name
, count
164 aname
= self
.axi_slave_name(name
, count
, typ
)
165 #dname = self.mksuffix(name, count)
166 #dname = "{0}{1}".format(name, dname)
167 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
168 return self
.__mk
_connection
(con
, aname
, fabricname
)
170 def _mk_connection(self
, name
=None, count
=0):
173 def pinname_out(self
, pname
):
176 def pinname_in(self
, pname
):
179 def pinname_outen(self
, pname
):
182 def ifname_tweak(self
, pname
, typ
, txt
):
185 def pinname_tweak(self
, pname
, typ
, txt
):
191 def mk_plic(self
, inum
, irq_offs
):
193 print "mk_plic", self
.name
, inum
, irq_offs
194 niq
= self
.num_irqs()
196 return ('', irq_offs
)
197 name
= self
.get_iname(inum
)
198 res
.append(" // PLIC rules for {0}".format(name
))
199 for idx
in range(niq
):
200 plic_obj
= self
.plic_object(name
, idx
)
201 print "plic_obj", name
, idx
, plic_obj
202 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
204 irq_offs
+= 1 # increment to next irq
205 return ('\n'.join(res
), irq_offs
)
207 def mk_ext_ifacedef(self
, iname
, inum
):
210 def extfastifinstance(self
, name
, count
):
213 def _extifinstance(self
, name
, count
, suffix
, prefix
, samename
=False):
214 pname
= self
.get_iname(count
)
218 sname
= self
.peripheral
.iname().format(count
)
219 template
= " interface {0}{3} = {2}{1};"
220 return template
.format(pname
, sname
, prefix
, suffix
)
222 def extifinstance(self
, name
, count
):
223 return self
._extifinstance
(name
, count
, "",
224 "pinmux.peripheral_side.")
228 rule rl_connect_{0}_to_plic_{2};
229 if({1} == 1'b1) begin
230 ff_gateway_queue[{2}].enq(1);
231 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
236 axi_master_declarations
= """\
237 typedef 0 Dmem_master_num;
238 typedef 1 Imem_master_num;
240 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif ) Debug_master_num;
241 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif ) DMA_master_num;
242 typedef TAdd#(DMA_master_num,1) Num_Masters;
245 axi_fastslave_declarations
= """\
247 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
248 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
249 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
250 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
251 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
252 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
253 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
254 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
255 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
256 typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
260 axi_slave_declarations
= """\
261 typedef 0 SlowMaster;
263 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
265 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
267 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
269 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
272 pinmux_cellrule
= """\
273 rule connect_select_lines_pinmux;
279 class CallFn(object):
280 def __init__(self
, peripheral
, name
):
281 self
.peripheral
= peripheral
284 def __call__(self
, *args
):
285 #print "__call__", self.name, self.peripheral.slow, args
286 if not self
.peripheral
.slow
:
288 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
291 class PeripheralIface(object):
292 def __init__(self
, ifacename
):
294 slow
= slowfactory
.getcls(ifacename
)
295 print "Iface", ifacename
, slow
297 self
.slow
= slow(ifacename
)
298 self
.slow
.peripheral
= self
299 for fname
in ['slowimport',
300 'extfastifinstance', 'extifinstance', 'extifdecl',
301 'slowifdecl', 'slowifdeclmux',
305 'mk_plic', 'mk_ext_ifacedef',
306 'mk_connection', 'mk_cellconn', 'mk_pincon']:
307 fn
= CallFn(self
, fname
)
308 setattr(self
, fname
, types
.MethodType(fn
, self
))
310 #print "PeripheralIface"
313 def mksuffix(self
, name
, i
):
314 if self
.slow
is None:
316 return self
.slow
.mksuffix(name
, i
)
318 def axi_reg_def(self
, start
, count
):
321 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
323 def axi_master_idx(self
, start
, count
, typ
):
324 if not self
.slow
or not self
.slow
.has_axi_master():
326 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
328 def axi_slave_idx(self
, start
, count
, typ
):
331 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
333 def axi_addr_map(self
, count
):
336 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
339 class PeripheralInterfaces(object):
341 self
.fastbusmode
= False
343 def slowimport(self
, *args
):
345 for (name
, count
) in self
.ifacecount
:
346 #print "slowimport", name, self.data[name].slowimport
347 ret
.append(self
.data
[name
].slowimport())
348 return '\n'.join(list(filter(None, ret
)))
350 def extfastifinstance(self
, *args
):
352 for (name
, count
) in self
.ifacecount
:
353 for i
in range(count
):
354 iname
= self
.data
[name
].iname().format(i
)
355 print "extfast", iname
, self
.is_on_fastbus(name
, i
)
356 if self
.is_on_fastbus(name
, i
):
358 ret
.append(self
.data
[name
].extfastifinstance(name
, i
))
359 return '\n'.join(list(filter(None, ret
)))
361 def extifinstance(self
, *args
):
363 for (name
, count
) in self
.ifacecount
:
364 for i
in range(count
):
365 iname
= self
.data
[name
].iname().format(i
)
366 if not self
.is_on_fastbus(name
, i
):
368 ret
.append(self
.data
[name
].extifinstance(name
, i
))
369 return '\n'.join(list(filter(None, ret
)))
371 def extifdecl(self
, *args
):
373 for (name
, count
) in self
.ifacecount
:
374 for i
in range(count
):
375 if not self
.is_on_fastbus(name
, i
):
377 ret
.append(self
.data
[name
].extifdecl(name
, i
))
378 return '\n'.join(list(filter(None, ret
)))
380 def slowifdeclmux(self
, *args
):
382 for (name
, count
) in self
.ifacecount
:
383 for i
in range(count
):
384 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
385 return '\n'.join(list(filter(None, ret
)))
387 def fastifdecl(self
, *args
):
389 for (name
, count
) in self
.ifacecount
:
390 for i
in range(count
):
391 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
392 if self
.is_on_fastbus(name
, i
):
394 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
395 return '\n'.join(list(filter(None, ret
)))
397 def slowifdecl(self
, *args
):
399 for (name
, count
) in self
.ifacecount
:
400 for i
in range(count
):
401 if self
.is_on_fastbus(name
, i
):
403 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
404 return '\n'.join(list(filter(None, ret
)))
406 def axi_reg_def(self
, *args
):
408 start
= 0x00011100 # start of AXI peripherals address
409 for (name
, count
) in self
.ifacecount
:
410 for i
in range(count
):
411 if self
.is_on_fastbus(name
, i
):
413 x
= self
.data
[name
].axi_reg_def(start
, i
)
414 #print ("ifc", name, x)
418 return '\n'.join(list(filter(None, ret
)))
420 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
422 for (name
, count
) in self
.ifacecount
:
423 for i
in range(count
):
424 if self
.is_on_fastbus(name
, i
):
427 fn
= self
.data
[name
].axi_master_idx
429 fn
= self
.data
[name
].axi_slave_idx
430 (rdef
, offs
) = fn(start
, i
, idxtype
)
431 #print ("ifc", name, rdef, offs)
434 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
435 decls
= '\n'.join(list(filter(None, ret
)))
436 return template
.format(decls
)
438 def axi_slave_idx(self
, *args
):
439 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
442 def axi_fastslave_idx(self
, *args
):
443 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
446 def axi_master_idx(self
, *args
):
447 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
450 def axi_fastslave_idx(self
, *args
):
451 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
454 def axi_addr_map(self
, *args
):
456 for (name
, count
) in self
.ifacecount
:
457 for i
in range(count
):
458 if self
.is_on_fastbus(name
, i
):
460 ret
.append(self
.data
[name
].axi_addr_map(i
))
461 return '\n'.join(list(filter(None, ret
)))
463 def mkfast_peripheral(self
, *args
):
465 for (name
, count
) in self
.ifacecount
:
466 for i
in range(count
):
467 if self
.is_on_fastbus(name
, i
):
469 #print "mkfast", name, count
470 x
= self
.data
[name
].mkfast_peripheral()
472 suffix
= self
.data
[name
].mksuffix(name
, i
)
473 ret
.append(x
.format(suffix
))
474 return '\n'.join(list(filter(None, ret
)))
476 def mkslow_peripheral(self
, *args
):
478 for (name
, count
) in self
.ifacecount
:
479 for i
in range(count
):
480 if self
.is_on_fastbus(name
, i
):
482 #print "mkslow", name, count
483 x
= self
.data
[name
].mkslow_peripheral()
485 suffix
= self
.data
[name
].mksuffix(name
, i
)
486 ret
.append(x
.format(suffix
))
487 return '\n'.join(list(filter(None, ret
)))
489 def mk_fast_connection(self
, *args
):
491 for (name
, count
) in self
.ifacecount
:
492 for i
in range(count
):
493 if self
.is_on_fastbus(name
, i
):
495 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
498 print self
.data
[name
].mk_connection
500 return '\n'.join(list(filter(None, ret
)))
502 def mk_connection(self
, *args
):
504 for (name
, count
) in self
.ifacecount
:
505 for i
in range(count
):
506 if self
.is_on_fastbus(name
, i
):
508 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
511 print self
.data
[name
].mk_connection
513 return '\n'.join(list(filter(None, ret
)))
515 def mk_cellconn(self
):
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_cellconn(cellcount
, name
, i
)
525 (txt
, cellcount
) = res
527 ret
= '\n'.join(list(filter(None, ret
)))
528 return pinmux_cellrule
.format(ret
)
532 for (name
, count
) in self
.ifacecount
:
533 for i
in range(count
):
534 if self
.is_on_fastbus(name
, i
):
536 txt
= self
.data
[name
].mk_pincon(name
, i
)
538 return '\n'.join(list(filter(None, ret
)))
540 def mk_ext_ifacedef(self
):
542 for (name
, count
) in self
.ifacecount
:
543 for i
in range(count
):
544 if self
.is_on_fastbus(name
, i
):
546 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
548 return '\n'.join(list(filter(None, ret
)))
552 irq_offs
= 8 # XXX: DMA scovers 0-7?
553 for (name
, count
) in self
.ifacecount
:
554 for i
in range(count
):
555 if self
.is_on_fastbus(name
, i
):
557 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
560 (txt
, irq_offs
) = res
562 self
.num_slow_irqs
= irq_offs
563 return '\n'.join(list(filter(None, ret
)))
565 def mk_sloirqsdef(self
):
566 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
568 def is_on_fastbus(self
, name
, i
):
569 #print "fastbus mode", self.fastbusmode, name, i
570 iname
= self
.data
[name
].iname().format(i
)
572 return iname
not in self
.fastbus
573 return iname
in self
.fastbus
576 class PFactory(object):
577 def getcls(self
, name
):
578 from uart
import uart
579 from quart
import quart
580 from sdmmc
import sdmmc
582 from eint
import eint
583 from rs232
import rs232
585 from eint
import eint
586 from jtag
import jtag
587 from spi
import spi
, mspi
588 from qspi
import qspi
, mqspi
589 from gpio
import gpio
590 from rgbttl
import rgbttl
592 for k
, v
in {'uart': uart
,
607 if name
.startswith(k
):
612 slowfactory
= PFactory()
614 if __name__
== '__main__':
618 i
= PeripheralIface('uart')
620 i
= PeripheralIface('gpioa')