Arithmétiques en VHDL
GE34
2024-2025
ENSA Marrakech
1
Additionneur complet à 1 bit (full adder)
4
Additionneur 4 bits
5
Additionneur 4 bits: équations logiques
library ieee;
use ieee.std_logic_1164.all;
entity adder4bits is
port( A, B: in std_logic_vector(3 downto 0);
sum: out std_logic_vector(3 downto 0);
cout, ovf: out std_logic);
end adder4bits;
architecture arch of adder4bits is
signal c : std_logic_vector(4 downto 0);
begin
c(0) <= '0';
sum <= A xor B xor c(3 downto 0);
c(4 downto 1) <= (A and B) or (C(3 downto 0) and (A xor B));
cout <= c(4);
ovf <= c(3) xor c(4);
end arch;
6
7
Package arithmétique (1)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
- numeric_std -- IEEE standard
– Définit les types signés, non signés
– Définit les opérateurs arithmétiques, de comparaison et logiques pour ces types
- Les opérateurs arithmétiques disponibles sont
- Addition (+)
- Soustraction (-)
- Multiplication (*)
- Division (/)
- Comparaison (=,>, <, <=,> =, / =)
8
Package arithmétique (2)
- Il y a autres packages qui sont utilisés
- std_logic_arith, std_logic_signed,
std_logic_unsigned
- Nous ne tiendrons compte que de
«numeric_std» car c’est le seul package
standard défini sur tous les outils
commerciaux de synthèse et de simulation.
9
Package arithmétique (3)
- numeric_std offre 2 types de données
- signed, unsigned
- Peuvent être déclarés comme signal, variable et
même dans les ports de l’entité
- Exemple de déclaration
- signal sig: unsigned (3 downto 0)
- Crée un signal qui prend une valeur de 0 -> 15
- signal count: signed (3 downto 0)
- Crée un signal qui prend une valeur de -8 -> +7
10
Les fonctions du package arithmétique
Fonctions arithmétiques signées: Fonctions de comparaison:
Fonctions arithmétiques non signées:
11
Addition (1)
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
entity add2u is entity add2s is
port(au, bu : in unsigned(3 downto 0); port(as, bs : in signed(3 downto 0);
yu : out unsigned(3 downto 0)); ys : out signed(3 downto 0));
end add2u; end add2s;
architecture arch of add2u is architecture arch of add2s is
begin begin
yu <= au + bu; ys <= as + bs;
end arch; end arch;
Le problème est que ces additions peuvent conduire à des
dépassements de capacité si le résultat dépasse la taille de 4 bits.
12
Addition (2)
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
entity add2u is entity add2s is
port( port(
au, bu : in unsigned(3 downto 0); as, bs : in signed(3 downto 0);
yu : out unsigned(4 downto 0)); ys : out signed(4 downto 0));
end add2u; end add2s;
architefcture arch of add2u is architecture arch of add2s is
Begin begin
ys <= (as(as'left) & as) + (bs(bs'left) & bs);
yu <= ('0' & au) + ('0' & bu);
end arch;
end arch;
L’augmentation de la taille de la sortie permet de gérer les éventuels
dépassements
13
Les fonctions de conversion du package arithmétique
14
Exemples (1)
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
entity C1_add is entity C2_add is
port(a, b : in std_logic_vector(3 downto 0); port(a, b : in std_logic_vector( 3 downto 0);
y : out std_logic_vector(4 downto 0)); y : out std_logic_vector( 3 downto 0));
end C1_add; end C2_add;
architecture arch of C2_add is
architecture arch of C1_add is
signal a_int, b_int: integer range -8 to 7;
signal ys: signed(4 downto 0);
signal y_int: integer range -8 to 7;
begin
begin
ys <= signed(a(a'left) & a) +
signed(b(b'left) &b); a_int <= to_integer(signed(a));
y <= std_logic_vector(ys); b_int <= to_integer(signed(b));
end arch;
y_int <= a_int + b_int;
y <= std_logic_vector(to_signed(y_int, 4));
end arch;
15
Exemples (2): Décodeur général
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity decodeur is
generic (n : positive := 3 );
port (
A : in std_logic_vector(n - 1 downto 0);
F: out std_logic_vector(2 ** n - 1 downto 0)
);
end decodeur;
architecture comportementale of decodeur is
begin
process(A)
begin
F <= (to_integer(unsigned(A)) => '1', others => '0');
end process;
end comportementale;
16
Multiplication
signal Acc, mult: signed(2*N – 1 downto 0);
signal A, B : signed(N – 1 downto 0);
…
process (clk)
begin
if rising_edge(clk) then
mult <= A * B; En général, les FPGAs contiennent
Acc <= Acc + mult; des blocs DSP pour faire du
end if;
traitement de signal. Ces blocs
end process;
contiennent des multiplieurs. Sur
Cyclone II, il y a des multiplieurs
embarqués 18x18.
Signal P : signed(2*N – 1 downto 0);
Signal A, B : signed(N – 1 downto 0);
…
P <= A * B;
17