2 from string
import digits
4 from string
import maketrans
6 maketrans
= str.maketrans
9 # ============== common bsv templates ============ #
10 # first argument is the io-cell number being assigned.
11 # second argument is the mux value.
12 # Third argument is the signal from the pinmap file
14 rule assign_{2}_on_cell{0}(wrcell{0}_mux=={1});
19 rule assign_{1}_on_cell{0};
23 # ============================================================
24 digits
= maketrans('0123456789', ' ' * 10) # delete space later
27 def get_cell_bit_width(p
):
29 for cell
in p
.muxed_cells
:
30 max_num_cells
= max(len(cell
) - 1, max_num_cells
)
31 return int(math
.log(max_num_cells
+1, 2))
34 def cn(idx
): # idx is an integer
35 return "cell%s_mux" % str(idx
)
39 """ removes the number from the string of signal name.
41 temp
= temp
.split('_')
43 temp
[0] = temp
[0].translate(digits
)
44 temp
[0] = temp
[0] .replace(' ', '')
48 """ blank entries need to output a 0 to the pin (it could just as
49 well be a 1 but we choose 0). reason: blank entries in
50 the pinmap.txt file indicate that there's nothing to choose
51 from. however the user may still set the muxer to that value,
52 and rather than throw an exception we choose to output... zero.
59 return "%s_io" % cell
if cell
else '0'
62 def mkcomment(p
, cell
, idx
):
63 """ returns a comment string for the cell when muxed
68 """ generates the actual output pinmux for each io-cell. blank lines
69 need to output "0" to the iopad, if there is no entry in
72 text is outputted in the format:
79 last line doesn't need selector-logic, obviously.
81 note that it's *important* that all muxer options be covered
82 (hence going up to 1<<cell_bitwidth) even if the muxer cells
83 are blank (no entries), because muxer selection could be to
84 the last one, and we do not want the "default" (last line)
87 p
.cell_bitwidth
= get_cell_bit_width(p
)
90 fmtstr
= "\t\t\twr%s == %d ? %s :%s\n" # mux-selector format
91 for cell
in p
.muxed_cells
:
92 p
.pinmux
+= " // output muxer for cell idx %s\n" % cell
[0]
93 p
.pinmux
+= " %s_out=\n" % cn(cell
[0])
94 for i
in range(0, (1<<p
.cell_bitwidth
)-1): # full mux range (minus 1)
95 comment
= mkcomment(p
, cell
, i
)
96 p
.pinmux
+= fmtstr
% (cn(cell
[0]), i
, fmt(cell
, i
), comment
)
97 comment
= mkcomment(p
, cell
, i
+1)
98 p
.pinmux
+= "\t\t\t" + fmt(cell
, i
+1) + comment
# last line
100 # ======================================================== #
102 # check each cell if "peripheral input/inout" then assign its wire
103 # Here we check the direction of each signal in the dictionary.
104 # We choose to keep the dictionary within the code and not user-input
105 # since the interfaces are always standard and cannot change from
106 # user-to-user. Plus this also reduces human-error as well :)
107 for i
in range(0, len(cell
) - 1):
109 if not cname
: # skip blank entries, no need to test
111 temp
= transfn(cname
)
112 x
= ifaces
.getifacetype(temp
)
113 #print (cname, temp, x)
114 assert x
is not None, "ERROR: The signal : " + \
116 " of pinmap.txt isn't present \nin the current" + \
117 " dictionary. Update dictionary or fix-typo."
120 mux_wire
.format(cell
[0], i
, "wr" + cname
) + "\n"
123 mux_wire
.format(cell
[0], i
, "wr" + cname
+
125 # ============================================================ #
127 # ================== Logic for dedicated pins ========= #
128 for cell
in p
.dedicated_cells
:
129 p
.pinmux
+= " %s_out=%s_io;\n" % (cn(cell
[0]), cell
[1])
130 temp
= cell
[1].translate(digits
)
131 x
= ifaces
.getifacetype(temp
)
134 dedicated_wire
.format(cell
[0], "wr" + cell
[1]) + "\n"
137 dedicated_wire
.format(cell
[0], "wr" + cell
[1] + "_in") + "\n"
138 # =======================================================#