X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbsv%2Fperipheral_gen.py;h=bd479eaf4a12b5e2883ae7e1fc3c70f4c9889261;hb=8786435aba803a3892d77c246ef74338b3c0ca36;hp=20cc1883368fc415fe3fedce27732f253637c910;hpb=0d9fd4eafc7327131b788c8a909202e6baa721d1;p=pinmux.git diff --git a/src/bsv/peripheral_gen.py b/src/bsv/peripheral_gen.py index 20cc188..bd479ea 100644 --- a/src/bsv/peripheral_gen.py +++ b/src/bsv/peripheral_gen.py @@ -21,8 +21,8 @@ class PBase(object): bname = self.axibase(name, ifacenum) bend = self.axiend(name, ifacenum) comment = "%d 32-bit regs" % self.num_axi_regs32() - return (" `define%(bname)s 'h%(start)08X\n" - " `define%(bend)s 'h%(end)08X // %(comment)s" % locals(), + return (" `define %(bname)s 'h%(start)08X\n" + " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(), offs) def axi_slave_name(self, name, ifacenum): @@ -42,13 +42,66 @@ class PBase(object): return tuple2(True,fromInteger(valueOf({2}))); else""".format(bname, bend, name) - def mkslow_peripheral(self): + def mk_pincon(self, name, count): + # TODO: really should be using bsv.interface_decl.Interfaces + # pin-naming rules.... logic here is hard-coded to duplicate + # it (see Interface.__init__ outen) + ret = [] + for p in self.peripheral.pinspecs: + typ = p['type'] + pname = p['name'] + #n = "{0}{1}".format(self.name, self.mksuffix(name, count)) + n = name # "{0}{1}".format(self.name, self.mksuffix(name, count)) + ret.append(" //%s %s" % (n, str(p))) + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s" % sname + if typ == 'out' or typ == 'inout': + ret.append(" rule con_%s%d_%s_out;" % (name, count, pname)) + fname = self.pinname_out(pname) + if fname: + if p.get('outen'): + ps_ = ps + '_out' + else: + ps_ = ps + n_ = "{0}{1}".format(n, count) + ret.append(" {0}({1}.{2});".format(ps_, n_, fname)) + fname = None + if p.get('outen'): + fname = self.pinname_outen(pname) + if fname: + if isinstance(fname, str): + fname = "{0}{1}.{2}".format(n, count, fname) + fname = self.pinname_tweak(pname, 'outen', fname) + ret.append(" {0}_outen({1});".format(ps, fname)) + ret.append(" endrule") + if typ == 'in' or typ == 'inout': + fname = self.pinname_in(pname) + if fname: + if p.get('outen'): + ps_ = ps + '_in' + else: + ps_ = ps + ret.append( + " rule con_%s%d_%s_in;" % + (name, count, pname)) + n_ = "{0}{1}".format(n, count) + ret.append(" {1}.{2}({0});".format(ps_, n_, fname)) + ret.append(" endrule") + return '\n'.join(ret) + + def mk_cellconn(self, *args): + return '' + + def mkslow_peripheral(self, size=0): return '' + def mksuffix(self, name, i): + return i + def __mk_connection(self, con, aname): - txt = " mkConnection (slow_fabric.v_to_slaves\n" + \ - " [fromInteger(valueOf({1}))],\n" + \ - " {0});" + txt = " mkConnection (slow_fabric.v_to_slaves\n" + \ + " [fromInteger(valueOf({1}))],\n" + \ + " {0});" print "PBase __mk_connection", self.name, aname if not con: @@ -60,12 +113,26 @@ class PBase(object): name = self.name print "PBase mk_conn", self.name, count aname = self.axi_slave_name(name, count) - con = self._mk_connection(name).format(count, aname) + #dname = self.mksuffix(name, count) + #dname = "{0}{1}".format(name, dname) + con = self._mk_connection(name, count).format(count, aname) return self.__mk_connection(con, aname) - def _mk_connection(self, name=None): + def _mk_connection(self, name=None, count=0): return '' + def pinname_out(self, pname): + return '' + + def pinname_in(self, pname): + return '' + + def pinname_outen(self, pname): + return '' + + def pinname_tweak(self, pname, typ, txt): + return txt + class uart(PBase): @@ -79,14 +146,19 @@ class uart(PBase): def num_axi_regs32(self): return 8 - def mkslow_peripheral(self): + def mkslow_peripheral(self, size=0): return " Uart16550_AXI4_Lite_Ifc uart{0} <- \n" + \ " mkUart16550(clocked_by uart_clock,\n" + \ " reset_by uart_reset, sp_clock, sp_reset);" - def _mk_connection(self, name=None): + def _mk_connection(self, name=None, count=0): return "uart{0}.slave_axi_uart" + def pinname_out(self, pname): + return {'tx': 'coe_rs232.sout'}.get(pname, '') + + def pinname_in(self, pname): + return {'rx': 'coe_rs232.sin'}.get(pname, '') class rs232(PBase): @@ -101,7 +173,7 @@ class rs232(PBase): def num_axi_regs32(self): return 2 - def mkslow_peripheral(self): + def mkslow_peripheral(self, size=0): return " //Ifc_Uart_bs uart{0} <-" + \ " // mkUart_bs(clocked_by uart_clock,\n" + \ " // reset_by uart_reset,sp_clock, sp_reset);" +\ @@ -109,9 +181,15 @@ class rs232(PBase): " mkUart_bs(clocked_by sp_clock,\n" + \ " reset_by sp_reset, sp_clock, sp_reset);" - def _mk_connection(self, name=None): + def _mk_connection(self, name=None, count=0): return "uart{0}.slave_axi_uart" + def pinname_out(self, pname): + return {'tx': 'coe_rs232.sout'}.get(pname, '') + + def pinname_in(self, pname): + return {'rx': 'coe_rs232.sin'}.get(pname, '') + class twi(PBase): @@ -119,17 +197,34 @@ class twi(PBase): return " import I2C_top :: *;" def slowifdecl(self): - return " interface I2C_out i2c{0}_out;\n" + \ - " method Bit#(1) i2c{0}_isint;" + return " interface I2C_out twi{0}_out;\n" + \ + " method Bit#(1) twi{0}_isint;" def num_axi_regs32(self): return 8 - def mkslow_peripheral(self): - return " I2C_IFC i2c{0} <- mkI2CController();" + def mkslow_peripheral(self, size=0): + return " I2C_IFC twi{0} <- mkI2CController();" + + def _mk_connection(self, name=None, count=0): + return "twi{0}.slave_i2c_axi" + + def pinname_out(self, pname): + return {'sda': 'out.sda_out', + 'scl': 'out.scl_out'}.get(pname, '') + + def pinname_in(self, pname): + return {'sda': 'out.sda_in', + 'scl': 'out.scl_in'}.get(pname, '') - def _mk_connection(self, name=None): - return "i2c{0}.slave_i2c_axi" + def pinname_outen(self, pname): + return {'sda': 'out.sda_outen', + 'scl': 'out.scl_outen'}.get(pname, '') + + def pinname_tweak(self, pname, typ, txt): + if typ == 'outen': + return "pack({0})".format(txt) + return txt class qspi(PBase): @@ -144,12 +239,54 @@ class qspi(PBase): def num_axi_regs32(self): return 13 - def mkslow_peripheral(self): + def mkslow_peripheral(self, size=0): return " Ifc_qspi qspi{0} <- mkqspi();" - def _mk_connection(self, name=None): + def _mk_connection(self, name=None, count=0): return "qspi{0}.slave" + def pinname_out(self, pname): + return {'ck': 'out.clk_o', + 'nss': 'out.ncs_o', + 'io0': 'out.io_o[0]', + 'io1': 'out.io_o[1]', + 'io2': 'out.io_o[2]', + 'io3': 'out.io_o[3]', + }.get(pname, '') + + def pinname_outen(self, pname): + return {'ck': 1, + 'nss': 1, + 'io0': 'out.io_enable[0]', + 'io1': 'out.io_enable[1]', + 'io2': 'out.io_enable[2]', + 'io3': 'out.io_enable[3]', + }.get(pname, '') + + 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(" // XXX NSS and CLK are hard-coded master") + ret.append(" // TODO: must add qspi slave-mode") + ret.append(" // all ins done in one rule from 4-bitfield") + ret.append(" rule con_%s%d_io_in;" % (name, count)) + ret.append(" {0}{1}.out.io_i({{".format(name, count)) + for i, p in enumerate(self.peripheral.pinspecs): + typ = p['type'] + pname = p['name'] + if not pname.startswith('io'): + continue + idx = pname[1:] + n = name + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s_in" % sname + comma = '' if i == 5 else ',' + ret.append(" {0}{1}".format(ps, comma)) + ret.append(" });") + ret.append(" endrule") + return '\n'.join(ret) + class pwm(PBase): @@ -162,12 +299,15 @@ class pwm(PBase): def num_axi_regs32(self): return 4 - def mkslow_peripheral(self): + def mkslow_peripheral(self, size=0): return " Ifc_PWM_bus pwm{0}_bus <- mkPWM_bus(sp_clock);" - def _mk_connection(self, name=None): + def _mk_connection(self, name=None, count=0): return "pwm{0}_bus.axi4_slave" + def pinname_out(self, pname): + return {'out': 'pwm_io.pwm_o'}.get(pname, '') + class gpio(PBase): @@ -187,27 +327,72 @@ class gpio(PBase): 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, "mux", ifacenum) + (ret2, x) = PBase.axi_slave_idx(self, idx, mname, ifacenum) return ("%s\n%s" % (ret, ret2), 2) - def mkslow_peripheral(self): - return " MUX#(%(name)s) mux{0} <- mkmux();\n" + \ - " GPIO#(%(name)s) gpio{0} <- mkgpio();" % \ - {'name': self.name} + 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 = [] - for i, n in enumerate(['gpio', 'mux']): + 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): + def _mk_connection(self, name=None, count=0): + n = self.mksuffix(name, count) if name.startswith('gpio'): - return "gpio{0}.axi_slave" + 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 "mux{0}.axi_slave" + 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 {'sda': 'out.sda_outen', + 'scl': 'out.scl_outen'}.get(pname, '') + + 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 = """\ @@ -248,14 +433,20 @@ class PeripheralIface(object): print "Iface", ifacename, slow if slow: self.slow = slow(ifacename) + self.slow.peripheral = self for fname in ['slowimport', 'slowifdecl', 'mkslow_peripheral', - 'mk_connection']: + '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) @@ -311,7 +502,7 @@ class PeripheralInterfaces(object): #print ("ifc", name, rdef, offs) ret.append(rdef) start += offs - ret.append("typedef %d LastGen_slave_num" % (start - 1)) + ret.append("typedef %d LastGen_slave_num;" % (start - 1)) decls = '\n'.join(list(filter(None, ret))) return axi_slave_declarations.format(decls) @@ -326,9 +517,11 @@ class PeripheralInterfaces(object): 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 - ret.append(x.format(i)) + suffix = self.data[name].mksuffix(name, i) + ret.append(x.format(suffix)) return '\n'.join(list(filter(None, ret))) def mk_connection(self, *args): @@ -345,22 +538,35 @@ class PeripheralInterfaces(object): def mk_cellconn(self): ret = [] - txt = " pinmux.mux_lines.cell{0}_mux(muxa.mux_config.mux[{0}]);" + cellcount = 0 for (name, count) in self.ifacecount: for i in range(count): - ret.append(txt.format(i)) + 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))) + + class PFactory(object): def getcls(self, name): for k, v in {'uart': uart, - 'rs232': rs232, - 'twi': twi, - 'qspi': qspi, - 'pwm': pwm, - 'gpio': gpio - }.items(): + 'rs232': rs232, + 'twi': twi, + 'qspi': qspi, + 'pwm': pwm, + 'gpio': gpio + }.items(): if name.startswith(k): return v return None