Generate statement with varying signal width

M

Matt Longbrake

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?
 
Joined
Jan 29, 2009
Messages
152
Reaction score
0
You can do this using recursion -- an entity containing a 'smaller' component which is again the same entity;

That way, the signal would be a single vector, with the scope of the complete architecture body, not an array, of an indicated size (of a generic value)
 
A

Amal

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
 
T

Tricky

 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.  

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.
 
M

Matt Longbrake

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.
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.
 
J

Jonathan Bromley

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top