VHDL's Evil Obsession with Static Expressions

R

rickman

Guest
The following line of code where PhA, PhB, PhA_Old and PhB_Old are all
std_logic

CASE std_logic_vector'(PhA & PhB & PhA_Old & PhB_Old) IS

produces the following warning.

subtype of case expression is not locally static

I've played with this and keep getting an error of one type or another
so I consider a warning to at least be a partial victory. ;)

I am not getting what is wrong with this. The old "not locally static"
or "not globally static" expression thing seems to kick my butt a lot.

What do they mean "subtype"??? Is that because the vector is
constrained while the type SLV is unconstrained? Why is this not
locally static?

--

Rick C
 
rickman wrote:

The following line of code where PhA, PhB, PhA_Old and PhB_Old are all
std_logic

CASE std_logic_vector'(PhA & PhB & PhA_Old & PhB_Old) IS

produces the following warning.

subtype of case expression is not locally static

I've played with this and keep getting an error of one type or another
so I consider a warning to at least be a partial victory. ;)

I am not getting what is wrong with this. The old "not locally static"
or "not globally static" expression thing seems to kick my butt a lot.

What do they mean "subtype"??? Is that because the vector is
constrained while the type SLV is unconstrained? Why is this not
locally static?

Can't tell you why it's wrong, but I can probably tell you how to fix
it.

variable casethejoint : std_logic_vector(3 downto 0);

....

casethejoint := PhA & PhB & PhA_Old & PhB_Old;
case casethejoint is


--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
On 7/7/2016 4:32 PM, Rob Gaddi wrote:
rickman wrote:

The following line of code where PhA, PhB, PhA_Old and PhB_Old are all
std_logic

CASE std_logic_vector'(PhA & PhB & PhA_Old & PhB_Old) IS

produces the following warning.

subtype of case expression is not locally static

I've played with this and keep getting an error of one type or another
so I consider a warning to at least be a partial victory. ;)

I am not getting what is wrong with this. The old "not locally static"
or "not globally static" expression thing seems to kick my butt a lot.

What do they mean "subtype"??? Is that because the vector is
constrained while the type SLV is unconstrained? Why is this not
locally static?


Can't tell you why it's wrong, but I can probably tell you how to fix
it.

variable casethejoint : std_logic_vector(3 downto 0);

....

casethejoint := PhA & PhB & PhA_Old & PhB_Old;
case casethejoint is

Yes, I'm sure that will work, but I hate the verbosity, defining
temporary variables that make the code less readable rather than more
readable.

VHDL-2008 was a big step forward in reducing verbosity and making core
more readable. I'm still learning how to use it though. Sometimes I
wonder about VHDL and whether I should just bite the bullet and learn
Verilog.

--

Rick C
 
On Friday, July 8, 2016 at 8:39:19 AM UTC+12, rickman wrote:

VHDL-2008 was a big step forward in reducing verbosity and making core
more readable. I'm still learning how to use it though. Sometimes I
wonder about VHDL and whether I should just bite the bullet and learn
Verilog.

A subtype is a type and a constraint, in this case an index constraint.

There are no VHDL language defined warnings and the requirement is that a case
expression have a locally static subtype. In your original example
std_logic_vector is an unconstrained type (or subtype for -2008).

A different solution and an explanation might help to understand VHDL a bit
better.

This is also legal:

library ieee;
use ieee.std_logic_1164.all;

entity evil is
end entity;

architecture obsession of evil is
signal PhA, PhB, PhA_old, PhB_old: std_logic;
-- type necessary_evil is array (3 downto 0) of std_ulogic; -- also legal
subtype necessary_evil is std_logic_vector(3 downto 0);
begin
process (PhA, PhB, PhA_old, PhB_old)
begin
-- case std_logic_vector'(PhA & PhB & PhA_old & PhB_old) is
case necessary_evil'(PhA & PhB & PhA_old & PhB_old) is
when others =>
end case;
end process;
end architecture;

