remove tab indentation
[pinmux.git] / src / bsv / peripheral_gen / base.py
index 72385cf2b5f5f26f5b3e33ae59b9dd8a23fd4145..609e821f381be2df32daf952dbe05725e448b719 100644 (file)
@@ -76,6 +76,31 @@ class PBase(object):
     def slowimport(self):
         return ''
 
+    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 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
+
     def num_axi_regs32(self):
         return 0
 
@@ -85,56 +110,94 @@ class PBase(object):
     def get_iname(self, inum):
         return "{0}{1}".format(self.name, self.mksuffix(self.name, inum))
 
-    def axibase(self, name, ifacenum):
+    def axibase(self, name, ifacenum, idx):
         name = name.upper()
-        return "%(name)s%(ifacenum)dBase" % locals()
+        return "%(name)s%(ifacenum)d%(idx)sBase" % locals()
 
-    def axiend(self, name, ifacenum):
+    def axiend(self, name, ifacenum, idx):
         name = name.upper()
-        return "%(name)s%(ifacenum)dEnd" % locals()
+        return "%(name)s%(ifacenum)d%(idx)sEnd" % locals()
 
-    def axi_reg_def(self, start, name, ifacenum):
+    def _axi_reg_def(self, idx, numregs, start, name, ifacenum):
         name = name.upper()
-        offs = self.num_axi_regs32() * 4 * 16
+        offs = numregs * 4 * 16
         if offs == 0:
             return ('', 0)
         end = start + offs - 1
-        bname = self.axibase(name, ifacenum)
-        bend = self.axiend(name, ifacenum)
-        comment = "%d 32-bit regs" % self.num_axi_regs32()
-        return ("    `define %(bname)s 'h%(start)08X\n"
-                "    `define %(bend)s  'h%(end)08X // %(comment)s" % locals(),
+        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(),
                 offs)
 
+    def axi_reg_def(self, start, name, ifacenum):
+        offs = self.num_axi_regs32cfg()
+        if offs == 0:
+            return ('', 0)
+        if not isinstance(offs, list):
+            offs = [offs]
+        res = []
+        offstotal = 0
+        print offs
+        for (idx, nregs) in enumerate(offs):
+            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)
+        return ('\n'.join(res), offstotal)
+
     def axi_master_name(self, name, ifacenum, typ=''):
         name = name.upper()
         return "{0}{1}_master_num".format(name, ifacenum)
 
-    def axi_slave_name(self, name, ifacenum, typ=''):
+    def axi_slave_name(self, idx, name, ifacenum, typ=''):
         name = name.upper()
-        return "{0}{1}_{2}slave_num".format(name, ifacenum, typ)
+        return "{0}{1}{3}_{2}slave_num".format(name, ifacenum, typ, idx)
 
     def axi_master_idx(self, idx, name, ifacenum, typ):
         name = self.axi_master_name(name, ifacenum, typ)
         return ("typedef {0} {1};".format(idx, name), 1)
 
     def axi_slave_idx(self, idx, name, ifacenum, typ):
-        name = self.axi_slave_name(name, ifacenum, typ)
-        return ("typedef {0} {1};".format(idx, name), 1)
+        offs = self.num_axi_regs32()
+        if offs == 0:
+            return ''
+        if not isinstance(offs, list):
+            offs = [offs]
+        res = []
+        for (i, nregs) in enumerate(offs):
+            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):
         return self.axi_addr_map(name, ifacenum, 'fast')
 
-    def axi_addr_map(self, name, ifacenum, typ=""):
-        bname = self.axibase(name, ifacenum)
-        bend = self.axiend(name, ifacenum)
-        name = self.axi_slave_name(name, ifacenum, typ)
+    def _axi_addr_map(self, idx, name, ifacenum, typ=""):
+        bname = self.axibase(name, ifacenum, idx)
+        bend = self.axiend(name, ifacenum, idx)
+        name = self.axi_slave_name(idx, name, ifacenum, typ)
         template = """\
 if(addr>=`{0} && addr<=`{1})
     return tuple2(True,fromInteger(valueOf({2})));
 else"""
         return template.format(bname, bend, name)
 
