Dominando std_logic_vector: Creando vectores de señal en VHDL
El tipo std_logic_vector es el estándar de VHDL para definir buses de señales. Mientras que std_logic modela el estado de un solo cable, std_logic_vector extiende eso a un array de cables, permitiendo la representación de buses multi-bit.
A diferencia del std_logic de un solo bit, std_logic_vector es un tipo compuesto —una colección indexada de elementos std_logic. Puede contener un número arbitrario de bits, lo que lo hace ideal para conectar componentes que intercambian datos multi-bit.
Esta entrada de blog es parte de la serie Tutoriales Básicos de VHDL.
Declare una señal std_logic_vector con la siguiente sintaxis:
signal <name> : std_logic_vector(<lsb> to <msb>) := <initial_value>;
o
signal <name> : std_logic_vector(<msb> downto <lsb>) := <initial_value>;
donde <name> es un identificador elegido por el usuario y <initial_value> es opcional. <lsb> y <msb> denotan los índices del bit menos y más significativo, respectivamente.
La palabra clave to o downto especifica la dirección del rango (es decir, endianness). Ambas formas funcionan, pero la mayoría de los diseñadores favorecen downto por claridad. Recomiendo consistentemente usar downto al declarar vectores de bits para evitar confusión.
El código VHDL para un vector de tamaño byte es:
signal MySlv : std_logic_vector(7 downto 0);
El código VHDL para un vector de un bit es:
signal MySlv : std_logic_vector(0 downto 0);
El código VHDL para un rango vacío (cero bits) es:
signal MySlv : std_logic_vector(-1 downto 0);
Ejercicio
En este tutorial en video aprenderemos cómo declarar señales std_logic_vector y darles valores iniciales. También aprendemos cómo iterar sobre los bits en un vector usando un For-Loop para crear un registro de desplazamiento:
El código final que creamos en este tutorial:
library ieee;
use ieee.std_logic_1164.all;
entity T11_StdLogicVectorTb is
end entity;
architecture sim of T11_StdLogicVectorTb is
signal Slv1 : std_logic_vector(7 downto 0);
signal Slv2 : std_logic_vector(7 downto 0) := (others => '0');
signal Slv3 : std_logic_vector(7 downto 0) := (others => '1');
signal Slv4 : std_logic_vector(7 downto 0) := x"AA";
signal Slv5 : std_logic_vector(0 to 7) := "10101010";
signal Slv6 : std_logic_vector(7 downto 0) := "00000001";
begin
-- Registro de desplazamiento
process is
begin
wait for 10 ns;
for i in Slv6'left downto Slv6'right + 1 loop
Slv6(i) <= Slv6(i-1);
end loop;
Slv6(Slv6'right) <= Slv6(Slv6'left);
end process;
end architecture;
La ventana de forma de onda en ModelSim después de presionar run, y hacer zoom en la línea de tiempo:
Análisis
En este ejercicio declaramos seis buses std_logic_vector, cada uno de ocho bits (un byte).
La señal Slv1 fue declarada sin valor inicial. El bus aparece como XX en la captura de pantalla de la forma de onda porque la visualización hexadecimal no puede representar valores desconocidos. Un vistazo más cercano revela que los bits individuales son en realidad U.
La señal Slv2 usa la asignación agregada (others => '0') para establecer todos los bits a cero. Esta sintaxis concisa asegura que cada elemento reciba el valor especificado independientemente del ancho del vector.
La señal Slv3 emplea la misma técnica agregada para inicializar cada bit a uno, lo que se muestra como FF (hex para ocho 1s).
La señal Slv4 demuestra un inicializador hexadecimal: AA. Ya que cada dígito hex mapea a cuatro bits, dos dígitos cubren el vector de 8 bits.
La señal Slv5 contiene el valor idéntico, pero expresado en binario (10101010). Tanto Slv4 como Slv5 se renderizan como AA en la forma de onda.
La señal Slv6 comienza con todos ceros excepto el bit menos significativo establecido a 1. Un proceso implementa un registro de desplazamiento hacia la izquierda que cicla el 1 a través del vector cada 10 ns.
El proceso aprovecha los atributos left y right para mantener el código genérico; redimensionar el vector no requiere cambios de código.
Atributos adicionales existen, pero están fuera del alcance de este tutorial introductorio.
Conclusión
- Los vectores de N bits deben declararse usando
std_logic_vector(N-1 downto 0). - Un vector puede asignarse como un todo o se pueden acceder bits individuales.
- Todos los bits pueden ponerse a cero con la asignación agregada
(others => '0'). - Usar atributos como
'lefty'righthace el código genérico y mantenible.
Tome el Cuestionario Básico VHDL – parte 2 »
o
Vaya al siguiente tutorial »
VHDL
- Guía completa de conversiones de tipos VHDL con Numeric_Std y Std_Logic_Arith
- Dominando tipos Signed vs Unsigned en VHDL: Perspectivas prácticas
- Creación de listas de cadenas en VHDL: Buenas prácticas y ejemplo
- Creación de un testbench dirigido por Tcl para un módulo VHDL de cerradura por código
- Finalizar elegantemente una simulación de testbench VHDL
- Implementación de un controlador PWM en VHDL: Diseño, simulación y demo en FPGA
- Generación de números aleatorios en VHDL: De uniforme a OSVVM
- Diseño de un búfer circular FIFO robusto en VHDL usando RAM de bloques
- Cómo construir un testbench de auto-comprobación en VHDL: Guía práctica
- Implementación de lista enlazada dinámica en VHDL con tipos protegidos y punteros de acceso
- Aprovechando procedimientos en-proceso para diseños FSM más limpios en VHDL