This solution provides a subtype constraint, as does Rob's example using a
variable, whose declaration provides a subtype indication (an index constraint).

So why is the requirement there (and what is the requirement)?

IEEE Std 1076-2008 10.9 Case statement

para 1:

A case statement selects for execution one of a number of alternative sequences
of statements; the chosen alternative is defined by the value of an expression.

para 4:

The expression shall be of a discrete type or of a one-dimensional array type
whose element base type is a character type. This type shall be determined by
applying the rules of 12.5 to the expression considered as a complete context,
using the rule that the expression shall be of a discrete type or a
one-dimensional character array type. (In particular, the type of the case
expression must be determinable independent of the type of the case statement
choices.) It is an error if the type of the expression in a matching case
statement is other than BIT, STD_ULOGIC, or a one-dimensional array type whose
element type is BIT or STD_ULOGIC. Each choice in a case statement alternative
shall be of the same type as the expression; the list of choices specifies for
which values of the expression the alternative is chosen.

para 5:

For an ordinary case statement, or for a matching case statement in which the
expression is of type BIT or an array type whose element type is BIT, if the
expression is the name of an object whose subtype is locally static, whether a
scalar type or an array type, then each value of the subtype shall be
represented once and only once in the set of choices of the case statement, and
no other value is allowed; this rule is likewise applied if the expression is a
qualified expression or type conversion whose type mark denotes a locally
static subtype, or if the expression is a call to a function whose return type
mark denotes a locally static subtype, or if the expression is an expression
described in this paragraph and enclosed in parentheses.

--

So the requirement is the subtype of the expression PhA & PhB & PhA_old &
PhB_old is locally static and determinable other than by choice context. This
is demonstrated in the legal solution above by having only one choice, others.
There is no context that can provide the subtype even should you subscribe to
the notion the case statement should be evaluated in multiple passes to
determine the subtype.

The idea here is that the legality of a choice can be determined at analysis
time.

In your original the error message we see is

ghdl -a necessary_evil.vhdl
necessary_evil.vhdl:14:14: type mark is not a locally static subtype
ghdl: compilation error

Where line 14:14 is your original case expression uncommented.

So why can't the subtype be taken from the case expression? The qualified
expression Rick C provided stating the type mark is std_logic_vector doesn't
provide a subtype constraint.

And about here we get the idea that evaluating thel legality of a choice is
accomplished by referencing the subtype constraint of the case expression (an
unnamed object). That subtype constraint isn't available with a qualified
expression using a type mark that is unconstrained.

An expression can be of arbitrary complexity and something like <a
href="http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/FunctionKnowsVectorSize">F
unction Knows Vector Size</a> is practically intractable.

A little investigation shows the subtype of a function return value is not
declared and all predefined operators ("&amp;") are implemented as pure functions.
 
On 7/8/2016 6:42 PM, diogratia@gmail.com wrote:
On Friday, July 8, 2016 at 8:39:19 AM UTC+12, rickman wrote:


VHDL-2008 was a big step forward in reducing verbosity and making core
more readable. I'm still learning how to use it though. Sometimes I
wonder about VHDL and whether I should just bite the bullet and learn
Verilog.

A subtype is a type and a constraint, in this case an index constraint.

There are no VHDL language defined warnings and the requirement is that a case
expression have a locally static subtype. In your original example
std_logic_vector is an unconstrained type (or subtype for -2008).

A different solution and an explanation might help to understand VHDL a bit
better.

This is also legal:

library ieee;
use ieee.std_logic_1164.all;

entity evil is
end entity;

