Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why no generate else?

10,178 views
Skip to first unread message

Tom Loftus

unread,
Aug 7, 2001, 3:52:01 PM8/7/01
to
Am I missing something or is it really true that you can't
use an "else" in a generate if statement but have to do two
complementary if conditions?

Here's a simple example:

If I have a loop of 8 and for 4 of the values I want
one thing and for the other 4 I want something else,
do I really have to do it like this:

************************************************

g1: for index in 0 to 7 generate

g1a: if (index <= 3) generate

output(index) <= something(index)

end generate g1a;

g1b: if (index > 3) generate

output(index) <= something_else(index)

end generate g1b;

end generate g1;

************************************************

Obviously, I could also do two different for
loops for this simple case, but I'm surprised
I can't use an "else" to get the something_else case.

I'm curious why this would be.

Tom

Allan Herriman

unread,
Aug 7, 2001, 9:05:51 PM8/7/01
to
On Tue, 07 Aug 2001 15:52:01 -0400, Tom Loftus <tlo...@intrinsix.com>
wrote:

>Am I missing something or is it really true that you can't
>use an "else" in a generate if statement but have to do two
>complementary if conditions?

That's right. There's no else or elsif for an if generate.

There's a web page that allows you to make submissions to the body
that forms the new VHDL standards.

I submitted a request for an else ages ago, but it didn't make it into
the standard. Think about it, it would hurt more to change the
existing tools than we'd gain by having a language that made sense.

Allan.

Arnaud Dion

unread,
Aug 8, 2001, 3:07:31 AM8/8/01
to
Hi
You are mixing up "for...generate" and "if...then...else" statements.

Try this :


g1: for index in 0 to 7 generate

if (index <= 3) then
output(index) <= something(index)
else
output(index) <= something_else(index)
end if;
end generate;

Arnaud.

"Tom Loftus" <tlo...@intrinsix.com> a écrit dans le message news:
3B7046E1...@intrinsix.com...

Edwin Naroska

unread,
Aug 8, 2001, 9:32:25 AM8/8/01
to Tom Loftus
Hi,

Tom Loftus wrote:

I'm not sure whether this is the real reason, but how about
this:

As shown in the example there is a label associated with
the "generate-if" in order to uniquely name the objects
(components, processes, concurrent statements, ...) embedded
in the "then-clause". However, if an "else-clause" would have
been specified which label should be assigned to the embedded
objects? The same as for the "then-clause"? Then objects in the
"then-clause" would get the same label as objects emitted in the
"else-clause". This might produce problems during configuration
as you might run into a situation where you cannot distinguish
between a component instantiated in the "then-clause" and
a similar component instantiated within the "else" section:

g1a: if (index <= 3) generate

comp: test port map ( ... );
else
comp: test port map ( ... );
end generate g1a;

If you want to configure these instances differently your are out of
luck as both are labeled "...:g1a:comp".

To use another "if-generate" statement forces you to choose another
label for your "else" section.

Perhaps, this is the (or one) reason...

--
Edwin


Tom Loftus

unread,
Aug 8, 2001, 10:13:09 AM8/8/01
to
Arnaud Dion wrote:
>
> Hi
> You are mixing up "for...generate" and "if...then...else" statements.
>
> Try this :
> g1: for index in 0 to 7 generate
> if (index <= 3) then
> output(index) <= something(index)
> else
> output(index) <= something_else(index)
> end if;
> end generate;
>
> Arnaud.
>

Interesting...

This compiles but I am still skeptical that this is really
equivalent to the "if ... generate" in my original question.

My if...generate example clearly indicates that I
desire two independent circuits for index 0-3 and 4-7.

The above code looks more like a mux circuit based on index.
However, since index is known at compile time, maybe it ends
up being equivalent????

For an "if...then...else" statement with generate type
values, do synthesis tools ignore the if/else code which is
known to be false or do they blindly generate circuits and
then attempt to optimize the unused logic away?

Tom

