# Combinational tree like accumulatioin

**URL:** https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349
**Category:** Support
**Created:** [December 4, 2018, 3:26pm UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349 "2018-12-04T15:26:45Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![mkarwat](https://avatars.discourse-cdn.com/v4/letter/m/bbe5ce/32.png) [@mkarwat](https://discourse.myhdl.org/u/mkarwat)
#### Post date: [December 4, 2018, 3:26pm UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349/1 "2018-12-04T15:26:45Z")

</div>

Hello,  
I want to create a (convertible) structure that will accumulate a list of signals in always\_comb, here is a code that works perfectly fine (calc\_elems is a list of signals, filled from 0 to in\_size):

```
    calc_elems_len = 2 * in_size - 1
    @block
    def add(z, x, y):
            @always_comb
            def logic():
                    z.next = x + y
            return logic

    add_inst = list()
    for i in range(in_size, calc_elems_len):
            a = 2 * i - 2 * in_size
            b = a + 1
            add_inst.append(add(calc_elems[i], calc_elems[a], calc_elems[b]))

```

I can use it in simulation and it converts into correct VHDL. But its not very nice to use, I would like to do something like this:

```
    calc_elems_len = 2 * in_size - 1
    for i in range(in_size, calc_elems_len):
            a = 2 * i - 2 * in_size
            b = a + 1
            @always_comb
            def add_me():
                calc_elems[i].next = calc_elems[a] + calc_elems[b]

```

The problem is that I get:  
`myhdl.AlwaysCombError: signal ({'calc_elems'}) used as inout in always_comb function argument`  
Which is not true, because each signal in the list is used exactly in one direction in one always\_comb. Unless list of signals is treated as a whole, which is wrong.  
Is there a way to achieve this without the need to create an extra add block?

---

<div class="post-metadata">

### Author: ![cfelton](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/cfelton/32/3_2.png) [@cfelton](https://discourse.myhdl.org/u/cfelton)
#### Post date: [December 5, 2018, 11:30am UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349/2 "2018-12-05T11:30:13Z")

</div>

The option is to create `a` and `b` outside the `@always`, make them a list of ints, and then move the loop inside the `@always`.

---

<div class="post-metadata">

### Author: ![DrPi](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/drpi/32/36_2.png) [@DrPi](https://discourse.myhdl.org/u/DrPi)
#### Post date: [December 10, 2018, 8:07am UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349/3 "2018-12-10T08:07:59Z")

</div>

The error you get is a problem already discussed in other threads.  
You can try this (not tested) :

```python
    calc_elems_len = 2 * in_size - 1
    for i in range(in_size, calc_elems_len):
            a = 2 * i - 2 * in_size
            b = a + 1
            c = calc_elems[a] + calc_elems[b]
            @always_comb
            def add_me():
                calc_elems[i].next = c

```

---

<div class="post-metadata">

### Author: ![DrPi](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/drpi/32/36_2.png) [@DrPi](https://discourse.myhdl.org/u/DrPi)
#### Post date: [December 10, 2018, 8:12am UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349/4 "2018-12-10T08:12:19Z")

</div>

This one will more likely work (still not tested) :

```python
    calc_elems_len = 2 * in_size - 1
    c = [Signal(calc_elems[0].val) for _ in range(len(calc_elems))]
    for i in range(in_size, calc_elems_len):
            a = 2 * i - 2 * in_size
            b = a + 1
            @always_comb
            def add_me():
                c[i].next = calc_elems[a] + calc_elems[b]
            @always_comb
            def assign_me():
                calc_elems[i].next = c[i]

```

---

<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: [December 10, 2018, 8:48am UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349/5 "2018-12-10T08:48:44Z")

</div>

> [@mkarwat](#):
>
> myhdl.AlwaysCombError: signal ({‘calc\_elems’}) used as inout in always\_comb function argument

IMO, and certainly if when converting to VHDL, that check in the code can be removed. The only issue is that when that signal is a top-level signal (which in this case I presume it isn’t) you would get an inout port …

---

<div class="post-metadata">

### Author: ![mkarwat](https://avatars.discourse-cdn.com/v4/letter/m/bbe5ce/32.png) [@mkarwat](https://discourse.myhdl.org/u/mkarwat)
#### Post date: [December 10, 2018, 10:07am UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349/6 "2018-12-10T10:07:01Z")

</div>

Thanks for help, its not top-level signal, what worked at the end is:

```auto
    @always_comb
    def add_me():
        for i in range(in_size, calc_elems_len):
            calc_elems_helper[i].next = calc_elems[2 * i - 2 * in_size] + calc_elems[2 * i - 2 * in_size + 1]

    @always_comb
    def assign_me():
        for i in range(in_size, calc_elems_len):
            calc_elems[i].next = calc_elems_helper[i]

```

For unknown to me reason when I moved loop outside always\_comb I didn’t get any warnings/errors but signals were not assigned.

---

<div class="post-metadata">

### Author: ![DrPi](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/drpi/32/36_2.png) [@DrPi](https://discourse.myhdl.org/u/DrPi)
#### Post date: [December 10, 2018, 10:42am UTC](https://discourse.myhdl.org/t/combinational-tree-like-accumulatioin/349/7 "2018-12-10T10:42:49Z")

</div>

> [@mkarwat](#):
>
> For unknown to me reason when I moved loop outside always\_comb I didn’t get any warnings/errors but signals were not assigned.

That makes sense.  
With loop outside always\_comb, you have to `add_inst.append(add_me)` and `add_inst.append(assign_me)` inside the loop… if it works.
