use class iterator for mk_connection (all of them)
[pinmux.git] / src / bsv / peripheral_gen / base.py
index fd5ef04cbeaae6e7659275f6fa9d36e6c8204675..582a035016560882fa6e4dca52b8000786e1cb32 100644 (file)
@@ -20,9 +20,56 @@ def li(txt, indent):
     return res
 
 
-class PBase(object):
+class MMapConfig(object):
+
+    def get_mmap_configs(self):
+        res = []
+        for cfg in self.peripheral.configs:
+            res.append(cfg.get('mmap', None))
+        # XXX HACK!  assume all configs same for each peripheral!
+        return res[0]
+
+    def map_to_idx(self, cfg, idx):
+        if isinstance(idx, int):
+            return idx
+        for (i, c) in enumerate(cfg):
+            if c[0] == idx:
+                return i
+        assert "config name %s not found" % s
+
+    def get_mmap_cfg_start(self, idx):
+        cfg = self.get_mmap_configs()
+        if cfg is None:
+            nregs = self.num_axi_regs32()
+            if isinstance(nregs, int) or len(nregs) == 1:
+                return 0
+            return "_%d_" % idx
+        idx = self.map_to_idx(cfg, idx)
+        return cfg[idx][1]
+
+    def get_mmap_cfg_name(self, idx):
+        cfg = self.get_mmap_configs()
+        if cfg is None:
+            nregs = self.num_axi_regs32()
+            if isinstance(nregs, int) or len(nregs) == 1:
+                return ""
+            return "_%d_" % idx
+        return cfg[idx][0]
+
+    def num_axi_regs32cfg(self):
+        cfg = self.get_mmap_configs()
+        if cfg is None:
+            return self.num_axi_regs32()
+        regs = []
+        for c in cfg:
+            regs.append(c[2])
+        return regs
+
+
+class PBase(MMapConfig):
     def __init__(self, name):
         self.name = name
+        MMapConfig.__init__(self)
 
     def extifdecl(self, name, count):
         sname = self.get_iname(count)
@@ -98,16 +145,22 @@ class PBase(object):
         offs = numregs * 4 * 16
         if offs == 0:
             return ('', 0)
-        end = start + offs - 1
+        cfgstart = self.get_mmap_cfg_start(idx)
+        if cfgstart:
+            start = cfgstart
+            end = start + offs - 1
+            offs = 0  # don't do contiguous addressing
+        else:
+            end = start + offs - 1
         bname = self.axibase(name, ifacenum, idx)
         bend = self.axiend(name, ifacenum, idx)
         comment = "%d 32-bit regs" % numregs
-        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_reg_def(self, start, name, ifacenum):
-        offs = self.num_axi_regs32()
+        offs = self.num_axi_regs32cfg()
         if offs == 0:
             return ('', 0)
         if not isinstance(offs, list):
@@ -116,11 +169,8 @@ class PBase(object):
         offstotal = 0
         print offs
         for (idx, nregs) in enumerate(offs):
-            if len(offs) == 1:
-                idx = ""
-            else:
-                idx = "_%d_" % idx
-            (txt, off) = self._axi_reg_def(idx, nregs, start, name, ifacenum)
+            cfg = self.get_mmap_cfg_name(idx)
+            (txt, off) = self._axi_reg_def(cfg, nregs, start, name, ifacenum)
             start += off
             offstotal += off
             res.append(txt)
@@ -146,12 +196,9 @@ class PBase(object):
             offs = [offs]
         res = []
         for (i, nregs) in enumerate(offs):
-            if len(offs) == 1:
-                idx_ = ""
-            else:
-                idx_ = "_%d_" % i
-            name_ = self.axi_slave_name(idx_, name, ifacenum, typ)
-            res.append("typedef {0} {1};".format(idx+i, name_))
+            cfg = self.get_mmap_cfg_name(i)
+            name_ = self.axi_slave_name(cfg, name, ifacenum, typ)
+            res.append("typedef {0} {1};".format(idx + i, name_))
         return ('\n'.join(res), len(offs))
 
     def axi_fastaddr_map(self, name, ifacenum):