Edwin Naroska

unread,
Aug 9, 2001, 6:49:12 AM8/9/01
to
Hi,

Arnaud Dion wrote:

> Hi
> You are mixing up "for...generate" and "if...then...else" statements.
>
> Try this :
> g1: for index in 0 to 7 generate
> if (index <= 3) then
> output(index) <= something(index)
> else
> output(index) <= something_else(index)
> end if;
> end generate;
>

IMHO, this code is illegal: the generate-for-statement is a concurrent
statement while the if-statement is a sequential statement
(note that if-statements and a generate-if-statements are different).
In order to make this work you need to embed it into a process:

g1: for index in 0 to 7 generate

process (...)
begin


if (index <= 3) then
output(index) <= something(index)
else
output(index) <= something_else(index)
end if;

end if;
end generate;

--
Edwin


Andy Rushton

unread,
Aug 9, 2001, 7:29:29 AM8/9/01
to
> You are mixing up "for...generate" and "if...then...else" statements.
>
> Try this :
> g1: for index in 0 to 7 generate
> if (index <= 3) then
> output(index) <= something(index)
> else
> output(index) <= something_else(index)
> end if;
> end generate;

Unfortunately this is not legal VHDL. You cannot have if statements in a
generate statement since it is a sequential statement and generate statements
can only contain concurrent statements.

The original poster is right - there is no way of doing an else-generate
except by having two complementary if-generate statements. This is clumsy, but
works.
--
Andy Rushton
LME Design Automation Limited, UK

Ray Andraka

unread,
Aug 9, 2001, 9:46:20 AM8/9/01
to
You can however make signal assignment conditional upon the index. For example:

G1: for idx in 0 to 7 generate
begin
output(idx)<= something when (idx<4)
else output(idx)<=something_else;
end generate G1;

This works nicely, for example if you have a structurally constructed delay queue
whose length is parameterized from 0 to N

Andy Rushton wrote:

--
-Ray Andraka, P.E.
President, the Andraka Consulting Group, Inc.
401/884-7930 Fax 401/884-7950
email r...@andraka.com
http://www.andraka.com


David G. Koontz

unread,
Aug 11, 2001, 1:51:09 PM8/11/01
to

Sure there is. A conncurrent signal assignment statement as a
conditional signal assignment with a conditional waveform, or a
conncurrent process statement.


attendez:

generate_statement ::=
generate_label :
generation_scheme generate
[ { block_declarative_item }
begin ]
{ concurrent_statement } *****
end generate [ generate_label ] ;

generation_scheme ::=
for generate_parameter_specification
| if condition

label ::= identifier

concurrent_statement
::=
block_statement
| process_statement ++++ an alternative
| concurrent_procedure_call_statement
| concurrent_assertion_statement
| concurrent_signal_assignment_statement *****
| component_instantiation_statement
| generate_statement

concurrent_signal_assignment_statement
::=
[ label : ] [ postponed ] conditional_signal_assignment *****
| [ label : ] [ postponed ] selected_signal_assignment


conditional_signal_assignment
::=
target <= options conditional_waveforms ; *****

conditional_waveforms
::=
{ waveform when condition else } *****
waveform [ when condition ]

waveform
::=
waveform_element { , waveform_element } *****
| unaffected

waveform_element
::=
value__expression [ after time_expression ] *****
| null [ after time_expression ]

expression
::=
relation { and relation } *****
| relation { or relation }
| relation { xor relation }
| relation [ nand relation ]
| relation [ nor relation ]
| relation { xnor relation }

relation
::=
shift_expression [ relational_operator shift_expression ] *****

shift_expression
::=
simple_expression [ shift_operator simple_expression ] *****

simple_expression
::=
[ sign ] term { adding_operator term } *****

term
::=
factor { multiplying_operator factor }

factor
::=
primary [ ** primary ] *****
| abs primary
| not primary

primary
::=
name *****
| literal
| aggregate
| function_call
| qualified_expression
| type_conversion
| allocator
| ( expression )

