X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbsv%2Factual_pinmux.py;h=7156fd154af5d8edbadbfbcdad481f6e309568bf;hb=468e620ba89e3fa05b53d8f89b10b6673e3a4307;hp=c382e7e512cc05ddd12227da7c72398ca8fe9522;hpb=348986f861e007cc2ee70ade84f5f4770f5ef7f7;p=pinmux.git diff --git a/src/bsv/actual_pinmux.py b/src/bsv/actual_pinmux.py index c382e7e..7156fd1 100644 --- a/src/bsv/actual_pinmux.py +++ b/src/bsv/actual_pinmux.py @@ -1,3 +1,4 @@ +import math from string import digits try: from string import maketrans @@ -9,7 +10,7 @@ except ImportError: # first argument is the io-cell number being assigned. # second argument is the mux value. # Third argument is the signal from the pinmap file -mux_wire = ''' +mux_wire = '''\ rule assign_{2}_on_cell{0}(wrcell{0}_mux=={1}); {2}<=cell{0}_mux_in; endrule @@ -23,11 +24,13 @@ dedicated_wire = ''' digits = maketrans('0123456789', ' ' * 10) # delete space later -def cn(idx): +def cn(idx): # idx is an integer return "cell%s_mux" % str(idx) def transfn(temp): + """ removes the number from the string of signal name. + """ temp = temp.split('_') if len(temp) == 2: temp[0] = temp[0].translate(digits) @@ -35,21 +38,129 @@ def transfn(temp): return '_'.join(temp) +# XXX this needs to move into interface_decl.py +# and made to use ifaceoutfmtfn and ifaceinfmtfn +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(cells): + cell = cells[idx] + else: + cell = '' + #print "fmt", idx, cells, cell + if not cell: + return 'val0' + temp = transfn(cell) + x = ifaces.getifacetype(temp) + if x == 'input': + return 'val0' # inputs don't get passed through to the out mux + if suffix == '_outen' and x == 'out': + 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 + + +def mkcomment(ifaces, cell, idx, outenmode=False): + """ returns a comment string for the cell when muxed + """ + idx += 1 + if idx >= len(cell): + return ' // unused' + cname = cell[idx] + if not cname: + return ' // unused' + temp = transfn(cname) + x = ifaces.getifacetype(temp) + #print (cname, x) + if x == 'input': + return ' // %s is an input' % cname + if outenmode and x == 'inout': + return ' // bi-directional' + if outenmode and x == 'out': + return ' // %s is an output' % cname + + return "" + + +def mkmux(p, ifaces, cell, suffix, outenmode): + """ creates a straight many-to-one muxer that accepts + 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, 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 + + def init(p, ifaces): """ generates the actual output pinmux for each io-cell. blank lines need to output "0" to the iopad, if there is no entry in that column. + + text is outputted in the format: + x_out = + muxer_sel==0 ? a : + muxer_sel==1 ? b : + muxer_sel==2 ? 0 : + d + + last line doesn't need selector-logic, obviously. + + note that it's *important* that all muxer options be covered + (hence going up to 1< 0: + muxcell(p, cname, x, cell, i) + else: + dedcell(p, x, cell) # ================== Logic for dedicated pins ========= # + p.pinmux += "\n /*=========================================*/\n" + p.pinmux += " // dedicated cells\n\n" for cell in p.dedicated_cells: + p.pinmux += " // dedicated cell idx %s\n" % (cell[0]) p.pinmux += " %s_out=%s_io;\n" % (cn(cell[0]), cell[1]) - temp = cell[1].translate(digits) + temp = transfn(cell[1]) x = ifaces.getifacetype(temp) - if x == "input": - pinmux = pinmux + \ - dedicated_wire.format(cell[0], "wr" + cell[1]) + "\n" - elif x == "inout": - pinmux = pinmux + \ - dedicated_wire.format(cell[0], "wr" + cell[1] + "_in") + "\n" - # =======================================================# + #print cell, temp, x + 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"