Opérateurs
Opérateurs logiques, relationnels, arithmétiques et de décalage en VHDL.
Catégories d'opérateurs
VHDL dispose de plusieurs familles d'opérateurs, présentées par priorité croissante :
| Priorité | Catégorie | Opérateurs |
|---|---|---|
| 1 (plus faible) | Logiques | and, or, nand, nor, xor, xnor |
| 2 | Relationnels | =, /=, <, <=, >, >= |
| 3 | Décalage / rotation | shift_left, shift_right, rotate_left, rotate_right |
| 4 | Additifs | +, -, & |
| 5 | Multiplicatifs | *, /, mod, rem |
| 6 (plus fort) | Divers | **, abs, not |
Important : En VHDL, les opérateurs logiques ont la même priorité. Utilisez des parenthèses !
Opérateurs logiques
Opèrent sur std_logic, std_logic_vector, bit, boolean.
-- Sur std_logic (1 bit)
w_y <= i_a AND i_b;
w_y <= i_a OR i_b;
w_y <= i_a XOR i_b;
w_y <= NOT i_a;
w_y <= i_a NAND i_b;
w_y <= i_a NOR i_b;
w_y <= i_a XNOR i_b;
-- Sur std_logic_vector (bit à bit)
w_mask <= w_data AND "11110000"; -- masquage des 4 bits de poids faible
w_set <= w_data OR "00001111"; -- forçage des 4 bits de poids faiblePriorité - attention !
-- INCORRECT : ambiguïté de priorité
w_y <= i_a AND i_b OR i_c; -- erreur de compilation !
-- CORRECT : parenthèses obligatoires si mélange
w_y <= (i_a AND i_b) OR i_c;
w_y <= i_a AND (i_b OR i_c);Opérateurs relationnels
Retournent un boolean. Utilisables dans les if, when, etc.
if i_a = i_b then -- égalité
if i_a /= i_b then -- différent
if r_counter < 100 then -- strictement inférieur
if r_counter >= c_MAX then -- supérieur ou égalPour comparer des
unsigned/signed, utiliserNUMERIC_STD. Pour desstd_logic_vector, la comparaison est lexicographique (bits à bits) - utiliserunsignedpour de l'arithmétique.
Opérateurs arithmétiques
Nécessitent IEEE.NUMERIC_STD pour les types unsigned/signed.
library IEEE;
use IEEE.NUMERIC_STD.ALL;
signal r_a, r_b : unsigned(7 downto 0);
signal r_sum : unsigned(8 downto 0); -- +1 bit pour éviter overflow
-- Addition et soustraction
r_sum <= ('0' & r_a) + ('0' & r_b); -- extension de signe
r_a <= r_a + 1; -- incrément
r_a <= r_a - r_b;
-- Multiplication (attention : double la largeur)
signal r_prod : unsigned(15 downto 0);
r_prod <= r_a * r_b; -- 8 * 8 = 16 bitsDivision, mod et rem
/, mod et rem existent en VHDL, mais ils ne doivent pas être utilisés comme de simples opérations "gratuites" en FPGA. Une division ou un modulo par une valeur variable peut inférer un circuit coûteux. Pour un compteur modulo fixe, on préfère souvent un test explicite :
if r_count = 9 then
r_count <= 0;
else
r_count <= r_count + 1;
end if;mod et rem donnent le même résultat avec des entiers positifs :
7 mod 4 = 3
7 rem 4 = 3La différence apparaît avec les valeurs négatives :
A mod Bprend le signe deB;A rem Bprend le signe deA.
Exemple :
(-7) mod 4 = 1
(-7) rem 4 = -3En RTL synthétisable, gardez surtout cette règle pratique : sur des compteurs et des indices positifs, mod est généralement celui qu'on veut ; pour du matériel efficace, remplacez-le par une comparaison quand le modulo est connu.
Décalages et rotations
signal w_data : std_logic_vector(7 downto 0);
signal w_uns : unsigned(7 downto 0);
signal w_sig : signed(7 downto 0);
-- Décalage logique (remplissage par '0')
w_uns <= shift_left(w_uns, 2); -- décalage gauche de 2 (×4)
w_uns <= shift_right(w_uns, 1); -- décalage droit de 1 (÷2)
-- Décalage arithmétique sur signed : shift_right propage le bit de signe
w_sig <= shift_right(w_sig, 1);
-- Rotation
w_uns <= rotate_left(w_uns, 3);
w_uns <= rotate_right(w_uns, 3);Les opérateurs sll, srl, sla, sra, rol et ror existent dans VHDL. En pratique, pour du code RTL moderne avec numeric_std, on privilégie les fonctions shift_left, shift_right, rotate_left et rotate_right sur les types unsigned et signed : l'intention est plus claire, les surcharges sont mieux maîtrisées, et le sens du décalage ne dépend pas d'un opérateur moins explicite.
Pour un unsigned, shift_right remplit à gauche avec des 0. Pour un signed, shift_right conserve le signe en recopiant le bit de poids fort. C'est la différence importante entre décalage logique et décalage arithmétique.
Opérateur de concaténation &
Permet d'assembler des vecteurs de bits.
signal w_byte : std_logic_vector(7 downto 0);
signal w_hi : std_logic_vector(3 downto 0) := x"A";
signal w_lo : std_logic_vector(3 downto 0) := x"5";
signal w_bit : std_logic := '1';
w_byte <= w_hi & w_lo; -- "10100101" = 0xA5
w_byte <= w_bit & "0110011"; -- insertion d'un bit
w_byte <= "0000" & w_lo; -- extension zéroRécapitulatif des opérations courantes
-- Tester un bit
if w_flags(3) = '1' then ...
-- Masquer des bits
w_result <= w_data AND x"0F"; -- garder les 4 bits de poids faible
-- Tronquer / étendre
w_16bit <= x"00" & w_8bit; -- zero-extend 8→16 bits
w_16bit <= (15 downto 8 => w_8bit(7)) & w_8bit; -- sign-extend 8→16 bits
-- Inverser tous les bits
w_inv <= NOT w_data;
-- Compter avec débordement
r_counter <= r_counter + 1; -- déborde naturellement à 0 (type unsigned)📝 Tester mes connaissances - Quiz du chapitre