name
::=
simple_name
| operator_symbol
| selected_name
| indexed_name *****
| slice_name
| attribute_name

indexed_name ::= prefix ( expression { , expression }
)

(follow expression -> relation-> shift expression ->
simple expression -> term -> factor ->primary -> name)

(You never seen so many stack operations)

Section 9.5.1 of the LRM93 says this

and yields:

g1: for index in 0 to 7 generate

output(index) <= something(index) when (index <= 3)
else
something_else(index) ;
end generate;

Or use a process statement sensitive to index.

Section 9.5.1 of the LRM93 (elaboration of a generate statement) says this:
-
For a given conditional signal assignment, there is an equivalent process
statement corresponding to it as defined for any concurrent signal
assignment
statement. If the conditional signal assignment is of the form

target <= options waveform1 when condition1 else
waveform2 when condition2 else
·
·
·
waveformN-1 when conditionN-1 else
waveformN when conditionN;

then the signal transform in the corresponding process statement is of the
form

if condition1 then
wave_transform1
elsif condition2 then
wave_transform2
·
·
·
elsif conditionN-1 then
wave_transformN-1
elsif conditionN then
wave_transformN
end if ;
-
Elaboration is accomplished before simulation and requires cycle increment.
One wonders if there is a way to hang elaboration using wait or after. The
above implies that the process statement have an equivalent conditional
waveform.


process_statement ::=
[ process_label : ]
[ postponed ] process [ ( sensitivity_list ) ] [ is ]
process_declarative_part
begin
process_statement_part *****
end [ postponed ] process [ process_label ] ;

process_statement_part
::=
{ sequential_statement } *****

sequential_statement
::=
wait_statement
| assertion_statement
| report_statement
| signal_assignment_statement
| variable_assignment_statement
| procedure_call_statement
| if_statement *****
| case_statement
| loop_statement
| next_statement
| exit_statement
| return_statement
| null_statement
...
-


g1: for index in 0 to 7 generate

process (index)
begin


if (index <= 3) then
output(index) <= something(index) ;
else
output(index) <= something_else(index) ;
end if ;

end process;
end generate;


--
remove "no_spam_" from Reply-to address

David Koontz

unread,
Aug 11, 2001, 5:34:14 PM8/11/01
to
"David G. Koontz" <koo...@ariolimax.com> wrote in message news:<3B75708D...@ariolimax.com>...

> Andy Rushton wrote:
> >
>
> > > You are mixing up "for...generate" and "if...then...else" statements.
>
> > >
> > > Try this :
> > > g1: for index in 0 to 7 generate
> > > if (index <= 3) then
> > > output(index) <= something(index)
> > > else
> > > output(index) <= something else(index)

> > > end if;
> > > end generate;
> >
>
> > Unfortunately this is not legal VHDL. You cannot have if statements in
> a
> > generate statement since it is a sequential statement and generate stat
> ements
> > can only contain concurrent statements.
> >
>
> > The original poster is right - there is no way of doing an else-generat
> e
> > except by having two complementary if-generate statements. This is clum
> sy, but
> > works.
>
> Sure there is. A conncurrent signal assignment statement as a
>
> conditional signal assignment with a conditional waveform, or a
> conncurrent process statement.
>

> g1: for index in 0 to 7 generate


>
>
> output(index) <= something(index) when (index <= 3)
> else

> something else(index) ;


> end generate;
>
> Or use a process statement sensitive to index.
>

> g1: for index in 0 to 7 generate
> process (index)
> begin
> if (index <= 3) then
> output(index) <= something(index) ;
>
> else
> output(index) <= something_else(index) ;
> end if ;
> end process;
> end generate;

This should have something and something_else in the sensitivity list
instead of index.

In both forms you will elaborate 8 block statements that have a particular
index value passed as a constant. The block statements will otherwise
contain copies of the concurrent statements found in the generate statement.

0 new messages