courses:system_design:vhdl_language_and_syntax:sequential_statements:for_loops

FOR Loops

entity FOR_LOOP is
  port(A : in integer range 0 to 3;
       Z : out bit_vector (3 downto 0));
end FOR_LOOP;
architecture EXAMPLE of FOR_LOOP is
begin
 
  process (A)
  begin
    Z <= "0000";
    for i in 0 to 3 loop
      if (A = i) then
        Z(i) <=1;
       end if;
    end loop;
  end process;
 
end EXAMPLE;
  • Loop parameter is implicitly declared
    • Can not be declared externally
    • Read only access
  • The loop parameter adopts all values from the range definition
    • Integer ranges
    • Enumerated types

Notes

Loops operate in the usual way, i.e. they are used to execute the same VHDL code a couple of times.

The loop variable is the only object in VHDL which is implicitly defined.

The loop variable can not be declared externally and is only visible within the loop.

Its value is read only, i.e. the number of cycles is fixed when the execution of the for loop begins.

[LOOP_LABEL :]
for IDENTIFIER in DISCRETE_RANGE
loop
   -- sequential statements
end loop [LOOP_LABEL];
 
[LOOP_LABEL :]
while CONDITION loop
   -- sequential statements
end loop [LOOP_LABEL];
  • Optional label
  • FOR loop identifier
    • Not declared
    • Read only
    • Not visible outside the loop
  • Range attributes
    • ‘low
    • ‘high
    • ‘range
Synthesis requirements:
  • Loops must have a fixed range
  • ‘while’ constructs usually cannot be synthesized

Notes

Loop labels may be used to enhance readability, especially when loops are nested or the code block executed within the loop is rather long.

If a for loop is to be synthesized, the range of the loop variable must not depend on signal or variable values (i.e., it has to be locally static). By means of the range assignment, both the direction and the range of the loop variable is determined.

If a variable number of cycles is needed, the while statement will have to be used. While loops are executed as long as condition evaluates to a ’true’ value. Therefore this construct is usually not synthesizable.

entity CONV_INT is
   port(DIN    : in bit_vector(7 downto 0);
        RESULT : out integer);
end CONV_INT;
-- EXAMPLE 1
...
process(DIN)
 variable TMP: integer;
 
begin
 TMP := 0;
 
 for I in 0 to 7 loop
  if (DIN(I)=1) then
    TMP := TMP + 2**I;
  end if;
 end loop;
 
 RESULT <= TMP;
end process;
...
-- EXAMPLE 2
...
process(DIN)
 variable TMP: integer;
 
begin
 TMP := 0;
 
 for I in DIN’range loop
  if (DIN(I)=1) then
    TMP := TMP + 2**I;
  end if;
 end loop;
 
 RESULT <= TMP;
end process;
...
-- EXAMPLE 3
...
process(DIN)
 variable TMP : integer;
 variable I   : integer;
begin
 TMP := 0;
 I := DIN’high
 while (I >= DIN’low) loop
  if (DIN(I)=1) then
    TMP := TMP + 2**I;
  end if;
  I := I - 1;
 end loop;
 RESULT <= TMP;
end process;
...

Notes

The three loop example architectures are functionally equivalent. The difference lies in the specification of the loop range. ➔ on process entry, all variables (may) have the last assigned value (of the last process execution)!

Examples 1 and 2 use the for statement. Instead of a hard coded range specification, signal attributes that are dependent on the signal type and are therefore fixed during runtime in example 2.

Example 3 shows an equivalent implementation using a while construct. Please note, that an additional loop variable I has to be declared in this case. ➔ while loops are not synthesizable (only for some synthesis tools, if funktional equivalent to a for loop, i.e. range is fixed during compile time)

Range attributes are used to make the same VHDL code applicable to a number of signals, independent of their width. They are especially useful when dealing with integer or array types. The following lines represent equal functionality, provided that Z’s range is from 0 to 3.

for I in 0 to 3 loop;
for I in Z’low to Z’high loop;
for I in Z’range loop;

Chapters of System Design > VHDL Language and Syntax > Sequential Statements