a9dab0106acc2a2efdb10fcc39a595a36716d1a8
[pinmux.git] / src / myhdl / pinmux_generator.py
1 from parse import Parse
2 from ifacebase import InterfacesBase
3 try:
4 from string import maketrans
5 except ImportError:
6 maketrans = str.maketrans
7
8 # XXX hmmm duplicated from src/bsc/actual_pinmux.py
9 digits = maketrans('0123456789', ' ' * 10) # delete space later
10
11 # XXX hmmm duplicated from src/bsc/actual_pinmux.py
12
13
14 def transfn(temp):
15 """ removes the number from the string of signal name.
16 """
17 temp = temp.split('_')
18 if len(temp) == 2:
19 temp[0] = temp[0].translate(digits)
20 temp[0] = temp[0] .replace(' ', '')
21 return '_'.join(temp)
22
23
24 class Pin(object):
25 """ pin interface declaration.
26 * name is the name of the pin
27 * ready, enabled and io all create a (* .... *) prefix
28 * action changes it to an "in" if true
29 """
30
31 def __init__(self, name,
32 ready=True,
33 enabled=True,
34 io=False,
35 action=False,
36 bitspec=None,
37 outenmode=False):
38 self.name = name
39 self.ready = ready
40 self.enabled = enabled
41 self.io = io
42 self.action = action
43 self.bitspec = bitspec if bitspec else 'Bit#(1)'
44 self.outenmode = outenmode
45
46
47 class Interface(object):
48 """ create an interface from a list of pinspecs.
49 each pinspec is a dictionary, see Pin class arguments
50 single indicates that there is only one of these, and
51 so the name must *not* be extended numerically (see pname)
52 """
53 # sample interface object:
54 """
55 twiinterface_decl = Interface('twi',
56 [{'name': 'sda', 'outen': True},
57 {'name': 'scl', 'outen': True},
58 ])
59 """
60
61 def __init__(self, ifacename, pinspecs, ganged=None, single=False):
62 self.ifacename = ifacename
63 self.ganged = ganged or {}
64 self.pins = [] # a list of instances of class Pin
65 self.pinspecs = pinspecs # a list of dictionary
66 self.single = single
67 for p in pinspecs:
68 _p = {}
69 _p.update(p)
70 if p.get('outen') is True: # special case, generate 3 pins
71 del _p['outen']
72 for psuffix in ['out', 'outen', 'in']:
73 # changing the name (like sda) to (twi_sda_out)
74 _p['name'] = "%s_%s" % (self.pname(p['name']), psuffix)
75 _p['action'] = psuffix != 'in'
76 self.pins.append(Pin(**_p))
77 # will look like {'name': 'twi_sda_out', 'action': True}
78 # {'name': 'twi_sda_outen', 'action': True}
79 #{'name': 'twi_sda_in', 'action': False}
80 # NOTice - outen key is removed
81 else:
82 _p['name'] = self.pname(p['name'])
83 self.pins.append(Pin(**_p))
84
85 def getifacetype(self, name):
86 for p in self.pinspecs:
87 fname = "%s_%s" % (self.ifacename, p['name'])
88 #print "search", self.ifacename, name, fname
89 if fname == name:
90 if p.get('action'):
91 return 'out'
92 elif p.get('outen'):
93 return 'inout'
94 return 'input'
95 return None
96
97 def pname(self, name):
98 """ generates the interface spec e.g. flexbus_ale
99 if there is only one flexbus interface, or
100 sd{0}_cmd if there are several. string format
101 function turns this into sd0_cmd, sd1_cmd as
102 appropriate. single mode stops the numerical extension.
103 """
104 if self.single:
105 return '%s_%s' % (self.ifacename, name)
106 return '%s{0}_%s' % (self.ifacename, name)
107
108
109 class Interfaces(InterfacesBase):
110 """ contains a list of interface definitions
111 """
112
113 def __init__(self, pth=None):
114 InterfacesBase.__init__(self, Interface, pth)
115
116
117 def init(p, ifaces):
118 for cell in p.muxed_cells:
119
120 for i in range(0, len(cell) - 1):
121 cname = cell[i + 1]
122 if not cname: # skip blank entries, no need to test
123 continue
124 temp = transfn(cname)
125 x = ifaces.getifacetype(temp)
126 print (cname, temp, x)
127
128
129 def pinmuxgen(pth=None, verify=True):
130 p = Parse(pth, verify)
131 print p, dir(p)
132 ifaces = Interfaces(pth)
133 init(p, ifaces)