+    def axi_addr_map(self, name, ifacenum, typ=""):
+        offs = self.num_axi_regs32()
+        if offs == 0:
+            return ''
+        if not isinstance(offs, list):
+            offs = [offs]
+        res = []
+        for (idx, nregs) in enumerate(offs):
+            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):
         # TODO: really should be using bsv.interface_decl.Interfaces
         # pin-naming rules.... logic here is hard-coded to duplicate
@@ -166,7 +229,7 @@ else"""
                     else:
                         ps_ = ps
                     cn = self._mk_actual_connection('out', name,
-                                                    count, typ, 
+                                                    count, typ,
                                                     pname, ps_, n_, fname)
                     ret += cn
                 fname = None
@@ -177,7 +240,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':
@@ -200,6 +263,7 @@ else"""
         if stype is None:
             stype = pname
         ret = []
+        ret.append("//%s %s %s %s %s" % (name, ptyp, typ, pname, stype))
         if ptyp == 'fast':
             sname = self.get_iname(count)
             ps = "slow_peripherals.%s" % sname
@@ -207,6 +271,8 @@ else"""
             sname = self.peripheral.iname().format(count)
             ps = "pinmux.peripheral_side.%s" % sname
         n = self.get_iname(count)
+        if typ == 'in':
+            n = "{0}.{1}".format(n, stype)
         ps_ = "{0}.{1}".format(ps, pname)
         ret += self._mk_actual_connection(typ, name, count, typ,
                                           pname, ps_, n, stype)
@@ -233,35 +299,33 @@ 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)
-                n = "{0}.{1}".format(n, fname)
                 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)
         if ck == PBase.get_clock_reset(self, name, count):
             return ''
         if ctype == 'slow':
-            spc = "sp_clock, sp_reset"
+            spc = self.get_clk_spc(ctype)
         else:
             spc = ck
-            ck = "core_clock, core_reset"
+            ck = self.get_clk_spc(ctype)
         template = """\
 Ifc_sync#({0}) {1}_sync <-mksyncconnection(
             {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:
@@ -283,23 +347,30 @@ Ifc_sync#({0}) {1}_sync <-mksyncconnection(
                 ret.append(template.format("Bit#(1)", n_, spc, ck))
         return '\n'.join(ret)
 
+    def get_clk_spc(self, ctype):
+        if ctype == 'slow':
+            return "sp_clock, sp_reset"
+        else:
+            return "core_clock, core_reset"
+
     def _mk_clk_vcon(self, name, count, ctype, typ, pname, bitspec):
         ck = self.get_clock_reset(name, count)
         if ck == PBase.get_clock_reset(self, name, count):
             return ''
         if ctype == 'slow':
-            spc = "sp_clock, sp_reset"
+            spc = self.get_clk_spc(ctype)
         else:
             spc = ck
-            ck = "core_clock, core_reset"
+            ck = self.get_clk_spc(ctype)
         template = """\
 Ifc_sync#({0}) {1}_sync <-mksyncconnection(
             {2}, {3});"""
 
         n_ = "{0}{1}".format(name, count)
         n_ = '{0}_{1}'.format(n_, pname)
-        return template.format(bitspec,  n_, ck, spc)
-
+        if typ == 'in' or typ == 'inout':
+            ck, spc = spc, ck
+        return template.format(bitspec, n_, ck, spc)
 
     def mk_cellconn(self, *args):
         return ''
@@ -313,7 +384,7 @@ Ifc_sync#({0}) {1}_sync <-mksyncconnection(
     def mksuffix(self, name, i):
         return i
 
-    def __mk_connection(self, con, aname, fabricname):
+    def __mk_connection(self, con, aname, count, fabricname):
         txt = "mkConnection ({2}.v_to_slaves\n" + \
               "            [fromInteger(valueOf({1}))],\n" + \
               "            {0});"
@@ -321,27 +392,51 @@ Ifc_sync#({0}) {1}_sync <-mksyncconnection(
         print "PBase __mk_connection", self.name, aname
         if not con:
             return ''
+        con = con.format(count, aname)
         return txt.format(con, aname, fabricname)
 
-    def __mk_master_connection(self, con, aname):
-        txt = "mkConnection (slow_fabric.v_to_slaves\n" + \
-              "            [fromInteger(valueOf({1}))],\n" + \
-              "            {0});"
+    def __mk_master_connection(self, con, aname, count, fabricname):
+        txt = "mkConnection ({0}, {2}.v_from_masters\n" + \
+              "            [fromInteger(valueOf({1}))]);\n"
 
-        print "PBase __mk_connection", self.name, aname
+        print "PBase __mk_master_connection", self.name, aname
         if not con:
             return ''
-        return txt.format(con, aname)
+        con = con.format(count, aname)
+        return txt.format(con, aname, fabricname)
+
+    def mk_master_connection(self, count, fabricname, typ, name=None):
+        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 = []
+        connections = self._mk_connection(name, count, True)
+        if not isinstance(connections, list):
+            connections = [connections]
+        for con in connections:
+            ret.append(self.__mk_master_connection(con, aname, count,
+                                                   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
-        aname = self.axi_slave_name(name, count, typ)
-        #dname = self.mksuffix(name, count)
-        #dname = "{0}{1}".format(name, dname)
-        con = self._mk_connection(name, count).format(count, aname)
-        return self.__mk_connection(con, aname, fabricname)
+        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)
+            ret.append(self.__mk_connection(con, aname, count, fabricname))
+        return '\n'.join(ret)
 
     def _mk_connection(self, name=None, count=0):
         return ''
@@ -495,7 +590,8 @@ class PeripheralIface(object):
                       'mkfast_peripheral',
                       'mk_plic', 'mk_ext_ifacedef',
                       '_mk_clk_con', 'mk_ext_ifacedef',
-                      'mk_connection', 'mk_cellconn', '_mk_pincon']:
+                      'mk_connection', 'mk_master_connection',
+                      'mk_cellconn', '_mk_pincon']:
             fn = CallFn(self, fname)
             setattr(self, fname, types.MethodType(fn, self))
 
