# New user help: communication between two blocks in same function

**URL:** <https://discourse.myhdl.org/t/new-user-help-communication-between-two-blocks-in-same-function/192>\
**Category:** Support\
**Created:** [June 3, 2017, 8:45pm UTC](https://discourse.myhdl.org/t/new-user-help-communication-between-two-blocks-in-same-function/192 "2017-06-03T20:45:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![krbonne](https://avatars.discourse-cdn.com/v4/letter/k/47e85d/32.png) [@krbonne](https://discourse.myhdl.org/u/krbonne)\
**Post date:** [June 3, 2017, 8:45pm UTC](https://discourse.myhdl.org/t/new-user-help-communication-between-two-blocks-in-same-function/192/1 "2017-06-03T20:45:12Z")

</div>

Hi,

I am new to myhdl, trying to learn the language by implementing the “hello world” of VGA (the “bouncing ball”).

I started out with the vga-signal generator module, which is a pretty standard design:

- a “clocked” block to generate internal two counters (hcounter from 0 to 799, vcounter from 0 to 520)
- a “combinational” block to generate the sync signals, external counters and some additional signals, based on the internal counters generated in the clocked block

The code is here:

> **[on1arf/myhdl-vga\_bounceball](https://github.com/on1arf/myhdl-vga_bounceball)**
>
> vga bouncing ball in myhdl. Contribute to on1arf/myhdl-vga\_bounceball development by creating an account on GitHub.

My idea is to use variables on the scope of the function to communicate between the two blocks, but this does not seams to work. The comb block is only executed once.  
The changes in the variables in the clocked block do not seams to ripple throu to the comb block.

Adding “nonlocal” in the embedded functions does not help.

What am I doing wrong here?  
What is the proper way to implement this?

Cheerio! Kr. Bonne.

---

<div class="post-metadata">

**Author:** ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)\
**Post date:** [June 5, 2017, 6:39pm UTC](https://discourse.myhdl.org/t/new-user-help-communication-between-two-blocks-in-same-function/192/2 "2017-06-05T18:39:33Z")

</div>

There are few _improvements / corrections_:  
You can declare the counters as:

```auto
	hcounter_internal = Signal(intbv(0,min=0, max=800))
	vcounter_internal = Signal(intbv(0,min=0, max=521))

```

so without the _[10:]_, using _min_ and _max_ will calculate the width for you.

I (most of us) always declare a clocked process with `@always_seq(clk.posedge, reset)` rather than with `@always(clk.posedge, reset.posedge)`, but the latter works as well. The `always_seq` has the advantage that the _reset_ action is implied.

But where the simulation stumbles upon is that you forgot the `.next` attributes in your clocked process.  
I downloaded you code and Simulation didn’t dun at all.  
You can find my changes here:

```auto
from __future__ import print_function

from myhdl import Signal, intbv, always_comb, always_seq, ResetSignal, always, instance, delay, traceSignals, Simulation

def vga640x480(clk25MhzPulse, reset, vga_hs, vga_vs, vga_videoon, vga_offscreen, hcounter_external, vcounter_external):
    """ vga640x480 generator
    input:	25Mhz clock
            reset
    output:	vga_hs (horizontal sync)
            vga_vs (vertical sync)
            vga_videoon (video on, visible screen)
            vga_offscreen (vga is above or below visible screen)
            hcounter: horizontal counter: 0 to 799
            vcounter: vertical counter: 0 to 520
    """

    # local data
    # total resolution = 800 * 521 (640x480 visible) @ 25 Mhz = 60 Hz
    hcounter_internal = Signal(intbv(0, min=0, max=800))
    vcounter_internal = Signal(intbv(0, min=0, max=521))

    # combinatorial logic
    @always_comb
    def assign():

        if hcounter_internal < 96:
            vga_hs.next = 1
# # DEBUG
# print("1")
        else:
            vga_hs.next = 0
# # DEBUG
# print("0")

        if vcounter_internal < 2:
            vga_vs.next = 1
        else:
            vga_vs.next = 0

        if (hcounter_internal >= 144) and (hcounter_internal < 784) and (vcounter_internal >= 31) and (vcounter_internal < 510):
            vga_videoon.next = 1
        else:
            vga_videoon.next = 0

        # copy counters to output
        if hcounter_internal >= 144:
            hcounter_external.next = hcounter_internal - 144
        else:
            hcounter_external.next = 0

        if vcounter_internal >= 144:
            vcounter_external.next = vcounter_internal - 144
        else:
            vcounter_external.next = 0

    # clock driven logic
    @always_seq(clk25MhzPulse.posedge, reset)
    def Clock25Mhz():
        # DEBUG
        # print("hcounter = "+str(hcounter_internal))
        # print("vcounter = "+str(vcounter_internal))

        if hcounter_internal != 799:
            hcounter_internal.next = hcounter_internal + 1
        else:
            # end of horizontal line
            hcounter_internal.next = 0
            if vcounter_internal != 520:
                vcounter_internal.next = vcounter_internal + 1
            else:
                vcounter_internal.next = 0
        # end horizontal and vertical counters
        # end else (not reset)

    return Clock25Mhz, assign

"""
	test suite
"""
def test_vga640x480():
    # local vars
    clk25MhzPulse, vga_hs, vga_vs, vga_videoon, vga_offscreen = [Signal(bool(0)) for _ in range(5)]
    reset = ResetSignal(0, 1, True)
    hcounter_external = Signal(intbv(0, min=0, max=800)[10:])
    vcounter_external = Signal(intbv(0, min=0, max=521)[10:])

    vga640x480_inst = vga640x480(clk25MhzPulse, reset, vga_hs, vga_vs, vga_videoon, vga_offscreen, hcounter_external, vcounter_external)

    @always(delay(20))
    def clkgen():
        clk25MhzPulse.next = not clk25MhzPulse

    @instance
    def stimulus():
        reset.next = 1
        yield delay(100)
        reset.next = 0

    return vga640x480_inst, clkgen, stimulus

"""
	simulation
"""
def simulate(timesteps):
    tb = traceSignals(test_vga640x480)
    sim = Simulation(tb)
    sim.run(timesteps)

simulate(800 * 521 * 40 + 5000)

```

You see that there is no extra work necessary to use the two _communicating_ SIgnals, hcounter\_internal and vcounter\_internal, in both processes. (as they been declared on the same level as those two processes and are thus inherently visible by those two processes)

There is more to say about the way you structured your code, but it basically does what you intended.

Regards,

Josy.

---

<div class="post-metadata">

**Author:** ![krbonne](https://avatars.discourse-cdn.com/v4/letter/k/47e85d/32.png) [@krbonne](https://discourse.myhdl.org/u/krbonne)\
**Post date:** [June 8, 2017, 8:48pm UTC](https://discourse.myhdl.org/t/new-user-help-communication-between-two-blocks-in-same-function/192/3 "2017-06-08T20:48:11Z")

</div>

Hi Josy,

First my apologies or the late reply. (a busy couple of days)  
Thank you very much for the answer. I know there was something fundamentatlly wrong as my code, but I couldn’t put my finger on it.

Your remark about @always\_seq and the general structuring of the code is valid, but this is just development code and my first use of myhdl. I hope that my coding-skills get better in the future 🙂

Thanks for the help  
Cheerio! Kr. Bonne.
