Can a constant expression ever be valid in a VHDL case statement?

I remember that in Verilog it is possible to use a constant in a case statement, but is it also valid in VHDL?

// Verilog example
case(1'b1)                                
  A[2]:   Y<=2'b11;  
  A[1]:   Y<=2'b10;  
  A[0]:   Y<=2'b01;  
  default:Y<=2'b00;
endcase

      

+3


source to share


2 answers


No, you cannot express a case statement as a VHDL case statement

Contrary to Verilog, IEEE Std 1364-2005 9.5 Case example, clause 4:

The case expression and case element expression can be evaluated at run time; no expression should be a constant expression.

In IEEE Std 1076-1993 8.8 Statement of Case, paragraph 8 (also Representative -2008):

Simple expression and discrete ranges, specified as a choice in case statement must be locally static. A discrete range selection denotes all values ​​within the corresponding range. The other choice is allowed only the last alternative and as the only choice; This means all values ​​(perhaps not) not specified in the options of the previous alternatives. The simple name element (see 7.3.2) is not allowed as a case alternative choice.

From the glossary:

locally static expression : An expression that can be evaluated during the analysis of the design unit in which it appears.

parsing : parsing and semantic analysis of the source code in a VHDL design file and inserting intermediate representations of design units into the design library.

(A fancy way of telling us compile time, not development (linking and loading) VHDL definitions also cover interpreted implementation.)

Defining a locally static expression requires A to be declared as a constant, and in VHDL LRM -1993, the name or slice name is not locally static (see IEEE Std 1076-1993, 7.4.1 Locally Static Primaries Clause 1, 7.4.2 Globally static primaries, i.e. globally static tools during development). This is changed in IEEE Std 1076-2008 for static indexes or static indexes (see IEEE Std 1076-2008, 9.4.2, n. & O.). Synthetic instrument maker tools are probably lagging behind, even if you can imitate it, you probably cannot synthesize it today.

There is also a problem with multiple choices with the same value. See IEEE Std 1076-1993 8.8 Compliance Statement Clause 3 (also Representative -2008 for this issue):



The expression must be a discrete type or a one-dimensional array type whose element type is the character type. This type must be defined regardless of the context in which the expression occurs, but using the fact that the expression must be a discrete type or a one-dimensional character array. Each choice in a case statement must be of the same type as the expression; the list of options determines for which expression values ​​the alternative is selected.

If expressions std_logic '(' 1 ') or S are of base type std_ulogic. And this removes the selection that is not of the base std_logic type (std_ulogic - 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' See IEEE Std 1076-2008 16.7 Standard Multi-Shaft Logic Package and Appendix A footnote 15, which provides a source link for the std_logic_1164 package).

Note that fru1tbat showed options "0", "1" and others, evaluating expressions A (2), A (1) or (0) returns a subtype of std_ulogic and will give you multiple choices representing the same value ('1 '). See IEEE Std 1076-1993, 8.8, Clause 7:

For other forms of expression, each value of the (base) type expression must be represented once and only once in the selection set and no other value is allowed.

Thus, the case statement is not directly expressed in VHDL, we are only interested in cases where A (2), A (1) and A (0) are "1" and only one choice is allowed. Instead, we can use the conditional signal assignment operator:

library ieee;
use ieee.std_logic_1164.all;

entity constexp is
end entity;

architecture foo of constexp is
    signal A:   std_logic_vector (2 downto 0) := "001";
    signal Y:   std_logic_vector (1 downto 0);
begin

COND: -- Conditional Signal Assignment statement

    Y <= "11" when A(2) = '1' else
         "10" when A(1) = '1' else
         "01" when A(0) = '1' else
         "00";

end architecture;

      

(And this design specification analyzes, designs, and models.)

A conditional signal assignment is a parallel operator in the 1076-1993 standard (see 9.5.1 Signal conditional assignments), while a conditional signal assignment can be used as a sequential operator also in the 1076-2008 standard (see 11.6 Parallel Signal Assignment Statements and 10.5 .3 Conditional signal assignment). Today, most likely synthesis manufacturers will be compatible with -1993.

And by definition, any of the constructs here can be passed into if statements, which are sequential statements.

+2


source


The following code is not exactly parallel to your example, but you might find it helpful:

This compiles:

process
  constant S : std_logic := '1';
begin
  case S is
    when '0' =>
    when '1' =>
    when others =>
  end case;
end process;

      

This is how it does it:

process
begin
  case std_logic'('1') is
    when '0' =>
    when '1' =>
    when others =>
  end case;
end process;

      



It does not mean:

process
begin
  case '1' is
    when '0' =>
    when '1' =>
    when others =>
  end case;
end process;

      

'1'

is ambiguous ( std_logic

/ character

).

Now what you are actually doing is a little different and I'm not sure what your intentions are. You seem to want to determine the most significant bit that is set. In VHDL, your construct will only be valid syntactically if A

it is also a constant (case selection must be locally static), in which case there are much easier ways to do this (like a for loop). There's a mutual exclusion issue, though - in general, case selection inevitably overlaps, and I think it should be illegal (although ModelSim didn't complain when I tried it), synthesis tools might be a different story). I would say that this is definitely not a good idea.

+6


source







All Articles