X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbsv%2Fperipheral_gen.py;h=ff74a04ec92a7901d362d86cc10541e53704eb3b;hb=5959f9f2d0c5bd5275223a016367df41a8f21656;hp=8b450251492d2dd5060d4ed3bf48130dfc5e63d7;hpb=41378d83fa3d06d3e898a041644fd72b855383a6;p=pinmux.git diff --git a/src/bsv/peripheral_gen.py b/src/bsv/peripheral_gen.py index 8b45025..ff74a04 100644 --- a/src/bsv/peripheral_gen.py +++ b/src/bsv/peripheral_gen.py @@ -6,6 +6,21 @@ class PBase(object): def __init__(self, name): self.name = name + def slowifdeclmux(self): + return '' + + def slowifinstance(self): + return '' + + def slowimport(self): + return '' + + def num_axi_regs32(self): + return 0 + + def slowifdecl(self): + return '' + def axibase(self, name, ifacenum): name = name.upper() return "%(name)s%(ifacenum)dBase" % locals() @@ -17,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) @@ -58,19 +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 - 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 = "{0}.{1}".format(n_, fname) fname = self.pinname_tweak(pname, 'outen', fname) ret.append(" {0}_outen({1});".format(ps, fname)) ret.append(" endrule") @@ -84,7 +104,10 @@ class PBase(object): ret.append( " rule con_%s%d_%s_in;" % (name, count, pname)) - ret.append(" {1}.{2}({0});".format(ps_, n, fname)) + n_ = "{0}{1}".format(n, count) + 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) @@ -129,12 +152,43 @@ 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 class uart(PBase): + def slowimport(self): + return " import Uart_bs :: *;\n" + \ + " import RS232_modified::*;" + + def slowifdecl(self): + return " interface RS232 uart{0}_coe;\n" + \ + " method Bit#(1) uart{0}_intr;" + + def num_axi_regs32(self): + return 8 + + def mkslow_peripheral(self, size=0): + return " Ifc_Uart_bs uart{0} <- \n" + \ + " mkUart_bs(clocked_by sp_clock,\n" + \ + " reset_by uart_reset, sp_clock, sp_reset);" + + 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 qquart(PBase): + def slowimport(self): return " import Uart16550 :: *;" @@ -147,7 +201,7 @@ class uart(PBase): def mkslow_peripheral(self, size=0): return " Uart16550_AXI4_Lite_Ifc uart{0} <- \n" + \ - " mkUart16550(clocked_by uart_clock,\n" + \ + " mkUart16550(clocked_by sp_clock,\n" + \ " reset_by uart_reset, sp_clock, sp_reset);" def _mk_connection(self, name=None, count=0): @@ -217,8 +271,8 @@ class twi(PBase): 'scl': 'out.scl_in'}.get(pname, '') def pinname_outen(self, pname): - return {'sda': 'out.sda_outen', - 'scl': 'out.scl_outen'}.get(pname, '') + return {'sda': 'out.sda_out_en', + 'scl': 'out.scl_out_en'}.get(pname, '') def pinname_tweak(self, pname, typ, txt): if typ == 'outen': @@ -226,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): @@ -271,7 +494,7 @@ class qspi(PBase): 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 p in self.peripheral.pinspecs: + for i, p in enumerate(self.peripheral.pinspecs): typ = p['type'] pname = p['name'] if not pname.startswith('io'): @@ -280,7 +503,8 @@ class qspi(PBase): n = name sname = self.peripheral.pname(pname).format(count) ps = "pinmux.peripheral_side.%s_in" % sname - ret.append(" {0},".format(ps)) + comma = '' if i == 5 else ',' + ret.append(" {0}{1}".format(ps, comma)) ret.append(" });") ret.append(" endrule") return '\n'.join(ret) @@ -292,16 +516,16 @@ class pwm(PBase): return " import pwm::*;" def slowifdecl(self): - return " interface PWMIO pwm{0}_o;" + return " interface PWMIO pwm{0}_io;" def num_axi_regs32(self): return 4 def mkslow_peripheral(self, size=0): - return " Ifc_PWM_bus pwm{0}_bus <- mkPWM_bus(sp_clock);" + return " Ifc_PWM_bus pwm{0} <- mkPWM_bus(sp_clock);" def _mk_connection(self, name=None, count=0): - return "pwm{0}_bus.axi4_slave" + return "pwm{0}.axi4_slave" def pinname_out(self, pname): return {'out': 'pwm_io.pwm_o'}.get(pname, '') @@ -314,8 +538,9 @@ class gpio(PBase): " import mux::*;\n" + \ " import gpio::*;\n" - def slowifdecl(self): - return " interface GPIO_config#({1}) pad_config{0};" + def slowifdeclmux(self): + size = len(self.peripheral.pinspecs) + return " interface GPIO_config#(%d) pad_config{0};" % size def num_axi_regs32(self): return 2 @@ -325,12 +550,15 @@ 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 + 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 @@ -368,8 +596,7 @@ class gpio(PBase): return "func.gpio_out[{0}]".format(pname[1:]) def pinname_outen(self, pname): - return {'sda': 'out.sda_outen', - 'scl': 'out.scl_outen'}.get(pname, '') + return "func.gpio_out_en[{0}]".format(pname[1:]) def mk_pincon(self, name, count): ret = [PBase.mk_pincon(self, name, count)] @@ -429,7 +656,9 @@ class PeripheralIface(object): if slow: self.slow = slow(ifacename) self.slow.peripheral = self - for fname in ['slowimport', 'slowifdecl', 'mkslow_peripheral', + 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)) @@ -469,6 +698,20 @@ 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: + 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: @@ -559,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):