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 extifinstance(self
, name
, count
):
211 sname
= self
.peripheral
.iname().format(count
)
212 pname
= self
.get_iname(count
)
213 template
= " interface {0} = pinmux.peripheral_side.{1};"
214 return template
.format(pname
, sname
)
218 rule rl_connect_{0}_to_plic_{2};
219 if({1} == 1'b1) begin
220 ff_gateway_queue[{2}].enq(1);
221 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
226 axi_master_declarations
= """\
227 typedef 0 Dmem_master_num;
228 typedef 1 Imem_master_num;
230 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif ) Debug_master_num;
231 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif ) DMA_master_num;
232 typedef TAdd#(DMA_master_num,1) Num_Masters;
235 axi_fastslave_declarations
= """\
237 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
238 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
239 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
240 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
241 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
242 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
243 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
244 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
245 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
246 typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
250 axi_slave_declarations
= """\
251 typedef 0 SlowMaster;
253 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
255 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
257 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
259 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
262 pinmux_cellrule
= """\
263 rule connect_select_lines_pinmux;
269 class CallFn(object):
270 def __init__(self
, peripheral
, name
):
271 self
.peripheral
= peripheral
274 def __call__(self
, *args
):
275 #print "__call__", self.name, self.peripheral.slow, args
276 if not self
.peripheral
.slow
:
278 return getattr(self
.peripheral
.slow
, self
.name
)(*args
[1:])
281 class PeripheralIface(object):
282 def __init__(self
, ifacename
):
284 slow
= slowfactory
.getcls(ifacename
)
285 print "Iface", ifacename
, slow
287 self
.slow
= slow(ifacename
)
288 self
.slow
.peripheral
= self
289 for fname
in ['slowimport',
290 'extifinstance', 'extifdecl',
291 'slowifdecl', 'slowifdeclmux',
295 'mk_plic', 'mk_ext_ifacedef',
296 'mk_connection', 'mk_cellconn', 'mk_pincon']:
297 fn
= CallFn(self
, fname
)
298 setattr(self
, fname
, types
.MethodType(fn
, self
))
300 #print "PeripheralIface"
303 def mksuffix(self
, name
, i
):
304 if self
.slow
is None:
306 return self
.slow
.mksuffix(name
, i
)
308 def axi_reg_def(self
, start
, count
):
311 return self
.slow
.axi_reg_def(start
, self
.ifacename
, count
)
313 def axi_master_idx(self
, start
, count
, typ
):
314 if not self
.slow
or not self
.slow
.has_axi_master():
316 return self
.slow
.axi_master_idx(start
, self
.ifacename
, count
, typ
)
318 def axi_slave_idx(self
, start
, count
, typ
):
321 return self
.slow
.axi_slave_idx(start
, self
.ifacename
, count
, typ
)
323 def axi_addr_map(self
, count
):
326 return self
.slow
.axi_addr_map(self
.ifacename
, count
)
329 class PeripheralInterfaces(object):
331 self
.fastbusmode
= False
333 def slowimport(self
, *args
):
335 for (name
, count
) in self
.ifacecount
:
336 #print "slowimport", name, self.data[name].slowimport
337 ret
.append(self
.data
[name
].slowimport())
338 return '\n'.join(list(filter(None, ret
)))
340 def extifinstance(self
, *args
):
342 for (name
, count
) in self
.ifacecount
:
343 for i
in range(count
):
344 iname
= self
.data
[name
].iname().format(i
)
345 if not self
.is_on_fastbus(name
, i
):
347 ret
.append(self
.data
[name
].extifinstance(name
, i
))
348 return '\n'.join(list(filter(None, ret
)))
350 def extifdecl(self
, *args
):
352 for (name
, count
) in self
.ifacecount
:
353 for i
in range(count
):
354 if not self
.is_on_fastbus(name
, i
):
356 ret
.append(self
.data
[name
].extifdecl(name
, i
))
357 return '\n'.join(list(filter(None, ret
)))
359 def slowifdeclmux(self
, *args
):
361 for (name
, count
) in self
.ifacecount
:
362 for i
in range(count
):
363 ret
.append(self
.data
[name
].slowifdeclmux(name
, i
))
364 return '\n'.join(list(filter(None, ret
)))
366 def fastifdecl(self
, *args
):
368 for (name
, count
) in self
.ifacecount
:
369 for i
in range(count
):
370 print "fastifdecl", name
, i
, self
.is_on_fastbus(name
, i
)
371 if self
.is_on_fastbus(name
, i
):
373 ret
.append(self
.data
[name
].fastifdecl(name
, i
))
374 return '\n'.join(list(filter(None, ret
)))
376 def slowifdecl(self
, *args
):
378 for (name
, count
) in self
.ifacecount
:
379 for i
in range(count
):
380 if self
.is_on_fastbus(name
, i
):
382 ret
.append(self
.data
[name
].slowifdecl().format(i
, name
))
383 return '\n'.join(list(filter(None, ret
)))
385 def axi_reg_def(self
, *args
):
387 start
= 0x00011100 # start of AXI peripherals address
388 for (name
, count
) in self
.ifacecount
:
389 for i
in range(count
):
390 if self
.is_on_fastbus(name
, i
):
392 x
= self
.data
[name
].axi_reg_def(start
, i
)
393 #print ("ifc", name, x)
397 return '\n'.join(list(filter(None, ret
)))
399 def _axi_num_idx(self
, start
, template
, typ
, idxtype
, *args
):
401 for (name
, count
) in self
.ifacecount
:
402 for i
in range(count
):
403 if self
.is_on_fastbus(name
, i
):
406 fn
= self
.data
[name
].axi_master_idx
408 fn
= self
.data
[name
].axi_slave_idx
409 (rdef
, offs
) = fn(start
, i
, idxtype
)
410 #print ("ifc", name, rdef, offs)
413 ret
.append("typedef %d LastGen_%s_num;" % (start
- 1, typ
))
414 decls
= '\n'.join(list(filter(None, ret
)))
415 return template
.format(decls
)
417 def axi_slave_idx(self
, *args
):
418 return self
._axi
_num
_idx
(0, axi_slave_declarations
, 'slave',
421 def axi_fastslave_idx(self
, *args
):
422 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
425 def axi_master_idx(self
, *args
):
426 return self
._axi
_num
_idx
(2, axi_master_declarations
, 'master',
429 def axi_fastslave_idx(self
, *args
):
430 return self
._axi
_num
_idx
(0, axi_fastslave_declarations
, 'fastslave',
433 def axi_addr_map(self
, *args
):
435 for (name
, count
) in self
.ifacecount
:
436 for i
in range(count
):
437 if self
.is_on_fastbus(name
, i
):
439 ret
.append(self
.data
[name
].axi_addr_map(i
))
440 return '\n'.join(list(filter(None, ret
)))
442 def mkfast_peripheral(self
, *args
):
444 for (name
, count
) in self
.ifacecount
:
445 for i
in range(count
):
446 if self
.is_on_fastbus(name
, i
):
448 #print "mkfast", name, count
449 x
= self
.data
[name
].mkfast_peripheral()
451 suffix
= self
.data
[name
].mksuffix(name
, i
)
452 ret
.append(x
.format(suffix
))
453 return '\n'.join(list(filter(None, ret
)))
455 def mkslow_peripheral(self
, *args
):
457 for (name
, count
) in self
.ifacecount
:
458 for i
in range(count
):
459 if self
.is_on_fastbus(name
, i
):
461 #print "mkslow", name, count
462 x
= self
.data
[name
].mkslow_peripheral()
464 suffix
= self
.data
[name
].mksuffix(name
, i
)
465 ret
.append(x
.format(suffix
))
466 return '\n'.join(list(filter(None, ret
)))
468 def mk_fast_connection(self
, *args
):
470 for (name
, count
) in self
.ifacecount
:
471 for i
in range(count
):
472 if self
.is_on_fastbus(name
, i
):
474 txt
= self
.data
[name
].mk_connection(i
, "fabric", "fast")
477 print self
.data
[name
].mk_connection
479 return '\n'.join(list(filter(None, ret
)))
481 def mk_connection(self
, *args
):
483 for (name
, count
) in self
.ifacecount
:
484 for i
in range(count
):
485 if self
.is_on_fastbus(name
, i
):
487 txt
= self
.data
[name
].mk_connection(i
, "slow_fabric", "")
490 print self
.data
[name
].mk_connection
492 return '\n'.join(list(filter(None, ret
)))
494 def mk_cellconn(self
):
497 for (name
, count
) in self
.ifacecount
:
498 for i
in range(count
):
499 if self
.is_on_fastbus(name
, i
):
501 res
= self
.data
[name
].mk_cellconn(cellcount
, name
, i
)
504 (txt
, cellcount
) = res
506 ret
= '\n'.join(list(filter(None, ret
)))
507 return pinmux_cellrule
.format(ret
)
511 for (name
, count
) in self
.ifacecount
:
512 for i
in range(count
):
513 if self
.is_on_fastbus(name
, i
):
515 txt
= self
.data
[name
].mk_pincon(name
, i
)
517 return '\n'.join(list(filter(None, ret
)))
519 def mk_ext_ifacedef(self
):
521 for (name
, count
) in self
.ifacecount
:
522 for i
in range(count
):
523 if self
.is_on_fastbus(name
, i
):
525 txt
= self
.data
[name
].mk_ext_ifacedef(name
, i
)
527 return '\n'.join(list(filter(None, ret
)))
531 irq_offs
= 8 # XXX: DMA scovers 0-7?
532 for (name
, count
) in self
.ifacecount
:
533 for i
in range(count
):
534 if self
.is_on_fastbus(name
, i
):
536 res
= self
.data
[name
].mk_plic(i
, irq_offs
)
539 (txt
, irq_offs
) = res
541 self
.num_slow_irqs
= irq_offs
542 return '\n'.join(list(filter(None, ret
)))
544 def mk_sloirqsdef(self
):
545 return " `define NUM_SLOW_IRQS {0}".format(self
.num_slow_irqs
)
547 def is_on_fastbus(self
, name
, i
):
548 #print "fastbus mode", self.fastbusmode, name, i
549 iname
= self
.data
[name
].iname().format(i
)
551 return iname
not in self
.fastbus
552 return iname
in self
.fastbus
555 class PFactory(object):
556 def getcls(self
, name
):
557 from uart
import uart
558 from quart
import quart
559 from sdmmc
import sdmmc
561 from eint
import eint
562 from rs232
import rs232
564 from eint
import eint
565 from jtag
import jtag
566 from spi
import spi
, mspi
567 from qspi
import qspi
, mqspi
568 from gpio
import gpio
569 from rgbttl
import rgbttl
571 for k
, v
in {'uart': uart
,
586 if name
.startswith(k
):
591 slowfactory
= PFactory()
593 if __name__
== '__main__':
597 i
= PeripheralIface('uart')
599 i
= PeripheralIface('gpioa')