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