ad9f92c5f2c66b65c2db4fb25fc4990b1eff7c51
[pinmux.git] / src / myhdl / mux.py
1 # mux.py
2
3 from math import log
4 from myhdl import *
5
6 period = 20 # clk frequency = 50 MHz
7
8 class Inputs(object):
9 def __init__(self, ins):
10 self.ins = ins
11 self.in_a = ins[0]
12 self.in_b = ins[1]
13 self.in_c = ins[2]
14 self.in_d = ins[3]
15
16 class Selectors(object):
17 def __init__(self, sels):
18 self.sels = sels
19 self.sel_a = sels[0]
20 self.sel_b = sels[1]
21 self.sel_c = sels[2]
22 self.sel_d = sels[3]
23
24 @block
25 def mux4(clk, in_a, in_b, in_c, in_d,
26 selector, out):
27
28 @always(selector, in_a, in_b, in_c, in_d)
29 def make_out():
30 out.next = bool(in_a if selector == 0 else False) | \
31 bool(in_b if selector == 1 else False) | \
32 bool(in_c if selector == 2 else False) | \
33 bool(in_d if selector == 3 else False)
34
35 return instances() # return all instances
36
37
38 @block
39 def pmux1(clk, in_a,
40 sel_a, out):
41
42 @always(sel_a,
43 in_a)
44 def make_out():
45 if sel_a:
46 out.next = in_a
47 else:
48 out.next = False
49
50 return instances() # return all instances
51
52
53 @block
54 def pmux2(clk, in_a, in_b,
55 sel_a, sel_b, out):
56
57 @always(sel_a, sel_b,
58 in_a, in_b)
59 def make_out():
60 if sel_a:
61 out.next = in_a
62 elif sel_b:
63 out.next = in_b
64 else:
65 out.next = False
66
67 return instances() # return all instances
68
69
70 @block
71 def pmux3(clk, in_a, in_b, in_c,
72 sel_a, sel_b, sel_c, out):
73
74 @always(sel_a, sel_b, sel_c,
75 in_a, in_b, in_c)
76 def make_out():
77 if sel_a:
78 out.next = in_a
79 elif sel_b:
80 out.next = in_b
81 elif sel_c:
82 out.next = in_c
83 else:
84 out.next = False
85
86 return instances() # return all instances
87
88
89 @block
90 def pmux4(clk, ins, sels, out):
91
92 @always(*list(sels.sels) + list(ins.ins))
93 def make_out():
94 if sels.sel_a:
95 out.next = ins.in_a
96 elif sels.sel_b:
97 out.next = ins.in_b
98 elif sels.sel_c:
99 out.next = ins.in_c
100 elif sels.sel_d:
101 out.next = ins.in_d
102 else:
103 out.next = False
104
105 i = instances()
106 print dir(i), i
107 return i # return all instances
108
109
110 # testbench
111 @block
112 def pmux_tb4():
113
114 clk = Signal(bool(0))
115 in_a = Signal(bool(0))
116 in_b = Signal(bool(0))
117 in_c = Signal(bool(0))
118 in_d = Signal(bool(0))
119 sel_a = Signal(bool(0))
120 sel_b = Signal(bool(0))
121 sel_c = Signal(bool(0))
122 sel_d = Signal(bool(0))
123 out = Signal(bool(0))
124
125 sels = Selectors((sel_a, sel_b, sel_c, sel_d))
126 ins = Inputs((in_a, in_b, in_c, in_d))
127 mux_inst = pmux4(clk, ins, sels, out)
128
129 @instance
130 def clk_signal():
131 while True:
132 sel_set = False
133 clk.next = not clk
134 if clk:
135 in_a.next = not in_a
136 if in_a:
137 in_b.next = not in_b
138 if in_b:
139 in_c.next = not in_c
140 if in_c:
141 in_d.next = not in_d
142 if in_d:
143 sel_set = True
144 if sel_set:
145 sel_a.next = not sel_a
146 if sel_a:
147 sel_b.next = not sel_b
148 if sel_b:
149 sel_c.next = not sel_c
150 if sel_c:
151 sel_d.next = not sel_d
152 yield delay(period // 2)
153
154 # print simulation data on screen and file
155 file_data = open("pmux.csv", 'w') # file for saving data
156 # # print header on screen
157 s = "{0},{1},{2},{3},{4},{5},{6},{7},{8}".format(
158 "in_a", "in_b", "in_c", "in_d",
159 "sel_a", "sel_b", "sel_c", "sel_d",
160 "out")
161 print(s)
162 # # print header to file
163 file_data.write(s)
164 # print data on each clock
165
166 @always(clk.posedge)
167 def print_data():
168 # print on screen
169 # print.format is not supported in MyHDL 1.0
170 print ("%s,%s,%s,%s,%s,%s,%s,%s,%s" %
171 (in_a, in_b,
172 in_c, in_d,
173 sel_a, sel_b,
174 sel_c, sel_d, out))
175
176 if sel_a:
177 assert out == in_a
178 elif sel_b:
179 assert out == in_b
180 elif sel_c:
181 assert out == in_c
182 elif sel_d:
183 assert out == in_d
184 # print in file
185 # print.format is not supported in MyHDL 1.0
186 #file_data.write(s + "\n")
187
188 return instances()
189
190 # testbench
191
192
193 @block
194 def mux_tb():
195
196 clk = Signal(bool(0))
197 in_a = Signal(bool(0))
198 in_b = Signal(bool(0))
199 in_c = Signal(bool(0))
200 in_d = Signal(bool(0))
201 selector = Signal(intbv(0)[2:0])
202 out = Signal(bool(0))
203
204 mux_inst = mux4(clk, in_a, in_b, in_c, in_d, selector, out)
205
206 @instance
207 def clk_signal():
208 while True:
209 clk.next = not clk
210 if clk:
211 in_a.next = not in_a
212 if in_a:
213 in_b.next = not in_b
214 if in_b:
215 in_c.next = not in_c
216 if in_c:
217 in_d.next = not in_d
218 if in_d:
219 if selector == 3:
220 selector.next = 0
221 else:
222 selector.next = selector + 1
223 yield delay(period // 2)
224
225 # print simulation data on screen and file
226 file_data = open("mux.csv", 'w') # file for saving data
227 # # print header on screen
228 s = "{0},{1},{2},{3},{4},{5}".format("in_a", "in_b", "in_c", "in_d",
229 "selector", "out")
230 print(s)
231 # # print header to file
232 file_data.write(s)
233 # print data on each clock
234
235 @always(clk.posedge)
236 def print_data():
237 # print on screen
238 # print.format is not supported in MyHDL 1.0
239 print ("%s,%s,%s,%s,%s,%s" %
240 (in_a, in_b,
241 in_c, in_d,
242 selector, out))
243
244 if selector == 0:
245 assert out == in_a
246 elif selector == 1:
247 assert out == in_b
248 elif selector == 2:
249 assert out == in_c
250 elif selector == 3:
251 assert out == in_d
252 # print in file
253 # print.format is not supported in MyHDL 1.0
254 #file_data.write(s + "\n")
255
256 return instances()
257
258
259 def test_mux():
260
261 clk = Signal(bool(0))
262 in_a = Signal(bool(0))
263 in_b = Signal(bool(0))
264 in_c = Signal(bool(0))
265 in_d = Signal(bool(0))
266 selector = Signal(intbv(0)[2:0])
267 out = Signal(bool(0))
268
269 mux_v = mux4(clk, in_a, in_b, in_c, in_d, selector, out)
270 mux_v.convert(hdl="Verilog", initial_values=True)
271
272 # test bench
273 tb = mux_tb()
274 tb.convert(hdl="Verilog", initial_values=True)
275 # keep following lines below the 'tb.convert' line
276 # otherwise error will be reported
277 tb.config_sim(trace=True)
278 tb.run_sim(66 * period) # run for 15 clock cycle
279
280
281 def test_pmux4():
282
283 clk = Signal(bool(0))
284 in_a = Signal(bool(0))
285 in_b = Signal(bool(0))
286 in_c = Signal(bool(0))
287 in_d = Signal(bool(0))
288 sel_a = Signal(bool(0))
289 sel_b = Signal(bool(0))
290 sel_c = Signal(bool(0))
291 sel_d = Signal(bool(0))
292 out = Signal(bool(0))
293
294 sels = Selectors((sel_a, sel_b, sel_c, sel_d))
295 ins = Inputs((in_a, in_b, in_c, in_d))
296 pmux_v = pmux4(clk, ins, sels, out)
297 pmux_v.convert(hdl="Verilog", initial_values=True)
298
299 # test bench
300 tb = pmux_tb4()
301 tb.convert(hdl="Verilog", initial_values=True)
302 # keep following lines below the 'tb.convert' line
303 # otherwise error will be reported
304 tb.config_sim(trace=True)
305 tb.run_sim(4 * 66 * period) # run for 15 clock cycle
306
307
308 if __name__ == '__main__':
309 # test_mux()
310 print "test pmux"
311 test_pmux4()