+ def axi_slave_idx(self, idx, name, ifacenum):
+ """ generates AXI slave number definition, except
+ GPIO also has a muxer per bank
+ """
+ name = name.upper()
+ mname = 'mux' + name[4:]
+ mname = mname.upper()
+ print "AXIslavenum", name, mname
+ (ret, x) = PBase.axi_slave_idx(self, idx, name, ifacenum)
+ (ret2, x) = PBase.axi_slave_idx(self, idx + 1, mname, ifacenum)
+ return ("%s\n%s" % (ret, ret2), 2)
+
+ def mkslow_peripheral(self, size=0):
+ print "gpioslow", self.peripheral, dir(self.peripheral)
+ size = len(self.peripheral.pinspecs)
+ return " MUX#(%d) mux{0} <- mkmux();\n" % size + \
+ " GPIO#(%d) gpio{0} <- mkgpio();" % size
+
+ def mk_connection(self, count):
+ print "GPIO mk_conn", self.name, count
+ res = []
+ dname = self.mksuffix(self.name, count)
+ for i, n in enumerate(['gpio' + dname, 'mux' + dname]):
+ res.append(PBase.mk_connection(self, count, n))
+ return '\n'.join(res)
+
+ def _mk_connection(self, name=None, count=0):
+ n = self.mksuffix(name, count)
+ if name.startswith('gpio'):
+ return "gpio{0}.axi_slave".format(n)
+ if name.startswith('mux'):
+ return "mux{0}.axi_slave".format(n)
+
+ def mksuffix(self, name, i):
+ if name.startswith('mux'):
+ return name[3:]
+ return name[4:]
+
+ def mk_cellconn(self, cellnum, name, count):
+ ret = []
+ bank = self.mksuffix(name, count)
+ txt = " pinmux.mux_lines.cell{0}_mux(mux{1}.mux_config.mux[{2}]);"
+ for p in self.peripheral.pinspecs:
+ ret.append(txt.format(cellnum, bank, p['name'][1:]))
+ cellnum += 1
+ return ("\n".join(ret), cellnum)
+
+ def pinname_out(self, pname):
+ return "func.gpio_out[{0}]".format(pname[1:])
+
+ def pinname_outen(self, pname):
+ return "func.gpio_out_en[{0}]".format(pname[1:])
+
+ def mk_pincon(self, name, count):
+ ret = [PBase.mk_pincon(self, name, count)]
+ # special-case for gpio in, store in a temporary vector
+ plen = len(self.peripheral.pinspecs)
+ ret.append(" rule con_%s%d_in;" % (name, count))
+ ret.append(" Vector#({0},Bit#(1)) temp;".format(plen))
+ for p in self.peripheral.pinspecs:
+ typ = p['type']
+ pname = p['name']
+ idx = pname[1:]
+ n = name
+ sname = self.peripheral.pname(pname).format(count)
+ ps = "pinmux.peripheral_side.%s_in" % sname
+ ret.append(" temp[{0}]={1};".format(idx, ps))
+ ret.append(" {0}.func.gpio_in(temp);".format(name))
+ ret.append(" endrule")
+ return '\n'.join(ret)
+
+
+axi_slave_declarations = """\
+typedef 0 SlowMaster;
+{0}
+typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
+ CLINT_slave_num;
+typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
+ Plic_slave_num;
+typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
+ AxiExp1_slave_num;
+typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
+"""
+
+pinmux_cellrule = """\
+ rule connect_select_lines_pinmux;
+{0}
+ endrule
+"""
+
+
+class CallFn(object):
+ def __init__(self, peripheral, name):
+ self.peripheral = peripheral
+ self.name = name
+
+ def __call__(self, *args):
+ #print "__call__", self.name, self.peripheral.slow, args
+ if not self.peripheral.slow:
+ return ''
+ return getattr(self.peripheral.slow, self.name)(*args[1:])
+
+
+class PeripheralIface(object):
+ def __init__(self, ifacename):
+ self.slow = None
+ slow = slowfactory.getcls(ifacename)
+ print "Iface", ifacename, slow
+ if slow:
+ self.slow = slow(ifacename)
+ self.slow.peripheral = self
+ for fname in ['slowimport',
+ 'slowifinstance', 'slowifdecl', 'slowifdeclmux',
+ 'mkslow_peripheral',
+ 'mk_connection', 'mk_cellconn', 'mk_pincon']:
+ fn = CallFn(self, fname)
+ setattr(self, fname, types.MethodType(fn, self))
+
+ #print "PeripheralIface"
+ #print dir(self)
+
+ def mksuffix(self, name, i):
+ if self.slow is None:
+ return i
+ return self.slow.mksuffix(name, i)
+
+ def axi_reg_def(self, start, count):
+ if not self.slow:
+ return ('', 0)
+ return self.slow.axi_reg_def(start, self.ifacename, count)
+
+ def axi_slave_idx(self, start, count):
+ if not self.slow:
+ return ('', 0)
+ return self.slow.axi_slave_idx(start, self.ifacename, count)
+
+ def axi_addr_map(self, count):
+ if not self.slow:
+ return ''
+ return self.slow.axi_addr_map(self.ifacename, count)
+
+
+class PeripheralInterfaces(object):
+ def __init__(self):
+ pass
+
+ def slowimport(self, *args):
+ ret = []
+ for (name, count) in self.ifacecount:
+ #print "slowimport", name, self.data[name].slowimport
+ ret.append(self.data[name].slowimport())
+ return '\n'.join(list(filter(None, ret)))
+
+ def slowifinstance(self, *args):
+ ret = []
+ for (name, count) in self.ifacecount:
+ #print "slowimport", name, self.data[name].slowimport
+ ret.append(self.data[name].slowifinstance())
+ return '\n'.join(list(filter(None, ret)))
+
+ def slowifdeclmux(self, *args):
+ ret = []
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ ret.append(self.data[name].slowifdeclmux().format(i, name))
+ return '\n'.join(list(filter(None, ret)))
+
+ def slowifdecl(self, *args):
+ ret = []
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ ret.append(self.data[name].slowifdecl().format(i, name))
+ return '\n'.join(list(filter(None, ret)))
+
+ def axi_reg_def(self, *args):
+ ret = []
+ start = 0x00011100 # start of AXI peripherals address
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ x = self.data[name].axi_reg_def(start, i)
+ #print ("ifc", name, x)
+ (rdef, offs) = x
+ ret.append(rdef)
+ start += offs
+ return '\n'.join(list(filter(None, ret)))
+
+ def axi_slave_idx(self, *args):
+ ret = []
+ start = 0
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ (rdef, offs) = self.data[name].axi_slave_idx(start, i)
+ #print ("ifc", name, rdef, offs)
+ ret.append(rdef)
+ start += offs
+ ret.append("typedef %d LastGen_slave_num;" % (start - 1))
+ decls = '\n'.join(list(filter(None, ret)))
+ return axi_slave_declarations.format(decls)
+
+ def axi_addr_map(self, *args):
+ ret = []
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ ret.append(self.data[name].axi_addr_map(i))
+ return '\n'.join(list(filter(None, ret)))
+
+ def mkslow_peripheral(self, *args):
+ ret = []
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ print "mkslow", name, count
+ x = self.data[name].mkslow_peripheral()
+ print name, count, x
+ suffix = self.data[name].mksuffix(name, i)
+ ret.append(x.format(suffix))
+ return '\n'.join(list(filter(None, ret)))
+
+ def mk_connection(self, *args):
+ ret = []
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ print "mk_conn", name, i
+ txt = self.data[name].mk_connection(i)
+ if name == 'gpioa':
+ print "txt", txt
+ print self.data[name].mk_connection
+ ret.append(txt)
+ return '\n'.join(list(filter(None, ret)))
+
+ def mk_cellconn(self):
+ ret = []
+ cellcount = 0
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ res = self.data[name].mk_cellconn(cellcount, name, i)
+ if not res:
+ continue
+ (txt, cellcount) = res
+ ret.append(txt)
+ ret = '\n'.join(list(filter(None, ret)))
+ return pinmux_cellrule.format(ret)
+
+ def mk_pincon(self):
+ ret = []
+ for (name, count) in self.ifacecount:
+ for i in range(count):
+ txt = self.data[name].mk_pincon(name, i)
+ ret.append(txt)
+ return '\n'.join(list(filter(None, ret)))
+