cae4e37ce448f5b13fa258347acd6e5dcd5b2abf
[pinmux.git] / src / interface_decl.py
1 from UserDict import UserDict
2
3
4 class Pin(object):
5 """ pin interface declaration.
6 * name is the name of the pin
7 * ready, enabled and io all create a (* .... *) prefix
8 * action changes it to an "in" if true
9 """
10
11 def __init__(self, name,
12 ready=True,
13 enabled=True,
14 io=False,
15 action=False,
16 bitspec=None):
17 self.name = name
18 self.ready = ready
19 self.enabled = enabled
20 self.io = io
21 self.action = action
22 self.bitspec = bitspec if bitspec else '1'
23
24 def ifacefmt(self, fmtfn=None):
25 res = ' '
26 status = []
27 if self.ready:
28 status.append('always_ready')
29 if self.enabled:
30 status.append('always_enabled')
31 if self.io:
32 status.append('result="io"')
33 if status:
34 res += '(*'
35 res += ','.join(status)
36 res += '*)'
37 res += " method "
38 if self.io:
39 res += "\n "
40 name = fmtfn(self.name)
41 if self.action:
42 res += " Action "
43 res += name
44 res += ' (Bit#(%s) in)' % self.bitspec
45 else:
46 res += " Bit#(%s) " % self.bitspec
47 res += name
48 res += ";"
49 return res
50
51 def ifacedef(self, fmtoutfn=None, fmtinfn=None, fmtdecfn=None):
52 res = ' method '
53 if self.action:
54 fmtname = fmtinfn(self.name)
55 res += "Action "
56 res += fmtdecfn(self.name)
57 res += '(Bit#(%s) in);\n' % self.bitspec
58 res += ' %s<=in;\n' % fmtname
59 res += ' endmethod'
60 else:
61 fmtname = fmtoutfn(self.name)
62 res += "%s=%s;" % (self.name, fmtname)
63 return res
64
65 def wirefmt(self, fmtoutfn=None, fmtinfn=None, fmtdecfn=None):
66 res = ' Wire#(Bit#(%s)) ' % self.bitspec
67 if self.action:
68 res += '%s' % fmtinfn(self.name)
69 else:
70 res += '%s' % fmtoutfn(self.name)
71 res += "<-mkDWire(0);"
72 return res
73
74
75 class Interface(object):
76 """ create an interface from a list of pinspecs.
77 each pinspec is a dictionary, see Pin class arguments
78 """
79
80 def __init__(self, ifacename, pinspecs):
81 self.ifacename = ifacename
82 self.pins = []
83 self.pinspecs = pinspecs
84 for p in pinspecs:
85 _p = {}
86 _p.update(p)
87 if p.get('outen') is True: # special case, generate 3 pins
88 del _p['outen']
89 for psuffix in ['out', 'outen', 'in']:
90 _p['name'] = "%s_%s" % (self.pname(p['name']), psuffix)
91 _p['action'] = psuffix != 'in'
92 self.pins.append(Pin(**_p))
93 else:
94 _p['name'] = self.pname(p['name'])
95 self.pins.append(Pin(**_p))
96
97 def pname(self, name):
98 return '%s{0}_%s' % (self.ifacename, name)
99
100 def wirefmt(self, *args):
101 res = '\n'.join(map(self.wirefmtpin, self.pins)).format(*args)
102 res += '\n'
103 for p in self.pinspecs:
104 name = self.pname(p['name']).format(*args)
105 res += " GenericIOType %s_io = GenericIOType{\n" % name
106 params = []
107 if p.get('outen') is True:
108 outname = self.ifacefmtoutfn(name)
109 params.append('outputval:%s_out,' % outname)
110 params.append('output_en:%s_outen,' % outname)
111 params.append('input_en:~%s_outen,' % outname)
112 elif p.get('action'):
113 outname = self.ifacefmtoutfn(name)
114 params.append('outputval:%s,' % outname)
115 params.append('output_en:1,')
116 params.append('input_en:0,')
117 else:
118 params.append('outputval:0,')
119 params.append('output_en:0,')
120 params.append('input_en:1,')
121 params += ['pullup_en:0,', 'pulldown_en:0,',
122 'pushpull_en:0,', 'drivestrength:0,',
123 'opendrain_en:0']
124 for param in params:
125 res += ' %s\n' % param
126 res += ' };\n'
127 return '\n' + res
128
129 def ifacefmt(self, *args):
130 res = '\n'.join(map(self.ifacefmtdecpin, self.pins)).format(*args)
131 return '\n' + res
132
133 def ifacefmtdecfn(self, name):
134 return name
135
136 def ifacefmtdecfn2(self, name):
137 return name
138
139 def ifacefmtoutfn(self, name):
140 return "wr%s" % name
141
142 def ifacefmtinfn(self, name):
143 return "wr%s" % name
144
145 def wirefmtpin(self, pin):
146 return pin.wirefmt(self.ifacefmtoutfn, self.ifacefmtinfn,
147 self.ifacefmtdecfn2)
148
149 def ifacefmtdecpin(self, pin):
150 return pin.ifacefmt(self.ifacefmtdecfn)
151
152 def ifacefmtpin(self, pin):
153 return pin.ifacedef(self.ifacefmtoutfn, self.ifacefmtinfn,
154 self.ifacefmtdecfn2)
155
156 def ifacedef(self, *args):
157 res = '\n'.join(map(self.ifacefmtpin, self.pins))
158 res = res.format(*args)
159 return '\n' + res + '\n'
160
161
162 class IOInterface(Interface):
163
164 def ifacefmtoutfn(self, name):
165 """ for now strip off io{0}_ part """
166 return "cell{0}_mux_out.%s" % name[6:]
167
168 def ifacefmtinfn(self, name):
169 return "cell{0}_mux_in"
170
171
172 class Interfaces(UserDict):
173 """ contains a list of interface definitions
174 """
175
176 def __init__(self):
177 self.ifacecount = []
178 UserDict.__init__(self, {})
179 with open('interfaces.txt', 'r') as ifile:
180 for l in ifile.readlines():
181 l = l.strip()
182 l = l.split("\t")
183 print l
184 name = l[0]
185 count = int(l[1])
186 spec = self.read_spec(name)
187 self.ifaceadd(name, count, Interface(name, spec))
188
189 def ifaceadd(self, name, count, iface):
190 self.ifacecount.append((name, count))
191 self[name] = iface
192
193 def read_spec(self, name):
194 spec = []
195 with open('%s.txt' % name, 'r') as sfile:
196 for l in sfile.readlines():
197 l = l.strip()
198 l = l.split("\t")
199 print l
200 d = {'name': l[0]}
201 if l[1] == 'out':
202 d['action'] = True
203 elif l[1] == 'inout':
204 d['outen'] = True
205 spec.append(d)
206 return spec
207
208 def ifacedef(self, f, *args):
209 for (name, count) in self.ifacecount:
210 for i in range(count):
211 f.write(self.data[name].ifacedef(i))
212
213 def ifacefmt(self, f, *args):
214 comment = '''
215 // interface declaration between %s-{0} and pinmux'''
216 for (name, count) in self.ifacecount:
217 for i in range(count):
218 c = comment % name.upper()
219 f.write(c.format(i))
220 f.write(self.data[name].ifacefmt(i))
221
222 def wirefmt(self, f, *args):
223 comment = '\n // following wires capture signals ' \
224 'to IO CELL if %s-{0} is\n' \
225 ' // allotted to it'
226 for (name, count) in self.ifacecount:
227 for i in range(count):
228 c = comment % name
229 f.write(c.format(i))
230 f.write(self.data[name].wirefmt(i))
231
232
233 # ========= Interface declarations ================ #
234
235 mux_interface = Interface('cell', [{'name': 'mux', 'ready': False,
236 'enabled': False,
237 'bitspec': '{1}', 'action': True}])
238
239 io_interface = IOInterface('io',
240 [{'name': 'outputval', 'enabled': False},
241 {'name': 'output_en', 'enabled': False},
242 {'name': 'input_en', 'enabled': False},
243 {'name': 'pullup_en', 'enabled': False},
244 {'name': 'pulldown_en', 'enabled': False},
245 {'name': 'drivestrength', 'enabled': False},
246 {'name': 'pushpull_en', 'enabled': False},
247 {'name': 'opendrain_en', 'enabled': False},
248 {'name': 'inputval', 'action': True, 'io': True},
249 ])
250
251 # == Peripheral Interface definitions == #
252 # these are the interface of the peripherals to the pin mux
253 # Outputs from the peripherals will be inputs to the pinmux
254 # module. Hence the change in direction for most pins
255
256 ifaces = Interfaces()
257
258 # ======================================= #
259
260 # basic test
261 if __name__ == '__main__':
262
263 uartinterface_decl = Interface('uart',
264 [{'name': 'rx'},
265 {'name': 'tx', 'action': True},
266 ])
267
268 twiinterface_decl = Interface('twi',
269 [{'name': 'sda', 'outen': True},
270 {'name': 'scl', 'outen': True},
271 ])
272
273 def _pinmunge(p, sep, repl, dedupe=True):
274 """ munges the text so it's easier to compare.
275 splits by separator, strips out blanks, re-joins.
276 """
277 p = p.strip()
278 p = p.split(sep)
279 if dedupe:
280 p = filter(lambda x: x, p) # filter out blanks
281 return repl.join(p)
282
283 def pinmunge(p):
284 """ munges the text so it's easier to compare.
285 """
286 # first join lines by semicolons, strip out returns
287 p = p.split(";")
288 p = map(lambda x: x.replace('\n', ''), p)
289 p = '\n'.join(p)
290 # now split first by brackets, then spaces (deduping on spaces)
291 p = _pinmunge(p, "(", " ( ", False)
292 p = _pinmunge(p, ")", " ) ", False)
293 p = _pinmunge(p, " ", " ")
294 return p
295
296 def zipcmp(l1, l2):
297 l1 = l1.split("\n")
298 l2 = l2.split("\n")
299 for p1, p2 in zip(l1, l2):
300 print repr(p1)
301 print repr(p2)
302 print
303 assert p1 == p2
304
305 ifaceuart = ifaces['uart']
306 print ifaceuart.ifacedef(0)
307 print uartinterface_decl.ifacedef(0)
308 assert ifaceuart.ifacedef(0) == uartinterface_decl.ifacedef(0)
309
310 ifacetwi = ifaces['twi']
311 print ifacetwi.ifacedef(0)
312 print twiinterface_decl.ifacedef(0)
313 assert ifacetwi.ifacedef(0) == twiinterface_decl.ifacedef(0)