Connecting signals between modules

I’ve come to the conclusion that I apparently don’t have a clue how to connect signals between modules. As an example, I have made a DFFE module which I can simualte and convert to V*. When I try to connect two of these flip-flops together into a 2-bit shift register, it does not work. I’ve tried with and without the def logic wrapper but have had no success. I’ve read the Structural Modeling section five times and browsed the forums looking for a simple example on how to interconnect two modules properly but have not had success. Are there any examples?

I have this:

from myhdl import *
from dffe import dffe
from random import randrange


@block
def shift_reg(reset=None, clock=None, data_in=None, data_out=None):

    @always_seq(clock.posedge, reset=reset)
    def logic():
        x = Signal(bool(0))

        ff_1 = dffe(reset=reset, clock=clock, data_in=data_in, data_out=x)
        ff_2 = dffe(reset=reset, clock=clock, data_in=x, data_out=data_out)

    return logic


@block
def test_shift_reg():

    clock = Signal(bool(0))
    reset = ResetSignal(0, active=1, async=True)
    data_in = Signal(bool())
    data_out = Signal(bool())

    inst = shift_reg(reset=reset, clock=clock, data_in=data_in, data_out=data_out)

    @always(delay(10))
    def clock_generator():
        clock.next = not clock

    @instance
    def reset_generator():
        reset.next = True
        yield delay(100)
        reset.next = False

    @instance
    def stimulus():
        yield delay(150)

        for _ in range(10):
            yield delay(randrange(50, 100))
            data_in.next = randrange(0, 1)

        yield delay(100)

        raise StopSimulation

    return inst, clock_generator, reset_generator, stimulus


def simulate():
    tb = test_shift_reg()
    tb.config_sim(trace=True)
    tb.run_sim()


def convert(hdl='Verilog'):
    clock = Signal(bool(0))
    reset = ResetSignal(0, active=1, async=True)
    data_in = Signal(bool(0))
    data_out = Signal(bool(0))

    inst = shift_reg(reset=reset, clock=clock, data_in=data_in, data_out=data_out)
    inst.convert(hdl)


if __name__ == '__main__':
    simulate()
    convert()

But get this:

Traceback (most recent call last):
  File "C:/MyPython/timing_engine/interconnects.py", line 72, in <module>
	convert()
  File "C:/MyPython/timing_engine/interconnects.py", line 67, in convert
	inst.convert(hdl)
  File "C:\MyPython\timing_engine\venv\lib\site-packages\myhdl\_block.py", line 342, in convert
	return converter(self)
  File "C:\MyPython\timing_engine\venv\lib\site-packages\myhdl\conversion\_toVerilog.py", line 177, in __call__
	genlist = _analyzeGens(arglist, h.absnames)
  File "C:\MyPython\timing_engine\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 170, in _analyzeGens
	v.visit(tree)
  File "C:\Python_v3.6.2\lib\ast.py", line 253, in visit
	return visitor(node)
  File "C:\MyPython\timing_engine\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 1068, in visit_Module
	self.generic_visit(node)
  File "C:\Python_v3.6.2\lib\ast.py", line 261, in generic_visit
	self.visit(item)
  File "C:\Python_v3.6.2\lib\ast.py", line 253, in visit
	return visitor(node)
  File "C:\MyPython\timing_engine\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 1139, in visit_FunctionDef
	self.visit(n)
  File "C:\Python_v3.6.2\lib\ast.py", line 253, in visit
	return visitor(node)
  File "C:\MyPython\timing_engine\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 533, in visit_Assign
	self.raiseError(node, _error.TypeInfer, n)
  File "C:\MyPython\timing_engine\venv\lib\site-packages\myhdl\conversion\_misc.py", line 148, in raiseError
	raise ConversionError(kind, msg, info)
myhdl.ConversionError: in file C:/MyPython/timing_engine/interconnects.py, line 11:
	Can't infer variable type: x
from myhdl import *
# from dffe import dffe
from random import randrange


@block
def dffe(clock, reset, clear, enable, data_in, data_out):

    @always_seq(clock.posedge, reset=reset)
    def logic():
        if clear:
            data_out.next = 0
        elif enable:
            data_out.next = data_in

    return logic


@block
def shift_reg(clock, reset, clear, enable, data_in, data_out):

#     @always_seq(clock.posedge, reset=reset)
#     def logic():
    x = Signal(bool(0))

    ff_1 = dffe(clock, reset, clear, enable, data_in, x)
    ff_2 = dffe(clock, reset, clear, enable, x, data_out)

    return ff_1, ff_2


@block
def test_shift_reg():

    clock = Signal(bool(0))
    reset = ResetSignal(0, active=1, async=True)
    clear = Signal(bool(0))
    enable = Signal(bool(0))

    data_in = Signal(bool())
    data_out = Signal(bool())

    inst = shift_reg(clock, reset, clear, enable, data_in, data_out)

    @always(delay(10))
    def clock_generator():
        clock.next = not clock

    @instance
    def reset_generator():
        reset.next = True
        yield delay(100)
        reset.next = False

    @instance
    def stimulus():
        yield delay(150)

        for _ in range(10):
            yield delay(randrange(50, 100))
            data_in.next = randrange(0, 1)

        yield delay(100)

        raise StopSimulation

    return inst, clock_generator, reset_generator, stimulus


def simulate():
    tb = test_shift_reg()
    tb.config_sim(trace=True)
    tb.run_sim()


def convert(hdl='Verilog'):
    clock = Signal(bool(0))
    reset = ResetSignal(0, active=1, async=True)
    clear = Signal(bool(0))
    enable = Signal(bool(0))

    data_in = Signal(bool())
    data_out = Signal(bool())

    inst = shift_reg(clock, reset, clear, enable, data_in, data_out)
    inst.convert('VHDL')


if __name__ == '__main__':
    simulate()
    convert()
    

@josyb

Thank you for your quick and helpful reply. So, what I know about you so far:

  1. You prefer VHDL to Verilog.
  2. You prefer positional arguments to named.
  3. You know your stuff and teach it well.

Since named arguments are not working for me, I think I will abandon their use. I have not succeeded in using them for default values as MyHDL disregards those such values. There must be some better way to deal with this like the class approach you demonstrated in your earlier post that also helped me but I’m too green to wander off there yet.

Many thanks.