pep8 cleanup
[pinmux.git] / src / bsv / actual_pinmux.py
1 import math
2 from string import digits
3 try:
4 from string import maketrans
5 except ImportError:
6 maketrans = str.maketrans
7
8
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
13 mux_wire = '''
14 rule assign_{2}_on_cell{0}(wrcell{0}_mux=={1});
15 {2}<=cell{0}_mux_in;
16 endrule
17 '''
18 dedicated_wire = '''
19 rule assign_{1}_on_cell{0};
20 {1}<=cell{0}_mux_in;
21 endrule
22 '''
23 # ============================================================
24 digits = maketrans('0123456789', ' ' * 10) # delete space later
25
26
27 def get_cell_bit_width(p):
28 max_num_cells = 0
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))
32
33
34 def cn(idx): # idx is an integer
35 return "cell%s_mux" % str(idx)
36
37
38 def transfn(temp):
39 """ removes the number from the string of signal name.
40 """
41 temp = temp.split('_')
42 if len(temp) == 2:
43 temp[0] = temp[0].translate(digits)
44 temp[0] = temp[0] .replace(' ', '')
45 return '_'.join(temp)
46
47
48 def fmt(cell, idx):
49 """ blank entries need to output a 0 to the pin (it could just as
50 well be a 1 but we choose 0). reason: blank entries in
51 the pinmap.txt file indicate that there's nothing to choose
52 from. however the user may still set the muxer to that value,
53 and rather than throw an exception we choose to output... zero.
54 """
55 idx += 1
56 if idx < len(cell):
57 cell = cell[idx]
58 else:
59 cell = ''
60 return "%s_io" % cell if cell else '0'
61
62
63 def mkcomment(p, cell, idx):
64 """ returns a comment string for the cell when muxed
65 """
66 return ""
67
68
69 def init(p, ifaces):
70 """ generates the actual output pinmux for each io-cell. blank lines
71 need to output "0" to the iopad, if there is no entry in
72 that column.
73
74 text is outputted in the format:
75 x_out =
76 muxer_sel==0 ? a :
77 muxer_sel==1 ? b :
78 muxer_sel==2 ? 0 :
79 d
80
81 last line doesn't need selector-logic, obviously.
82
83 note that it's *important* that all muxer options be covered
84 (hence going up to 1<<cell_bitwidth) even if the muxer cells
85 are blank (no entries), because muxer selection could be to
86 the last one, and we do not want the "default" (last line)
87 to be the output.
88 """
89 p.cell_bitwidth = get_cell_bit_width(p)
90 p.pinmux = ' '
91 global dedicated_wire
92 fmtstr = "\t\t\twr%s == %d ? %s :%s\n" # mux-selector format
93 for cell in p.muxed_cells:
94 p.pinmux += " // output muxer for cell idx %s\n" % cell[0]
95 p.pinmux += " %s_out=\n" % cn(cell[0])
96 for i in range(
97 0, (1 << p.cell_bitwidth) - 1): # full mux range (minus 1)
98 comment = mkcomment(p, cell, i)
99 p.pinmux += fmtstr % (cn(cell[0]), i, fmt(cell, i), comment)
100 comment = mkcomment(p, cell, i + 1)
101 p.pinmux += "\t\t\t" + fmt(cell, i + 1) + comment # last line
102 p.pinmux += ";\n"
103 # ======================================================== #
104
105 # check each cell if "peripheral input/inout" then assign its wire
106 # Here we check the direction of each signal in the dictionary.
107 # We choose to keep the dictionary within the code and not user-input
108 # since the interfaces are always standard and cannot change from
109 # user-to-user. Plus this also reduces human-error as well :)
110 for i in range(0, len(cell) - 1):
111 cname = cell[i + 1]
112 if not cname: # skip blank entries, no need to test
113 continue
114 temp = transfn(cname)
115 x = ifaces.getifacetype(temp)
116 #print (cname, temp, x)
117 assert x is not None, "ERROR: The signal : " + \
118 str(cname) + \
119 " of pinmap.txt isn't present \nin the current" + \
120 " dictionary. Update dictionary or fix-typo."
121 if x == "input":
122 p.pinmux += \
123 mux_wire.format(cell[0], i, "wr" + cname) + "\n"
124 elif x == "inout":
125 p.pinmux += \
126 mux_wire.format(cell[0], i, "wr" + cname +
127 "_in") + "\n"
128 # ============================================================ #
129
130 # ================== Logic for dedicated pins ========= #
131 for cell in p.dedicated_cells:
132 p.pinmux += " %s_out=%s_io;\n" % (cn(cell[0]), cell[1])
133 temp = cell[1].translate(digits)
134 x = ifaces.getifacetype(temp)
135 if x == "input":
136 pinmux = pinmux + \
137 dedicated_wire.format(cell[0], "wr" + cell[1]) + "\n"
138 elif x == "inout":
139 pinmux = pinmux + \
140 dedicated_wire.format(cell[0], "wr" + cell[1] + "_in") + "\n"
141 # =======================================================#