add io_interface spec, fix bug where \n was in spec
[pinmux.git] / src / interface_decl.py
1 # ========= Interface declarations ================ #
2 mux_interface = '''
3 method Action cell{0}_mux(Bit#({1}) in);'''
4
5 io_interface = '''
6 (*always_ready*) method Bit#(1) io_outputval_{0};
7 (*always_ready*) method Bit#(1) io_output_en_{0};
8 (*always_ready*) method Bit#(1) io_input_en_{0};
9 (*always_ready*) method Bit#(1) io_pullup_en_{0};
10 (*always_ready*) method Bit#(1) io_pulldown_en_{0};
11 (*always_ready*) method Bit#(1) io_drivestrength_{0};
12 (*always_ready*) method Bit#(1) io_pushpull_en_{0};
13 (*always_ready*) method Bit#(1) io_opendrain_en_{0};
14 (*always_ready,always_enabled,result="io"*)
15 method Action io_inputval_{0}(Bit#(1) in);
16 '''
17 # == Peripheral Interface definitions == #
18 # these are the interface of the peripherals to the pin mux
19 # Outputs from the peripherals will be inputs to the pinmux
20 # module. Hence the change in direction for most pins
21
22 uartinterface_decl = '''
23 (*always_ready,always_enabled*) method Action tx_{0}(Bit#(1) in);
24 (*always_ready,always_enabled*) method Bit#(1) rx_{0};
25 '''
26
27 spiinterface_decl = '''
28 (*always_ready,always_enabled*) method Action sclk_{0} (Bit#(1) in);
29 (*always_ready,always_enabled*) method Action mosi_{0} (Bit#(1) in);
30 (*always_ready,always_enabled*) method Action ss_{0} (Bit#(1) in);
31 (*always_ready,always_enabled*) method Bit#(1) miso_{0};
32 '''
33
34 twiinterface_decl = '''
35 (*always_ready,always_enabled*) method Action sda{0}_out (Bit#(1) in);
36 (*always_ready,always_enabled*) method Action sda{0}_outen (Bit#(1) in);
37 (*always_ready,always_enabled*) method Bit#(1) sda{0}_in;
38 (*always_ready,always_enabled*) method Action scl{0}_out (Bit#(1) in);
39 (*always_ready,always_enabled*) method Action scl{0}_outen (Bit#(1) in);
40 (*always_ready,always_enabled*) method Bit#(1) scl{0}_in;
41 '''
42
43 sdinterface_decl = '''
44 (*always_ready,always_enabled*) method Action sd{0}_clk (Bit#(1) in);
45 (*always_ready,always_enabled*) method Action sd{0}_cmd (Bit#(1) in);
46 (*always_ready,always_enabled*) method Action sd{0}_d0_out (Bit#(1) in);
47 (*always_ready,always_enabled*) method Action sd{0}_d0_outen (Bit#(1) in);
48 (*always_ready,always_enabled*) method Bit#(1) sd{0}_d0_in;
49 (*always_ready,always_enabled*) method Action sd{0}_d1_out (Bit#(1) in);
50 (*always_ready,always_enabled*) method Action sd{0}_d1_outen (Bit#(1) in);
51 (*always_ready,always_enabled*) method Bit#(1) sd{0}_d1_in;
52 (*always_ready,always_enabled*) method Action sd{0}_d2_out (Bit#(1) in);
53 (*always_ready,always_enabled*) method Action sd{0}_d2_outen (Bit#(1) in);
54 (*always_ready,always_enabled*) method Bit#(1) sd{0}_d2_in;
55 (*always_ready,always_enabled*) method Action sd{0}_d3_out (Bit#(1) in);
56 (*always_ready,always_enabled*) method Action sd{0}_d3_outen (Bit#(1) in);
57 (*always_ready,always_enabled*) method Bit#(1) sd{0}_d3_in;
58 '''
59
60 jtaginterface_decl = '''
61 (*always_ready,always_enabled*) method Bit#(1) jtag{0}_tdi;
62 (*always_ready,always_enabled*) method Bit#(1) jtag{0}_tms;
63 (*always_ready,always_enabled*) method Bit#(1) jtag{0}_tclk;
64 (*always_ready,always_enabled*) method Bit#(1) jtag{0}_trst;
65 (*always_ready,always_enabled*) method Action jtag{0}_tdo(Bit#(1) in);
66 '''
67
68 pwminterface_decl = '''
69 (*always_ready,always_enabled*) method Action pwm{0}(Bit#(1) in);
70 '''
71 # ======================================= #
72
73
74 class Pin(object):
75 """ pin interface declaration.
76 * name is the name of the pin
77 * ready, enabled and io all create a (* .... *) prefix
78 * action changes it to an "in" if true
79 """
80
81 def __init__(self, name,
82 ready=True,
83 enabled=True,
84 io=False,
85 action=False):
86 self.name = name
87 self.ready = ready
88 self.enabled = enabled
89 self.io = io
90 self.action = action
91
92 def __str__(self):
93 res = ' '
94 status = []
95 if self.ready:
96 status.append('always_ready')
97 if self.enabled:
98 status.append('always_enabled')
99 if self.io:
100 status.append('result="io"')
101 if status:
102 res += '(*'
103 res += ','.join(status)
104 res += '*)'
105 res += " method "
106 if self.action:
107 res += " Action "
108 res += self.name
109 res += ' (Bit#(1) in)'
110 else:
111 res += " Bit#(1) "
112 res += self.name
113 res += ";"
114 return res
115
116
117 class Interface(object):
118 """ create an interface from a list of pinspecs.
119 each pinspec is a dictionary, see Pin class arguments
120 """
121
122 def __init__(self, pinspecs):
123 self.pins = []
124 for p in pinspecs:
125 if p.get('outen') is True: # special case, generate 3 pins
126 _p = {}
127 _p.update(p)
128 del _p['outen']
129 for psuffix in ['out', 'outen', 'in']:
130 _p['name'] = "%s_%s" % (p['name'], psuffix)
131 _p['action'] = psuffix != 'in'
132 self.pins.append(Pin(**_p))
133 else:
134 self.pins.append(Pin(**p))
135
136 def __str__(self):
137 return '\n'.join(map(str, self.pins))
138
139
140 # basic test
141 if __name__ == '__main__':
142
143 def _pinmunge(p, sep, repl, dedupe=True):
144 """ munges the text so it's easier to compare.
145 splits by separator, strips out blanks, re-joins.
146 """
147 p = p.strip()
148 p = p.split(sep)
149 if dedupe:
150 p = filter(lambda x: x, p) # filter out blanks
151 return repl.join(p)
152
153 def pinmunge(p):
154 """ munges the text so it's easier to compare.
155 """
156 # first join lines by semicolons, strip out returns
157 p = p.split(";")
158 p = map(lambda x: x.replace('\n', ''), p)
159 p = '\n'.join(p)
160 # now split first by brackets, then spaces (deduping on spaces)
161 p = _pinmunge(p, "(", " ( ", False)
162 p = _pinmunge(p, ")", " ) ", False)
163 p = _pinmunge(p, " ", " ")
164 return p
165
166 pwm = Interface([{'name': "pwm{0}", 'action': True}])
167 print pwm
168 print
169 assert pinmunge(str(pwm)) == pinmunge(pwminterface_decl)
170
171 jtag = Interface([{'name': 'jtag{0}_tdi'},
172 {'name': 'jtag{0}_tms'},
173 {'name': 'jtag{0}_tclk'},
174 {'name': 'jtag{0}_trst'},
175 {'name': 'jtag{0}_tdo', 'action': True}])
176 print jtag
177 print
178 assert pinmunge(str(jtag)) == pinmunge(jtaginterface_decl)
179
180 sd = Interface([{'name': 'sd{0}_clk', 'action': True},
181 {'name': 'sd{0}_cmd', 'action': True},
182 {'name': 'sd{0}_d0', 'outen': True},
183 {'name': 'sd{0}_d1', 'outen': True},
184 {'name': 'sd{0}_d2', 'outen': True},
185 {'name': 'sd{0}_d3', 'outen': True}
186 ])
187 print sd
188 print
189 assert pinmunge(str(sd)) == pinmunge(sdinterface_decl)
190
191 twi = Interface([{'name': 'sda{0}', 'outen': True},
192 {'name': 'scl{0}', 'outen': True},
193 ])
194 print twi
195 print
196 assert pinmunge(str(twi)) == pinmunge(twiinterface_decl)
197
198 spi = Interface([{'name': 'sclk_{0}', 'action': True},
199 {'name': 'mosi_{0}', 'action': True},
200 {'name': 'ss_{0}', 'action': True},
201 {'name': 'miso_{0}'},
202 ])
203 print spi
204 print
205 assert pinmunge(str(spi)) == pinmunge(spiinterface_decl)
206
207 uart = Interface([{'name': 'tx_{0}', 'action': True},
208 {'name': 'rx_{0}'},
209 ])
210 print uart
211 print
212 assert pinmunge(str(uart)) == pinmunge(uartinterface_decl)
213
214 io = Interface([{'name': 'io_outputval_{0}', 'enabled': False},
215 {'name': 'io_output_en_{0}', 'enabled': False},
216 {'name': 'io_input_en_{0}', 'enabled': False},
217 {'name': 'io_pullup_en_{0}', 'enabled': False},
218 {'name': 'io_pulldown_en_{0}', 'enabled': False},
219 {'name': 'io_drivestrength_{0}', 'enabled': False},
220 {'name': 'io_pushpull_en_{0}', 'enabled': False},
221 {'name': 'io_opendrain_en_{0}', 'enabled': False},
222 {'name': 'io_inputval_{0}', 'action': True, 'io': True},
223 ])
224 print io
225 print
226 assert pinmunge(str(io)) == pinmunge(io_interface)