# Iterating over a group of elements

**URL:** <https://discourse.myhdl.org/t/iterating-over-a-group-of-elements/258>\
**Category:** Support\
**Created:** [March 21, 2018, 10:12pm UTC](https://discourse.myhdl.org/t/iterating-over-a-group-of-elements/258 "2018-03-21T22:12:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kc64](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/kc64/32/83_2.png) [@kc64](https://discourse.myhdl.org/u/kc64)\
**Post date:** [March 21, 2018, 10:12pm UTC](https://discourse.myhdl.org/t/iterating-over-a-group-of-elements/258/1 "2018-03-21T22:12:23Z")

</div>

I am designing an interface that implements an 8-bit-to-32-bit register. Upon clear or reset, I want to reset the byte value registers to 0. I hoped to do this using an elegant approach but have only succeeded with something that feels crufty.

The overview is that you can write to any byte of the 4-byte register with data\_in, when all 4 bytes have been loaded, the data valid signal is generated so that a 32-bit word my be read from data\_out.

Any recommendations for a beginner?

This is the code that works. If I swap out the comments for the 4 explicit register assignements, things go badly. I’ve included the trace below the code when this happens.

```
def register_32(data_in=None, data_out=None, data_valid=None, byte=None, enable=None, clear=None, clock=None, reset=None):

    register = [Signal(intbv(0)[8:0]) for _ in range(4)]
    q = ConcatSignal(*register[::-1])
    flags = [Signal(bool(0)) for _ in range(4)]

    @always_comb
    def pack():
        data_out.next = q
        data_valid.next = flags[0] and flags[1] and flags[2] and flags[3]

    @always(clock.posedge, reset.posedge)
    def logic():

        if reset or clear:

# for i in range(3):
# register[i].next = 0

            register[0].next = 0
            register[1].next = 0
            register[2].next = 0
            register[3].next = 0

            flags[0].next = False
            flags[1].next = False
            flags[2].next = False
            flags[3].next = False

        if enable:
            register[byte].next = data_in
            flags[byte].next = True

    return pack, logic

```

Trace:

```
Traceback (most recent call last):
  File "C:/MyPython/myhdl_demo/register_32.py", line 122, in <module>
    convert()
  File "C:/MyPython/myhdl_demo/register_32.py", line 118, in convert
    toVerilog(register_32, data_in, data_out, data_valid, byte, enable, clear, clock, reset)
  File "C:\MyPython\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_toVerilog.py", line 151, in __call__
    genlist = _analyzeGens(arglist, h.absnames)
  File "C:\MyPython\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 164, in _analyzeGens
    v.visit(tree)
  File "C:\Python_v3.6.2\lib\ast.py", line 253, in visit
    return visitor(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\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 290, in visit_FunctionDef
    self.visitList(node.body)
  File "C:\MyPython\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_misc.py", line 162, in visitList
    self.visit(n)
  File "C:\Python_v3.6.2\lib\ast.py", line 253, in visit
    return visitor(node)
  File "C:\MyPython\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 312, in visit_If
    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\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 261, in visit_Assign
    self.visit(node.value)
  File "C:\Python_v3.6.2\lib\ast.py", line 253, in visit
    return visitor(node)
  File "C:\MyPython\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_analyze.py", line 248, in visit_List
    self.raiseError(node, _error.NotSupported, "list")
  File "C:\MyPython\myhdl_demo\venv\lib\site-packages\myhdl\conversion\_misc.py", line 149, in raiseError
    raise ConversionError(kind, msg, info)
myhdl.ConversionError: in file C:/MyPython/myhdl_demo/register_32.py, line 24:
    Not supported: list
```

---

<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:** [March 22, 2018, 10:07am UTC](https://discourse.myhdl.org/t/iterating-over-a-group-of-elements/258/2 "2018-03-22T10:07:52Z")

</div>

I have no issues with that.  
But this is with MyHDL 0.10dev.

I had to correct the coding and adapted it also to my style.

```python
'''
Created on 22 mrt. 2018

@author: kc64 / josyb
'''

from myhdl import Signal, intbv, ConcatSignal, ResetSignal, always, always_comb, always_seq, toVHDL

def register_32(data_in, data_out, data_valid, byte, enable, clear, clock, reset):

    register4x8 = [Signal(intbv(0)[8:0]) for _ in range(4)]
    q = ConcatSignal(*register4x8[::-1])
    flags = [Signal(bool(0)) for _ in range(4)]

    @always_comb
    def pack():
        data_out.next = q
        data_valid.next = flags[0] and flags[1] and flags[2] and flags[3]

    @always(clock.posedge, reset.posedge)
    def logic():
        if reset:
            for i in range(3):
                register4x8[i].next = 0
                flags[i].next = False
            
        else:
            if clear or enable:
                if clear:
                    for i in range(3):
                        register4x8[i].next = 0
                        flags[i].next = False
    # register4x8[0].next = 0
    # register4x8[1].next = 0
    # register4x8[2].next = 0
    # register4x8[3].next = 0
    #     
    # flags[0].next = False
    # flags[1].next = False
    # flags[2].next = False
    # flags[3].next = False
                else:
                    register4x8[byte].next = data_in
                    flags[byte].next = True

    return pack, logic

data_in = Signal(intbv(0)[8:])
data_out = Signal(intbv(0)[32:])
data_valid = Signal(bool(0))
byte = Signal(intbv(0)[2:])
enable = Signal(bool(0))
clear = Signal(bool(0))
clock = Signal(bool(0))
reset = Signal(bool(0))
# reset = ResetSignal(0, 1, True)

toVHDL(register_32, data_in, data_out, data_valid, byte, enable, clear, clock, reset)

```

generates valid VHDL:

```auto
-- File: register_32.vhd
-- Generated by MyHDL 1.0dev
-- Date: Thu Mar 22 10:48:11 2018

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;

use work.pck_myhdl_10.all;

entity register_32 is
	port(
		data_in : in unsigned(7 downto 0);
		data_out : out unsigned(31 downto 0);
		data_valid : out std_logic;
		byte : in unsigned(1 downto 0);
		enable : in std_logic;
		clear : in std_logic;
		clock : in std_logic;
		reset : in std_logic
	);
end entity register_32;

architecture MyHDL of register_32 is

	signal q : unsigned(31 downto 0);
	type t_array_flags is array (0 to 4 - 1) of std_logic;
	signal flags : t_array_flags;
	type t_array_register4x8 is array (0 to 4 - 1) of unsigned(7 downto 0);
	signal register4x8 : t_array_register4x8;

begin

	q(32-1 downto 24) <= register4x8(3);
	q(24-1 downto 16) <= register4x8(2);
	q(16-1 downto 8) <= register4x8(1);
	q(8-1 downto 0) <= register4x8(0);

	data_out <= q;
	data_valid <= stdl(bool(flags(0)) and bool(flags(1)) and bool(flags(2)) and bool(flags(3)));

	REGISTER_32_LOGIC : process(clock, reset) is
	begin
		if bool(reset) then
			for i in 0 to 3 - 1 loop
				register4x8(i) <= to_unsigned(0, 8);
				flags(i) <= '0';
			end loop;
		elsif rising_edge(clock) then
			if (bool(clear) or bool(enable)) then
				if bool(clear) then
					for i in 0 to 3 - 1 loop
						register4x8(i) <= to_unsigned(0, 8);
						flags(i) <= '0';
					end loop;
				else
					register4x8(to_integer(byte)) <= data_in;
					flags(to_integer(byte)) <= '1';
				end if;
			end if;
		end if;
	end process REGISTER_32_LOGIC;

end architecture MyHDL;

```

Most of us code clocked processes with the `@always_seq` decorator which infers the correct sequence.

```python
'''
Created on 22 mrt. 2018

@author: josy
'''

from myhdl import Signal, intbv, ConcatSignal, ResetSignal, always, always_comb, always_seq, toVHDL

def register_32(data_in, data_out, data_valid, byte, enable, clear, clock, reset):

    register4x8 = [Signal(intbv(0)[8:0]) for _ in range(4)]
    q = ConcatSignal(*register4x8[::-1])
    flags = [Signal(bool(0)) for _ in range(4)]

    @always_comb
    def pack():
        data_out.next = q
        data_valid.next = flags[0] and flags[1] and flags[2] and flags[3]

    @always_seq(clock.posedge, reset)
    def logic():
        if clear:
            for i in range(3):
                register4x8[i].next = 0
                flags[i].next = False
        elif enable:
            register4x8[byte].next = data_in
            flags[byte].next = True

    return pack, logic

data_in = Signal(intbv(0)[8:])
data_out = Signal(intbv(0)[32:])
data_valid = Signal(bool(0))
byte = Signal(intbv(0)[2:])
enable = Signal(bool(0))
clear = Signal(bool(0))
clock = Signal(bool(0))
# reset = Signal(bool(0))
reset = ResetSignal(0, 1, True)

toVHDL(register_32, data_in, data_out, data_valid, byte, enable, clear, clock, reset)

```

giving this VHDL:

```auto
-- File: register_32.vhd
-- Generated by MyHDL 1.0dev
-- Date: Thu Mar 22 11:05:12 2018

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;

use work.pck_myhdl_10.all;

entity register_32 is
	port(
		data_in : in unsigned(7 downto 0);
		data_out : out unsigned(31 downto 0);
		data_valid : out std_logic;
		byte : in unsigned(1 downto 0);
		enable : in std_logic;
		clear : in std_logic;
		clock : in std_logic;
		reset : in std_logic
	);
end entity register_32;

architecture MyHDL of register_32 is

	signal q : unsigned(31 downto 0);
	type t_array_flags is array (0 to 4 - 1) of std_logic;
	signal flags : t_array_flags;
	type t_array_register4x8 is array (0 to 4 - 1) of unsigned(7 downto 0);
	signal register4x8 : t_array_register4x8;

begin

	q(32-1 downto 24) <= register4x8(3);
	q(24-1 downto 16) <= register4x8(2);
	q(16-1 downto 8) <= register4x8(1);
	q(8-1 downto 0) <= register4x8(0);

	data_out <= q;
	data_valid <= stdl(bool(flags(0)) and bool(flags(1)) and bool(flags(2)) and bool(flags(3)));

	REGISTER_32_LOGIC : process(clock, reset) is
	begin
		if (reset = '1') then
			flags(0) <= '0';
			flags(1) <= '0';
			flags(2) <= '0';
			flags(3) <= '0';
			register4x8(0) <= to_unsigned(0, 8);
			register4x8(1) <= to_unsigned(0, 8);
			register4x8(2) <= to_unsigned(0, 8);
			register4x8(3) <= to_unsigned(0, 8);
		elsif rising_edge(clock) then
			if bool(clear) then
				for i in 0 to 3 - 1 loop
					register4x8(i) <= to_unsigned(0, 8);
					flags(i) <= '0';
				end loop;
			elsif bool(enable) then
				register4x8(to_integer(byte)) <= data_in;
				flags(to_integer(byte)) <= '1';
			end if;
		end if;
	end process REGISTER_32_LOGIC;

end architecture MyHDL;

```

Regards,  
Josy

---

<div class="post-metadata">

**Author:** ![kc64](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/kc64/32/83_2.png) [@kc64](https://discourse.myhdl.org/u/kc64)\
**Post date:** [March 22, 2018, 3:21pm UTC](https://discourse.myhdl.org/t/iterating-over-a-group-of-elements/258/3 "2018-03-22T15:21:48Z")

</div>

@josyb

Wow! Thank you for such an excellent reply–very thorough and more broadly useful than what I had hoped for.

I am not finding v0.10dev anywhere for download. I check pypi, github, and sourceforge. All seem to be offering the 0.9 version only.

Many thanks.

---

<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:** [March 22, 2018, 3:35pm UTC](https://discourse.myhdl.org/t/iterating-over-a-group-of-elements/258/4 "2018-03-22T15:35:54Z")

</div>

Using git or Tortoisegit you can _clone_ the 0.1 development repository from here: [https://github.com/myhdl/myhdl.git](https://github.com/myhdl/myhdl.git)
