myhdl experimentation
[pinmux.git] / src / myhdlgen / 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(fncls, npins=2, nfns=4):
53 x = """\
54 from myhdl import block
55 @block
56 def test(testfn, clk, fncls, num_pins, num_fns, {0}):
57 args = [{0}]
58 return testfn(clk, fncls, 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 class FnCls(object):
90 def __init__(self):
91 self.attrs = ['uart', 'i2c', 'spi', 'gpio']
92
93 def setfn(self, idx, fn):
94 return setattr(self, self.attrs[idx], fn)
95
96 def getfn(self, idx):
97 return getattr(self, self.attrs[idx])
98
99 @block
100 def muxer(clk, p, ifaces, args):
101 muxes = []
102 pins = []
103 fns = []
104 for i in range(len(p.muxed_cells)):
105 pins.append(args.pop(0))
106 muxes.append(args.pop(0))
107 kl = sorted(ifaces.keys())
108 for i in range(len(p.myhdlifaces)):
109 fns.append(args.pop(0))
110
111 muxinst = []
112
113 inputs = []
114 for i in range(2):
115 x = getattr(fns[i], fns[i].pnames[0])
116 print x, dir(x)
117 inputs.append(getattr(fns[i], fns[i].pnames[0]).out)
118 inputs.append(getattr(fns[i], fns[i].pnames[0]).out)
119
120 print "inputs", inputs
121
122 for i in range(len(muxes)):
123 mux = muxes[i]
124 pin = pins[i]
125 print "mux", mux
126 print mux4
127 inst = mux4(clk, inputs, mux.sel, pin.out)
128 muxinst.append(inst)
129
130 return muxinst
131
132
133 @block
134 def test2(clk, fncls, num_pins, num_fns, args):
135 muxes = []
136 pins = []
137 for i in range(num_pins):
138 muxes.append(args.pop(0))
139 pins.append(args.pop(0))
140
141 muxinst = []
142
143 inputs = []
144 inputs.append(fncls.uart.out)
145 inputs.append(fncls.i2c.out)
146 inputs.append(fncls.spi.out)
147 inputs.append(fncls.gpio.out)
148 #for i in range(4):
149 #inputs.append(fncls.getfn(i).out)
150
151 for i in range(len(muxes)):
152 mux = muxes[i]
153 pin = pins[i]
154 inst = mux4(clk, inputs, mux.sel, pin.out)
155 muxinst.append(inst)
156
157 return muxinst
158
159
160 # testbench
161
162
163 @block
164 def mux_tb(fncls):
165
166 muxvals = []
167 muxes = []
168 pins = []
169 ins = []
170 outs = []
171 dirs = []
172 args = []
173 for i in range(2):
174 m = Mux()
175 muxes.append(m)
176 muxvals.append(m.sel)
177 args.append(m)
178 pin = IO("inout", "name%d" % i)
179 pins.append(pin)
180 args.append(pin)
181 ins.append(pin.inp)
182 outs.append(pin.out)
183 dirs.append(pin.dirn)
184 fns = []
185 clk = Signal(bool(0))
186
187 mux_inst = test(test2, clk, fncls, 2, 4, *args)
188
189 @instance
190 def clk_signal():
191 while True:
192 clk.next = not clk
193 yield delay(period // 2)
194
195 @always(clk.posedge)
196 def print_data():
197 # print on screen
198 # print.format is not supported in MyHDL 1.0
199 for i in range(len(muxes)):
200 sel = muxvals[i]
201 out = outs[i]
202 print ("%d: %s %s" % (i, sel, out))
203
204 return instances()
205
206
207 class Deco(object):
208 def __init__(self):
209 self.calls = 0
210
211
212 def test_mux(fncls):
213
214 muxvals = []
215 muxes = []
216 pins = []
217 ins = []
218 outs = []
219 dirs = []
220 fins = []
221 fouts = []
222 fdirs = []
223 args = []
224 for i in range(2):
225 m = Mux()
226 muxes.append(m)
227 muxvals.append(m.sel)
228 args.append(m)
229 pin = IO("inout", "name%d" % i)
230 pins.append(pin)
231 args.append(pin)
232 ins.append(pin.inp)
233 outs.append(pin.out)
234 dirs.append(pin.dirn)
235 clk = Signal(bool(0))
236
237 mux_inst = test(test2, clk, fncls, 2, 4, *args)
238 mux_inst.convert(hdl="Verilog", initial_values=True, testbench=False)
239 #mux_inst = Test(clk, muxes, pins, fns)
240 #toVerilog(mux_inst, clk, muxes, pins, fns)
241 #deco = Deco()
242 #b = _Block(mux_inst, deco, "test", "test.py", 1, clk, muxes, pins, fns)
243 #b.convert(hdl="Verilog", name="test", initial_values=True)
244 #mux_inst.convert(hdl="Verilog", initial_values=True)
245 #block(mux_inst).convert(hdl="Verilog", initial_values=True)
246
247 # test bench
248 tb = mux_tb(fncls)
249 tb.convert(hdl="Verilog", initial_values=True, testbench=True)
250 # keep following lines below the 'tb.convert' line
251 # otherwise error will be reported
252 tb.config_sim(trace=True)
253 tb.run_sim(66 * period) # run for 15 clock cycle
254
255
256 def muxgen(fn, p, ifaces):
257 args = []
258 for i in range(len(p.muxed_cells)):
259 args.append(p.muxers[i])
260 args.append(p.muxsel[i])
261 for i in p.myhdlifaces:
262 args.append(i)
263 clk = Signal(bool(0))
264
265 mux_inst = fn(muxer, clk, p, ifaces, *args)
266 mux_inst.convert(hdl="Verilog", initial_values=True, testbench=False)
267
268
269
270
271 if __name__ == '__main__':
272 fncls = FnCls()
273 num_fns = 4
274 for i in range(num_fns):
275 fn = IO("inout", fncls.attrs[i])
276 fncls.setfn(i, fn)
277 test = create_test(fncls)
278 test_mux(fncls)