refactor peripheral_gen, split out interface classes
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 22 Jul 2018 09:22:20 +0000 (10:22 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 22 Jul 2018 09:22:20 +0000 (10:22 +0100)
13 files changed:
src/bsv/peripheral_gen/__init__.py
src/bsv/peripheral_gen/base.py
src/bsv/peripheral_gen/eint.py [new file with mode: 0644]
src/bsv/peripheral_gen/gpio.py [new file with mode: 0644]
src/bsv/peripheral_gen/jtag.py [new file with mode: 0644]
src/bsv/peripheral_gen/pwm.py [new file with mode: 0644]
src/bsv/peripheral_gen/qspi.py [new file with mode: 0644]
src/bsv/peripheral_gen/quart.py [new file with mode: 0644]
src/bsv/peripheral_gen/rs232.py [new file with mode: 0644]
src/bsv/peripheral_gen/sdmmc.py [new file with mode: 0644]
src/bsv/peripheral_gen/spi.py [new file with mode: 0644]
src/bsv/peripheral_gen/twi.py [new file with mode: 0644]
src/bsv/peripheral_gen/uart.py [new file with mode: 0644]

index 0e1bfdb03179154629cb39ec206ce7dfdcfb6b09..42cac84d7b73d68345005915873f21c7b607b1ab 100644 (file)
@@ -1,6 +1,13 @@
-from base import PeripheralInterfaces
+from bsv.peripheral_gen.base import PeripheralInterfaces, PeripheralIface
 from uart import uart
 from quart import quart
 from sdmmc import sdmmc
 from pwm import pwm
 from eint import eint
 from uart import uart
 from quart import quart
 from sdmmc import sdmmc
 from pwm import pwm
 from eint import eint
+from rs232 import rs232
+from twi import twi
+from eint import eint
+from jtag import jtag
+from spi import spi
+from qspi import qspi
+from gpio import gpio
index 15d029576747dec3ab33b28f24f349c212bbd056..c77e1cf1645624bbd1688bc0a6cb671847e2f682 100644 (file)
@@ -1,6 +1,4 @@
 import types
 import types
-from copy import deepcopy
-
 
 class PBase(object):
     def __init__(self, name):
 
 class PBase(object):
     def __init__(self, name):
@@ -193,548 +191,6 @@ mkplic_rule = """\
      endrule
 """
 
      endrule
 """
 
-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 quart(PBase):
-
-    def slowimport(self):
-        return "    import Uart16550         :: *;"
-
-    def slowifdecl(self):
-        return "            interface RS232_PHY_Ifc quart{0}_coe;\n" + \
-               "            method Bit#(1) quart{0}_intr;"
-
-    def num_axi_regs32(self):
-        return 8
-
-    def mkslow_peripheral(self, size=0):
-        return "        Uart16550_AXI4_Lite_Ifc quart{0} <- \n" + \
-               "                mkUart16550(clocked_by sp_clock,\n" + \
-               "                    reset_by uart_reset, sp_clock, sp_reset);"
-
-    def _mk_connection(self, name=None, count=0):
-        return "quart{0}.slave_axi_uart"
-
-    def pinname_out(self, pname):
-        return {'tx' : 'coe_rs232.modem_output_stx',
-                'rts': 'coe_rs232.modem_output_rts',
-               }.get(pname, '')
-
-    def _pinname_in(self, pname):
-        return {'rx': 'coe_rs232.modem_input.srx', 
-                'cts': 'coe_rs232.modem_input.cts'
-               }.get(pname, '')
-
-    def mk_pincon(self, name, count):
-        ret = [PBase.mk_pincon(self, name, count)]
-        ret.append("    rule con_%s%d_io_in;" % (name, count))
-        ret.append("       {0}{1}.coe_rs232.modem_input(".format(name, count))
-        for idx, pname in enumerate(['rx', 'cts']):
-            sname = self.peripheral.pname(pname).format(count)
-            ps = "pinmux.peripheral_side.%s" % sname
-            ret.append("            {0},".format(ps))
-        ret.append("            1'b1,1'b0,1'b1")
-        ret.append("        );")
-        ret.append("    endrule")
-
-        return '\n'.join(ret)
-
-    def num_irqs(self):
-        return 1
-
-    def plic_object(self, pname, idx):
-        return "{0}_interrupt.read".format(pname)
-
-    def mk_plic(self, inum, irq_offs):
-        name = self.get_iname(inum)
-        ret = [uart_plic_template.format(name, irq_offs)]
-        (ret2, irq_offs) = PBase.mk_plic(self, inum, irq_offs)
-        ret.append(ret2)
-        return ('\n'.join(ret), irq_offs)
-
-    def mk_ext_ifacedef(self, iname, inum):
-        name = self.get_iname(inum)
-        return "        method {0}_intr = {0}.irq;".format(name)
-
-    def slowifdeclmux(self):
-        return "        method Bit#(1) {1}{0}_intr;"
-
-uart_plic_template = """\
-     // PLIC {0} synchronisation with irq {1}
-     SyncBitIfc#(Bit#(1)) {0}_interrupt <-
-                                mkSyncBitToCC(sp_clock, uart_reset);
-     rule plic_synchronize_{0}_interrupt_{1};
-         {0}_interrupt.send({0}.irq);
-     endrule
-"""
-
-class rs232(PBase):
-
-    def slowimport(self):
-        return "    import Uart_bs::*;\n" + \
-               "    import RS232_modified::*;"
-
-    def slowifdecl(self):
-        return "            interface RS232 uart{0}_coe;"
-
-    def num_axi_regs32(self):
-        return 2
-
-    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);" +\
-               "        Ifc_Uart_bs uart{0} <-" + \
-               "                mkUart_bs(clocked_by sp_clock,\n" + \
-               "                    reset_by sp_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 twi(PBase):
-
-    def slowimport(self):
-        return "    import I2C_top           :: *;"
-
-    def slowifdecl(self):
-        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, 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 pinname_outen(self, pname):
-        return {'sda': 'out.sda_out_en',
-                'scl': 'out.scl_out_en'}.get(pname, '')
-
-    def pinname_tweak(self, pname, typ, txt):
-        if typ == 'outen':
-            return "pack({0})".format(txt)
-        return txt
-
-    def num_irqs(self):
-        return 3
-
-    def plic_object(self, pname, idx):
-        return ["{0}.isint()",
-                "{0}.timerint()",
-                "{0}.isber()"
-               ][idx].format(pname)
-
-    def mk_ext_ifacedef(self, iname, inum):
-        name = self.get_iname(inum)
-        return "        method {0}_isint = {0}.isint;".format(name)
-
-    def slowifdeclmux(self):
-        return "        method Bit#(1) {1}{0}_isint;"
-
-
-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 = '''\
-    // EINT is offset at end of other peripheral interrupts
-`ifdef PLIC
-    for(Integer i=0;i<{0};i=i+ 1)begin
-      rule connect_int_to_plic(wr_interrupt[i]==1);
-                ff_gateway_queue[i+`NUM_SLOW_IRQS].enq(1);
-                plic.ifc_external_irq[i+`NUM_SLOW_IRQS].irq_frm_gateway(True);
-      endrule
-    end
-`endif
-'''
-
-
-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)
-
-    def mk_ext_ifacedef(self, iname, inum):
-        name = self.get_iname(inum)
-        return "        method {0}_isint = {0}.interrupts[5];".format(name)
-
-    def slowifdeclmux(self):
-        return "        method Bit#(1) {1}{0}_isint;"
-
-
-class qspi(PBase):
-
-    def slowimport(self):
-        return "    import qspi              :: *;"
-
-    def slowifdecl(self):
-        return "            interface QSPI_out qspi{0}_out;\n" + \
-               "            method Bit#(1) qspi{0}_isint;"
-
-    def num_axi_regs32(self):
-        return 13
-
-    def mkslow_peripheral(self, size=0):
-        return "        Ifc_qspi qspi{0} <-  mkqspi();"
-
-    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)
-
-    def num_irqs(self):
-        return 6
-
-    def plic_object(self, pname, idx):
-        return "{0}.interrupts()[{1}]".format(pname, idx)
-
-    def mk_ext_ifacedef(self, iname, inum):
-        name = self.get_iname(inum)
-        return "        method {0}_isint = {0}.interrupts[5];".format(name)
-
-    def slowifdeclmux(self):
-        return "        method Bit#(1) {1}{0}_isint;"
-
-
-
-class pwm(PBase):
-
-    def slowimport(self):
-        return "    import pwm::*;"
-
-    def slowifdecl(self):
-        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} <- mkPWM_bus(sp_clock);"
-
-    def _mk_connection(self, name=None, count=0):
-        return "pwm{0}.axi4_slave"
-
-    def pinname_out(self, pname):
-        return {'out': 'pwm_io.pwm_o'}.get(pname, '')
-
-
-class gpio(PBase):
-
-    def slowimport(self):
-        return "    import pinmux::*;\n" + \
-               "    import mux::*;\n" + \
-               "    import gpio::*;\n"
-
-    def slowifdeclmux(self):
-        size = len(self.peripheral.pinspecs)
-        return "        interface GPIO_config#(%d) pad_config{0};" % size
-
-    def num_axi_regs32(self):
-        return 2
-
-    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;
 
 axi_slave_declarations = """\
 typedef  0  SlowMaster;
@@ -942,6 +398,19 @@ class PeripheralInterfaces(object):
 
 class PFactory(object):
     def getcls(self, name):
 
 class PFactory(object):
     def getcls(self, name):
+        from uart import uart
+        from quart import quart
+        from sdmmc import sdmmc
+        from pwm import pwm
+        from eint import eint
+        from rs232 import rs232
+        from twi import twi
+        from eint import eint
+        from jtag import jtag
+        from spi import spi
+        from qspi import qspi
+        from gpio import gpio
+
         for k, v in {'uart': uart,
                      'rs232': rs232,
                      'twi': twi,
         for k, v in {'uart': uart,
                      'rs232': rs232,
                      'twi': twi,
@@ -958,7 +427,6 @@ class PFactory(object):
                 return v
         return None
 
                 return v
         return None
 
-
 slowfactory = PFactory()
 
 if __name__ == '__main__':
 slowfactory = PFactory()
 
 if __name__ == '__main__':
diff --git a/src/bsv/peripheral_gen/eint.py b/src/bsv/peripheral_gen/eint.py
new file mode 100644 (file)
index 0000000..cd3be2c
--- /dev/null
@@ -0,0 +1,56 @@
+from bsv.peripheral_gen.base import PBase
+
+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 = '''\
+    // EINT is offset at end of other peripheral interrupts
+`ifdef PLIC
+    for(Integer i=0;i<{0};i=i+ 1)begin
+      rule connect_int_to_plic(wr_interrupt[i]==1);
+                ff_gateway_queue[i+`NUM_SLOW_IRQS].enq(1);
+                plic.ifc_external_irq[i+`NUM_SLOW_IRQS].irq_frm_gateway(True);
+      endrule
+    end
+`endif
+'''
diff --git a/src/bsv/peripheral_gen/gpio.py b/src/bsv/peripheral_gen/gpio.py
new file mode 100644 (file)
index 0000000..93dcd3b
--- /dev/null
@@ -0,0 +1,86 @@
+from bsv.peripheral_gen.base import PBase
+
+class gpio(PBase):
+
+    def slowimport(self):
+        return "    import pinmux::*;\n" + \
+               "    import mux::*;\n" + \
+               "    import gpio::*;\n"
+
+    def slowifdeclmux(self):
+        size = len(self.peripheral.pinspecs)
+        return "        interface GPIO_config#(%d) pad_config{0};" % size
+
+    def num_axi_regs32(self):
+        return 2
+
+    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)
diff --git a/src/bsv/peripheral_gen/jtag.py b/src/bsv/peripheral_gen/jtag.py
new file mode 100644 (file)
index 0000000..09c049d
--- /dev/null
@@ -0,0 +1,34 @@
+from bsv.peripheral_gen.base import PBase
+
+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
+"""
diff --git a/src/bsv/peripheral_gen/pwm.py b/src/bsv/peripheral_gen/pwm.py
new file mode 100644 (file)
index 0000000..1a43c13
--- /dev/null
@@ -0,0 +1,21 @@
+from bsv.peripheral_gen.base import PBase
+
+class pwm(PBase):
+
+    def slowimport(self):
+        return "    import pwm::*;"
+
+    def slowifdecl(self):
+        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} <- mkPWM_bus(sp_clock);"
+
+    def _mk_connection(self, name=None, count=0):
+        return "pwm{0}.axi4_slave"
+
+    def pinname_out(self, pname):
+        return {'out': 'pwm_io.pwm_o'}.get(pname, '')
diff --git a/src/bsv/peripheral_gen/qspi.py b/src/bsv/peripheral_gen/qspi.py
new file mode 100644 (file)
index 0000000..0ed26b3
--- /dev/null
@@ -0,0 +1,74 @@
+from bsv.peripheral_gen.base import PBase
+
+class qspi(PBase):
+
+    def slowimport(self):
+        return "    import qspi              :: *;"
+
+    def slowifdecl(self):
+        return "            interface QSPI_out qspi{0}_out;\n" + \
+               "            method Bit#(1) qspi{0}_isint;"
+
+    def num_axi_regs32(self):
+        return 13
+
+    def mkslow_peripheral(self, size=0):
+        return "        Ifc_qspi qspi{0} <-  mkqspi();"
+
+    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)
+
+    def num_irqs(self):
+        return 6
+
+    def plic_object(self, pname, idx):
+        return "{0}.interrupts()[{1}]".format(pname, idx)
+
+    def mk_ext_ifacedef(self, iname, inum):
+        name = self.get_iname(inum)
+        return "        method {0}_isint = {0}.interrupts[5];".format(name)
+
+    def slowifdeclmux(self):
+        return "        method Bit#(1) {1}{0}_isint;"
diff --git a/src/bsv/peripheral_gen/quart.py b/src/bsv/peripheral_gen/quart.py
new file mode 100644 (file)
index 0000000..0d314dd
--- /dev/null
@@ -0,0 +1,75 @@
+from bsv.peripheral_gen.base import PBase
+
+class quart(PBase):
+
+    def slowimport(self):
+        return "    import Uart16550         :: *;"
+
+    def slowifdecl(self):
+        return "            interface RS232_PHY_Ifc quart{0}_coe;\n" + \
+               "            method Bit#(1) quart{0}_intr;"
+
+    def num_axi_regs32(self):
+        return 8
+
+    def mkslow_peripheral(self, size=0):
+        return "        Uart16550_AXI4_Lite_Ifc quart{0} <- \n" + \
+               "                mkUart16550(clocked_by sp_clock,\n" + \
+               "                    reset_by uart_reset, sp_clock, sp_reset);"
+
+    def _mk_connection(self, name=None, count=0):
+        return "quart{0}.slave_axi_uart"
+
+    def pinname_out(self, pname):
+        return {'tx' : 'coe_rs232.modem_output_stx',
+                'rts': 'coe_rs232.modem_output_rts',
+               }.get(pname, '')
+
+    def _pinname_in(self, pname):
+        return {'rx': 'coe_rs232.modem_input.srx', 
+                'cts': 'coe_rs232.modem_input.cts'
+               }.get(pname, '')
+
+    def mk_pincon(self, name, count):
+        ret = [PBase.mk_pincon(self, name, count)]
+        ret.append("    rule con_%s%d_io_in;" % (name, count))
+        ret.append("       {0}{1}.coe_rs232.modem_input(".format(name, count))
+        for idx, pname in enumerate(['rx', 'cts']):
+            sname = self.peripheral.pname(pname).format(count)
+            ps = "pinmux.peripheral_side.%s" % sname
+            ret.append("            {0},".format(ps))
+        ret.append("            1'b1,1'b0,1'b1")
+        ret.append("        );")
+        ret.append("    endrule")
+
+        return '\n'.join(ret)
+
+    def num_irqs(self):
+        return 1
+
+    def plic_object(self, pname, idx):
+        return "{0}_interrupt.read".format(pname)
+
+    def mk_plic(self, inum, irq_offs):
+        name = self.get_iname(inum)
+        ret = [uart_plic_template.format(name, irq_offs)]
+        (ret2, irq_offs) = PBase.mk_plic(self, inum, irq_offs)
+        ret.append(ret2)
+        return ('\n'.join(ret), irq_offs)
+
+    def mk_ext_ifacedef(self, iname, inum):
+        name = self.get_iname(inum)
+        return "        method {0}_intr = {0}.irq;".format(name)
+
+    def slowifdeclmux(self):
+        return "        method Bit#(1) {1}{0}_intr;"
+
+uart_plic_template = """\
+     // PLIC {0} synchronisation with irq {1}
+     SyncBitIfc#(Bit#(1)) {0}_interrupt <-
+                                mkSyncBitToCC(sp_clock, uart_reset);
+     rule plic_synchronize_{0}_interrupt_{1};
+         {0}_interrupt.send({0}.irq);
+     endrule
+"""
+
diff --git a/src/bsv/peripheral_gen/rs232.py b/src/bsv/peripheral_gen/rs232.py
new file mode 100644 (file)
index 0000000..597ad3e
--- /dev/null
@@ -0,0 +1,30 @@
+from bsv.peripheral_gen.base import PBase
+
+class rs232(PBase):
+
+    def slowimport(self):
+        return "    import Uart_bs::*;\n" + \
+               "    import RS232_modified::*;"
+
+    def slowifdecl(self):
+        return "            interface RS232 uart{0}_coe;"
+
+    def num_axi_regs32(self):
+        return 2
+
+    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);" +\
+               "        Ifc_Uart_bs uart{0} <-" + \
+               "                mkUart_bs(clocked_by sp_clock,\n" + \
+               "                    reset_by sp_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, '')
diff --git a/src/bsv/peripheral_gen/sdmmc.py b/src/bsv/peripheral_gen/sdmmc.py
new file mode 100644 (file)
index 0000000..f51b5a9
--- /dev/null
@@ -0,0 +1,31 @@
+from bsv.peripheral_gen.base import PBase
+
+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
diff --git a/src/bsv/peripheral_gen/spi.py b/src/bsv/peripheral_gen/spi.py
new file mode 100644 (file)
index 0000000..be51297
--- /dev/null
@@ -0,0 +1,60 @@
+from bsv.peripheral_gen.base import PBase
+
+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)
+
+    def mk_ext_ifacedef(self, iname, inum):
+        name = self.get_iname(inum)
+        return "        method {0}_isint = {0}.interrupts[5];".format(name)
+
+    def slowifdeclmux(self):
+        return "        method Bit#(1) {1}{0}_isint;"
+
+
diff --git a/src/bsv/peripheral_gen/twi.py b/src/bsv/peripheral_gen/twi.py
new file mode 100644 (file)
index 0000000..4c0d815
--- /dev/null
@@ -0,0 +1,54 @@
+from bsv.peripheral_gen.base import PBase
+
+class twi(PBase):
+
+    def slowimport(self):
+        return "    import I2C_top           :: *;"
+
+    def slowifdecl(self):
+        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, 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 pinname_outen(self, pname):
+        return {'sda': 'out.sda_out_en',
+                'scl': 'out.scl_out_en'}.get(pname, '')
+
+    def pinname_tweak(self, pname, typ, txt):
+        if typ == 'outen':
+            return "pack({0})".format(txt)
+        return txt
+
+    def num_irqs(self):
+        return 3
+
+    def plic_object(self, pname, idx):
+        return ["{0}.isint()",
+                "{0}.timerint()",
+                "{0}.isber()"
+               ][idx].format(pname)
+
+    def mk_ext_ifacedef(self, iname, inum):
+        name = self.get_iname(inum)
+        return "        method {0}_isint = {0}.isint;".format(name)
+
+    def slowifdeclmux(self):
+        return "        method Bit#(1) {1}{0}_isint;"
+
+
diff --git a/src/bsv/peripheral_gen/uart.py b/src/bsv/peripheral_gen/uart.py
new file mode 100644 (file)
index 0000000..c757c83
--- /dev/null
@@ -0,0 +1,28 @@
+from bsv.peripheral_gen.base import PBase
+
+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, '')