How to implement different encodings for subsets some enumeration in VHDL?
You can't overload a or b, so the signal names were changed to aa and bb.

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

entity somethings is
end entity;

architecture foo of somethings is
    TYPE things IS (A, B, C, D, E, F, G, H); -- requires 3 bit
    SIGNAL encoded : std_ulogic_vector(2 downto 0) := "100";
    SIGNAL decoded : things;

    -- This is how encoding would work:
    --encoded &lt;= std_ulogic_vector(to_unsigned(decoded'POS(decoded)));

    SUBTYPE subthings IS things RANGE A TO D;                   -- works
    --TYPE subthings2 IS things RANGE A TO B + RANGE E TO F; -- would be cool
    TYPE some_things is (A, B, E, F);                        -- not a subtype

    SIGNAL aa : things;
    SIGNAL bb : some_things;
    SIGNAL some_things_encoded : std_ulogic_vector(1 downto 0);


begin
    decoded &lt;= things'VAL(to_integer(unsigned(encoded))); -- results in "E"
    bb &lt;= some_things'VAL(to_integer(unsigned(some_things_encoded)));
    -- a &lt;= b;  -- Doesn't work although the literals are a subset.

-- This converts between somethings expression bb for assignment to aa 
-- whose type is things:

    aa &lt;= things'VALUE(some_things'IMAGE(bb));

-- Demonstrate the value of aa:

TEST:
    process
    begin
        wait for 1 ns;
        report "aa = " &amp; things'IMAGE(aa);
        wait;
    end process;

end architecture;


This analyzes, elaborates and simulates (while not actually doing anything interesting by itself).