VHDL: conversión de un tipo INTEGER a un STD_LOGIC_VECTOR

28

Construí un contador mod-16, y el resultado de salida es un INTEGER (todos los ejemplos que vi usaban INTEGER).

Construí un decodificador de pantalla hexadecimal a 7 segmentos, y su entrada es un STD_LOGIC_VECTOR (lo escribió de esa manera porque era fácil mapear la tabla de verdad).

Me gustaría conectar la salida del contador a la entrada del decodificador, pero obtengo errores de "falta de coincidencia de tipos" cuando intento compilar en QuartusII.

¿Hay alguna forma de convertir de un tipo INTEGER a un tipo STD_LOGIC_VECTOR en una lista de VHDL?

J. Polfer
fuente

Respuestas:

20

Como otros dijeron, use ieee.numeric_std, nunca ieee.std_logic_unsigned, que no es realmente un paquete IEEE.

Sin embargo, si está utilizando herramientas con soporte VHDL 2008, puede usar el nuevo paquete ieee.numeric_std_unsigned, que esencialmente hace que se std_logic_vectorcomporte como sin firmar.

Además, como no lo vi explícitamente, aquí hay un ejemplo de código real para convertir de un entero (sin signo) a un std_logic_vector:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
wjl
fuente
16

Como dice LoneTech, use ieee.numeric_stdes tu amigo. Puedes convertir un std_logic_vectora integer, pero tendrás que convertirlo como signedo unsignedprimero (ya que el compilador no tiene idea de lo que quieres decir). VHDL es un lenguaje fuertemente tipado. He escrito más sobre este tema en mi blog.

Básicamente, cambiaría su convertidor de 7 segundos para que tome un integer(o en realidad un natural, dado que solo tratará con números positivos): la conversión es entonces una simple búsqueda de matriz. Configure una matriz constante con las conversiones y simplemente indexe con el entero que usa en la entidad como entrada.

Martin Thompson
fuente
Gracias por esto. Agradezco mucho tus comentarios. Estaba en una posición de TA, aprendiendo VHDL para ayudar a un profesor a comenzar, que era un poco inestable en los conceptos de programación. Voy a transmitirle su información: el libro de texto que utilizamos no profundizó en las preguntas de 'moralidad' del VHDL.
J. Polfer
1
Es menos una cuestión de "moralidad" que una garantía de coherencia. Numeric_std lib es un estándar real instituido por el IEEE, mientras que la biblioteca std_logic_unsigned fue creada por un proveedor y adoptada en la industria sin ninguna definición formal real. No hay garantía de compatibilidad entre proveedores con las librerías no estándar, aunque generalmente funciona bien. Sin embargo, ahora es una buena forma de pasar al estándar.
MattG
1

Digamos que su contador de 4 bits tenía una salida INTEGER SOME_INTEGER y deseaba convertirlo en un STD_LOGIC_VECTOR de 4 bits.

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

También puede usar esto para inicializar vectores con números significativos

SOME_VECTOR <= conv_std_logic_vector(9, 4); -- instead of "1001"

Creo que es posible que deba agregar "use IEEE.STD_LOGIC_ARITH.ALL;" y / o STD_LOGIC_UNSIGNED.

La operación complementaria es conv_integer (vector). Me gusta usar esto cuando hago comparaciones. Entonces podría declarar

constant SOME_CONSTANT : integer := 999;

Y luego, más tarde, puedo usar esto en una declaración if

if (conv_integer(SOME_VECTOR)=SOME_CONSTANT)
  then OTHER_VECTOR <= (others => '0');
end if;

EDITAR: no debería necesitar declarar la variable como un entero. Intente cambiar la declaración a std_logic_vector en su lugar. Los operadores + y - trabajan en std_logic_vectors.

ajs410
fuente
3
¡Por favor no hagas esto! Use numeric_std (vea LoneTech y mis respuestas)
Martin Thompson
Si tiene una mejor manera de hacerlo, está bien, pero mi sugerencia funciona, así que creo que su voto negativo fue innecesario. He usado std_logic_arith durante años y nunca tuve ningún problema con él. Creo que los temores acerca de que los proveedores cambien sus implementaciones son infundados; ¿Qué proveedor en su sano juicio se arriesgará a romper los diseños de sus clientes?
ajs410
1
Ya tiene una respuesta sobre qué proveedor pondrá voluntariamente material específico del proveedor en el espacio de nombres de IEEE. Sigue siendo crudo, particularmente cuando se trata de valores con y sin signo.
Yann Vernier el
"Los operadores + y - trabajan en std_logic_vectors". AFAIK, no funcionan, a menos que no entienda su significado. Por lo general, es necesario convertir a un tipo que contenga datos firmados / sin firmar primero.
stanri
1

Puede interesarle usar los tipos unsignedy signedde ieee.numeric_std. Son compatibles con std_logic_vector, pero tienen una interpretación numérica (binaria o de 2 complementos). También existe la opción de poner tal interpretación std_logic_vector, pero esto no es recomendable .

Yann Vernier
fuente
0

Como dice la respuesta principal, el método recomendado es el siguiente:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Sin embargo, me gustaría explicar por qué se recomienda esto y por qué VHDL tiene una forma aparentemente complicada de convertir enteros en std_logic_vectors.

Se trata de cómo estos tipos son vistos por las herramientas.

Un standard_logic_vector es literalmente un grupo de 1s o 0s. Tengo 10001. ¿Qué número es este? Bueno, eso depende. ¿Está firmado o sin firmar? El SLV no lo sabe ni le importa. Cuantos pedazos Bueno, ¿cuánto dura tu SLV?

Se firma un número entero, y generalmente 32 bits (si no recuerdo mal).

Etapa 1: acortar mi número entero y sin firmar. Esa es esta parte:

to_unsigned(my_int, my_slv'length));

"Tengo este número entero, quiero que no esté firmado y quiero que se ajuste a la longitud de mi SLV".

Etapa 2: Luego, toma esos bits y úsalos para manejar my_slv.

my_slv <= std_logic_vector(...)

"Toma estos bits y úsalos para manejar mi slv"

(Una nota sobre terminología. A <= BEn VHDL se lee en voz alta como "A es impulsado por B")

Combinado, esto te lleva a:

my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Cuando proviene de un fondo de programación tradicional, es muy fácil quedarse atrapado en una forma de pensar de programación. Pero en VHDL, el código que escribe tiene implicaciones físicas en el hardware. Saber por qué este método funciona y se recomienda está un paso más cerca de pensar en lo que está escribiendo en términos de hardware.

Consejo adicional: las funciones con el prefijo to_ son las que acortan / cambian los operandos. Los hacen sin firmar o una cierta longitud o ambos. Es por eso que to_unsigned requiere que especifique la longitud. Las funciones sin to_ (straight std_logic_vector (...) en este ejemplo) se usan cuando los tipos ya son directamente compatibles. "Toma estos bits y mételos en este tipo, no se requieren modificaciones". Estos no tienen un argumento de longitud porque ambos lados ya son iguales. Entonces, cuando construyo cosas como esta, no necesito buscarlo, solo pienso en cómo estoy cambiando los datos.

Stanri
fuente
0

Para convertir un entero a std_logic_vector, tiene varias opciones. Usando numeric_std:

vect <= std_logic_vector( to_unsigned( your_int, vect'length));

o

vect <= std_logic_vector( to_signed( your_int, vect'length));

Usando std_logic_arith:

vect <= conv_std_logic_vector( your_int, vect'length);

std_logic_arith no es un estándar ieee, pero la mayoría de las herramientas lo compilan en la biblioteca IEEE y es ampliamente utilizado.

Craig
fuente