@@ -705,31 +801,29 @@ class PeripheralInterfaces(object):
                 ret.append(x.format(suffix))
         return '\n'.join(li(list(filter(None, ret)), 8))
 
-    def mk_fast_connection(self, *args):
+    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
-                txt = self.data[name].mk_connection(i, "fabric", "fast")
+                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
-                    print self.data[name].mk_connection
                 ret.append(txt)
-        return '\n'.join(li(list(filter(None, ret)), 12))
+        return '\n'.join(li(list(filter(None, ret)), indent))
+
+    def mk_master_connection(self, *args):
+        return self._mk_connection("fabric", "fast", 8, True, *args)
+
+    def mk_fast_connection(self, *args):
+        return self._mk_connection("fabric", "fast", 12, False, *args)
 
     def mk_connection(self, *args):
-        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_connection(i, "slow_fabric", "")
-                if name == 'gpioa':
-                    print "txt", txt
-                    print self.data[name].mk_connection
-                ret.append(txt)
-        return '\n'.join(li(list(filter(None, ret)), 8))
+        return self._mk_connection("slow_fabric", "", 8, False, *args)
 
     def mk_cellconn(self):
         ret = []
@@ -877,10 +971,12 @@ class PFactory(object):
         from gpio import gpio
         from rgbttl import rgbttl
         from flexbus import flexbus
+        from sdram import sdram
 
         for k, v in {'uart': uart,
                      'rs232': rs232,
                      'twi': twi,
+                     'sdr': sdram,
                      'quart': quart,
                      'mqspi': mqspi,
                      'mspi': mspi,
@@ -888,7 +984,7 @@ class PFactory(object):
                      'spi': spi,
                      'pwm': pwm,
                      'eint': eint,
-                     'sd': sdmmc,
+                     'mmc': sdmmc,
                      'jtag': jtag,
                      'lcd': rgbttl,
                      'fb': flexbus,