'for' loops in VHDL

T

Thunder

Guest
How exactly is a 'for' loop in VHDL synthesised, as in what is the
hardware equivalent of a for loop?
 
On Wed, 27 Jun 2007 00:43:46 -0700,
Thunder <sounderrajan@gmail.com> wrote:

How exactly is a 'for' loop in VHDL synthesised, as in what is the
hardware equivalent of a for loop?
By "unrolling":

for i in 1 to 4 loop
a(i) <= b(5-i);
end loop;

is synthesised as four copies of the logic:

a(1) <= b(5-1);
a(2) <= b(5-2);
a(3) <= b(5-3);
a(4) <= b(5-4);

That's why synthesisable "for" loops generally need to
have constant bounds. Many tools permit "exit" inside
such loops; the following example:

for i in 1 to 4 loop
if b(i) = '0' then exit; end if;
a(i) <= b(5-i);
end loop;

would become four copies of the logic, with a ripple-OR chain
to control whether the later copies are enabled or not:

if b(1) /- '0' then
a(1) <= b(5-1);
if b(2) /= '0' then
a(2) <= b(5-2);
... and so on, ad nauseam
end if;
end if;

And a few tools permit the use of a wait-for-clock-edge
inside loops, in which case it's no longer necessary for
the loop to have constant bounds. Instead, the tool must
construct a state machine. That's known as "implicit
state machine" style:

while input_data /= "0000" loop
wait until rising_edge(clock);
output_port <= input_data;
end loop;

Clearly the synth tool must now invent a counter and some
control logic. Much trickier.

HTH
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Jun 27, 1:15 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Wed, 27 Jun 2007 00:43:46 -0700,

Thunder <sounderra...@gmail.com> wrote:
How exactly is a 'for' loop in VHDL synthesised, as in what is the
hardware equivalent of a for loop?

By "unrolling":

for i in 1 to 4 loop
a(i) <= b(5-i);
end loop;

is synthesised as four copies of the logic:

a(1) <= b(5-1);
a(2) <= b(5-2);
a(3) <= b(5-3);
a(4) <= b(5-4);

That's why synthesisable "for" loops generally need to
have constant bounds. Many tools permit "exit" inside
such loops; the following example:

for i in 1 to 4 loop
if b(i) = '0' then exit; end if;
a(i) <= b(5-i);
end loop;

would become four copies of the logic, with a ripple-OR chain
to control whether the later copies are enabled or not:

if b(1) /- '0' then
a(1) <= b(5-1);
if b(2) /= '0' then
a(2) <= b(5-2);
... and so on, ad nauseam
end if;
end if;

And a few tools permit the use of a wait-for-clock-edge
inside loops, in which case it's no longer necessary for
the loop to have constant bounds. Instead, the tool must
construct a state machine. That's known as "implicit
state machine" style:

while input_data /= "0000" loop
wait until rising_edge(clock);
output_port <= input_data;
end loop;

Clearly the synth tool must now invent a counter and some
control logic. Much trickier.

HTH
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
thanks a lot !!One more thing... When are multiplexers usually used
during synthesis? Are they used for implementing 'if' statements?
 
On Wed, 27 Jun 2007 02:37:46 -0700,
Thunder <sounderrajan@gmail.com> wrote:

One more thing... When are multiplexers usually used
during synthesis? Are they used for implementing 'if' statements?
Only if you read the textbooks :)

if select = '1' then
y <= a;
else
y <= b;
end if;

That, surely, is a multiplexer; although, of course,
in a typical FPGA it will become just another lookup table.
But what about this (in a clocked process, of course):

if select = '1' then
p <= a;
else
q <= a;
end if;

I see no multiplexer. I just see two registers, one
whose clock enable is "select" and another whose clock
enable is "not select".

Synthesis builds logic to implement the truth table that
it infers for the input of each register. Sometimes that
is best implemented using multiplexers, sometimes not.
If you're writing the answer to a homework assignment, then
you'll probably get at least a B grade for saying "if statements
in VHDL processes synthesise to multiplexers in hardware"; but,
like a lot of correct answers to homework assignments, that is
almost total garbage in the real world.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Jonathan Bromley wrote:
On Wed, 27 Jun 2007 00:43:46 -0700,
Thunder <sounderrajan@gmail.com> wrote:

