X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbsv%2Factual_pinmux.py;h=c5644307e3d5a34c0efae188ff41427b81a81a03;hb=c68ea7590aa3aaa449cf9c4edb1ac56219ac9a92;hp=2db44186be650986cbabe077a1b89a2e2cb45c68;hpb=6581aeb82a869d6e58f001700c9e4cbdbc71dc90;p=pinmux.git diff --git a/src/bsv/actual_pinmux.py b/src/bsv/actual_pinmux.py index 2db4418..c564430 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,9 +10,11 @@ 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 = ''' - if(wrcell{0}_mux=={1}) - {2}<=cell{0}_mux_in;''' +mux_wire = '''\ + rule assign_{2}_on_cell{0}(wrcell{0}_mux=={1}); + {2}<=cell{0}_mux_in; + endrule +''' dedicated_wire = ''' rule assign_{1}_on_cell{0}; {1}<=cell{0}_mux_in; @@ -21,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) @@ -33,30 +38,137 @@ 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 = '' + 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 + for i in range( + 0, p.get_muxwidth(cellnum) - 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\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<