Les types fondamentaux du VHDL : std_logic, std_logic_vector, integer, unsigned, signed.
Le type fixe les valeurs qu'un objet peut prendre et les opérations qu'il accepte. Choisis-le selon le rôle du signal : niveau logique, paquet de bits, nombre ou groupe de champs.
Type
Librairie
Usage typique
std_logic
STD_LOGIC_1164
Signal 1 bit
std_logic_vector
STD_LOGIC_1164
Bus N bits (sans arithmétique)
unsigned
NUMERIC_STD
Bus N bits non signé (arithmétique)
signed
NUMERIC_STD
Bus N bits signé complément à 2
integer
STD (natif)
Entier - paramètres, indices et compteurs
boolean
STD (natif)
true / false
bit
STD (natif)
0 ou 1 ; sans états inconnus de simulation
Distinguer un signal d'un nombre
std_logic modélise un signal avec neuf valeurs, utiles notamment pour voir les états non initialisés et les conflits en simulation :
Valeur
Signification
'0'
Zéro logique
'1'
Un logique
'Z'
Haute impédance (tristate)
'U'
Non initialisé (simulation)
'X'
Inconnu - conflit de drivers (simulation)
'W', 'L', 'H', '-'
Valeurs faibles, don't care
'0' et '1' représentent les niveaux logiques. 'Z' représente la haute impédance, réalisable selon les ressources, surtout aux E/S. Les autres valeurs servent au modèle de simulation ou aux conventions de synthèse ; un 'X' n'est pas un niveau matériel supplémentaire.
std_logic_vector regroupe des bits sans imposer de sens numérique :
signal w_bus : std_logic_vector(7 downto 0); -- 8 bits, bit 7 = MSBsignal w_adr : std_logic_vector(0 to 7); -- 8 bits, bit 0 = MSB (rare)signal w_bit3 : std_logic;signal w_nibble : std_logic_vector(3 downto 0);-- Affectationw_bus <= "10110011"; -- binairew_bus <= x"B3"; -- hexadécimalw_bus <= (others => '0'); -- tous les bits à 0-- Accès à des bits ou sous-vecteursw_bit3 <= w_bus(3); -- bit 3w_nibble <= w_bus(7 downto 4); -- 4 bits de poids fort
Les plages downto et to sont légales. Ici, downto est la convention usuelle pour les bus numériques ; précise toujours quel indice représente le poids fort.
unsigned et signed donnent un sens arithmétique au vecteur avec numeric_std :
Un cast entre vecteurs conserve les bits tout en changeant leur interprétation. Les conversions vers un entier, ou depuis un entier, doivent aussi respecter la plage et la largeur choisies.
De → Vers
std_logic_vector
unsigned
signed
integer
std_logic_vector
-
unsigned(x)
signed(x)
to_integer(unsigned(x))
unsigned
std_logic_vector(x)
-
signed(x)
to_integer(x)
signed
std_logic_vector(x)
unsigned(x)
-
to_integer(x)
integer
std_logic_vector(to_unsigned(x,N))
to_unsigned(x,N)
to_signed(x,N)
-
Utiliser des types adaptés au comportement
integer sert aux paramètres, indices et compteurs, en simulation comme en synthèse lorsque l'outil le prend en charge. Contraindre sa plage rend les limites visibles. Les ports à vecteurs restent souvent préférables pour rendre la largeur de l'interface explicite.
boolean contient true et false ; les comparaisons produisent ce type :
signal w_valid : boolean;w_valid <= true;w_valid <= (r_counter = to_unsigned(0, 8)); -- comparaison retourne booleanif w_valid then -- ...end if;
Une énumération donne des noms aux états ou aux codes :
-- Déclaration dans la zone architecturaletype t_state is (IDLE, INIT, RUN, DONE, ERROR);type t_couleur is (ROUGE, ORANGE, VERT);type t_direction is (NORD, SUD, EST, OUEST);signal r_state : t_state := IDLE;signal r_couleur : t_couleur := ROUGE;
-- Utilisation dans un processprocess(i_clk)begin if rising_edge(i_clk) then case r_state is when IDLE => r_state <= INIT; when INIT => r_state <= RUN; when RUN => if i_done = '1' then r_state <= DONE; end if; when others => r_state <= IDLE; end case; end if;end process;
Le synthétiseur choisit l'encodage, par exemple binaire ou one-hot. Certains attributs permettent de l'orienter selon l'outil.
Regrouper et dimensionner les données
Les types tableaux décrivent une ROM, une RAM ou une matrice :
-- Tableau de 8 octets (ROM simple)type t_rom_8x8 is array (0 to 7) of std_logic_vector(7 downto 0);constant c_ROM : t_rom_8x8 := ( x"00", x"1F", x"3C", x"7E", x"FF", x"7E", x"3C", x"1F");-- Tableau 2D (matrice 4 × 4 de bits)type t_matrice is array (0 to 3, 0 to 3) of std_logic;-- Tableau de std_logic_vector (RAM inférée)type t_ram is array (0 to 255) of std_logic_vector(7 downto 0);signal r_mem : t_ram;
Une description d'accès synchrone permet l'inférence d'une mémoire, sous réserve des ressources et options de la cible :
-- RAM synchrone inférée à partir d'un tableauprocess(i_clk)begin if rising_edge(i_clk) then if i_we = '1' then r_mem(to_integer(unsigned(i_addr))) <= i_data; end if; o_data <= r_mem(to_integer(unsigned(i_addr))); end if;end process;
Un tableau non contraint reporte le choix de sa plage à la déclaration de l'objet :
subtype t_byte is std_logic_vector(7 downto 0);type t_byte_array is array (natural range <>) of t_byte;signal r_window : t_byte_array(0 to 3);signal r_fifo : t_byte_array(0 to 15);
Le subtype nomme ici un octet et facilite sa réutilisation. On peut aussi écrire directement le type de ses éléments :
type t_byte_array is array (natural range <>) of std_logic_vector(7 downto 0);
Pour nommer une version contrainte de std_logic_vector, écris un subtype, et non type t_byte is std_logic_vector(7 downto 0);. Le même t_byte_array peut ensuite décrire quatre octets, seize octets ou une table plus grande :
Les records rendent les interfaces de bus et les port map plus lisibles. Pour les utiliser dans les ports, place leur déclaration dans un package visible par les unités concernées.