0
\$\begingroup\$

When trying to decode/encode a large number of distinct 'things' in VHDL, I stumbled across the following technique, which I find quite intriguing:

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;
decoded <= things'VAL(to_integer(unsigned(encoded))); -- results in "E"
-- This is how encoding would work:
--encoded <= std_ulogic_vector(to_unsigned(decoded'POS(decoded)));

Now what if I want to encode/decode a subset of things like (A, B, E, F) with 2 bit? VHDL has the notion of subtypes. However, as far as I know, subtypes must be specified by a single range attribute and can not have 'holes'. Note that I can't simply change the order of the elements because the order is fixed and because there are different subsets with different 'holes' so eliminating all of them would be impossible anyways.

TYPE 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 a : things;
SIGNAL b : some_things;
SIGNAL some_things_encoded : std_ulogic_vector(1 downto 0);

b <= some_things'VAL(to_integer(unsigned(some_things_encoded)));
a <= b;  -- Doesn't work although the literals are a subset.

Now the easiest way to convert from some_things to things would be to write a silly looking conversion function and use that to do the assignment:

FUNCTION to_things(x : some_things) RETURN things IS
BEGIN
    CASE x IS
        WHEN A => return A;
        WHEN B => return B;
        WHEN E => return E;
        WHEN F => return F;
    end case;
end;

a <= to_things(b);

Now this works, but it gets a bit tedious and verbose with a large number ob subsets and a large number of items. I'm not really into writing 20 functions consisting only of 32 nearly identical lines.

So I'm wondering if there is any more elegant and synthesizable way to do this, preferably without VHDL 2008, due to the poor tool support. Would something along the lines of the following work?

FUNCTION to_things(x : some_things) RETURN things IS
BEGIN
    RETURN things'VALUE(some_things'IMAGE(x))
end;
\$\endgroup\$
1
  • \$\begingroup\$ In the original assignment instead of a <= b you should be able to use a <= things'VALUE(some_things'IMAGE(b)) \$\endgroup\$
    – user8352
    Apr 13, 2014 at 20:04

1 Answer 1

2
\$\begingroup\$

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 <= 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 <= things'VAL(to_integer(unsigned(encoded))); -- results in "E"
    bb <= some_things'VAL(to_integer(unsigned(some_things_encoded)));
    -- a <= 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 <= things'VALUE(some_things'IMAGE(bb));

-- Demonstrate the value of aa:

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

end architecture;

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.