Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   VHDL (http://www.velocityreviews.com/forums/f18-vhdl.html)
-   -   Discrete range in CASE (http://www.velocityreviews.com/forums/t710670-discrete-range-in-case.html)

 hssig 01-04-2010 11:03 AM

Discrete range in CASE

Hi,

I have the following VHDL case structure:

signal numa : unsigned(2 downto 0);

constant cA : unsigned(2 downto 0) := "000";
constant cB : unsigned(2 downto 0) := "001";
constant cC : unsigned(2 downto 0) := "100";

process(rstn, clk)
begin
if rstn='0' then
numa <= "000";

elsif rising_edge(clk) then
...

case to_integer(numa) is
when to_integer(cA) => ...
when to_integer(cB) to to_integer(cC) => ...
when others => ...
end case;

end if;

end process;

When trying to insert a (Lattice) Reveal core I get the following
error message:

"ERROR: case choice must be a locally static expression (VHDL-1438)"

How can I make use of the discrete range choice without violating the
static expression rule ?

Cheers,
hssig

 Jonathan Bromley 01-04-2010 11:15 AM

Re: Discrete range in CASE

On Mon, 4 Jan 2010 03:03:25 -0800 (PST), hssig wrote:

>signal numa : unsigned(2 downto 0);
>
>constant cA : unsigned(2 downto 0) := "000";
>constant cB : unsigned(2 downto 0) := "001";
>constant cC : unsigned(2 downto 0) := "100";
>
>process(rstn, clk)
>begin
> if rstn='0' then
> numa <= "000";
>
> elsif rising_edge(clk) then
> ...
>
> case to_integer(numa) is
> when to_integer(cA) => ...
> when to_integer(cB) to to_integer(cC) => ...
> when others => ...
> end case;
>
> end if;
>
>end process;

>"ERROR: case choice must be a locally static expression (VHDL-1438)"
>
>How can I make use of the discrete range choice without violating the
>static expression rule ?

"Locally static" in VHDL is a very aggressive restriction and
there's not much you can do about it. Function call in the
case choice is a no-no, sorry.

I suggest you re-cast your code so that the original constants
are integers:

--- Useful bits and pieces
subtype u3 is unsigned(2 downto 0);
subtype i3 is integer range 0 to (2**u3'length - 1);
function to_u3(n: i3) return u3 is begin
end;

--- Your constants as proper integers
constant nA : i3 := 0;
constant nB : i3 := 1;
constant nC : i3 := 4;

--- Your unsigned signals and constants,
--- derived from the original integers
signal numa: u3;
constant cA: u3 := to_u3(nA);
constant cB: u3 := to_u3(nB);
constant cC: u3 := to_u3(nC);

--- Now the case statement should be OK,
--- as well as being easier to read:
case to_integer(numa) is
when nA => ...
when nB to nC => ...
when others => ...
end case;

Hope this helps
--
Jonathan Bromley

 Andy 01-04-2010 03:20 PM

Re: Discrete range in CASE

On Jan 4, 6:43*am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
> On Mon, 4 Jan 2010 03:03:25 -0800 (PST), hssig <hs...@gmx.net> wrote:
> >Hi,

>
> >I have the following VHDL case structure:

>
> >signal numa : unsigned(2 downto 0);
> >constant cA : unsigned(2 downto 0) := "000";
> >constant cB : unsigned(2 downto 0) := "001";
> >constant cC : unsigned(2 downto 0) := "100";

>
> ...
>
> > * * * * case to_integer(numa) is
> > * * * * * *when to_integer(cA) => ...
> > * * * * * *when to_integer(cB) to to_integer(cC) => ...
> > * * * * * *when others => *...
> > * * * * end case;
> >"ERROR: case choice must be a locally static expression (VHDL-1438)"

>
> >How can I make use of the discrete range choice without violating the
> >static expression rule ?

>
> The number of type conversions here suggest you are fighting the type system
> instead of using it... that's often a hint that the design can be improved.
>
> Assuming you need to write the constant values in binary for clarity, one way is
> to keep them in integer form, and write
>
> subtype numaRange is
> constant cA : natural range 0 to 7 := 2#000#;
> subtype BtoC is natural range 2#
> and
> * * * * *case to_integer(numa) is
> * * * * * * * * when cA => ...
> * * * * * * * * when BtoC => ...
>
> Much less clutter. And it avoids functions in the case arm branches, which is
> the likely cause of the error...
>
> The meaning of "to_integer" is not locally defined; since it is a function
> declared somewhere else, it may not even have been written yet!
>
> Thinking hardware, a case statement typically generates a multiplexer.
>
> So while a function call in the case variable is allowed (you can select a
> different multiplexer input depending on external conditions), a function call
> in a case arm would change the shape of the hardware implementation if the
> function evaluated differently ... it's not surprising that isn't allowed..
>
> The fact that it is a standard function from a standard library is known to you,
> but not to me, or the compiler. *From the code you posted (no use clauses) I
> can't tell if you are using the "real" unsigned, (from numeric_std), or an
> impostor (from the Synopsis libraries) or even your own implementation.
>
> VHDL doesn't cheat and impose special case meanings on your code - even at the
> level of assuming '1' = true and '0' = false. That decision is (IMO, correctly)
> kept outside the language, in the libraries. So you could implement negative
> logic systems simply by replacing std_logic_1164 and numeric_std with their
> negative logit equivalents. (If ECL ever comes back into fashion, this could be
> a big win for VHDL over that other language, but I'm not holding my breath!)
>
> You do have to be explicit about what you mean - in your case, simply using
> integer ranges will do. IMO the result is cleaner - and easier for the next guy
>
> - Brian

IINM, the reason for the locally static restriction on choice
expressions is because the case statement choices must be evaluated at
analysis time (before elaboration) to determine that they are complete
and mutually exclusive. Non-locally static function calls cannot be
evaluated at analysis time, and therefore the set of choices cannot be
evaluated for completeness and mutual exclusivity.

Andy

 hssig 01-04-2010 03:58 PM

Re: Discrete range in CASE

Hi,

@Brian:
I use "std_logic_arith" and "numeric_std".

The constant definition "constant cA : natural range 0 to 7 :=
2#000#;"
is clear to me. But how do you use the proposed subtypes

subtype numaRange is
subtype BtoC is natural range 2#

? What is their purpose ?

Cheers,
hssig

 hssig 01-04-2010 03:59 PM

Re: Discrete range in CASE

Sorry, I mean:
"std_logic_1164" and "numeric_std"

Cheers,
hssig

 Mike Treseler 01-05-2010 03:46 AM

Re: Discrete range in CASE

hssig wrote:

> How can I make use of the discrete range choice without violating the
> static expression rule ?

I like to use cases of enumerated types, but ...

If I couldn't change your declarations, I would use
if, elsif, elsif, ..., else
You will get no such errors,
the conditions can be whatever you like,
and it won't cost any gates unless you really need them.

-- Mike Treseler

 Jonathan Bromley 01-05-2010 09:12 AM

Re: Discrete range in CASE

On Tue, 05 Jan 2010 00:18:34 +0000, Brian Drummond wrote:

>And when you extend the design, hopefully you only need to change the subtype
>and maybe constant declarations:
> subtype u3 is unsigned(4 downto 0);
> -- oops! hence in my opinion: name it after its purpose, not its size!
> subtype numaRange is unsigned(4 downto 0);

unless, as occasionally happens, the size is an essential
part of the nature of the thing. Apologies for the
illiterate programming.[*]
[*] If Brian can use Knuth as a stick to beat me with,
there's no reason why I shouldn't do so myself :-)
--
Jonathan Bromley

 hssig 01-06-2010 02:19 PM

Re: Discrete range in CASE

Thank you.

Cheers,
hssig

 JimLewis 01-07-2010 01:14 AM

Re: Discrete range in CASE

Hssig,
In VHDL-2008, array types and functions in std_logic_1164 and
numeric_std became locally static.

Does lattice have a language switch for VHDL-2008? If not submit the
issue as a bug since it is supported in the current revision of the
language - approved by IEEE in September 2008 and approved by
Accellera as a trial standard in July 2006, so vendors really don't
have an excuse for not having implemented it at this point.

Best,
Jim
SynthWorks

 HT-Lab 01-08-2010 09:58 AM

Re: Discrete range in CASE

"JimLewis" <Jim@SynthWorks.com> wrote in message
> Hssig,
> In VHDL-2008, array types and functions in std_logic_1164 and
> numeric_std became locally static.
>
> Does lattice have a language switch for VHDL-2008? If not submit the
> issue as a bug since it is supported in the current revision of the
> language - approved by IEEE in September 2008 and approved by
> Accellera as a trial standard in July 2006, so vendors really don't
> have an excuse for not having implemented it at this point.

Unfortunately the excuse they gave me is that not many users are asking for it!
I find this very frustrating since there are some very basic language
enhancements which can make your code a lot cleaner, examples are:

2) Case statement with don't care support
3) Expressions in port maps
4) Process(all)
5) Generic on packages

So have a look at the new language features and then send an email to your
vendor, it shouldn't take long!

Hans
www.ht-lab.com

>
> Best,
> Jim
> SynthWorks

All times are GMT. The time now is 01:11 AM.