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