Discrete range in CASE

Discussion in 'VHDL' started by hssig, Jan 4, 2010.

  1. hssig

    hssig Guest

    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 ?
    Thank you for your opinion.


    Cheers,
    hssig
    hssig, Jan 4, 2010
    #1
    1. Advertising

  2. 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
    return to_unsigned(n, u3'length);
    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
    Jonathan Bromley, Jan 4, 2010
    #2
    1. Advertising

  3. hssig

    Andy Guest

    On Jan 4, 6:43 am, Brian Drummond <>
    wrote:
    > On Mon, 4 Jan 2010 03:03:25 -0800 (PST), hssig <> 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
    > to read and understand..
    >
    > - 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
    Andy, Jan 4, 2010
    #3
  4. hssig

    hssig Guest

    Hi,

    thank you for your answers.

    @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, Jan 4, 2010
    #4
  5. hssig

    hssig Guest

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

    Cheers,
    hssig
    hssig, Jan 4, 2010
    #5
  6. 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
    Mike Treseler, Jan 5, 2010
    #6
  7. 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);


    Yes, of course Brian is completely right about this -
    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
    Jonathan Bromley, Jan 5, 2010
    #7
  8. hssig

    hssig Guest

    Thank you.

    Cheers,
    hssig
    hssig, Jan 6, 2010
    #8
  9. hssig

    JimLewis Guest

    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
    JimLewis, Jan 7, 2010
    #9
  10. hssig

    HT-Lab Guest

    "JimLewis" <> wrote in message
    news:...
    > 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:

    1) Reading output ports
    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
    HT-Lab, Jan 8, 2010
    #10
  11. hssig

    hssig Guest

    Hi Jim,

    when compiling such case description including the "to_integer"
    function in the when-tree(s)
    "when to_integer(cA) => ..."

    Modelsim PE 6.5d (Compile Options 2008) also shows the warning: "Case
    choice must be a locally static expression."

    So if Mentor did implement the VHDL-2008 feature correctly there would
    be no warning ?

    Cheers,
    hssig
    hssig, Jan 16, 2010
    #11
  12. hssig wrote:

    > So if Mentor did implement the VHDL-2008 feature correctly there would
    > be no warning ?


    I don't know, and it doesn't really matter in this moment.
    If we put the function in the case clause, like this:

    case to_integer(unsigned(in_vec)) is

    everything just works.

    -- Mike

    ____________________________________________________
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity case_of_function is
    port (
    in_vec : in std_logic_vector(7 downto 0) := x"06");
    end case_of_function;

    architecture sim of case_of_function is
    begin
    case_test : process is
    constant vec_len_c : natural := in_vec'length;
    begin
    case to_integer(unsigned(in_vec)) is
    when 5|6 => report "it's a 5 or 6";
    when 7 => report "it's a 7";
    when others => report "it's not 5-7";
    end case;
    wait;
    end process case_test;
    end sim;
    -- _______________________________
    -- Sample run:
    -- vsim -c case_of_function

    -- VSIM 1> run
    -- ** Note: it's a 5 or 6
    -- Time: 0 ns Iteration: 0 Instance: /case_of_function
    Mike Treseler, Jan 16, 2010
    #12
  13. hssig

    hssig Guest

    >I don't know, and it doesn't really matter in this moment.

    Yes, it does matter because I am trying to find out whether it is
    allowed to put the function "to_integer"
    in the when trees of a case statement.


    Cheers,
    hssig
    hssig, Jan 17, 2010
    #13
  14. hssig wrote:

    > Yes, it does matter because I am trying to find out whether it is
    > allowed to put the function "to_integer"
    > in the when trees of a case statement.


    All I can tell you is that both Modelsim and Quartus disapprove.
    This makes the reason irrelevant to me.
    Besides, cases of integers or enums are easier for me to read.

    So reread this thread.
    Others have spent time given you rational reasons for the restriction.
    Good luck.

    -- Mike Treseler
    Mike Treseler, Jan 17, 2010
    #14
  15. hssig

    jr Guest

    hssig a écrit :

    >> I don't know, and it doesn't really matter in this moment.

    >
    > Yes, it does matter because I am trying to find out whether it is
    > allowed to put the function "to_integer"
    > in the when trees of a case statement.


    Nope. You can't have a non static computed value in a choice. The
    compiler would have no means to determine if the case statement covers
    each choice once and only once (think that the body of the function
    might be not compiled yet).

    You can use if/elsif instead.

    --
    jr
    Particulier non cumulable
    jr, Jan 17, 2010
    #15
  16. hssig

    hssig Guest

    >Others have spent time given you rational reasons for the restriction.

    Yes, I agree. But at this point we are trying to find out if these
    restrictions are still applicable for VHDL-2008 and whether M, X, A, L
    or whatever vendors are implementing functions in case statements
    the way the new standard is telling them.

    >All I can tell you is that both Modelsim and Quartus disapprove.
    >This makes the reason irrelevant to me.


    But that does not prove that they are implementing it correctly (or at
    all), doesn't it ?

    Cheers,
    hssig
    hssig, Jan 18, 2010
    #16
  17. hssig

    HT-Lab Guest

    "hssig" <> wrote in message
    news:...
    > Hi Jim,
    >
    > when compiling such case description including the "to_integer"
    > function in the when-tree(s)
    > "when to_integer(cA) => ..."
    >
    > Modelsim PE 6.5d (Compile Options 2008) also shows the warning: "Case
    > choice must be a locally static expression."
    >
    > So if Mentor did implement the VHDL-2008 feature correctly there would
    > be no warning ?


    Modelsim's VHDL2008 support is very limited, just look under
    help->technotes->vhdl2008 to see what is currently supported (in 6.6),

    Hans
    www.ht-lab.com

    >
    > Cheers,
    > hssig
    >
    HT-Lab, Jan 18, 2010
    #17
  18. hssig

    hssig Guest

    Hi Jim,
    to get to the point: Before asking Lattice and Mentor I want to be
    sure whether the following code should be warning-free or not
    when compiling with VHDL-2008 option:


    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;


    entity function_in_case is
    port( Clk : in std_logic;
    Ad : in std_logic_vector(7 downto 0);
    Sig : out std_logic_vector(1 downto 0)
    );
    end function_in_case;

    architecture beh of function_in_case is

    constant A : unsigned(7 downto 0) := x"00";
    constant B : unsigned(7 downto 0) := x"01";
    constant C : unsigned(7 downto 0) := x"EE";

    signal addr : unsigned(7 downto 0);

    begin

    addr <= unsigned(Ad);

    process(Clk)
    begin
    if rising_edge(Clk) then
    case to_integer(addr) is
    when to_integer(A) =>
    Sig <= "00";
    when to_integer(B) to to_integer(C) =>
    Sig <= "01";
    when others =>
    Sig <= "11";

    end case;
    end if;
    end process;
    end beh;

    Cheers,
    hssig
    hssig, Jan 18, 2010
    #18
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Manfred Balik
    Replies:
    3
    Views:
    4,240
    Brian Drummond
    Apr 30, 2005
  2. Sim Nanda
    Replies:
    3
    Views:
    390
  3. Saikrishna
    Replies:
    0
    Views:
    625
    Saikrishna
    Apr 12, 2004
  4. omara007
    Replies:
    0
    Views:
    652
    omara007
    May 6, 2009
  5. SameerDS
    Replies:
    4
    Views:
    1,186
    joris
    Mar 24, 2010
Loading...

Share This Page