hack up a python module for myhdl
[pinmux.git] / src / myhdlgen / pinmux_generator.py
1 import os
2 import sys
3 from parse import Parse
4 from myhdlgen.pins import IO
5 from ifacebase import InterfacesBase
6 try:
7 from string import maketrans
8 except ImportError:
9 maketrans = str.maketrans
10
11 # XXX hmmm duplicated from src/bsc/actual_pinmux.py
12 digits = maketrans('0123456789', ' ' * 10) # delete space later
13
14 # XXX hmmm duplicated from src/bsc/actual_pinmux.py
15
16
17 def transfn(temp):
18 """ removes the number from the string of signal name.
19 """
20 temp = temp.split('_')
21 if len(temp) == 2:
22 temp[0] = temp[0].translate(digits)
23 temp[0] = temp[0] .replace(' ', '')
24 return '_'.join(temp)
25
26
27 class Interface(object):
28 """ create an interface from a list of pinspecs.
29 each pinspec is a dictionary, see Pin class arguments
30 single indicates that there is only one of these, and
31 so the name must *not* be extended numerically (see pname)
32 """
33 # sample interface object:
34 """
35 twiinterface_decl = Interface('twi',
36 [{'name': 'sda', 'type': 'in'},
37 {'name': 'scl', 'type': 'inout'},
38 ])
39 """
40
41 def __init__(self, ifacename, pinspecs, ganged=None, single=False):
42 self.ifacename = ifacename
43 self.ganged = ganged or {}
44 self.pins = [] # a list of instances of class Pin
45 self.pinspecs = pinspecs # a list of dictionary
46 self.single = single
47 for p in pinspecs:
48 _p = {}
49 _p['name'] = self.pname(p['name'])
50 _p['typ'] = self.pname(p['type'])
51 self.pins.append(IO(**_p))
52
53 def getifacetype(self, name):
54 for p in self.pinspecs:
55 fname = "%s_%s" % (self.ifacename, p['name'])
56 #print "search", self.ifacename, name, fname
57 if fname == name:
58 if p.get('action'):
59 return 'out'
60 elif p.get('outen'):
61 return 'inout'
62 return 'input'
63 return None
64
65 def pname(self, name):
66 """ generates the interface spec e.g. flexbus_ale
67 if there is only one flexbus interface, or
68 sd{0}_cmd if there are several. string format
69 function turns this into sd0_cmd, sd1_cmd as
70 appropriate. single mode stops the numerical extension.
71 """
72 if self.single:
73 return '%s_%s' % (self.ifacename, name)
74 return '%s{0}_%s' % (self.ifacename, name)
75
76
77 class Interfaces(InterfacesBase):
78 """ contains a list of interface definitions
79 """
80
81 def __init__(self, pth=None):
82 InterfacesBase.__init__(self, Interface, pth)
83
84 def create_module(p, ifaces):
85 x = """\
86 from myhdl import block
87 @block
88 def pinmux(muxfn, clk, p, ifaces, {0}):
89 args = [{0}]
90 return muxfn(clk, p, ifaces, args)
91 """
92
93 args = []
94 for cell in p.muxed_cells:
95 args.append("sel%d" % int(cell[0]))
96 args.append("io%d" % int(cell[0]))
97 print args
98 kl = ifaces.keys()
99 kl.sort()
100 for k, count in ifaces.ifacecount:
101 i = ifaces[k]
102 for c in range(count):
103 print k
104 args.append("%s%d" % (k, c))
105 args = ',\n\t\t'.join(args)
106 x = x.format(args)
107 path = os.path.abspath(__file__)
108 fname = os.path.split(path)[0]
109 fname = os.path.join(fname, "myhdlautogen.py")
110
111 with open(fname, "w") as f:
112 f.write(x)
113 x = "from myhdlgen.myhdlautogen import pinmux"
114 code = compile(x, '<string>', 'exec')
115 y = {}
116 exec code in y
117 x = y["pinmux"]
118
119 return x
120
121
122 def init(p, ifaces):
123 for cell in p.muxed_cells:
124
125 for i in range(0, len(cell) - 1):
126 cname = cell[i + 1]
127 if not cname: # skip blank entries, no need to test
128 continue
129 temp = transfn(cname)
130 x = ifaces.getifacetype(temp)
131 print (cname, temp, x)
132
133
134 def pinmuxgen(pth=None, verify=True):
135 p = Parse(pth, verify)
136 print (p, dir(p))
137 ifaces = Interfaces(pth)
138 init(p, ifaces)
139 create_module(p, ifaces)