From: Luke Kenneth Casson Leighton Date: Tue, 10 Jul 2018 05:48:45 +0000 (+0100) Subject: move myhdl to myhdlgen directory X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=681e100ab51ba1d31525b1f44bce5334dc00a798;p=pinmux.git move myhdl to myhdlgen directory --- diff --git a/src/myhdl/__init__.py b/src/myhdl/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/myhdl/mux.py b/src/myhdl/mux.py deleted file mode 100644 index 1495026..0000000 --- a/src/myhdl/mux.py +++ /dev/null @@ -1,317 +0,0 @@ -# mux.py - -from math import log -from myhdl import * - -period = 20 # clk frequency = 50 MHz - - -class Inputs(object): - def __init__(self, ins): - self.ins = ins - self.in_a = ins[0] - self.in_b = ins[1] - self.in_c = ins[2] - self.in_d = ins[3] - - -class Selectors(object): - def __init__(self, sels): - self.sels = sels - self.sel_a = sels[0] - self.sel_b = sels[1] - self.sel_c = sels[2] - self.sel_d = sels[3] - - -@block -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) | \ - bool(in_b if selector == 1 else False) | \ - bool(in_c if selector == 2 else False) | \ - bool(in_d if selector == 3 else False) - - return instances() # return all instances - - -@block -def pmux1(clk, in_a, - sel_a, out): - - @always(sel_a, - in_a) - def make_out(): - if sel_a: - out.next = in_a - else: - out.next = False - - return instances() # return all instances - - -@block -def pmux2(clk, in_a, in_b, - sel_a, sel_b, out): - - @always(sel_a, sel_b, - in_a, in_b) - def make_out(): - if sel_a: - out.next = in_a - elif sel_b: - out.next = in_b - else: - out.next = False - - return instances() # return all instances - - -@block -def pmux3(clk, in_a, in_b, in_c, - sel_a, sel_b, sel_c, out): - - @always(sel_a, sel_b, sel_c, - in_a, in_b, in_c) - def make_out(): - if sel_a: - out.next = in_a - elif sel_b: - out.next = in_b - elif sel_c: - out.next = in_c - else: - out.next = False - - return instances() # return all instances - - -@block -def pmux4(clk, ins, sels, out): - - @always(*list(sels.sels) + list(ins.ins)) - def make_out(): - if sels.sel_a: - out.next = ins.in_a - elif sels.sel_b: - out.next = ins.in_b - elif sels.sel_c: - out.next = ins.in_c - elif sels.sel_d: - out.next = ins.in_d - else: - out.next = False - - i = instances() - print dir(i), i - return i # return all instances - - -# testbench -@block -def pmux_tb4(): - - clk = Signal(bool(0)) - in_a = Signal(bool(0)) - in_b = Signal(bool(0)) - in_c = Signal(bool(0)) - in_d = Signal(bool(0)) - sel_a = Signal(bool(0)) - sel_b = Signal(bool(0)) - sel_c = Signal(bool(0)) - sel_d = Signal(bool(0)) - out = Signal(bool(0)) - - sels = Selectors((sel_a, sel_b, sel_c, sel_d)) - ins = Inputs((in_a, in_b, in_c, in_d)) - mux_inst = pmux4(clk, ins, sels, out) - - @instance - def clk_signal(): - while True: - sel_set = False - clk.next = not clk - if clk: - in_a.next = not in_a - if in_a: - in_b.next = not in_b - if in_b: - in_c.next = not in_c - if in_c: - in_d.next = not in_d - if in_d: - sel_set = True - if sel_set: - sel_a.next = not sel_a - if sel_a: - sel_b.next = not sel_b - if sel_b: - sel_c.next = not sel_c - if sel_c: - sel_d.next = not sel_d - yield delay(period // 2) - - # print simulation data on screen and file - file_data = open("pmux.csv", 'w') # file for saving data - # # print header on screen - s = "{0},{1},{2},{3},{4},{5},{6},{7},{8}".format( - "in_a", "in_b", "in_c", "in_d", - "sel_a", "sel_b", "sel_c", "sel_d", - "out") - print(s) - # # print header to file - file_data.write(s) - # print data on each clock - - @always(clk.posedge) - def print_data(): - # print on screen - # print.format is not supported in MyHDL 1.0 - print ("%s,%s,%s,%s,%s,%s,%s,%s,%s" % - (in_a, in_b, - in_c, in_d, - sel_a, sel_b, - sel_c, sel_d, out)) - - if sel_a: - assert out == in_a - elif sel_b: - assert out == in_b - elif sel_c: - assert out == in_c - elif sel_d: - assert out == in_d - # print in file - # print.format is not supported in MyHDL 1.0 - #file_data.write(s + "\n") - - return instances() - -# testbench - - -@block -def mux_tb(): - - clk = Signal(bool(0)) - in_a = Signal(bool(0)) - in_b = Signal(bool(0)) - in_c = Signal(bool(0)) - in_d = Signal(bool(0)) - selector = Signal(intbv(0)[2:0]) - out = Signal(bool(0)) - - mux_inst = mux4(clk, in_a, in_b, in_c, in_d, selector, out) - - @instance - def clk_signal(): - while True: - clk.next = not clk - if clk: - in_a.next = not in_a - if in_a: - in_b.next = not in_b - if in_b: - in_c.next = not in_c - if in_c: - in_d.next = not in_d - if in_d: - if selector == 3: - selector.next = 0 - else: - selector.next = selector + 1 - yield delay(period // 2) - - # print simulation data on screen and file - file_data = open("mux.csv", 'w') # file for saving data - # # print header on screen - s = "{0},{1},{2},{3},{4},{5}".format("in_a", "in_b", "in_c", "in_d", - "selector", "out") - print(s) - # # print header to file - file_data.write(s) - # print data on each clock - - @always(clk.posedge) - def print_data(): - # print on screen - # print.format is not supported in MyHDL 1.0 - print ("%s,%s,%s,%s,%s,%s" % - (in_a, in_b, - in_c, in_d, - selector, out)) - - if selector == 0: - assert out == in_a - elif selector == 1: - assert out == in_b - elif selector == 2: - assert out == in_c - elif selector == 3: - assert out == in_d - # print in file - # print.format is not supported in MyHDL 1.0 - #file_data.write(s + "\n") - - return instances() - - -def test_mux(): - - clk = Signal(bool(0)) - in_a = Signal(bool(0)) - in_b = Signal(bool(0)) - in_c = Signal(bool(0)) - in_d = Signal(bool(0)) - selector = Signal(intbv(0)[2:0]) - out = Signal(bool(0)) - - mux_v = mux4(clk, in_a, in_b, in_c, in_d, selector, out) - mux_v.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 - - -def test_pmux4(): - - clk = Signal(bool(0)) - in_a = Signal(bool(0)) - in_b = Signal(bool(0)) - in_c = Signal(bool(0)) - in_d = Signal(bool(0)) - sel_a = Signal(bool(0)) - sel_b = Signal(bool(0)) - sel_c = Signal(bool(0)) - sel_d = Signal(bool(0)) - out = Signal(bool(0)) - - sels = Selectors((sel_a, sel_b, sel_c, sel_d)) - ins = Inputs((in_a, in_b, in_c, in_d)) - pmux_v = pmux4(clk, ins, sels, out) - pmux_v.convert(hdl="Verilog", initial_values=True) - - # test bench - tb = pmux_tb4() - 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(4 * 66 * period) # run for 15 clock cycle - - -if __name__ == '__main__': - # test_mux() - print "test pmux" - test_pmux4() diff --git a/src/myhdl/pinmux_generator.py b/src/myhdl/pinmux_generator.py deleted file mode 100644 index 733694b..0000000 --- a/src/myhdl/pinmux_generator.py +++ /dev/null @@ -1,122 +0,0 @@ -from parse import Parse -from myhdl.pins import IO -from ifacebase import InterfacesBase -try: - from string import maketrans -except ImportError: - maketrans = str.maketrans - -# XXX hmmm duplicated from src/bsc/actual_pinmux.py -digits = maketrans('0123456789', ' ' * 10) # delete space later - -# XXX hmmm duplicated from src/bsc/actual_pinmux.py - - -def transfn(temp): - """ removes the number from the string of signal name. - """ - temp = temp.split('_') - if len(temp) == 2: - temp[0] = temp[0].translate(digits) - temp[0] = temp[0] .replace(' ', '') - return '_'.join(temp) - - -class Pin(object): - """ pin interface declaration. - * name is the name of the pin - * ready, enabled and io all create a (* .... *) prefix - * action changes it to an "in" if true - """ - - def __init__(self, name, - ready=True, - enabled=True, - io=False, - action=False, - bitspec=None, - outenmode=False): - self.name = name - self.ready = ready - self.enabled = enabled - self.io = io - self.action = action - self.bitspec = bitspec if bitspec else 'Bit#(1)' - self.outenmode = outenmode - - -class Interface(object): - """ create an interface from a list of pinspecs. - each pinspec is a dictionary, see Pin class arguments - single indicates that there is only one of these, and - so the name must *not* be extended numerically (see pname) - """ - # sample interface object: - """ - twiinterface_decl = Interface('twi', - [{'name': 'sda', 'outen': True}, - {'name': 'scl', 'outen': True}, - ]) - """ - - def __init__(self, ifacename, pinspecs, ganged=None, single=False): - self.ifacename = ifacename - self.ganged = ganged or {} - self.pins = [] # a list of instances of class Pin - self.pinspecs = pinspecs # a list of dictionary - self.single = single - for p in pinspecs: - _p = {} - _p['name'] = self.pname(p['name']) - _p['typ'] = self.pname(p['type']) - self.pins.append(IO(**_p)) - - def getifacetype(self, name): - for p in self.pinspecs: - fname = "%s_%s" % (self.ifacename, p['name']) - #print "search", self.ifacename, name, fname - if fname == name: - if p.get('action'): - return 'out' - elif p.get('outen'): - return 'inout' - return 'input' - return None - - def pname(self, name): - """ generates the interface spec e.g. flexbus_ale - if there is only one flexbus interface, or - sd{0}_cmd if there are several. string format - function turns this into sd0_cmd, sd1_cmd as - appropriate. single mode stops the numerical extension. - """ - if self.single: - return '%s_%s' % (self.ifacename, name) - return '%s{0}_%s' % (self.ifacename, name) - - -class Interfaces(InterfacesBase): - """ contains a list of interface definitions - """ - - def __init__(self, pth=None): - InterfacesBase.__init__(self, Interface, pth) - - -def init(p, ifaces): - for cell in p.muxed_cells: - - for i in range(0, len(cell) - 1): - cname = cell[i + 1] - if not cname: # skip blank entries, no need to test - continue - temp = transfn(cname) - x = ifaces.getifacetype(temp) - print (cname, temp, x) - - -def pinmuxgen(pth=None, verify=True): - p = Parse(pth, verify) - print (p, dir(p)) - ifaces = Interfaces(pth) - init(p, ifaces) diff --git a/src/myhdl/pins.py b/src/myhdl/pins.py deleted file mode 100644 index 24ddd1e..0000000 --- a/src/myhdl/pins.py +++ /dev/null @@ -1,234 +0,0 @@ -# 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 - self.name = name - 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(npins=2, nfns=4): - x = """\ -from myhdl import block -@block -def test(testfn, clk, num_pins, num_fns, {0}): - args = [{0}] - return testfn(clk, num_pins, num_fns, args) -""" - - args = [] - for pnum in range(npins): - args.append("sel%d" % pnum) - args.append("pin%d" % pnum) - for pnum in range(nfns): - args.append("fn%d" % pnum) - args = ','.join(args) - x = x.format(args) - print x - print repr(x) - with open("testmod.py", "w") as f: - f.write(x) - x = "from testmod import test" - code = compile(x, '', 'exec') - y = {} - exec code in y - x = y["test"] - - 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 - - -@block -def test2(clk, num_pins, num_fns, args): - muxes = [] - pins = [] - fns = [] - for i in range(num_pins): - muxes.append(args.pop(0)) - pins.append(args.pop(0)) - for i in range(num_fns): - fns.append(args.pop(0)) - - 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 = [] - dirs = [] - fins = [] - fouts = [] - fdirs = [] - args = [] - for i in range(2): - m = Mux() - muxes.append(m) - muxvals.append(m.sel) - args.append(m) - pin = IO("inout", "name%d" % i) - pins.append(pin) - args.append(pin) - ins.append(pin.inp) - outs.append(pin.out) - dirs.append(pin.dirn) - fns = [] - for i in range(4): - fn = IO("inout", "fnname%d" % i) - fns.append(fn) - fins.append(fn.inp) - fouts.append(fn.out) - fdirs.append(fn.dirn) - args.append(fn) - clk = Signal(bool(0)) - - mux_inst = test(test2, clk, 2, 4, *args) - - @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 = [] - dirs = [] - fins = [] - fouts = [] - fdirs = [] - args = [] - for i in range(2): - m = Mux() - muxes.append(m) - muxvals.append(m.sel) - args.append(m) - pin = IO("inout", "name%d" % i) - pins.append(pin) - args.append(pin) - ins.append(pin.inp) - outs.append(pin.out) - dirs.append(pin.dirn) - fns = [] - for i in range(4): - fn = IO("inout", "fnname%d" % i) - fns.append(fn) - fins.append(fn.inp) - fouts.append(fn.out) - fdirs.append(fn.dirn) - args.append(fn) - clk = Signal(bool(0)) - - mux_inst = test(test2, clk, 2, 4, *args) - mux_inst.convert(hdl="Verilog", initial_values=True, testbench=False) - #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, testbench=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() diff --git a/src/myhdlgen/__init__.py b/src/myhdlgen/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/myhdlgen/mux.py b/src/myhdlgen/mux.py new file mode 100644 index 0000000..1495026 --- /dev/null +++ b/src/myhdlgen/mux.py @@ -0,0 +1,317 @@ +# mux.py + +from math import log +from myhdl import * + +period = 20 # clk frequency = 50 MHz + + +class Inputs(object): + def __init__(self, ins): + self.ins = ins + self.in_a = ins[0] + self.in_b = ins[1] + self.in_c = ins[2] + self.in_d = ins[3] + + +class Selectors(object): + def __init__(self, sels): + self.sels = sels + self.sel_a = sels[0] + self.sel_b = sels[1] + self.sel_c = sels[2] + self.sel_d = sels[3] + + +@block +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) | \ + bool(in_b if selector == 1 else False) | \ + bool(in_c if selector == 2 else False) | \ + bool(in_d if selector == 3 else False) + + return instances() # return all instances + + +@block +def pmux1(clk, in_a, + sel_a, out): + + @always(sel_a, + in_a) + def make_out(): + if sel_a: + out.next = in_a + else: + out.next = False + + return instances() # return all instances + + +@block +def pmux2(clk, in_a, in_b, + sel_a, sel_b, out): + + @always(sel_a, sel_b, + in_a, in_b) + def make_out(): + if sel_a: + out.next = in_a + elif sel_b: + out.next = in_b + else: + out.next = False + + return instances() # return all instances + + +@block +def pmux3(clk, in_a, in_b, in_c, + sel_a, sel_b, sel_c, out): + + @always(sel_a, sel_b, sel_c, + in_a, in_b, in_c) + def make_out(): + if sel_a: + out.next = in_a + elif sel_b: + out.next = in_b + elif sel_c: + out.next = in_c + else: + out.next = False + + return instances() # return all instances + + +@block +def pmux4(clk, ins, sels, out): + + @always(*list(sels.sels) + list(ins.ins)) + def make_out(): + if sels.sel_a: + out.next = ins.in_a + elif sels.sel_b: + out.next = ins.in_b + elif sels.sel_c: + out.next = ins.in_c + elif sels.sel_d: + out.next = ins.in_d + else: + out.next = False + + i = instances() + print dir(i), i + return i # return all instances + + +# testbench +@block +def pmux_tb4(): + + clk = Signal(bool(0)) + in_a = Signal(bool(0)) + in_b = Signal(bool(0)) + in_c = Signal(bool(0)) + in_d = Signal(bool(0)) + sel_a = Signal(bool(0)) + sel_b = Signal(bool(0)) + sel_c = Signal(bool(0)) + sel_d = Signal(bool(0)) + out = Signal(bool(0)) + + sels = Selectors((sel_a, sel_b, sel_c, sel_d)) + ins = Inputs((in_a, in_b, in_c, in_d)) + mux_inst = pmux4(clk, ins, sels, out) + + @instance + def clk_signal(): + while True: + sel_set = False + clk.next = not clk + if clk: + in_a.next = not in_a + if in_a: + in_b.next = not in_b + if in_b: + in_c.next = not in_c + if in_c: + in_d.next = not in_d + if in_d: + sel_set = True + if sel_set: + sel_a.next = not sel_a + if sel_a: + sel_b.next = not sel_b + if sel_b: + sel_c.next = not sel_c + if sel_c: + sel_d.next = not sel_d + yield delay(period // 2) + + # print simulation data on screen and file + file_data = open("pmux.csv", 'w') # file for saving data + # # print header on screen + s = "{0},{1},{2},{3},{4},{5},{6},{7},{8}".format( + "in_a", "in_b", "in_c", "in_d", + "sel_a", "sel_b", "sel_c", "sel_d", + "out") + print(s) + # # print header to file + file_data.write(s) + # print data on each clock + + @always(clk.posedge) + def print_data(): + # print on screen + # print.format is not supported in MyHDL 1.0 + print ("%s,%s,%s,%s,%s,%s,%s,%s,%s" % + (in_a, in_b, + in_c, in_d, + sel_a, sel_b, + sel_c, sel_d, out)) + + if sel_a: + assert out == in_a + elif sel_b: + assert out == in_b + elif sel_c: + assert out == in_c + elif sel_d: + assert out == in_d + # print in file + # print.format is not supported in MyHDL 1.0 + #file_data.write(s + "\n") + + return instances() + +# testbench + + +@block +def mux_tb(): + + clk = Signal(bool(0)) + in_a = Signal(bool(0)) + in_b = Signal(bool(0)) + in_c = Signal(bool(0)) + in_d = Signal(bool(0)) + selector = Signal(intbv(0)[2:0]) + out = Signal(bool(0)) + + mux_inst = mux4(clk, in_a, in_b, in_c, in_d, selector, out) + + @instance + def clk_signal(): + while True: + clk.next = not clk + if clk: + in_a.next = not in_a + if in_a: + in_b.next = not in_b + if in_b: + in_c.next = not in_c + if in_c: + in_d.next = not in_d + if in_d: + if selector == 3: + selector.next = 0 + else: + selector.next = selector + 1 + yield delay(period // 2) + + # print simulation data on screen and file + file_data = open("mux.csv", 'w') # file for saving data + # # print header on screen + s = "{0},{1},{2},{3},{4},{5}".format("in_a", "in_b", "in_c", "in_d", + "selector", "out") + print(s) + # # print header to file + file_data.write(s) + # print data on each clock + + @always(clk.posedge) + def print_data(): + # print on screen + # print.format is not supported in MyHDL 1.0 + print ("%s,%s,%s,%s,%s,%s" % + (in_a, in_b, + in_c, in_d, + selector, out)) + + if selector == 0: + assert out == in_a + elif selector == 1: + assert out == in_b + elif selector == 2: + assert out == in_c + elif selector == 3: + assert out == in_d + # print in file + # print.format is not supported in MyHDL 1.0 + #file_data.write(s + "\n") + + return instances() + + +def test_mux(): + + clk = Signal(bool(0)) + in_a = Signal(bool(0)) + in_b = Signal(bool(0)) + in_c = Signal(bool(0)) + in_d = Signal(bool(0)) + selector = Signal(intbv(0)[2:0]) + out = Signal(bool(0)) + + mux_v = mux4(clk, in_a, in_b, in_c, in_d, selector, out) + mux_v.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 + + +def test_pmux4(): + + clk = Signal(bool(0)) + in_a = Signal(bool(0)) + in_b = Signal(bool(0)) + in_c = Signal(bool(0)) + in_d = Signal(bool(0)) + sel_a = Signal(bool(0)) + sel_b = Signal(bool(0)) + sel_c = Signal(bool(0)) + sel_d = Signal(bool(0)) + out = Signal(bool(0)) + + sels = Selectors((sel_a, sel_b, sel_c, sel_d)) + ins = Inputs((in_a, in_b, in_c, in_d)) + pmux_v = pmux4(clk, ins, sels, out) + pmux_v.convert(hdl="Verilog", initial_values=True) + + # test bench + tb = pmux_tb4() + 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(4 * 66 * period) # run for 15 clock cycle + + +if __name__ == '__main__': + # test_mux() + print "test pmux" + test_pmux4() diff --git a/src/myhdlgen/pinmux_generator.py b/src/myhdlgen/pinmux_generator.py new file mode 100644 index 0000000..09b11de --- /dev/null +++ b/src/myhdlgen/pinmux_generator.py @@ -0,0 +1,122 @@ +from parse import Parse +from myhdlgen.pins import IO +from ifacebase import InterfacesBase +try: + from string import maketrans +except ImportError: + maketrans = str.maketrans + +# XXX hmmm duplicated from src/bsc/actual_pinmux.py +digits = maketrans('0123456789', ' ' * 10) # delete space later + +# XXX hmmm duplicated from src/bsc/actual_pinmux.py + + +def transfn(temp): + """ removes the number from the string of signal name. + """ + temp = temp.split('_') + if len(temp) == 2: + temp[0] = temp[0].translate(digits) + temp[0] = temp[0] .replace(' ', '') + return '_'.join(temp) + + +class Pin(object): + """ pin interface declaration. + * name is the name of the pin + * ready, enabled and io all create a (* .... *) prefix + * action changes it to an "in" if true + """ + + def __init__(self, name, + ready=True, + enabled=True, + io=False, + action=False, + bitspec=None, + outenmode=False): + self.name = name + self.ready = ready + self.enabled = enabled + self.io = io + self.action = action + self.bitspec = bitspec if bitspec else 'Bit#(1)' + self.outenmode = outenmode + + +class Interface(object): + """ create an interface from a list of pinspecs. + each pinspec is a dictionary, see Pin class arguments + single indicates that there is only one of these, and + so the name must *not* be extended numerically (see pname) + """ + # sample interface object: + """ + twiinterface_decl = Interface('twi', + [{'name': 'sda', 'outen': True}, + {'name': 'scl', 'outen': True}, + ]) + """ + + def __init__(self, ifacename, pinspecs, ganged=None, single=False): + self.ifacename = ifacename + self.ganged = ganged or {} + self.pins = [] # a list of instances of class Pin + self.pinspecs = pinspecs # a list of dictionary + self.single = single + for p in pinspecs: + _p = {} + _p['name'] = self.pname(p['name']) + _p['typ'] = self.pname(p['type']) + self.pins.append(IO(**_p)) + + def getifacetype(self, name): + for p in self.pinspecs: + fname = "%s_%s" % (self.ifacename, p['name']) + #print "search", self.ifacename, name, fname + if fname == name: + if p.get('action'): + return 'out' + elif p.get('outen'): + return 'inout' + return 'input' + return None + + def pname(self, name): + """ generates the interface spec e.g. flexbus_ale + if there is only one flexbus interface, or + sd{0}_cmd if there are several. string format + function turns this into sd0_cmd, sd1_cmd as + appropriate. single mode stops the numerical extension. + """ + if self.single: + return '%s_%s' % (self.ifacename, name) + return '%s{0}_%s' % (self.ifacename, name) + + +class Interfaces(InterfacesBase): + """ contains a list of interface definitions + """ + + def __init__(self, pth=None): + InterfacesBase.__init__(self, Interface, pth) + + +def init(p, ifaces): + for cell in p.muxed_cells: + + for i in range(0, len(cell) - 1): + cname = cell[i + 1] + if not cname: # skip blank entries, no need to test + continue + temp = transfn(cname) + x = ifaces.getifacetype(temp) + print (cname, temp, x) + + +def pinmuxgen(pth=None, verify=True): + p = Parse(pth, verify) + print (p, dir(p)) + ifaces = Interfaces(pth) + init(p, ifaces) diff --git a/src/myhdlgen/pins.py b/src/myhdlgen/pins.py new file mode 100644 index 0000000..24ddd1e --- /dev/null +++ b/src/myhdlgen/pins.py @@ -0,0 +1,234 @@ +# 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 + self.name = name + 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(npins=2, nfns=4): + x = """\ +from myhdl import block +@block +def test(testfn, clk, num_pins, num_fns, {0}): + args = [{0}] + return testfn(clk, num_pins, num_fns, args) +""" + + args = [] + for pnum in range(npins): + args.append("sel%d" % pnum) + args.append("pin%d" % pnum) + for pnum in range(nfns): + args.append("fn%d" % pnum) + args = ','.join(args) + x = x.format(args) + print x + print repr(x) + with open("testmod.py", "w") as f: + f.write(x) + x = "from testmod import test" + code = compile(x, '', 'exec') + y = {} + exec code in y + x = y["test"] + + 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 + + +@block +def test2(clk, num_pins, num_fns, args): + muxes = [] + pins = [] + fns = [] + for i in range(num_pins): + muxes.append(args.pop(0)) + pins.append(args.pop(0)) + for i in range(num_fns): + fns.append(args.pop(0)) + + 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 = [] + dirs = [] + fins = [] + fouts = [] + fdirs = [] + args = [] + for i in range(2): + m = Mux() + muxes.append(m) + muxvals.append(m.sel) + args.append(m) + pin = IO("inout", "name%d" % i) + pins.append(pin) + args.append(pin) + ins.append(pin.inp) + outs.append(pin.out) + dirs.append(pin.dirn) + fns = [] + for i in range(4): + fn = IO("inout", "fnname%d" % i) + fns.append(fn) + fins.append(fn.inp) + fouts.append(fn.out) + fdirs.append(fn.dirn) + args.append(fn) + clk = Signal(bool(0)) + + mux_inst = test(test2, clk, 2, 4, *args) + + @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 = [] + dirs = [] + fins = [] + fouts = [] + fdirs = [] + args = [] + for i in range(2): + m = Mux() + muxes.append(m) + muxvals.append(m.sel) + args.append(m) + pin = IO("inout", "name%d" % i) + pins.append(pin) + args.append(pin) + ins.append(pin.inp) + outs.append(pin.out) + dirs.append(pin.dirn) + fns = [] + for i in range(4): + fn = IO("inout", "fnname%d" % i) + fns.append(fn) + fins.append(fn.inp) + fouts.append(fn.out) + fdirs.append(fn.dirn) + args.append(fn) + clk = Signal(bool(0)) + + mux_inst = test(test2, clk, 2, 4, *args) + mux_inst.convert(hdl="Verilog", initial_values=True, testbench=False) + #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, testbench=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()