architecture obsession of evil is
signal PhA, PhB, PhA_old, PhB_old: std_logic;
-- type necessary_evil is array (3 downto 0) of std_ulogic; -- also legal
subtype necessary_evil is std_logic_vector(3 downto 0);
begin
process (PhA, PhB, PhA_old, PhB_old)
begin
-- case std_logic_vector'(PhA &amp; PhB &amp; PhA_old &amp; PhB_old) is
case necessary_evil'(PhA &amp; PhB &amp; PhA_old &amp; PhB_old) is
when others =
end case;
end process;
end architecture;

This solution provides a subtype constraint, as does Rob's example using a
variable, whose declaration provides a subtype indication (an index constraint).

So why is the requirement there (and what is the requirement)?

IEEE Std 1076-2008 10.9 Case statement

para 1:

A case statement selects for execution one of a number of alternative sequences
of statements; the chosen alternative is defined by the value of an expression.

para 4:

The expression shall be of a discrete type or of a one-dimensional array type
whose element base type is a character type. This type shall be determined by
applying the rules of 12.5 to the expression considered as a complete context,
using the rule that the expression shall be of a discrete type or a
one-dimensional character array type. (In particular, the type of the case
expression must be determinable independent of the type of the case statement
choices.) It is an error if the type of the expression in a matching case
statement is other than BIT, STD_ULOGIC, or a one-dimensional array type whose
element type is BIT or STD_ULOGIC. Each choice in a case statement alternative
shall be of the same type as the expression; the list of choices specifies for
which values of the expression the alternative is chosen.

para 5:

For an ordinary case statement, or for a matching case statement in which the
expression is of type BIT or an array type whose element type is BIT, if the
expression is the name of an object whose subtype is locally static, whether a
scalar type or an array type, then each value of the subtype shall be
represented once and only once in the set of choices of the case statement, and
no other value is allowed; this rule is likewise applied if the expression is a
qualified expression or type conversion whose type mark denotes a locally
static subtype, or if the expression is a call to a function whose return type
mark denotes a locally static subtype, or if the expression is an expression
described in this paragraph and enclosed in parentheses.

--

So the requirement is the subtype of the expression PhA &amp; PhB &amp; PhA_old &amp;
PhB_old is locally static and determinable other than by choice context. This
is demonstrated in the legal solution above by having only one choice, others.
There is no context that can provide the subtype even should you subscribe to
the notion the case statement should be evaluated in multiple passes to
determine the subtype.

The idea here is that the legality of a choice can be determined at analysis
time.

In your original the error message we see is

ghdl -a necessary_evil.vhdl
necessary_evil.vhdl:14:14: type mark is not a locally static subtype
ghdl: compilation error

Where line 14:14 is your original case expression uncommented.

So why can't the subtype be taken from the case expression? The qualified
expression Rick C provided stating the type mark is std_logic_vector doesn't
provide a subtype constraint.

And about here we get the idea that evaluating thel legality of a choice is
accomplished by referencing the subtype constraint of the case expression (an
unnamed object). That subtype constraint isn't available with a qualified
expression using a type mark that is unconstrained.

An expression can be of arbitrary complexity and something like &lt;a
href="http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/FunctionKnowsVectorSize"&gt;F
unction Knows Vector Size</a> is practically intractable.

A little investigation shows the subtype of a function return value is not
declared and all predefined operators ("&amp;") are implemented as pure functions.

That was a lot to digest... but I believe the crux is that the range of
the SLV needs to be defined. Knowing it has four elements is not good
enough.

That brings me back to, "why"? VHDL seems to have a great many
restrictions that are of no purpose. The designers developed a
framework and designed a language within this framework which gave it a
variety of restrictions that are of little "real world" value.

I don't see the value in making VHDL as complex as it is. I have mostly
used VHDL trouble free by sticking with templates of work I have done
before. That is so constraining while VHDL should promote creativity.

--

Rick C
 
On Saturday, July 9, 2016 at 2:43:12 PM UTC+12, rickman wrote:

That was a lot to digest... but I believe the crux is that the range of
the SLV needs to be defined. Knowing it has four elements is not good
enough.