@@ -175,11 +222,8 @@ else"""
             offs = [offs]
         res = []
         for (idx, nregs) in enumerate(offs):
-            if len(offs) == 1:
-                idx = ""
-            else:
-                idx = "_%d_" % idx
-            res.append(self._axi_addr_map(idx, name, ifacenum, typ))
+            cfg = self.get_mmap_cfg_name(idx)
+            res.append(self._axi_addr_map(cfg, name, ifacenum, typ))
         return '\n'.join(res)
 
     def _mk_pincon(self, name, count, ptyp):
@@ -213,7 +257,7 @@ else"""
                     else:
                         ps_ = ps
                     cn = self._mk_actual_connection('out', name,
-                                                    count, typ, 
+                                                    count, typ,
                                                     pname, ps_, n_, fname)
                     ret += cn
                 fname = None
@@ -224,7 +268,7 @@ else"""
                         fname = "{0}.{1}".format(n_, fname)
                     fname = self.pinname_tweak(pname, 'outen', fname)
                     cn = self._mk_actual_connection('outen', name,
-                                                    count, typ, 
+                                                    count, typ,
                                                     pname, ps, n, fname)
                     ret += cn
             if typ == 'in' or typ == 'inout':
@@ -283,17 +327,16 @@ else"""
         elif ctype == 'in':
             if ck == PBase.get_clock_reset(self, name, count):
                 ret.append("mkConnection({1},\n\t\t\t{0});".format(
-                            ps, n))
+                    ps, n))
             else:
                 n2 = "{0}{1}".format(name, count)
                 sync = '{0}_{1}_sync'.format(n2, pname)
                 ret.append("mkConnection({1}.put,\n\t\t\t{0});".format(
-                            ps, sync))
+                    ps, sync))
                 ret.append("mkConnection({1},\n\t\t\t{0}.get);".format(
-                            sync, n))
+                    sync, n))
         return ret
 
-
     def _mk_clk_con(self, name, count, ctype):
         ret = []
         ck = self.get_clock_reset(name, count)
@@ -304,13 +347,12 @@ else"""
         else:
             spc = ck
             ck = self.get_clk_spc(ctype)
-        template = """\
-Ifc_sync#({0}) {1}_sync <-mksyncconnection(
-            {2}, {3});"""
+        template = "Ifc_sync#({0}) {1}_sync <-mksyncconnection(\n" + \
+                   "              {2}, {3});"
         for p in self.peripheral.pinspecs:
             typ = p['type']
             pname = p['name']
-            n = name  
+            n = name
             if typ == 'out' or typ == 'inout':
                 fname = self.pinname_out(pname)
                 if not fname:
@@ -347,16 +389,14 @@ Ifc_sync#({0}) {1}_sync <-mksyncconnection(
         else:
             spc = ck
             ck = self.get_clk_spc(ctype)
-        template = """\
-Ifc_sync#({0}) {1}_sync <-mksyncconnection(
-            {2}, {3});"""
+        template = "Ifc_sync#({0}) {1}_sync <-mksyncconnection(\n" + \
+                   "            {2}, {3});"""
 
         n_ = "{0}{1}".format(name, count)
         n_ = '{0}_{1}'.format(n_, pname)
         if typ == 'in' or typ == 'inout':
             ck, spc = spc, ck
-        return template.format(bitspec,  n_, ck, spc)
-
+        return template.format(bitspec, n_, ck, spc)
 
     def mk_cellconn(self, *args):
         return ''
@@ -383,7 +423,7 @@ Ifc_sync#({0}) {1}_sync <-mksyncconnection(
 
     def __mk_master_connection(self, con, aname, count, fabricname):
         txt = "mkConnection ({0}, {2}.v_from_masters\n" + \
-              "            [fromInteger(valueOf({1}))]);\n" 
+              "            [fromInteger(valueOf({1}))]);\n"
 
         print "PBase __mk_master_connection", self.name, aname
         if not con:
@@ -391,11 +431,9 @@ Ifc_sync#({0}) {1}_sync <-mksyncconnection(
         con = con.format(count, aname)
         return txt.format(con, aname, fabricname)
 
