VHDL: ¿Cómo se asignan valores personalizados a los identificadores de un tipo enumerado?

1

Para un diseño con pantallas de siete segmentos, será más fácil en simulación de modelos si se puede ver el valor real de la pantalla en la pantalla de siete segmentos, por ejemplo, hexadecimal D, que es "1000010" en binario, podría aparecer como un tipo enumerado 'ss_D 'en la forma de onda de simulación. ¿Cómo se crea una enumeración con valores asignados personalizados para este propósito?

Sé que no hace daño concentrarse solo en el valor que va al decodificador para la pantalla de siete segmentos y verlo como hexadecimal en la ventana de la onda. Pero la pregunta aquí es, en general, ¿cómo asignar un valor personalizado al tipo de enumeración VHDL?

    
pregunta quantum231

2 respuestas

4

Consulte Ashenden "Guía del diseñador para VHDL" (capítulo 20.2).

dada la definición de tipo de la otra respuesta

type ss_enum is (ss_0, ss_1, ss_2, ss_3, ss_4, ss_5, ss_6, ss_7, ss_8,
                     ss_9, ss_A, ss_B, ss_C, ss_D, ss_E, ss_F);

podemos asignarle una representación a través de un atributo:

attribute encoding of ss_d[return ss_enum] : literal is b"1000010";

y luego deberíamos poder acceder a ese valor a través de la sintaxis de atributo:

signal ss : ss_enum;
signal LED_port : std_logic_vector(6 downto 0);
...
LED_port <= ss'encoding;

No sé cómo Modelsim mostrará la señal LED_port , pero espero que muestre la señal ss_enum usando sus valores de enumeración ss_D etc.

En la práctica me parece innecesario asignar codificaciones, declararía una matriz constante para este propósito, la sintaxis es más breve y ordenada, y generalmente se sintetizará en la misma cosa.

constant lookup : array(ss_enum) of std_logic_vector(6 downto 0) := (
   ss_0 => ...
   ...
   ss_D => b"1000010",
   ... );
...
LED_Port <= lookup(ss);

Este enfoque no responde a su pregunta de visualización de la forma de onda, pero me parece que es mejor hacer que la simulación se compruebe automáticamente; entonces, mirar las formas de onda es la excepción (cuando algo salió mal) en lugar de la regla, y por lo tanto es mucho menos importante.

    
respondido por el Brian Drummond
2

Los tipos enumerados son fáciles de declarar:

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

entity enum is
end entity;

architecture foo of enum is
    type ss_enum is (ss_0, ss_1, ss_2, ss_3, ss_4, ss_5, ss_6, ss_7, ss_8,
                     ss_9, ss_A, ss_B, ss_C, ss_D, ss_E, ss_F);
    signal sseg: ss_enum;
    signal hex_in:   unsigned (3 downto 0) := "0000";
begin
COUNT:
    process
    begin
        wait for 10 ns;
        if hex_in < "1111" then
            hex_in <= hex_in + 1;
        else
            wait;
        end if;
    end process;

LOOKUP_ENUM:

    sseg <= ss_enum'VAL(to_integer(hex_in));

end architecture;

Este no es un tipo de enumeración de caracteres (todos sus miembros son identificadores).

Esencialmente, puede asociar un valor con un identificador o carácter literal. En este caso, la entrada del valor hexadecimal al bucle utilizado para producir su valor de visualización de siete segmentos también se usa para establecer el valor de una señal del tipo enumerado:

Puedeconsiderarlocomoinformaciónadicionalamenosqueuseeltipoenumeradocomoeltipodeíndiceparasubúsquedadevalordesietesegmentos.(YVHDLtepermitehacereso).

Si,comoDaveTweedsugierequedeseareconocerlosvaloresdesietesegmentosdeformadispersa,losasignaráasutipoenumerado:

architecturefieofenumistypess_enumis(ss_0,ss_1,ss_2,ss_3,ss_4,ss_5,ss_6,ss_7,ss_8,ss_9,ss_A,ss_B,ss_C,ss_D,ss_E,ss_F,unknown);signalsseg:ss_enum;signalseven_seg:unsigned(6downto0):="1000000";
    function sseg_enum (sevenseg: std_logic_vector(6 downto 0)) 
                                  return ss_enum is
    begin
        case sevenseg is
            when "1000010" =>  
                return ss_D;  
            when others =>       -- we're  going to fill this in, right?
                return unknown;
        end case;
    end function;
begin
COUNT:
    process
    begin
        wait for 10 ns;
        if seven_seg < "1000100" then
            seven_seg <= seven_seg + 1;
        else
            wait;
        end if;
    end process;

LOOKUP_ENUM:

    sseg <= sseg_enum(std_logic_vector(seven_seg));

end architecture;

En este caso, la búsqueda dispersa se realiza con una función que usa una declaración de caso (y podemos ver que el ejemplo es escaso).

Puede ver que hay un valor de enumeración agregado para los valores de siete segmentos que no son útiles asignados.

Eso nos da:

Este método también se puede realizar en la mayoría de los visores de forma de onda de alguna manera generalmente no portátil. Porque en este caso, la señal de tipo enumerado no se usaría en ningún lugar donde se esperaría que se comiera la compuerta en síntesis. (Sin ningún puerto de salida asignado a los pines, este ejemplo completo de 'diseño' se comerá de todos modos).

    
respondido por el user8352

Lea otras preguntas en las etiquetas