ddc6df233d88b589935127785f7e5e1ae5cce31a
[pinmux.git] / src / myhdlgen / pinmux_generator.py
1 import os
2 import sys
3 from parse import Parse
4 from myhdlgen.pins import IO, muxgen, Mux
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 IfPin(object):
28 """ pin interface declaration.
29 * name is the name of the pin
30 * ready, enabled and io all create a (* .... *) prefix
31 * action changes it to an "in" if true
32 """
33
34 def __init__(self, typ, name):
35 self.typ = typ
36 self.name = name
37
38
39 class Interface(object):
40 """ create an interface from a list of pinspecs.
41 each pinspec is a dictionary, see Pin class arguments
42 single indicates that there is only one of these, and
43 so the name must *not* be extended numerically (see pname)
44 """
45 # sample interface object:
46 """
47 twiinterface_decl = Interface('twi',
48 [{'name': 'sda', 'type': 'in'},
49 {'name': 'scl', 'type': 'inout'},
50 ])
51 """
52
53 def __init__(self, ifacename, pinspecs, ganged=None, single=False):
54 self.ifacename = ifacename
55 self.ganged = ganged or {}
56 self.pins = [] # a list of instances of class Pin
57 self.pinspecs = pinspecs # a list of dictionary
58 self.single = single
59 for p in pinspecs:
60 _p = {}
61 _p['name'] = self.pname(p['name'])
62 _p['typ'] = p['type']
63 self.pins.append(IfPin(**_p))
64
65 def getifacetype(self, name):
66 for p in self.pinspecs:
67 fname = "%s_%s" % (self.ifacename, p['name'])
68 #print "search", self.ifacename, name, fname
69 if fname == name:
70 if p.get('action'):
71 return 'out'
72 elif p.get('outen'):
73 return 'inout'
74 return 'input'
75 return None
76
77 def pname(self, name):
78 """ generates the interface spec e.g. flexbus_ale
79 if there is only one flexbus interface, or
80 sd{0}_cmd if there are several. string format
81 function turns this into sd0_cmd, sd1_cmd as
82 appropriate. single mode stops the numerical extension.
83 """
84 if self.single:
85 return '%s_%s' % (self.ifacename, name)
86 return '%s{0}_%s' % (self.ifacename, name)
87
88
89 class Interfaces(InterfacesBase):
90 """ contains a list of interface definitions
91 """
92
93 def __init__(self, pth=None):
94 InterfacesBase.__init__(self, Interface, pth)
95
96
97 class MyHdlIface(object):
98 def __init__(self, iface):
99 self.pnames = []
100 for p in iface.pins:
101 print "typ", p.typ, p.name
102 io = IO(p.typ, p.name)
103 setattr(self, p.name, io)
104 self.pnames.append(p.name)
105 print dir(self)
106
107
108 def create_module(p, ifaces):
109 x = """\
110 from myhdl import block
111 @block
112 def pinmux(muxfn, clk, p, ifaces, {0}):
113 args = [{0}]
114 return muxfn(clk, p, ifaces, args)
115 """
116
117 args = []
118 p.muxers = []
119 p.muxsel = []
120 for cell in p.muxed_cells:
121 args.append("sel%d" % int(cell[0]))
122 args.append("io%d" % int(cell[0]))
123 pin = IO("inout", "name%d" % int(cell[0]))
124 p.muxers.append(pin)
125 m = Mux(p.cell_bitwidth)
126 p.muxsel.append(m)
127 print args
128 p.myhdlifaces = []
129 for k, count in ifaces.ifacecount:
130 i = ifaces[k]
131 for c in range(count):
132 print k
133 args.append("%s%d" % (k, c))
134 p.myhdlifaces.append(MyHdlIface(ifaces[k]))
135
136 args = ',\n\t\t'.join(args)
137 x = x.format(args)
138 path = os.path.abspath(__file__)
139 fname = os.path.split(path)[0]
140 fname = os.path.join(fname, "myhdlautogen.py")
141
142 with open(fname, "w") as f:
143 f.write(x)
144 x = "from myhdlgen.myhdlautogen import pinmux"
145 code = compile(x, '<string>', 'exec')
146 y = {}
147 exec code in y
148 x = y["pinmux"]
149
150 return x
151
152
153 def init(p, ifaces):
154 for cell in p.muxed_cells:
155
156 for i in range(0, len(cell) - 1):
157 cname = cell[i + 1]
158 if not cname: # skip blank entries, no need to test
159 continue
160 temp = transfn(cname)
161 x = ifaces.getifacetype(temp)
162 print (cname, temp, x)
163
164
165 def pinmuxgen(pth=None, verify=True):
166 p = Parse(pth, verify)
167 print (p, dir(p))
168 ifaces = Interfaces(pth)
169 init(p, ifaces)
170 fn = create_module(p, ifaces)
171 muxgen(fn, p, ifaces)