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