How does the analyzer know there are four elements? What it's got is an
expression in an abstract syntax tree with four objects and three operators.

There are two ways to tell it there are four elements. Assign the expression to
a declared object or use a qualified expression providing a subtype.

Context has a specific meaning in 10.9 paragraph 4 telling us how much work the
analyzer must do. It specifically excludes looking at case statement choices which is the only place a simple expression as a choice can express the subtype
(which means length here, an index constraint on the unnamed object that is the
value produce by evaluating the simple_expression).

That the number of elements doesn't match a choice could be discovered at
simulation time executing the case expression and evaluating the choice simple
expressions. It unfortunately also implies pushing the legality of choices to
being validated in simulation as well. With a locally static subtype that
doesn't have to occur avoiding simulation complexity and effort.

Also imagine how much harder a time you would have if you only got an error
message telling you your case statement was invalid but not what was wrong with
it or where to look if you couldn't distinguish unknowns about the case
expression and choice simple expression.

Simply put the analyzer doesn't have to (and can't) evaluate the case
expression. During analysis time signals hold no value they haven't been
elaborated. The idea behind having a separate syntax production for a case
expression would be to simplify it enough you could extract subtype. There is
no limit otherwise to the complexity of an expression.

That brings me back to, "why"? VHDL seems to have a great many
restrictions that are of no purpose. The designers developed a
framework and designed a language within this framework which gave it a
variety of restrictions that are of little "real world" value.

VHDL provides a formal notation for writing a formal specification for those
parts of a design specification describing hardware. That excludes impure
expressions or the use of non-portable constructs.

I don't see the value in making VHDL as complex as it is. I have mostly
used VHDL trouble free by sticking with templates of work I have done
before. That is so constraining while VHDL should promote creativity.

The words creative and creativity don't appear in the standard.

Creation does ('the action or process of bringing something into existence' as
opposed to 'a thing that has been made or invented, especially something
showing artistic talent'). Both definitions are embraced by copyright
eligibility.

Those requirements you find annoying are to create hardware descriptions that
are unambiguous, can be concise (not open to interpretation), portable and fit
to purpose.

Something that would translate a description in another language into VHDL
would do the same thing you do - use a subset of language (templates). Rob does
that by using an intermediary object, a different template than found in some
other (programming) language. The advantages can include making a named object
visible in a waveform dump display instead of manually (or mentally) evaluating
the case expression. And about here you might discern a distinction in what is
being expressed here and why.

Changes to the language have added complexity for purposes largely unrelated to
creative expression. A mixture of removing ambiguity, adding new features and
folding in other related standards.

The VHDL standard has gone from 218 pages in 1987 to 630 pages in 2008 while
the Verilog standard has gone from 653 pages in 1995 to SystemVerilog's 1315
pages in 2012 (superseding Verilog in 2009).

Complexity it seems is in the eye of the beholder. It seems more likely your
expectation of what VHDL should provide and the purposes for which it was
created are not congruent.
 
On 7/9/2016 6:57 PM, diogratia@gmail.com wrote:
On Saturday, July 9, 2016 at 2:43:12 PM UTC+12, rickman wrote:


That was a lot to digest... but I believe the crux is that the range of
the SLV needs to be defined. Knowing it has four elements is not good
enough.

How does the analyzer know there are four elements? What it's got is an
expression in an abstract syntax tree with four objects and three operators.

The operators are concatenation which create a 4 element vector, no?
Without a conversion operation I would think this vector would be an
SLV. It is obvious this is a four element vector, the only thing
missing is the range of the four elements. It could be 0 to 3, 4 downto
1 or anything else.


There are two ways to tell it there are four elements. Assign the expression to
a declared object or use a qualified expression providing a subtype.

Context has a specific meaning in 10.9 paragraph 4 telling us how much work the
analyzer must do. It specifically excludes looking at case statement choices which is the only place a simple expression as a choice can express the subtype
(which means length here, an index constraint on the unnamed object that is the
value produce by evaluating the simple_expression).

That the number of elements doesn't match a choice could be discovered at
simulation time executing the case expression and evaluating the choice simple
expressions. It unfortunately also implies pushing the legality of choices to
being validated in simulation as well. With a locally static subtype that
doesn't have to occur avoiding simulation complexity and effort.

But the number of elements is four. That part is clear to any observer.


Also imagine how much harder a time you would have if you only got an error
message telling you your case statement was invalid but not what was wrong with
it or where to look if you couldn't distinguish unknowns about the case
expression and choice simple expression.

Simply put the analyzer doesn't have to (and can't) evaluate the case
expression. During analysis time signals hold no value they haven't been
elaborated. The idea behind having a separate syntax production for a case
expression would be to simplify it enough you could extract subtype. There is
no limit otherwise to the complexity of an expression.

