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
):
138 txt
= " mkConnection (slow_fabric.v_to_slaves\n" + \
139 " [fromInteger(valueOf({1}))],\n" + \
142 print "PBase __mk_connection", self
.name
, aname
145 return txt
.format(con
, aname
)
147 def mk_connection(self
, count
, name
=None):
150 print "PBase mk_conn", self
.name
, count
151 aname
= self
.axi_slave_name(name
, count
)
152 #dname = self.mksuffix(name, count)
153 #dname = "{0}{1}".format(name, dname)
154 con
= self
._mk
_connection
(name
, count
).format(count
, aname
)
155 return self
.__mk
_connection
(con
, aname
)
157 def _mk_connection(self
, name
=None, count
=0):
160 def pinname_out(self
, pname
):
163 def pinname_in(self
, pname
):
166 def pinname_outen(self
, pname
):
169 def ifname_tweak(self
, pname
, typ
, txt
):
172 def pinname_tweak(self
, pname
, typ
, txt
):
178 def mk_plic(self
, inum
, irq_offs
):
180 print "mk_plic", self
.name
, inum
, irq_offs
181 niq
= self
.num_irqs()
183 return ('', irq_offs
)
184 name
= self
.get_iname(inum
)
185 res
.append(" // PLIC rules for {0}".format(name
))
186 for idx
in range(niq
):
187 plic_obj
= self
.plic_object(name
, idx
)
188 print "plic_obj", name
, idx
, plic_obj
189 plic
= mkplic_rule
.format(name
, plic_obj
, irq_offs
)
191 irq_offs
+= 1 # increment to next irq
192 return ('\n'.join(res
), irq_offs
)
194 def mk_ext_ifacedef(self
, iname
, inum
):
197 def extifinstance(self
, name
, count
):
198 sname
= self
.peripheral
.iname().format(count
)
199 pname
= self
.get_iname(count
)
200 template
= " interface {0} = pinmux.peripheral_side.{1};"
201 return template
.format(pname
, sname
)
205 rule rl_connect_{0}_to_plic_{2};
206 if({1} == 1'b1) begin
207 ff_gateway_queue[{2}].enq(1);
208 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
213 axi_master_declarations
= """\
214 typedef 0 Dmem_master_num;
215 typedef 1 Imem_master_num;
217 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif ) Debug_master_num;
218 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif ) DMA_master_num;
219 typedef TAdd#(DMA_master_num,1) Num_Masters;
222 axi_fastslave_declarations
= """\
224 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
225 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
226 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
227 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
228 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
229 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
230 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
231 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
232 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
233 typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
237 axi_slave_declarations
= """\
238 typedef 0 SlowMaster;
240 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
242 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
244 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
246 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
249 pinmux_cellrule
= """\
250 rule connect_select_lines_pinmux;
256 class CallFn(object):
257 def __init__(self
, peripheral
, name
):
258 self
.peripheral
= peripheral
261 def __call__(self
, *args
):
262 #print "__call__", self.name, self.peripheral.slow, args
263 if not self
.peripheral
.slow
:
265 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
268 class PeripheralIface(object):
269 def __init__(self
, ifacename
):
271 slow
= slowfactory
.getcls(ifacename
)
272 print "Iface", ifacename
, slow
274 self
.slow
= slow(ifacename
)
275 self
.slow
.peripheral
= self
276 for fname
in ['slowimport',
277 'extifinstance', 'extifdecl',
278 'slowifdecl', 'slowifdeclmux',
281 'mk_plic', 'mk_ext_ifacedef',
282 'mk_connection', 'mk_cellconn', 'mk_pincon']:
283 fn
= CallFn(self
, fname
)
284 setattr(self
, fname
, types
.MethodType(fn
, self
))
286 #print "PeripheralIface"
289 def mksuffix(self
, name
, i
):
290 if self
.slow
is None:
292 return self
.slow
.mksuffix(name
, i
)
294 def axi_reg_def(self
, start
, count
):
297 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
299 def axi_master_idx(self
, start
, count
, typ
):
300 if not self
.slow
or not self
.slow
.has_axi_master():
302 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
304 def axi_slave_idx(self
, start
, count
, typ
):
307 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
309 def axi_addr_map(self
, count
):
312 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
315 class PeripheralInterfaces(object):
317 self
.fastbusmode
= False
319 def slowimport(self
, *args
):
321 for (name
, count
) in self
.ifacecount
:
322 #print "slowimport", name, self.data[name].slowimport
323 ret
.append(self
.data
[name
].slowimport())
324 return '\n'.join(list(filter(None, ret
)))
326 def extifinstance(self
, *args
):
328 for (name
, count
) in self
.ifacecount
:
329 for i
in range(count
):
330 iname
= self
.data
[name
].iname().format(i
)
331 if not self
.is_on_fastbus(name
, i
):
333 ret
.append(self
.data
[name
].extifinstance(name
, i
))
334 return '\n'.join(list(filter(None, ret
)))
336 def extifdecl(self
, *args
):
338 for (name
, count
) in self
.ifacecount
:
339 for i
in range(count
):
340 if not self
.is_on_fastbus(name
, i
):
342 ret
.append(self
.data
[name
].extifdecl(name
, i
))
343 return '\n'.join(list(filter(None, ret
)))
345 def slowifdeclmux(self
, *args
):
347 for (name
, count
) in self
.ifacecount
:
348 for i
in range(count
):
349 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
350 return '\n'.join(list(filter(None, ret
)))
352 def slowifdecl(self
, *args
):
354 for (name
, count
) in self
.ifacecount
:
355 for i
in range(count
):
356 if self
.is_on_fastbus(name
, i
):
358 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
359 return '\n'.join(list(filter(None, ret
)))
361 def axi_reg_def(self
, *args
):
363 start
= 0x00011100 # start of AXI peripherals address
364 for (name
, count
) in self
.ifacecount
:
365 for i
in range(count
):
366 if self
.is_on_fastbus(name
, i
):
368 x
= self
.data
[name
].axi_reg_def(start
, i
)
369 #print ("ifc", name, x)
373 return '\n'.join(list(filter(None, ret
)))
375 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
377 for (name
, count
) in self
.ifacecount
:
378 for i
in range(count
):
379 if self
.is_on_fastbus(name
, i
):
382 fn
= self
.data
[name
].axi_master_idx
384 fn
= self
.data
[name
].axi_slave_idx
385 (rdef
, offs
) = fn(start
, i
, idxtype
)
386 #print ("ifc", name, rdef, offs)
389 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
390 decls
= '\n'.join(list(filter(None, ret
)))
391 return template
.format(decls
)
393 def axi_slave_idx(self
, *args
):
394 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
397 def axi_fastslave_idx(self
, *args
):
398 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
401 def axi_master_idx(self
, *args
):
402 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
405 def axi_fastslave_idx(self
, *args
):
406 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
409 def axi_addr_map(self
, *args
):
411 for (name
, count
) in self
.ifacecount
:
412 for i
in range(count
):
413 if self
.is_on_fastbus(name
, i
):
415 ret
.append(self
.data
[name
].axi_addr_map(i
))
416 return '\n'.join(list(filter(None, ret
)))
418 def mkfast_peripheral(self
, *args
):
420 for (name
, count
) in self
.ifacecount
:
421 for i
in range(count
):
422 if self
.is_on_fastbus(name
, i
):
424 #print "mkfast", name, count
425 x
= self
.data
[name
].mkfast_peripheral()
427 suffix
= self
.data
[name
].mksuffix(name
, i
)
428 ret
.append(x
.format(suffix
))
429 return '\n'.join(list(filter(None, ret
)))
431 def mkslow_peripheral(self
, *args
):
433 for (name
, count
) in self
.ifacecount
:
434 for i
in range(count
):
435 if self
.is_on_fastbus(name
, i
):
437 #print "mkslow", name, count
438 x
= self
.data
[name
].mkslow_peripheral()
440 suffix
= self
.data
[name
].mksuffix(name
, i
)
441 ret
.append(x
.format(suffix
))
442 return '\n'.join(list(filter(None, ret
)))
444 def mk_connection(self
, *args
):
446 for (name
, count
) in self
.ifacecount
:
447 for i
in range(count
):
448 if self
.is_on_fastbus(name
, i
):
450 txt
= self
.data
[name
].mk_connection(i
)
453 print self
.data
[name
].mk_connection
455 return '\n'.join(list(filter(None, ret
)))
457 def mk_cellconn(self
):
460 for (name
, count
) in self
.ifacecount
:
461 for i
in range(count
):
462 if self
.is_on_fastbus(name
, i
):
464 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
467 (txt
, cellcount
) = res
469 ret
= '\n'.join(list(filter(None, ret
)))
470 return pinmux_cellrule
.format(ret
)
474 for (name
, count
) in self
.ifacecount
:
475 for i
in range(count
):
476 if self
.is_on_fastbus(name
, i
):
478 txt
= self
.data
[name
].mk_pincon(name
, i
)
480 return '\n'.join(list(filter(None, ret
)))
482 def mk_ext_ifacedef(self
):
484 for (name
, count
) in self
.ifacecount
:
485 for i
in range(count
):
486 if self
.is_on_fastbus(name
, i
):
488 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
490 return '\n'.join(list(filter(None, ret
)))
494 irq_offs
= 8 # XXX: DMA scovers 0-7?
495 for (name
, count
) in self
.ifacecount
:
496 for i
in range(count
):
497 if self
.is_on_fastbus(name
, i
):
499 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
502 (txt
, irq_offs
) = res
504 self
.num_slow_irqs
= irq_offs
505 return '\n'.join(list(filter(None, ret
)))
507 def mk_sloirqsdef(self
):
508 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
510 def is_on_fastbus(self
, name
, i
):
511 #print "fastbus mode", self.fastbusmode, name, i
512 iname
= self
.data
[name
].iname().format(i
)
514 return iname
not in self
.fastbus
515 return iname
in self
.fastbus
518 class PFactory(object):
519 def getcls(self
, name
):
520 from uart
import uart
521 from quart
import quart
522 from sdmmc
import sdmmc
524 from eint
import eint
525 from rs232
import rs232
527 from eint
import eint
528 from jtag
import jtag
529 from spi
import spi
, mspi
530 from qspi
import qspi
, mqspi
531 from gpio
import gpio
532 from rgbttl
import rgbttl
534 for k
, v
in {'uart': uart
,
549 if name
.startswith(k
):
554 slowfactory
= PFactory()
556 if __name__
== '__main__':
560 i
= PeripheralIface('uart')
562 i
= PeripheralIface('gpioa')