-    def mk_master_connection(self, count, fabricname, typ, name=None):
+    def mk_master_connection(self, name, count, fabricname, typ):
         if not self.has_axi_master():
             return ''
-        if name is None:
-            name = self.name
         print "PBase mk_master_conn", self.name, count
         aname = self.axi_master_name(name, count, typ)
         ret = []
@@ -407,20 +445,17 @@ Ifc_sync#({0}) {1}_sync <-mksyncconnection(
                                                    fabricname))
         return '\n'.join(ret)
 
-    def mk_connection(self, count, fabricname, typ, name=None):
-        if name is None:
-            name = self.name
-        print "PBase mk_conn", self.name, count
+    def mk_connection(self, name, count, fabricname, typ, name_override=None):
+        if name_override: # needed for GPIO
+            name = name_override
+        print "PBase mk_conn", name, count
         ret = []
         connections = self._mk_connection(name, count)
         if not isinstance(connections, list):
             connections = [connections]
         for (idx, con) in enumerate(connections):
-            if len(connections) == 1:
-                idx = ""
-            else:
-                idx = "_%d_" % idx
-            aname = self.axi_slave_name(idx, name, count, typ)
+            cfg = self.get_mmap_cfg_name(idx)
+            aname = self.axi_slave_name(cfg, name, count, typ)
             ret.append(self.__mk_connection(con, aname, count, fabricname))
         return '\n'.join(ret)
 
@@ -630,8 +665,6 @@ class PeripheralInterfaces(object):
         ret = []
         for (name, count) in self.ifacecount:
             for i in range(count):
-                iname = self.data[name].iname().format(i)
-                print "extfast", iname, self.is_on_fastbus(name, i)
                 if self.is_on_fastbus(name, i):
                     continue
                 ret.append(self.data[name].extfastifinstance(name, i))
@@ -641,7 +674,6 @@ class PeripheralInterfaces(object):
         ret = []
         for (name, count) in self.ifacecount:
             for i in range(count):
-                iname = self.data[name].iname().format(i)
                 ret.append(self.data[name].extifinstance2(name, i))
         return '\n'.join(li(list(filter(None, ret)), 8))
 
@@ -649,7 +681,6 @@ class PeripheralInterfaces(object):
         ret = []
         for (name, count) in self.ifacecount:
             for i in range(count):
-                iname = self.data[name].iname().format(i)
                 if not self.is_on_fastbus(name, i):
                     continue
                 ret.append(self.data[name].extifinstance(name, i))
@@ -790,16 +821,8 @@ class PeripheralInterfaces(object):
     def _mk_connection(self, fabric, typ, indent, master, *args):
         ret = []
         for (name, count) in self.ifacecount:
-            for i in range(count):
-                if self.is_on_fastbus(name, i):
-                    continue
-                if master:
-                    txt = self.data[name].mk_master_connection(i, fabric, typ)
-                else:
-                    txt = self.data[name].mk_connection(i, fabric, typ)
-                if name == 'gpioa':
-                    print "txt", txt
-                ret.append(txt)
+            ret += list(MkConnection(self, name, count,
+                            fabric, typ, master, *args))
         return '\n'.join(li(list(filter(None, ret)), indent))
 
     def mk_master_connection(self, *args):
@@ -818,7 +841,7 @@ class PeripheralInterfaces(object):
             for i in range(count):
                 if self.is_on_fastbus(name, i):
                     continue
-                res = self.data[name].mk_cellconn(cellcount, name, i)
+                res = self.data[name].mk_cellconn(name, i, cellcount)
                 if not res:
                     continue
                 (txt, cellcount) = res
@@ -835,12 +858,8 @@ class PeripheralInterfaces(object):
     def _mk_pincon(self, typ):
         ret = []
         for (name, count) in self.ifacecount:
-            for i in range(count):
-                if self.is_on_fastbus(name, i):
-                    continue
-                txt = self.data[name]._mk_pincon(name, i, typ)
-                ret.append(txt)
-        return '\n'.join(li(list(filter(None, ret)), 4))
+            ret += list(MkPinCon(self, name, count, typ))
+        return '\n'.join(li(list(ret), 4))
 
     def mk_dma_irq(self):
         ret = []
