vhdl "for loop" with step size not equal to 1

12.4k Views Asked by At

I have a simple question . Is it possible to write a VHDL for loop with step size not equal to 1 e.g 16

The loop should go like

0--> 16 --> 32--> 48.... to some value

any immediate help is appreciated

5

There are 5 best solutions below

7
On BEST ANSWER

A possible solution is to use a range that is 1/16th of the desired range and unroll the loop inside it to generate the desired range:

for i in 0 to 3 -- Actually 0 to 48
loop
    x(16*i) <= ...
    x((16*i)+1) <= ...
    (...)
    x((16*i)+15) <= ...
end loop;

Another solution would be to use a while instead. Assuming your count variable is an integer:

while (i < 48)
loop
   --Do something
   i := count + 16;
end loop;

Edit: I haven't tested the code above, you might be unable to change the variable count inside the loop, I'm not sure. Maybe the first solution is the best one.

It is not possible to have a for loop with a step different then 1. You are not even allowed to change it inside the for, like this:

--THIS WILL NOT WORK
for i in 0 to 48 loop
    --Do Something
    i := i + 15; -- This will NOT increment the loop index by 16
end loop; 

And finally, for steps of 2 or 3 you might use nested for's.

But anyway, What are you trying to accomplish? VHDL is a low-level hardware description language, you should be able to achieve whatever you are trying to without fancy for loops.

1
On

My research says no, but you can declare a second variable that acts as a multiple of your variable inside of your loop.

0
On

VHDL has no step parameter in for loop, so the step is always 1 for to range direction and -1 for downto range direction.

So if you need loop with start and step value, you can do:

...
constant FOR_START : natural := 1;
constant FOR_STEP  : natural := 2;
variable idx_v     : natural;       -- Support index variable
...
for idx_pre in 0 to 3 loop
  idx_v := FOR_START + FOR_STEP * idx_pre;
  z_o(idx_v) <= a_i(idx_v);
end loop;

A while loop can also be used as alternative:

constant FOR_START : natural := 1;
constant FOR_STEP  : natural := 2;
constant FOR_MAX   : natural := 7;
variable idx_v     : natural;
...
idx_v := FOR_START;
while idx_v <= FOR_MAX loop
  z_o(idx_v) <= a_i(idx_v);
  idx_v := idx_v + FOR_STEP;
end loop;
0
On

How about looping over the entire range, but then using an 'if' statement to only act on every 16th value?

for i in start_thing to end_thing loop
  if i mod 16 = 0 then
    do things(i)
  end if;
end loop; -- i

Or alternately use Next:

for i in start_thing to end_thing loop
  next when i mod 16 /= 0 ;
  do_things(i)
end loop; -- i
0
On

Yes, it is possible to "for loop" with a step size not equal to 1.

for i in range 1 downto 0 loop
    foo(i) <= bar(1-i);
end
loop;