create flexbus interface
[pinmux.git] / src / bsv / interface_decl.py
index 6edaa5ad0be7168d18510bf6f73caed8e3ef1334..ad1413996d840d52167bd93bbb5e5c528c9527cf 100644 (file)
@@ -20,7 +20,8 @@ class Pin(object):
     """
 
     def __init__(self, name,
-                 name_ = None,
+                 name_=None,
+                 idx=None,
                  ready=True,
                  enabled=True,
                  io=False,
@@ -29,6 +30,7 @@ class Pin(object):
                  outenmode=False):
         self.name = name
         self.name_ = name_
+        self.idx = idx
         self.ready = ready
         self.enabled = enabled
         self.io = io
@@ -119,7 +121,7 @@ class Pin(object):
     def ifacedef2(self, fmtoutfn, fmtinfn, fmtdecfn):
         if self.action:
             fmtname = fmtinfn(self.name)
-            res =  "            interface %s = interface Put\n" % self.name_
+            res = "            interface %s = interface Put\n" % self.name_
             res += '              method '
             res += "Action put"
             #res += fmtdecfn(self.name)
@@ -129,7 +131,7 @@ class Pin(object):
             res += '            endinterface;'
         else:
             fmtname = fmtoutfn(self.name)
-            res =  "            interface %s = interface Get\n" % self.name_
+            res = "            interface %s = interface Get\n" % self.name_
             res += '              method ActionValue#'
             res += '(%s) get;\n' % self.bitspec
             res += "                return %s;\n" % (fmtname)
@@ -137,6 +139,21 @@ class Pin(object):
             res += '            endinterface;'
         return res
 
+    def ifacedef3(self, idx, fmtoutfn, fmtinfn, fmtdecfn):
+        if self.action:
+            fmtname = fmtinfn(self.name)
+            if self.name.endswith('outen'):
+                name = "tputen"
+            else:
+                name = "tput"
+            res = "                   %s <= in[%d];" % (fmtname, idx)
+        else:
+            fmtname = fmtoutfn(self.name)
+            res = "                   tget[%d] = %s;" % (idx, fmtname)
+            name = 'tget'
+        return (name, res)
+
+
 class Interface(PeripheralIface):
     """ create an interface from a list of pinspecs.
         each pinspec is a dictionary, see Pin class arguments
@@ -159,7 +176,7 @@ class Interface(PeripheralIface):
         self.pinspecs = pinspecs  # a list of dictionary
         self.single = single
 
-        for p in pinspecs:
+        for idx, p in enumerate(pinspecs):
             _p = {}
             _p.update(p)
             if 'type' in _p:
@@ -171,6 +188,7 @@ class Interface(PeripheralIface):
                     _p['name_'] = "%s_%s" % (p['name'], psuffix)
                     _p['name'] = "%s_%s" % (self.pname(p['name']), psuffix)
                     _p['action'] = psuffix != 'in'
+                    _p['idx'] = idx
                     self.pins.append(Pin(**_p))
                     # will look like {'name': 'twi_sda_out', 'action': True}
                     # {'name': 'twi_sda_outen', 'action': True}
@@ -178,9 +196,10 @@ class Interface(PeripheralIface):
                     # NOTice - outen key is removed
             else:
                 name = p['name']
-                if self.single:
+                if name.isdigit():  # HACK!  deals with EINT case
                     name = self.pname(name)
                 _p['name_'] = name
+                _p['idx'] = idx
                 _p['name'] = self.pname(p['name'])
                 self.pins.append(Pin(**_p))
 
@@ -316,7 +335,7 @@ class Interface(PeripheralIface):
             decfn = self.ifacefmtdecfn3
             outfn = self.ifacefmtoutenfn
         return pin.ifacedef2(outfn, self.ifacefmtinfn,
-                            decfn)
+                             decfn)
 
     def ifacedef(self, *args):
         res = '\n'.join(map(self.ifacefmtpin, self.pins))
@@ -328,6 +347,60 @@ class Interface(PeripheralIface):
         res = res.format(*args)
         return '\n' + res + '\n'
 
+    def vectorifacedef2(self, pins, count, names, bitfmt, *args):
+        tput = []
+        tget = []
+        tputen = []
+        # XXX HACK! assume in, out and inout, create set of indices
+        # that are repeated three times.
+        plens = []
+        # ARG even worse hack for LCD *sigh*...
+        if names[1] is None and names[2] is None:
+            plens = range(len(pins))
+        else:
+            for i in range(0, len(pins), 3):
+                plens += [i / 3, i / 3, i / 3]
+        for (typ, txt) in map(self.ifacedef3pin, plens, pins):
+            if typ == 'tput':
+                tput.append(txt)
+            elif typ == 'tget':
+                tget.append(txt)
+            elif typ == 'tputen':
+                tputen.append(txt)
+        tput = '\n'.join(tput).format(*args)
+        tget = '\n'.join(tget).format(*args)
+        tputen = '\n'.join(tputen).format(*args)
+        bitfmt = bitfmt.format(count)
+        template = ["""\
+              interface {3} = interface Put#({0})
+                 method Action put({2} in);
+{1}
+                 endmethod
+               endinterface;
+""",
+                    """\
+               interface {3} = interface Put#({0})
+                 method Action put({2} in);
+{1}
+                 endmethod
+               endinterface;
+""",
+                    """\
+               interface {3} = interface Get#({0})
+                 method ActionValue#({2}) get;
+                   {2} tget;
+{1}
+                   return tget;
+                 endmethod
+               endinterface;
+"""]
+        res = ''
+        tlist = [tput, tputen, tget]
+        for i, n in enumerate(names):
+            if n:
+                res += template[i].format(count, tlist[i], bitfmt, n)
+        return '\n' + res + '\n'
+
 
 class MuxInterface(Interface):
 
