Search code examples
vhdl

Type to integer


I have the following (does not synthesize):

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

library work;
use work.bus_pkg;

entity gpio_controller is
    generic (
        gpio_count : natural range 1 to natural'high
    );
    port (
        clk : in std_logic;
        gpio : inout std_logic_vector(gpio_count - 1 downto 0)
    );
end entity;

architecture behavioral of gpio_controller is
    type inout_type is (
        DISABLED,
        OUTPUT,
        WEAK_PULLUP,
        WEAK_PULLDOWN);
    constant inout_type_bitlength : natural := integer(ceil(log2(real(inout_type'high))));
begin
    gpio <= (others => 'Z');
end architecture;

What I want is to determine inout_type_bitlength, the minimum amount of bits required to enumerate inout_type, which should be 2 in my case (since 2 bits are required to enumerate 4 states).

Now the approach I chose does not work, but is there a way to make this work?

Bonus question, can I somehow create something that will automatically map the integers 0 to n to a state, no matter how many states there are?


Solution

  • You can use the POS attribute to convert type values to int. Therefore, we get:

    inout_type'pos(inout_type'high)
    

    To get the integer value of the highest element in the type. Putting it together:

    constant inout_type_bitlength : natural := integer(ceil(log2(real(inout_type'pos(inout_type'high)))));
    

    For the bonus question: once again, it is the pos attribute:

    inout_type'pos(WEAK_PULLUP)
    

    Gives 2 in this instance.