@@ -892,11 +911,7 @@ class PeripheralInterfaces(object):
     def mk_ext_ifacedef(self):
         ret = []
         for (name, count) in self.ifacecount:
-            for i in range(count):
-                if self.is_on_fastbus(name, i):
-                    continue
-                txt = self.data[name].mk_ext_ifacedef(name, i)
-                ret.append(txt)
+            ret += list(MkExtIface(self, name, count))
         return '\n'.join(li(list(filter(None, ret)), 8))
 
     def mk_plic(self):
@@ -926,11 +941,7 @@ class PeripheralInterfaces(object):
     def _mk_clk_con(self, ctype):
         ret = []
         for (name, count) in self.ifacecount:
-            for i in range(count):
-                if self.is_on_fastbus(name, i):
-                    continue
-                txt = self.data[name]._mk_clk_con(name, i, ctype)
-                ret.append(txt)
+            ret += list(MkClkCon(self, name, count, ctype))
         return '\n'.join(li(list(filter(None, ret)), 8))
 
     def is_on_fastbus(self, name, i):
@@ -941,11 +952,92 @@ class PeripheralInterfaces(object):
         return iname in self.fastbus
 
 
+class IfaceIter(object):
+
+    def __init__(self, name, count, *args):
+        self.i = 0
+        self.name = name
+        self.maxcount = count
+        self.args = args
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        while True:
+            if self.i >= self.maxcount:
+                raise StopIteration
+            if self.check(self.name, self.i):
+                #print self.item, self.args
+                res = self.item(self.name, self.i, *self.args)
+                if res:
+                    self.i += 1
+                    return res
+            self.i += 1
+
+    def next(self):
+        return self.__next__()
+
+class MkConnection(IfaceIter):
+
+    def __init__(self, ifaces, name, count, *args):
+        self.ifaces = ifaces
+        IfaceIter.__init__(self, name, count, *args)
+
+    def check(self, name, i):
+        return not self.ifaces.is_on_fastbus(name, i)
+
+    def item(self, name, i, fabric, typ, master):
+        if master:
+            return self.ifaces.data[name].mk_master_connection(name,
+                                i, fabric, typ)
+        return self.ifaces.data[name].mk_connection(name, i, fabric, typ)
+
+class MkExtIface(IfaceIter):
+
+    def __init__(self, ifaces, name, count, *args):
+        self.ifaces = ifaces
+        IfaceIter.__init__(self, name, count, *args)
+
+    def check(self, name, i):
+        return not self.ifaces.is_on_fastbus(name, i)
+
+    def item(self, name, i):
+        return self.ifaces.data[name].mk_ext_ifacedef(name, i)
+
+
+class MkPinCon(IfaceIter):
+
+    def __init__(self, ifaces, name, count, *args):
+        self.ifaces = ifaces
+        IfaceIter.__init__(self, name, count, *args)
+
+    def check(self, name, i):
+        return not self.ifaces.is_on_fastbus(name, i)
+
+    def item(self, name, i, typ):
+        return self.ifaces.data[name]._mk_pincon(name, i, typ)
+
+
+class MkClkCon(IfaceIter):
+
+    def __init__(self, ifaces, name, count, *args):
+        self.ifaces = ifaces
+        IfaceIter.__init__(self, name, count, *args)
+
+    def check(self, name, i):
+        return not self.ifaces.is_on_fastbus(name, i)
+
+    def item(self, name, i, ctype):
+        return self.ifaces.data[name]._mk_clk_con(name, i, ctype)
+
+
 class PFactory(object):
     def getcls(self, name):
         from uart import uart
         from quart import quart
         from sdmmc import sdmmc
+        from emmc import emmc
         from pwm import pwm
         from eint import eint
         from rs232 import rs232
@@ -971,6 +1063,7 @@ class PFactory(object):
                      'pwm': pwm,
                      'eint': eint,
                      'mmc': sdmmc,
+                     'emmc': emmc,
                      'jtag': jtag,
                      'lcd': rgbttl,
                      'fb': flexbus,