@@ -351,12 +424,144 @@ class IOInterface(Interface):
         return generic_io.format(*args)
 
 
+class InterfaceBus(object):
+
+    def __init__(self, namelist, bitspec, filterbus):
+        self.namelist = namelist
+        self.bitspec = bitspec
+        self.fbus = filterbus  # filter identifying which are bus pins
+
+    def get_nonbuspins(self):
+        return filter(lambda x: not x.name_.startswith(self.fbus), self.pins)
+
+    def get_buspins(self):
+        return filter(lambda x: x.name_.startswith(self.fbus), self.pins)
+
+    def ifacepfmt(self, *args):
+        pins = self.get_nonbuspins()
+        res = '\n'.join(map(self.ifacepfmtdecpin, pins)).format(*args)
+        res = res.format(*args)
+
+        pins = self.get_buspins()
+        plen = self.get_n_iopins(pins)
+
+        res += '\n'
+        template = "          interface {1}#(%s) {2};\n" % self.bitspec
+        for i, n in enumerate(self.namelist):
+            if not n:
+                continue
+            ftype = 'Get' if i == 2 else "Put"
+            res += template.format(plen, ftype, n)
+
+        return "\n" + res
+
+    def ifacedef2(self, *args):
+        pins = self.get_nonbuspins()
+        res = '\n'.join(map(self.ifacedef2pin, pins))
+        res = res.format(*args)
+
+        pins = self.get_buspins()
+        plen = self.get_n_iopins(pins)
+        bitspec = self.bitspec.format(plen)
+        return '\n' + res + self.vectorifacedef2(
+            pins, plen, self.namelist, bitspec, *args) + '\n'
+
+    def ifacedef3pin(self, idx, pin):
+        decfn = self.ifacefmtdecfn2
+        outfn = self.ifacefmtoutfn
+        # print pin, pin.outenmode
+        if pin.outenmode:
+            decfn = self.ifacefmtdecfn3
+            outfn = self.ifacefmtoutenfn
+        return pin.ifacedef3(idx, outfn, self.ifacefmtinfn,
+                             decfn)
+
+
+class InterfaceLCD(InterfaceBus, Interface):
+
+    def __init__(self, *args):
+        InterfaceBus.__init__(self, ['data_out', None, None],
+                              "Bit#({0})", "out")
+        Interface.__init__(self, *args)
+
+    def get_n_iopins(self, pins):  # HACK! assume in/out/outen so div by 3
+        return len(pins)
+
+
+class InterfaceFlexBus(InterfaceBus, Interface):
+
+    def __init__(self, *args):
+        InterfaceBus.__init__(self, ['ad_out', 'ad_out_en', 'ad_in'],
+                              "Bit#({0})", "ad")
+        Interface.__init__(self, *args)
+
+    def get_n_iopins(self, pins):  # HACK! assume in/out/outen so div by 3
+        return len(pins) / 3
+
+
+class InterfaceSD(InterfaceBus, Interface):
+
+    def __init__(self, *args):
+        InterfaceBus.__init__(self, ['out', 'out_en', 'in'],
+                              "Bit#({0})", "d")
+        Interface.__init__(self, *args)
+
+    def get_n_iopins(self, pins):  # HACK! assume in/out/outen so div by 3
+        return len(pins) / 3
+
+
+class InterfaceNSPI(InterfaceBus, Interface):
+
+    def __init__(self, *args):
+        InterfaceBus.__init__(self, ['io_out', 'io_out_en', 'io_in'],
+                              "Bit#({0})", "io")
+        Interface.__init__(self, *args)
+
+    def get_n_iopins(self, pins):  # HACK! assume in/out/outen so div by 3
+        return len(pins) / 3
+
+
+class InterfaceEINT(Interface):
+    """ uses old-style (non-get/put) for now
+    """
+
+    def ifacepfmt(self, *args):
+        res = '\n'.join(map(self.ifacefmtdecpin, self.pins)).format(*args)
+        return '\n' + res  # pins is a list
+
+    def ifacedef2(self, *args):
+        return self.ifacedef(*args)
+
+
+class InterfaceGPIO(InterfaceBus, Interface):
+    """ note: the busfilter cuts out everything as the entire set of pins
+        is a bus, but it's less code.  get_nonbuspins returns empty list.
+    """
+
+    def __init__(self, ifacename, pinspecs, ganged=None, single=False):
+        InterfaceBus.__init__(self, ['out', 'out_en', 'in'],
+                              "Vector#({0},Bit#(1))", ifacename[-1])
+        Interface.__init__(self, ifacename, pinspecs, ganged, single)
+
+    def get_n_iopins(self, pins):  # HACK! assume in/out/outen so div by 3
+        return len(pins) / 3
+
+
 class Interfaces(InterfacesBase, PeripheralInterfaces):
     """ contains a list of interface definitions
     """
 
     def __init__(self, pth=None):
-        InterfacesBase.__init__(self, Interface, pth)
+        InterfacesBase.__init__(self, Interface, pth,
+                                {'gpio': InterfaceGPIO,
+                                 'spi': InterfaceNSPI,
+                                 'mspi': InterfaceNSPI,
+                                 'lcd': InterfaceLCD,
+                                 'sd': InterfaceSD,
+                                 'fb': InterfaceFlexBus,
+                                 'qspi': InterfaceNSPI,
+                                 'mqspi': InterfaceNSPI,
+                                 'eint': InterfaceEINT})
         PeripheralInterfaces.__init__(self)
 
     def ifacedef(self, f, *args):