X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbsv%2Fperipheral_gen.py;h=ff74a04ec92a7901d362d86cc10541e53704eb3b;hb=5959f9f2d0c5bd5275223a016367df41a8f21656;hp=00e67fb78c3192e3e29cfd6583fdf46f336d2317;hpb=acc9f56a7ff33a460aa6221cb689e31bc7eefd73;p=pinmux.git diff --git a/src/bsv/peripheral_gen.py b/src/bsv/peripheral_gen.py index 00e67fb..ff74a04 100644 --- a/src/bsv/peripheral_gen.py +++ b/src/bsv/peripheral_gen.py @@ -9,6 +9,15 @@ class PBase(object): def slowifdeclmux(self): return '' + def slowifinstance(self): + return '' + + def slowimport(self): + return '' + + def num_axi_regs32(self): + return 0 + def slowifdecl(self): return '' @@ -23,6 +32,8 @@ class PBase(object): def axi_reg_def(self, start, name, ifacenum): name = name.upper() offs = self.num_axi_regs32() * 4 * 16 + if offs == 0: + return ('', 0) end = start + offs - 1 bname = self.axibase(name, ifacenum) bend = self.axiend(name, ifacenum) @@ -64,22 +75,22 @@ class PBase(object): if typ == 'out' or typ == 'inout': ret.append(" rule con_%s%d_%s_out;" % (name, count, pname)) fname = self.pinname_out(pname) + if not n.startswith('gpio'): # XXX EURGH! horrible hack + n_ = "{0}{1}".format(n, count) + else: + n_ = n if fname: if p.get('outen'): ps_ = ps + '_out' else: ps_ = ps - if not n.startswith('gpio'): # XXX EURGH! horrible hack - n_ = "{0}{1}".format(n, count) - else: - n_ = n 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 = "{0}.{1}".format(n_, fname) fname = self.pinname_tweak(pname, 'outen', fname) ret.append(" {0}_outen({1});".format(ps, fname)) ret.append(" endrule") @@ -94,7 +105,9 @@ class PBase(object): " rule con_%s%d_%s_in;" % (name, count, pname)) n_ = "{0}{1}".format(n, count) - ret.append(" {1}.{2}({0});".format(ps_, n_, fname)) + n_ = '{0}.{1}'.format(n_, fname) + n_ = self.ifname_tweak(pname, 'in', n_) + ret.append(" {1}({0});".format(ps_, n_)) ret.append(" endrule") return '\n'.join(ret) @@ -139,6 +152,9 @@ class PBase(object): def pinname_outen(self, pname): return '' + def ifname_tweak(self, pname, typ, txt): + return txt + def pinname_tweak(self, pname, typ, txt): return txt @@ -264,6 +280,175 @@ class twi(PBase): return txt +class eint(PBase): + + def slowimport(self): + size = len(self.peripheral.pinspecs) + return " `define NUM_EINTS %d" % size + + def mkslow_peripheral(self, size=0): + size = len(self.peripheral.pinspecs) + return " Wire#(Bit#(%d)) wr_interrupt <- mkWire();" % size + + def axi_slave_name(self, name, ifacenum): + return '' + + def axi_slave_idx(self, idx, name, ifacenum): + return ('', 0) + + def axi_addr_map(self, name, ifacenum): + return '' + + def ifname_tweak(self, pname, typ, txt): + if typ != 'in': + return txt + print "ifnameweak", pname, typ, txt + return "wr_interrupt[{0}] <= ".format(pname) + + def mk_pincon(self, name, count): + ret = [PBase.mk_pincon(self, name, count)] + size = len(self.peripheral.pinspecs) + ret.append(eint_pincon_template.format(size)) + ret.append(" rule con_%s%d_io_in;" % (name, count)) + ret.append(" wr_interrupt <= ({") + for idx, p in enumerate(self.peripheral.pinspecs): + pname = p['name'] + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s" % sname + comma = '' if idx == size - 1 else ',' + ret.append(" {0}{1}".format(ps, comma)) + ret.append(" });") + ret.append(" endrule") + + return '\n'.join(ret) + + +eint_pincon_template = '''\ + // TODO: offset i by the number of eints already used + for(Integer i=0;i<{0};i=i+ 1)begin + rule connect_int_to_plic(wr_interrupt[i]==1); + ff_gateway_queue[i].enq(1); + plic.ifc_external_irq[i].irq_frm_gateway(True); + endrule + end +''' + + +class jtag(PBase): + + def axi_slave_name(self, name, ifacenum): + return '' + + def axi_slave_idx(self, idx, name, ifacenum): + return ('', 0) + + def axi_addr_map(self, name, ifacenum): + return '' + + def slowifdeclmux(self): + return " method Action jtag_ms (Bit#(1) in);\n" + \ + " method Bit#(1) jtag_di;\n" + \ + " method Action jtag_do (Bit#(1) in);\n" + \ + " method Action jtag_ck (Bit#(1) in);" + + def slowifinstance(self): + return jtag_method_template # bit of a lazy hack this... + +jtag_method_template = """\ + method Action jtag_ms (Bit#(1) in); + pinmux.peripheral_side.jtag_ms(in); + endmethod + method Bit#(1) jtag_di=pinmux.peripheral_side.jtag_di; + method Action jtag_do (Bit#(1) in); + pinmux.peripheral_side.jtag_do(in); + endmethod + method Action jtag_ck (Bit#(1) in); + pinmux.peripheral_side.jtag_ck(in); + endmethod +""" + +class sdmmc(PBase): + + def slowimport(self): + return " import sdcard_dummy :: *;" + + def slowifdecl(self): + return " interface QSPI_out sd{0}_out;\n" + \ + " method Bit#(1) sd{0}_isint;" + + def num_axi_regs32(self): + return 13 + + def mkslow_peripheral(self): + return " Ifc_sdcard_dummy sd{0} <- mksdcard_dummy();" + + def _mk_connection(self, name=None, count=0): + return "sd{0}.slave" + + def pinname_in(self, pname): + return "%s_in" % pname + + def pinname_out(self, pname): + if pname.startswith('d'): + return "%s_out" % pname + return pname + + def pinname_outen(self, pname): + if pname.startswith('d'): + return "%s_outen" % pname + + +class spi(PBase): + + def slowimport(self): + return " import qspi :: *;" + + def slowifdecl(self): + return " interface QSPI_out spi{0}_out;\n" + \ + " method Bit#(1) spi{0}_isint;" + + def num_axi_regs32(self): + return 13 + + def mkslow_peripheral(self): + return " Ifc_qspi spi{0} <- mkqspi();" + + def _mk_connection(self, name=None, count=0): + return "spi{0}.slave" + + def pinname_out(self, pname): + return {'clk': 'out.clk_o', + 'nss': 'out.ncs_o', + 'mosi': 'out.io_o[0]', + 'miso': 'out.io_o[1]', + }.get(pname, '') + + def pinname_outen(self, pname): + return {'clk': 1, + 'nss': 1, + 'mosi': 'out.io_enable[0]', + 'miso': 'out.io_enable[1]', + }.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 spi 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 idx, pname in enumerate(['mosi', 'miso']): + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s_in" % sname + ret.append(" {0},".format(ps)) + ret.append(" 1'b0,1'b0") + ret.append(" });") + ret.append(" endrule") + return '\n'.join(ret) + + class qspi(PBase): def slowimport(self): @@ -367,13 +552,13 @@ class gpio(PBase): name = name.upper() mname = 'mux' + name[4:] mname = mname.upper() - print "AXIslavenum", name, mname + 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) + (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) + 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 @@ -411,7 +596,7 @@ class gpio(PBase): return "func.gpio_out[{0}]".format(pname[1:]) def pinname_outen(self, pname): - return "func.gpio_outen[{0}]".format(pname[1:]) + return "func.gpio_out_en[{0}]".format(pname[1:]) def mk_pincon(self, name, count): ret = [PBase.mk_pincon(self, name, count)] @@ -471,7 +656,8 @@ class PeripheralIface(object): if slow: self.slow = slow(ifacename) self.slow.peripheral = self - for fname in ['slowimport', 'slowifdecl', 'slowifdeclmux', + for fname in ['slowimport', + 'slowifinstance', 'slowifdecl', 'slowifdeclmux', 'mkslow_peripheral', 'mk_connection', 'mk_cellconn', 'mk_pincon']: fn = CallFn(self, fname) @@ -512,6 +698,13 @@ class PeripheralInterfaces(object): 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: @@ -609,7 +802,11 @@ class PFactory(object): 'rs232': rs232, 'twi': twi, 'qspi': qspi, + 'spi': spi, 'pwm': pwm, + 'eint': eint, + 'sd': sdmmc, + 'jtag': jtag, 'gpio': gpio }.items(): if name.startswith(k):