add myhdl experiments
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 6 Jul 2018 02:39:12 +0000 (03:39 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 6 Jul 2018 02:39:12 +0000 (03:39 +0100)
src/myhdl/mux.py
src/myhdl/pins.py [new file with mode: 0644]

index ad9f92c5f2c66b65c2db4fb25fc4990b1eff7c51..1495026fa3257c4975a1ccf462282d7f33dbbf71 100644 (file)
@@ -5,6 +5,7 @@ from myhdl import *
 
 period = 20  # clk frequency = 50 MHz
 
+
 class Inputs(object):
     def __init__(self, ins):
         self.ins = ins
@@ -13,6 +14,7 @@ class Inputs(object):
         self.in_c = ins[2]
         self.in_d = ins[3]
 
+
 class Selectors(object):
     def __init__(self, sels):
         self.sels = sels
@@ -21,10 +23,14 @@ class Selectors(object):
         self.sel_c = sels[2]
         self.sel_d = sels[3]
 
+
 @block
-def mux4(clk, in_a, in_b, in_c, in_d,
+def mux4(clk, ins,
          selector, out):
 
+    (in_a, in_b, in_c, in_d) = ins
+    print repr(clk), ins, repr(selector), repr(out)
+
     @always(selector, in_a, in_b, in_c, in_d)
     def make_out():
         out.next = bool(in_a if selector == 0 else False) | \
diff --git a/src/myhdl/pins.py b/src/myhdl/pins.py
new file mode 100644 (file)
index 0000000..bc3c026
--- /dev/null
@@ -0,0 +1,189 @@
+# mux.py
+
+from myhdl import *
+from myhdl._block import _Block
+from mux import mux4
+from functools import wraps, partial
+import inspect
+
+period = 20  # clk frequency = 50 MHz
+
+
+class IO(object):
+    def __init__(self, typ, name):
+        self.typ = typ
+        if typ == 'in' or typ == 'inout':
+            self.inp = Signal(bool(0))
+        if typ == 'out' or typ == 'inout':
+            self.out = Signal(bool(0))
+        if typ == 'inout':
+            self.dirn = Signal(bool(0))
+
+
+class Mux(object):
+    def __init__(self, bwidth=2):
+        self.sel = Signal(intbv(0)[bwidth:0])
+
+
+def f(obj):
+    print('attr =', obj.attr)
+
+
+@classmethod
+def cvt(self, *args, **kwargs):
+    print('args', self, args, kwargs)
+    return block(test2)(*self._args).convert(*args, **kwargs)
+
+
+def Test(*args):
+    Foo = type(
+        'Foo',
+        (block,),
+        {
+            'test2': test2,
+            'convert': cvt,
+            '_args': args
+        }
+    )
+    return Foo(test2)
+
+
+def create_test():
+    x = """\
+def getfn({0}):
+    def test({0}):
+        args = ({0})
+        return test2(*args)
+    return test
+"""
+    args = ['clk', 'muxes', 'pins', 'fns']
+    args = ','.join(args)
+    x = x.format(args)
+    print x
+    print repr(x)
+    y = {'test2': test2, 'block': block}
+    code = compile(x, '<string>', 'exec')
+    exec code in y
+    x = y["getfn"]
+    #print inspect.getsourcelines(proxy)
+    #print inspect.getsourcelines(x)
+
+    def fn(*args):
+        return block(x)
+    return x
+
+
+def proxy(func):
+    def wrapper(*args):
+        return func(args[0], args[1], args[2], args[3])
+    return wrapper
+
+
+def test2(clk, muxes, pins, fns):
+
+    muxinst = []
+
+    inputs = []
+    for i in range(4):
+        inputs.append(fns[i].inp)
+
+    for i in range(len(muxes)):
+        mux = muxes[i]
+        pin = pins[i]
+        inst = mux4(clk, inputs, mux.sel, pin.out)
+        muxinst.append(inst)
+
+    return muxinst
+
+
+# testbench
+
+
+@block
+def mux_tb():
+
+    muxvals = []
+    muxes = []
+    pins = []
+    ins = []
+    outs = []
+    for i in range(2):
+        m = Mux()
+        muxes.append(m)
+        muxvals.append(m.sel)
+        pin = IO("inout", "name%d" % i)
+        pins.append(pin)
+        ins.append(pin.inp)
+        outs.append(pin.out)
+    fns = []
+    for i in range(4):
+        fns.append(IO("inout", "fnname%d" % i))
+    clk = Signal(bool(0))
+
+    mux_inst = Test(clk, muxes, pins, fns)
+
+    @instance
+    def clk_signal():
+        while True:
+            clk.next = not clk
+            yield delay(period // 2)
+
+    @always(clk.posedge)
+    def print_data():
+        # print on screen
+        # print.format is not supported in MyHDL 1.0
+        for i in range(len(muxes)):
+            sel = muxvals[i]
+            out = outs[i]
+            print ("%d: %s %s" % (i, sel, out))
+
+    return instances()
+
+
+class Deco(object):
+    def __init__(self):
+        self.calls = 0
+
+
+def test_mux():
+
+    muxvals = []
+    muxes = []
+    pins = []
+    ins = []
+    outs = []
+
+    for i in range(2):
+        m = Mux()
+        muxes.append(m)
+        muxvals.append(m.sel)
+        pin = IO("inout", "name%d" % i)
+        pins.append(pin)
+        ins.append(pin.inp)
+        outs.append(pin.out)
+    fns = []
+    for i in range(4):
+        fns.append(IO("inout", "fnname%d" % i))
+    clk = Signal(bool(0))
+
+    mux_inst = Test(clk, muxes, pins, fns)
+    #toVerilog(mux_inst, clk, muxes, pins, fns)
+    #deco = Deco()
+    #b = _Block(mux_inst, deco, "test", "test.py", 1, clk, muxes, pins, fns)
+    #b.convert(hdl="Verilog", name="test", initial_values=True)
+    mux_inst.convert(hdl="Verilog", initial_values=True)
+    #block(mux_inst).convert(hdl="Verilog", initial_values=True)
+
+    # test bench
+    tb = mux_tb()
+    tb.convert(hdl="Verilog", initial_values=True)
+    # keep following lines below the 'tb.convert' line
+    # otherwise error will be reported
+    tb.config_sim(trace=True)
+    tb.run_sim(66 * period)  # run for 15 clock cycle
+
+#test = create_test()
+
+
+if __name__ == '__main__':
+    test_mux()