Matt Longbrake
Guest
Thu Nov 04, 2010 11:19 pm
Is there any way to use a signal from a previous generate loop
iteration in a later iteration? As an example, say you were building
a variable length adder chain. The output of each adder is one bit
wider than the previous adder. The inelegant solution would be to
create an array of std_logic_vector where the width of each vector is
as wide as the widest needed. These vectors are just selected based
on the loop index. The problem with this is that you get all kinds of
unused signal warnings when you synthesize.
As an alternative approach, you could use the declarative region of
the generate loop to create a signal of the appropriate width for the
current iteration. Then, if you could somehow access that signal from
the next iteration you could have variable width signals and avoid a
bunch of warnings. Is something like this possible?
Amal
Guest
Fri Nov 05, 2010 2:44 am
On Nov 4, 5:19 pm, Matt Longbrake <longb...@gmail.com> wrote:
Quote:
Is there any way to use a signal from a previous generate loop
iteration in a later iteration? As an example, say you were building
a variable length adder chain. The output of each adder is one bit
wider than the previous adder. The inelegant solution would be to
create an array of std_logic_vector where the width of each vector is
as wide as the widest needed. These vectors are just selected based
on the loop index. The problem with this is that you get all kinds of
unused signal warnings when you synthesize.
As an alternative approach, you could use the declarative region of
the generate loop to create a signal of the appropriate width for the
current iteration. Then, if you could somehow access that signal from
the next iteration you could have variable width signals and avoid a
bunch of warnings. Is something like this possible?
There are a number of things you can do. You can declare signals
outside the generate block and make an assignment based on generate
index:
signal a : std_logic_vector(7 downto 0);
signal b : std_logic;
g_test: for i in 0 to 7 generate
if ( i = 0 ) then
b <= a(i);
end if
end generate : g_test
The other option you are looking for is possible by declaring signals
within the generate for:
g_test: for i in 0 to 7 generate
signal x : std_logic_vector(i+2 downto 0);
x(i+2 downto 0) <= whatever;
end generate : g_test
In this case, you will have 8 x's defined as: x(2:0), x(3:0), ...
x(9:0). But only accessible within the generate block.
Cheers,
-- Amal
Brian Drummond
Guest
Fri Nov 05, 2010 10:11 am
On Thu, 4 Nov 2010 14:19:31 -0700 (PDT), Matt Longbrake <longbrmb_at_gmail.com>
wrote:
Quote:
Is there any way to use a signal from a previous generate loop
iteration in a later iteration? As an example, say you were building
a variable length adder chain. The output of each adder is one bit
wider than the previous adder.
You may be able to do this by nesting two generate statements, using the outer
one's loop variable as the inner one's control parameter.
I would be wary of encountering synthesis bugs, and check the results unusually
carefully.
Alternatively, realise that synthesis warnings are merely warnings, not errors,
and can safely be ignored if you understand and expect them. Synthesis tools
will do an excellent job of trimming fixed-width adders down to the size
required.
- Brian
Tricky
Guest
Fri Nov 05, 2010 10:30 am
The inelegant solution would be to
Quote:
create an array of std_logic_vector where the width of each vector is
as wide as the widest needed.
Very inelegent, because unsigned/signed types are what you should be
using if you're doing arithmatic, not std_logic_vector.
But otherwise, you cannot access signals out of scope (as you were
suggesting with the 2nd paragraph). Personally, Id probably just
convert them to integers and back to unsigned/signed at the end (if I
really need to - why not just keep it an integer?) and then let the
synthesiser chose the correct bit length.
Matt Longbrake
Guest
Fri Nov 05, 2010 8:11 pm
Quote:
There are a number of things you can do. You can declare signals
outside the generate block and make an assignment based on generate
index:
signal a : std_logic_vector(7 downto 0);
signal b : std_logic;
g_test: for i in 0 to 7 generate
if ( i = 0 ) then
b <= a(i);
end if
end generate : g_test
The other option you are looking for is possible by declaring signals
within the generate for:
g_test: for i in 0 to 7 generate
signal x : std_logic_vector(i+2 downto 0);
x(i+2 downto 0) <= whatever;
end generate : g_test
In this case, you will have 8 x's defined as: x(2:0), x(3:0), ...
x(9:0). But only accessible within the generate block.
Cheers,
-- Amal
Here's an example of what I meant with option 1 (probably not
syntactically correct):
type input_array is array(0 to 3) of signed(3 downto 0);
signal inputs : input_array;
type sum_array is array(0 to 4) of signed(7 downto 0);
signal sums : sum_array;
signal input : signed(3 downto 0);
signal output : signed(7 downto 0);
sums(0)(3 downto 0) <= inputs(0);
output <= sums(4);
abc: for i in 0 to 3 generate
adder: adder2
generic map( width => i+4)
port map( A => resize(inputs(i+1), i+4),
B => sums(i),
S => sums(i+1)(i+4 downto 0));
end generate;
I wrote that off the cuff, but the point is that the width of the
adder is easily adjusted by the generate statement, but I can't see
any way to adjust the size of the signals feeding them. The above
solution works, but you get unused signal warnings.
Quote:
Alternatively, realise that synthesis warnings are merely warnings, not errors,
and can safely be ignored if you understand and expect them. Synthesis tools
will do an excellent job of trimming fixed-width adders down to the size
required.
I try to reduce the warnings as much as possible so that they actually
have some meaning when they happen, maybe I'm being to optimistic. I
just know that if I see a list of 1000 warnings, most of which can be
ignored, it's hard to find the one that's actually something that
needs fixing.
Jonathan Bromley
Guest
Sat Nov 06, 2010 10:53 am
On Fri, 5 Nov 2010 11:11:51 -0700 (PDT), Matt Longbrake wrote:
Quote:
I try to reduce the warnings as much as possible so that they actually
have some meaning when they happen
Sounds good.
I am not sure whether you got a clear response about whether you can
reference one generate block's signals from within another; the answer
is "no" (except by using VHDL-2008 cross-scope references or whatever
they're called).
The pragmatic solution is definitely to use interconnect vectors of
sufficient width. To remove the warnings, consider driving unused
bits of those vectors with a common value that preserves the
arithmetic meaning (typically zero-pad or sign-extend the MSBs).
Synthesis will strip out the common or constant logic. You may
get some note-level messages about that too, but that happens all
the time and there's not a lot we can do about it.
--
Jonathan Bromley