Johannes Scherle
Johannes Scherle

Reputation: 11

VHDL: Using an unsigned Case selector

I want to use a STD_LOGIC_VECTOR Input which should be converted to an Unsigned as the selector in a Case statement, like this:

`  port ( clk_24 : in std_logic;
         frequency : in STD_LOGIC_VECTOR(2 downto 0);
         led : out std_logic);
case unsigned(frequency) is
  when to_unsigned(1, 3) => counterlimit <= to_unsigned(48000000, 32);
  when to_unsigned(2, 3) => counterlimit <= to_unsigned(24000000, 32);
  when to_unsigned(3, 3) => counterlimit <= to_unsigned(12000000, 32);
  when to_unsigned(4, 3) => counterlimit <= to_unsigned(6000000, 32);
  when to_unsigned(5, 3) => counterlimit <= to_unsigned(3000000, 32);
  when to_unsigned(6, 3) => counterlimit <= to_unsigned(1500000, 32);
  when to_unsigned(7, 3) => counterlimit <= to_unsigned(750000, 32);            
end case;

` But I get the error:

Line 48. Selector (type conversion of type UNSIGNED) is an unconstrained array.

Anybody got an idea, what the problem could be?

Upvotes: 1

Views: 5441

Answers (2)

user1155120
user1155120

Reputation:

In addition to fru1bat's suggestion you either need an others choice that covers both 0 and 8 to integer'MAX or an intermediary variable that covers choice 0 with a range constraint:

Others choice 0 to integer'MAX:

UNLABELED:
    process(frequency)
    begin
        case to_integer(unsigned(frequency)) is
            when 1 => counterlimit <= to_unsigned(48000000, 32);
            when 2 => counterlimit <= to_unsigned(24000000, 32);
            when 3 => counterlimit <= to_unsigned(12000000, 32);
            when 4 => counterlimit <= to_unsigned(6000000, 32);
            when 5 => counterlimit <= to_unsigned(3000000, 32);
            when 6 => counterlimit <= to_unsigned(1500000, 32);
            when 7 => counterlimit <= to_unsigned(750000, 32);
         -- when 0 to integer'MAX;
            when others => counterlimit <= to_unsigned(96000000, 32);
        end case;
    end process;

range constrained variable:

UNLABELED:
    process(frequency)
    variable freq:      integer range 0 to 7;
    begin
        freq := to_integer(unsigned(frequency));
        case freq is
            when 0 => counterlimit <= to_unsigned(96000000, 32);
            when 1 => counterlimit <= to_unsigned(48000000, 32);
            when 2 => counterlimit <= to_unsigned(24000000, 32);
            when 3 => counterlimit <= to_unsigned(12000000, 32);
            when 4 => counterlimit <= to_unsigned(6000000, 32);
            when 5 => counterlimit <= to_unsigned(3000000, 32);
            when 6 => counterlimit <= to_unsigned(1500000, 32);
            when 7 => counterlimit <= to_unsigned(750000, 32);
        end case;
    end process;

The reason for the 0 and 8 to integer'MAX case is that the anonymous natural being evaluated after the to_integer conversion inherits natural'range, while freq is constrained in it's declaration.

Upvotes: 4

fru1tbat
fru1tbat

Reputation: 1625

Not sure exactly why it thinks it's an unconstrained array, but you could (should?) do the following instead:

case to_integer(unsigned(frequency)) is
  when 1 =>
    ...

Easier to read, and should compile just fine.

Upvotes: 1

Related Questions