when muxwidth == 1 output pin directly
[pinmux.git] / src / bsv / actual_pinmux.py
index d35757b65bd62a5c52fc77ecd771ef7d8ca0f788..7156fd154af5d8edbadbfbcdad481f6e309568bf 100644 (file)
@@ -24,13 +24,6 @@ dedicated_wire = '''
 digits = maketrans('0123456789', ' ' * 10)  # delete space later
 
 
-def get_cell_bit_width(p):
-    max_num_cells = 0
-    for cell in p.muxed_cells:
-        max_num_cells = max(len(cell) - 1, max_num_cells)
-    return int(math.log(max_num_cells + 1, 2))
-
-
 def cn(idx):  # idx is an integer
     return "cell%s_mux" % str(idx)
 
@@ -47,26 +40,38 @@ def transfn(temp):
 
 # XXX this needs to move into interface_decl.py
 # and made to use ifaceoutfmtfn and ifaceinfmtfn
-def fmt(ifaces, cell, idx, suffix=None):
+def fmt(ifaces, cells, idx, suffix=None):
     """ blank entries need to output a 0 to the pin (it could just as
         well be a 1 but we choose 0).  reason: blank entries in
         the pinmap.txt file indicate that there's nothing to choose
         from.  however the user may still set the muxer to that value,
         and rather than throw an exception we choose to output... zero.
+
+        NOTE: IMPORTANT.  when a function is an output-only there
+        is a special-case assumption that:
+        * (a) GPIO is always the first mux entry
+        * (b) GPIO's outen is also used to set the pad
+        the reason for this is that it is assumed better that
+        multiple pads be switched simutaneously to outputs
+        by setting the GPIO direction rather than having them
+        set arbitrarily by changing the muxer registers.
     """
     idx += 1
-    if idx < len(cell):
-        cell = cell[idx]
+    if idx < len(cells):
+        cell = cells[idx]
     else:
         cell = ''
+    #print "fmt", idx, cells, cell
     if not cell:
-        return '0'
+        return 'val0'
     temp = transfn(cell)
     x = ifaces.getifacetype(temp)
     if x == 'input':
-        return '0'  # inputs don't get passed through to the out mux
+        return 'val0'  # inputs don't get passed through to the out mux
     if suffix == '_outen' and x == 'out':
-        return '1'
+        return "wr%s%s" % (cells[1], suffix or '')  # USE GPIO FOR SELECTION
+    if x == 'out':  # sigh hack, should be using interface_decl
+        suffix = ''
     return "wr%s%s" % (cell, suffix or '')
 
 # XXX this needs to move into interface_decl.py
@@ -99,18 +104,22 @@ def mkmux(p, ifaces, cell, suffix, outenmode):
         multiple inputs and, based on an "address" routes
         a given indexed input through to the (one) output
     """
+    cellnum = cell[0]
     comment = 'outen' if outenmode else 'output'
     fmtstr = "\t\t\twr%s==%d?%s:%s\n"  # mux-selector format
     ret = ''
-    ret += "      // %s muxer for cell idx %s\n" % (comment, cell[0])
-    ret += "      %s%s=\n" % (cn(cell[0]), suffix)
-    for i in range(
-            0, (1 << p.cell_bitwidth) - 1):  # full mux range (minus 1)
-        comment = mkcomment(ifaces, cell, i, outenmode)
-        cf = fmt(ifaces, cell, i, suffix)
-        ret += fmtstr % (cn(cell[0]), i, cf, comment)
-    comment = mkcomment(ifaces, cell, i + 1, outenmode)
-    ret += "\t\t\t" + fmt(ifaces, cell, i + 1, suffix)  # last line
+    ret += "      // %s muxer for cell idx %s\n" % (comment, cellnum)
+    ret += "      %s%s=\n" % (cn(cellnum), suffix)
+    i = 0
+    mwid = p.get_muxwidth(cellnum)
+    if mwid > 1:
+        for i in range(0, mwid - 1):  # full mux range (minus 1)
+            comment = mkcomment(ifaces, cell, i, outenmode)
+            cf = fmt(ifaces, cell, i, suffix)
+            ret += fmtstr % (cn(cell[0]), i, cf, comment)
+        i += 1
+    comment = mkcomment(ifaces, cell, i, outenmode)
+    ret += "\t\t\t" + fmt(ifaces, cell, i, suffix)  # last line
     ret += ";%s\n" % comment
 
     return ret
@@ -136,11 +145,15 @@ def init(p, ifaces):
         the last one, and we do not want the "default" (last line)
         to be the output.
     """
-    p.cell_bitwidth = get_cell_bit_width(p)
     p.pinmux = ' '
     global dedicated_wire
     for cell in p.muxed_cells:
 
+        cellidx = cell[0]
+
+        p.pinmux += "      // --------------------\n"
+        p.pinmux += "      // ----- cell %s -----\n\n" % (cellidx)
+
         # first do the outputs
         p.pinmux += mkmux(p, ifaces, cell, '_out', False)
         p.pinmux += "\n"
@@ -156,26 +169,23 @@ def init(p, ifaces):
         # since the interfaces are always standard and cannot change from
         # user-to-user. Plus this also reduces human-error as well :)
         p.pinmux += "\n"
-        p.pinmux += "      // priority-in-muxer for cell idx %s\n" % (cell[0])
+        p.pinmux += "      // priority-in-muxer for cell idx %s\n" % (cellidx)
         for i in range(0, len(cell) - 1):
             cname = cell[i + 1]
             if not cname:  # skip blank entries, no need to test
                 continue
             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" + \
                 " dictionary. Update dictionary or fix-typo."
-            if x == "input":
-                p.pinmux += \
-                    mux_wire.format(cell[0], i, "wr" + cname) + "\n"
-            elif x == "inout":
-                p.pinmux += \
-                    mux_wire.format(cell[0], i, "wr" + cname +
-                                                "_in") + "\n"
-    # ============================================================ #
+            bwid = p.get_muxbitwidth(cellidx)
+            if bwid > 0:
+                muxcell(p, cname, x, cell, i)
+            else:
+                dedcell(p, x, cell)
 
     # ==================  Logic for dedicated pins ========= #
     p.pinmux += "\n      /*=========================================*/\n"
@@ -186,12 +196,20 @@ def init(p, ifaces):
         temp = transfn(cell[1])
         x = ifaces.getifacetype(temp)
         #print cell, temp, x
-        if x == "input":
-            p.pinmux += \
-                dedicated_wire.format(cell[0], "wr" + cell[1]) + "\n"
-        elif x == "inout":
-            p.pinmux += \
-                dedicated_wire.format(cell[0], "wr" + cell[1] + "_in") + "\n"
-        else:
-            p.pinmux += "\n"
-    # =======================================================#
+        dedcell(p, x, cell)
+
+def muxcell(p, cname, x, cell, i):
+    if x == "input":
+        p.pinmux += \
+            mux_wire.format(cell[0], i, "wr" + cname) + "\n"
+    elif x == "inout":
+        p.pinmux += \
+            mux_wire.format(cell[0], i, "wr" + cname +
+                                        "_in") + "\n"
+def dedcell(p, x, cell):
+    if x == "input":
+        p.pinmux += \
+            dedicated_wire.format(cell[0], "wr" + cell[1]) + "\n"
+    elif x == "inout":
+        p.pinmux += \
+            dedicated_wire.format(cell[0], "wr" + cell[1] + "_in") + "\n"