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