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.
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...
Comprehensive VHDL for FPGA / ASIC
Advanced VHDL for Synthesis
Copyright 1995-1999 Doulos
This page was last updated 12th April 1999
We welcome your e-mail comments. Please contact us at: webmaste@doulos.co.uk