idea icon Tip of the Month


We can update you automatically when our Tip of the Month changes.
To receive regular notification of updates to our Tip of the Month section, click here.


Unrolling Loops

Quite often, when you're debugging VHDL code, certain pieces of code just do not naturally give up the information you are looking for. This is particularly true of loop statements, whether they be for loops inside a process or generate statements using the for scheme in an architecture.

When generate statements need debugging, they tend to compile OK and then rather annoyingly, cause a FATAL at elaboration time. This is particularly galling, as you can't simulate (because of the FATAL) in order to debug the problem. All you usually get is a somewhat (un)helpful error message concerning port widths or such like. So a plea to compiler/simulator tool suppliers, some kind of elaboration-time debugger (please and thank you)! Until then, you have to manually unwrap the generate and write out the concurrent statements inside the generate wrapper explicitly in order to gain more insight into the problem. (In my experience, you only have to start writing out the first few statements and usually the penny drops).

But what about for loops in processes? Well, how about this...

One of the golden rules of writing synthesisable code to describe sequential logic runs somehing like this:

“If it is possible (no matter how convoluted) to read a variable before you write to it during the execution of a clocked process, you WILL get a register element”

For example:

AND_REG: process
  variable V: STD_LOGIC;
begin
  wait until Rising_edge(CLOCK);
  V := '1';
  for I in 0 to 7 loop
    V := V and INPUT(I);
  end loop;
  REG <= V;
end process;

How many register elements? Well, you might think by looking at the for loop,

  for I in 0 to 7 loop
    V := V and INPUT(I); -- V is read (and'ed with INPUT(I)) before being written (V := ...)
  end loop;

there would be a register element created from V. But how many? 1? (V is a std_logic) or is it 8? (number of times you read V before writing to it). Ok, lets unroll the loop...

  V := '1';              -- (1)
    -- loop unrolled
    V := V and INPUT(0); -- (2)
    V := V and INPUT(1); -- (3)
    V := V and INPUT(2);
    V := V and INPUT(3);
    V := V and INPUT(4);
    V := V and INPUT(5);
    V := V and INPUT(6);
    V := V and INPUT(7);
    -- to here

In line (1), V is written.

In line (2), we are reading the value of V (='1') which we have just written in line (1) and and'ing it with INPUT(0) to create a new value for V. So in line (1) we wrote to V before we read from it in line(2), whereupon we are writing to it a second time.

In line (3) we are reading this new (second) value of V that we wrote to in line (2) — again, write before read. Notice that V, in fact, is never read before it is written so there is no danger of creating a register element as the golden rule only applies to reading before writing.

So this months tip is “unroll loops for insight into your code”.

Bye for now...


Previous Tips of the Month can be downloaded from here...


wand iconComprehensive VHDL for FPGA / ASIC
chip iconAdvanced VHDL for Synthesis


river sceneDoulos Home Page

Copyright 1995-1999 Doulos
This page was last updated 12
th April 1999

mail iconWe welcome your e-mail comments. Please contact us at: webmaste@doulos.co.uk