b8b6b78482cd145e777d628db5c5110a62f96fb2
[pinmux.git] / src / myhdl / pins.py
1 # mux.py
2
3 from myhdl import *
4 from myhdl._block import _Block
5 from mux import mux4
6 from functools import wraps, partial
7 import inspect
8
9 period = 20 # clk frequency = 50 MHz
10
11
12 class IO(object):
13 def __init__(self, typ, name):
14 self.typ = typ
15 self.name = name
16 if typ == 'in' or typ == 'inout':
17 self.inp = Signal(bool(0))
18 if typ == 'out' or typ == 'inout':
19 self.out = Signal(bool(0))
20 if typ == 'inout':
21 self.dirn = Signal(bool(0))
22
23
24 class Mux(object):
25 def __init__(self, bwidth=2):
26 self.sel = Signal(intbv(0)[bwidth:0])
27
28
29 def f(obj):
30 print('attr =', obj.attr)
31
32
33 @classmethod
34 def cvt(self, *args, **kwargs):
35 print('args', self, args, kwargs)
36 return block(test2)(*self._args).convert(*args, **kwargs)
37
38
39 def Test(*args):
40 Foo = type(
41 'Foo',
42 (block,),
43 {
44 'test2': test2,
45 'convert': cvt,
46 '_args': args
47 }
48 )
49 return Foo(test2)
50
51
52 def create_test(npins=2, nfns=4):
53 x = """\
54 from myhdl import block
55 @block
56 def test(testfn, clk, num_pins, num_fns, {0}):
57 args = [{0}]
58 return testfn(clk, num_pins, num_fns, args)
59 """
60
61 args = []
62 for pnum in range(npins):
63 args.append("sel%d" % pnum)
64 args.append("pin%d" % pnum)
65 for pnum in range(nfns):
66 args.append("fn%d" % pnum)
67 args = ','.join(args)
68 x = x.format(args)
69 print x
70 print repr(x)
71 with open("testmod.py", "w") as f:
72 f.write(x)
73 x = "from testmod import test"
74 code = compile(x, '<string>', 'exec')
75 y = {}
76 exec code in y
77 x = y["test"]
78
79 def fn(*args):
80 return block(x)
81 return x
82
83
84 def proxy(func):
85 def wrapper(*args):
86 return func(args[0], args[1], args[2], args[3])
87 return wrapper
88
89
90 @block
91 def test2(clk, num_pins, num_fns, args):
92 muxes = []
93 pins = []
94 fns = []
95 for i in range(num_pins):
96 muxes.append(args.pop(0))
97 pins.append(args.pop(0))
98 for i in range(num_fns):
99 fns.append(args.pop(0))
100
101 muxinst = []
102
103 inputs = []
104 for i in range(4):
105 inputs.append(fns[i].inp)
106
107 for i in range(len(muxes)):
108 mux = muxes[i]
109 pin = pins[i]
110 inst = mux4(clk, inputs, mux.sel, pin.out)
111 muxinst.append(inst)
112
113 return muxinst
114
115
116 # testbench
117
118
119 @block
120 def mux_tb():
121
122 muxvals = []
123 muxes = []
124 pins = []
125 ins = []
126 outs = []
127 dirs = []
128 fins = []
129 fouts = []
130 fdirs = []
131 args = []
132 for i in range(2):
133 m = Mux()
134 muxes.append(m)
135 muxvals.append(m.sel)
136 args.append(m)
137 pin = IO("inout", "name%d" % i)
138 pins.append(pin)
139 args.append(pin)
140 ins.append(pin.inp)
141 outs.append(pin.out)
142 dirs.append(pin.dirn)
143 fns = []
144 for i in range(4):
145 fn = IO("inout", "fnname%d" % i)
146 fns.append(fn)
147 fins.append(fn.inp)
148 fouts.append(fn.out)
149 fdirs.append(fn.dirn)
150 args.append(fn)
151 clk = Signal(bool(0))
152
153 mux_inst = test(test2, clk, 2, 4, *args)
154
155 @instance
156 def clk_signal():
157 while True:
158 clk.next = not clk
159 yield delay(period // 2)
160
161 @always(clk.posedge)
162 def print_data():
163 # print on screen
164 # print.format is not supported in MyHDL 1.0
165 for i in range(len(muxes)):
166 sel = muxvals[i]
167 out = outs[i]
168 print ("%d: %s %s" % (i, sel, out))
169
170 return instances()
171
172
173 class Deco(object):
174 def __init__(self):
175 self.calls = 0
176
177
178 def test_mux():
179
180 muxvals = []
181 muxes = []
182 pins = []
183 ins = []
184 outs = []
185 dirs = []
186 fins = []
187 fouts = []
188 fdirs = []
189 args = []
190 for i in range(2):
191 m = Mux()
192 muxes.append(m)
193 muxvals.append(m.sel)
194 args.append(m)
195 pin = IO("inout", "name%d" % i)
196 pins.append(pin)
197 args.append(pin)
198 ins.append(pin.inp)
199 outs.append(pin.out)
200 dirs.append(pin.dirn)
201 fns = []
202 for i in range(4):
203 fn = IO("inout", "fnname%d" % i)
204 fns.append(fn)
205 fins.append(fn.inp)
206 fouts.append(fn.out)
207 fdirs.append(fn.dirn)
208 args.append(fn)
209 clk = Signal(bool(0))
210
211 mux_inst = test(test2, clk, 2, 4, *args)
212 mux_inst.convert(hdl="Verilog", initial_values=True, testbench=False)
213 #mux_inst = Test(clk, muxes, pins, fns)
214 #toVerilog(mux_inst, clk, muxes, pins, fns)
215 #deco = Deco()
216 #b = _Block(mux_inst, deco, "test", "test.py", 1, clk, muxes, pins, fns)
217 #b.convert(hdl="Verilog", name="test", initial_values=True)
218 #mux_inst.convert(hdl="Verilog", initial_values=True)
219 #block(mux_inst).convert(hdl="Verilog", initial_values=True)
220
221 # test bench
222 tb = mux_tb()
223 tb.convert(hdl="Verilog", initial_values=True, testbench=True)
224 # keep following lines below the 'tb.convert' line
225 # otherwise error will be reported
226 tb.config_sim(trace=True)
227 tb.run_sim(66 * period) # run for 15 clock cycle
228
229 test = create_test()
230
231
232 if __name__ == '__main__':
233 test_mux()