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;