¿Cómo implementar diferentes codificaciones para subconjuntos alguna enumeración en VHDL?

0

Al intentar decodificar / codificar una gran cantidad de "cosas" distintas en VHDL, me topé con la siguiente técnica, que me parece bastante intrigante:

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)));

¿Y ahora si quiero codificar / decodificar un subconjunto de things como (A, B, E, F) con 2 bits? VHDL tiene la noción de subtipos. Sin embargo, por lo que sé, los subtipos deben especificarse por un atributo de rango único y no pueden tener "agujeros". Tenga en cuenta que no puedo simplemente cambiar el orden de los elementos porque el orden es fijo y porque hay diferentes subconjuntos con diferentes 'agujeros', por lo que eliminarlos de todos modos sería imposible de todos modos.

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.

Ahora, la forma más fácil de convertir de some_things a things sería escribir una función de conversión de aspecto tonto y usarla para hacer la tarea:

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);

Ahora esto funciona, pero se vuelve un poco tedioso y detallado con un gran número de subconjuntos ob y una gran cantidad de elementos. Realmente no me gusta escribir 20 funciones que consistan solo en 32 líneas casi idénticas.

Así que me pregunto si hay alguna forma más elegante y sintetizable de hacerlo, preferiblemente sin VHDL 2008, debido al mal soporte de la herramienta. ¿Funcionaría algo similar al siguiente trabajo?

FUNCTION to_things(x : some_things) RETURN things IS
BEGIN
    RETURN things'VALUE(some_things'IMAGE(x))
end;
    
pregunta Fritz

1 respuesta

2

No puede sobrecargar a o b, por lo que los nombres de las señales se cambiaron a aa y 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;

Esto analiza, elabora y simula (aunque no hace nada interesante por sí mismo).

    
respondido por el user8352

Lea otras preguntas en las etiquetas