That brings me back to, "why"? VHDL seems to have a great many
restrictions that are of no purpose. The designers developed a
framework and designed a language within this framework which gave it a
variety of restrictions that are of little "real world" value.

VHDL provides a formal notation for writing a formal specification for those
parts of a design specification describing hardware. That excludes impure
expressions or the use of non-portable constructs.

I don't see the value in making VHDL as complex as it is. I have mostly
used VHDL trouble free by sticking with templates of work I have done
before. That is so constraining while VHDL should promote creativity.

The words creative and creativity don't appear in the standard.

That is my point. Why is VHDL the way it is? Why couldn't it be easier
to use?


Creation does ('the action or process of bringing something into existence' as
opposed to 'a thing that has been made or invented, especially something
showing artistic talent'). Both definitions are embraced by copyright
eligibility.

Mazel tov.


Those requirements you find annoying are to create hardware descriptions that
are unambiguous, can be concise (not open to interpretation), portable and fit
to purpose.

Concise? That is the issue at hand. It doesn't appear concise.


Something that would translate a description in another language into VHDL
would do the same thing you do - use a subset of language (templates). Rob does
that by using an intermediary object, a different template than found in some
other (programming) language. The advantages can include making a named object
visible in a waveform dump display instead of manually (or mentally) evaluating
the case expression. And about here you might discern a distinction in what is
being expressed here and why.

Changes to the language have added complexity for purposes largely unrelated to
creative expression. A mixture of removing ambiguity, adding new features and
folding in other related standards.

Recent changes have often improved "conciseness". A few more such
changes would be useful.


The VHDL standard has gone from 218 pages in 1987 to 630 pages in 2008 while
the Verilog standard has gone from 653 pages in 1995 to SystemVerilog's 1315
pages in 2012 (superseding Verilog in 2009).

Complexity it seems is in the eye of the beholder. It seems more likely your
expectation of what VHDL should provide and the purposes for which it was
created are not congruent.

Perhaps, very few things in life are congruent. I see opportunity for
VHDL to be more useful.

--

Rick C
 
Changes to the language have added complexity for purposes largely unrelated to
creative expression. A mixture of removing ambiguity, adding new features and
folding in other related standards.

The VHDL standard has gone from 218 pages in 1987 to 630 pages in 2008 while
the Verilog standard has gone from 653 pages in 1995 to SystemVerilog's 1315
pages in 2012 (superseding Verilog in 2009).

Since many years I work with FPGA but my first steps with "languages" was in Pascal with an old Apple-II to many years ago.

If someone follow the evolutions of Prof. Wirth languages' from Pascal to actual Oberon-07 lot of elegance and simplicity must be appreciated.
So, my question, since many years, why HDLs are going into the other sense ?

Could be as E.W.Dijkstra say "Simplicity is a great virtue but it requires hard work to achieve it and education to appreciate it. And to make matters worse: complexity sells better."

Walter
 

Welcome to EDABoard.com

Sponsor

Back
Top