How exactly is a 'for' loop in VHDL synthesised, as in what is the
hardware equivalent of a for loop?

By "unrolling":

for i in 1 to 4 loop
a(i) <= b(5-i);
end loop;

is synthesised as four copies of the logic:

a(1) <= b(5-1);
a(2) <= b(5-2);
a(3) <= b(5-3);
a(4) <= b(5-4);

That's why synthesisable "for" loops generally need to
have constant bounds. Many tools permit "exit" inside
such loops; the following example:

for i in 1 to 4 loop
if b(i) = '0' then exit; end if;
a(i) <= b(5-i);
end loop;

would become four copies of the logic, with a ripple-OR chain
to control whether the later copies are enabled or not:

if b(1) /- '0' then
a(1) <= b(5-1);
if b(2) /= '0' then
a(2) <= b(5-2);
... and so on, ad nauseam
end if;
end if;

And a few tools permit the use of a wait-for-clock-edge
inside loops, in which case it's no longer necessary for
the loop to have constant bounds. Instead, the tool must
construct a state machine. That's known as "implicit
state machine" style:

while input_data /= "0000" loop
wait until rising_edge(clock);
output_port <= input_data;
end loop;

Clearly the synth tool must now invent a counter and some
control logic. Much trickier.

HTH
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
A very good summary of what happens when synthesizing loops.

A couple more details...

In synthesis, since for loops are unrolled, the value of the index is
considered static, from a synthesis point of view, for each iteration.
Therefore, any otherwise static expressions are also considered
static, and do not consume hardware to compute (their value is
computed at synthesis time).

Therefore, perform any arithmetic possible on the index, not on
variables or signals. Thus, rather than comparing "addr + 1 = i", use
"addr = i - 1", etc.

Note also that non-synthesizable operations are just fine if their
arguments are considered static: "addr = i / 3" is just fine for a
loop index, constant, or generic "i".

Finally, when iterating on every element in a vector, get in the habit
of specifying the loop index range as vector'range (or
vector'reverse_range), rather than as a hard coded range. That not
only creates more flexible and maintainable code, it also communicates
to any human readers that your intent was to iterate on every element
of vector.

Andy
 
On Wed, 27 Jun 2007 06:04:47 -0700,
Andy <jonesandy@comcast.net> wrote:

A couple more details...

In synthesis, since for loops are unrolled, the value of the index is
considered static, from a synthesis point of view, for each iteration.
Therefore, any otherwise static expressions are also considered
static, and do not consume hardware to compute (their value is
computed at synthesis time).
Indeed - I should have said that explicitly.

Therefore, perform any arithmetic possible on the index, not on
variables or signals. Thus, rather than comparing "addr + 1 = i", use
"addr = i - 1", etc.

Note also that non-synthesizable operations are just fine if their
arguments are considered static: "addr = i / 3" is just fine for a
loop index, constant, or generic "i".
Nice insights, thanks. Is it the case that *all* synthesis tools
will support /, rem, mod, etc. in these situations?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Jun 27, 2:22 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Wed, 27 Jun 2007 06:04:47 -0700,

Andy <jonesa...@comcast.net> wrote:
A couple more details...

In synthesis, since for loops are unrolled, the value of the index is
considered static, from a synthesis point of view, for each iteration.
Therefore, any otherwise static expressions are also considered
static, and do not consume hardware to compute (their value is
computed at synthesis time).

Indeed - I should have said that explicitly.

Therefore, perform any arithmetic possible on the index, not on
variables or signals. Thus, rather than comparing "addr + 1 = i", use
"addr = i - 1", etc.

Note also that non-synthesizable operations are just fine if their
arguments are considered static: "addr = i / 3" is just fine for a
loop index, constant, or generic "i".

Nice insights, thanks. Is it the case that *all* synthesis tools
will support /, rem, mod, etc. in these situations?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
I've verified that synplify allows /, * and mod (haven't had occasion
to use rem) with arbitrary static arguments. From other tests, I'd be
very surprised if Quartus and Precision do not allow it, but I have
not explicitly tested it (I have run cases that I'm pretty sure had
stuff like that in them). Don't know about XST.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top