add busenable output
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 9 Apr 2018 14:04:36 +0000 (15:04 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 9 Apr 2018 14:04:36 +0000 (15:04 +0100)
src/bsv/actual_pinmux.py
src/bsv/interface_decl.py
src/bsv/pinmux_generator.py

index 337bd92e8a3bcda080f44da879f67d107a6e18d1..982cf46bf2f44113eb9799e46f125d9e341b42e0 100644 (file)
@@ -56,7 +56,7 @@ def init(p, ifaces):
             cname = cell[i + 1]
             temp = transfn(cname)
             x = ifaces.getifacetype(temp)
-            print (cname, temp, x)
+            #print (cname, temp, x)
             assert x is not None, "ERROR: The signal : " + \
                 str(cname) + \
                 " of pinmap.txt isn't present \nin the current" + \
index d9eed87d35fee58838468caad05691e6585f2984..a1313f46d027d785a031673ebc19e72e3a0c1e61 100644 (file)
@@ -87,8 +87,9 @@ class Interface(object):
         so the name must *not* be extended numerically (see pname)
     """
 
-    def __init__(self, ifacename, pinspecs, single=False):
+    def __init__(self, ifacename, pinspecs, ganged=None, single=False):
         self.ifacename = ifacename
+        self.ganged = ganged or {}
         self.pins = []
         self.pinspecs = pinspecs
         self.single = single
@@ -128,6 +129,33 @@ class Interface(object):
             return '%s_%s' % (self.ifacename, name)
         return '%s{0}_%s' % (self.ifacename, name)
 
+    def busfmt(self, *args):
+        """ this function creates a bus "ganging" system based
+            on input from the {interfacename}.txt file.
+            only inout pins that are under the control of the
+            interface may be "ganged" together.
+        """
+        if not self.ganged:
+            return ''
+        #print self.ganged
+        res = []
+        for (k, pnames) in self.ganged.items():
+            name = self.pname('%senable' % k).format(*args)
+            decl = 'Bit#(1) %s = 0;' % name
+            res.append(decl)
+            ganged = []
+            for p in self.pinspecs:
+                if p['name'] not in pnames:
+                    continue
+                pname = self.pname(p['name']).format(*args)
+                if p.get('outen') is True:
+                    outname = self.ifacefmtoutfn(pname)
+                    ganged.append("%s_outen" % outname) # match wirefmt
+            
+            gangedfmt = '{%s} = duplicate(%s);'
+            res.append(gangedfmt % (',\n  '.join(ganged), name))
+        return '\n'.join(res) + '\n\n'
+
     def wirefmt(self, *args):
         res = '\n'.join(map(self.wirefmtpin, self.pins)).format(*args)
         res += '\n'
@@ -138,7 +166,7 @@ class Interface(object):
             if p.get('outen') is True:
                 outname = self.ifacefmtoutfn(name)
                 params.append('outputval:%s_out,' % outname)
-                params.append('output_en:%s_outen,' % outname)
+                params.append('output_en:%s_outen,' % outname) # match busfmt
                 params.append('input_en:~%s_outen,' % outname)
             elif p.get('action'):
                 outname = self.ifacefmtoutfn(name)
@@ -226,8 +254,9 @@ class Interfaces(UserDict):
                 ln = ln.split("\t")
                 name = ln[0]
                 count = int(ln[1])
-                spec = self.read_spec(pth, name)
-                self.ifaceadd(name, count, Interface(name, spec, count == 1))
+                spec, ganged = self.read_spec(pth, name)
+                iface = Interface(name, spec, ganged, count == 1)
+                self.ifaceadd(name, count, iface)
 
     def getifacetype(self, fname):
         # finds the interface type, e.g sd_d0 returns "inout"
@@ -245,6 +274,7 @@ class Interfaces(UserDict):
 
     def read_spec(self, pth, name):
         spec = []
+        ganged = {}
         fname = '%s.txt' % name
         if pth:
             ift = os.path.join(pth, fname)
@@ -252,19 +282,32 @@ class Interfaces(UserDict):
             for ln in sfile.readlines():
                 ln = ln.strip()
                 ln = ln.split("\t")
-                d = {'name': ln[0]}
+                name = ln[0]
+                d = {'name': name}
                 if ln[1] == 'out':
                     d['action'] = True
                 elif ln[1] == 'inout':
                     d['outen'] = True
+                    if len(ln) == 3:
+                        bus = ln[2] 
+                        if not ganged.has_key(bus):
+                            ganged[bus] = []
+                        ganged[bus].append(name)
                 spec.append(d)
-        return spec
+        return spec, ganged
 
     def ifacedef(self, f, *args):
         for (name, count) in self.ifacecount:
             for i in range(count):
                 f.write(self.data[name].ifacedef(i))
 
+    def busfmt(self, f, *args):
+        f.write("import BUtils::*;\n\n")
+        for (name, count) in self.ifacecount:
+            for i in range(count):
+                bf = self.data[name].busfmt(i)
+                f.write(bf)
+
     def ifacefmt(self, f, *args):
         comment = '''
           // interface declaration between %s-{0} and pinmux'''
index dae7f94c8422ac932a664b5946895762d6ce6b0f..b80f65b9f05f54d03f53f6b86bd3d7de9150a1d8 100644 (file)
@@ -73,13 +73,22 @@ def pinmuxgen(pth=None, verify=True):
     if not os.path.exists(bp):
         os.makedirs(bp)
 
+    bus = os.path.join(bp, 'busenable.bsv')
     pmp = os.path.join(bp, 'pinmux.bsv')
     ptp = os.path.join(bp, 'PinTop.bsv')
     bvp = os.path.join(bp, 'bus.bsv')
 
     write_pmp(pmp, p, ifaces)
-    write_ptp(pmp, p, ifaces)
-    write_bvp(pmp, p, ifaces)
+    write_ptp(ptp, p, ifaces)
+    write_bvp(bvp, p, ifaces)
+    write_bus(bus, p, ifaces)
+
+
+def write_bus(bus, p, ifaces):
+    # package and interface declaration followed by
+    # the generic io_cell definition
+    with open(bus, "w") as bsv_file:
+        ifaces.busfmt(bsv_file)
 
 
 def write_pmp(pmp, p, ifaces):