New to MyHDL - how should I connect outputs to inputs properly?

I’m doing something wrong here - as a bit of a background, I’m a long-time software developer (boo, hiss! I get it) trying to get my head around MyHDL and Verilog for digital design, and in principle I think I understand how things work, but trying to put it into practice is giving me some headaches. I’ve played around with Verilog and managed to satisfy myself that I understand how it works, but I am more comfortable/productive working with Python and from what I’ve seen so far, I really like this MyHDL tool.

I’ve created a very stripped down example of what I’m trying to achieve, and I would be grateful if someone with more experience than me can tell me what I’m doing wrong.


# Create a basic clock

@block
def ClkDriver(clk):
    @instance
    def drive_clk():
        while True:
            yield delay(1)
            clk.next = 1
            yield delay(1)
            clk.next = 0

    return drive_clk

# Create a clocked component which produces an output

@block
def ComponentWithOutput(output, clk):
    output = Signal(modbv(0, min=0, max=4))

    @always(clk.posedge)
    def do_something():
        print ("OUTPUT:", output)
        output.next = output + 1

    return do_something

# Create a clocked component which takes an input and does something with it
@block
def ComponentWithInput(_input, clk):

    @always(clk.negedge)  # Use the negative edge just to keep the timings nice, but it shouldnt matter
    def show_something():
        print("\tINPUT:", _input)

    return show_something


@block
def TestTB():
    clk = Signal(0)

    output = Signal(modbv(0, min=0, max=4))

    clk_driver = ClkDriver(clk)
    out_comp = ComponentWithOutput(output, clk)
    in_comp = ComponentWithInput(output, clk)

    return instances()

When I run the simulation, the output is working fine, and I can see that both the input and output are reacting to the clocks, so as far as I can tell the components are “operating” but I’m obviously doing something wrong with the way I’m setting things up.

OUTPUT: 0
        INPUT: 0
OUTPUT: 1
        INPUT: 0
OUTPUT: 2
        INPUT: 0
OUTPUT: 3
        INPUT: 0
OUTPUT: 0
        INPUT: 0
...

I understand that in this particular case I could move things around and print my input statement in the output component and it would appear to work, but I’m not trying to simply make it print the correct numbers but understand why the signal that comes back from the output is not propagating into the input component.

I have a larger project that I’m trying to work on, and I’d like to keep my components separated like this (so I can parameterize and create multiple instances etc) and then tie them together with signals, so if anyone can point me in the right direction, I’d much appreciate it.

I think it may have something to do with ConcatSignal or shadow signals or something, but I’ve tried to follow the docs or find a nugget of wisdom that exposes my fundamental misunderstanding but I thought I’d come to where the “experts” are :slight_smile:

Can you upload the complete stripped-down design?

Thinking about it a bit more (and testing your code, copy edit):
In ComponentWithOutput remove the line output = Signal(modbv(0, min=0, max=4)) as this creates a local Signal which will be updated every clock cycle instead of updating the supplied external argument.
The def ComponentWithOutput(output, clk): was flagged in my editor (Eclipse with PyDev plugin):

1 Like

Ahhh, thank you Josy, that explanation makes sense to me (at least for now). I just tried that and it does indeed work. I will go ahead and apply this new knowledge to my bigger design and see how far I get.

:+1: