Vous êtes sur la page 1sur 7

Cours/TD

VHDL
OPERATEURS ARITHMETIQUES
1) Recopier, compiler, crire le testbench et simuler le code du composant dcrit
ci-dessous :
----------------------------------library ieee;
use ieee.std_logic_1164.all;
entity add4 is
port (r0:in std_logic;
a,b: in std_logic_vector ( 3 downto 0);
s: out std_logic_vector (4 downto 0));
end add4;
architecture archi of add4 is
signal r: std_logic_vector(4 downto 0);
component c2
port(a,b,rin: in std_logic; s, rout: out std_logic);
end component;
begin
r(0)<=r0;
s(4)<=r(4);
boucle:for i in 0 to 3 generate
inst: c2 port map (rin =>r(i) , a=> a(i), b=> b(i), rout=>r(i+1), s=>s(i));
end generate;
end archi;
----------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity add4_tb is
end add4_tb;
architecture archi of add4_tb is
signal rin: std_logic;
signal entree1, entree2: std_logic_vector(3 downto 0);
signal sortie: std_logic_vector(4 downto 0);
component add4
port (r0:in std_logic;
a,b: in std_logic_vector ( 3 downto 0);
s: out std_logic_vector (4 downto 0));
end component;
begin
uut: add4 port map (a=> entree1, b => entree2, r0 => rin, s => sortie);
rin <= '0';
entree2<="1011";
stimuli: process
begin
entree1 <= "0000";
wait for 50 ns;

loop
entree1 <= entree1 + 1;
wait for 50 ns;
end loop;
end process;
end archi;
-----------------------------------

- Quelle est la structure de cette entit ?



- Que signifie std_logic_vector ?

Cest un vecteur de std_logic , cest dire un bus. La taille de ce bus est
obligatoirement spcifie.

- Que signifie downto ?

signal s : std_logic_vector(3 downto 0) ;


Cela signifie que s est un vecteur (bus) de std_logic de 4 bits, le bit de poids fort tant
situ gauche et le bit de poids faible droite.

s <="1000"; --correspond la valeur 8 en base 10 (non-sign)


Il est possible en VHDL dcrire les vecteurs dans le sens inverse (bit de poids fort
droite et bit de poids faible gauche).

Exemple :
s : std_logic_vector(0 to 3) ;
s <="1000"; --correspond la valeur 1 en base 10 (non-sign)


- A quoi sert le for generate ?

Il permet dans ce cas de simplifier lcriture du port map par une boucle. Comme il est
ncessaire de faire 4 instanciations de c2, plutt que de lcrire 4 fois, on fait une boucle
avec une variable i variant de 0 3.

- Quelle est la fonctionnalit de cette entit ?

Il sagit dun additionneur 4 bits.

- Pourquoi la sortie est sur 5 bits alors que les entres sont sur 4 ?

Le 5me bit est le bit de carry (retenue).

- Quelle alternative aurait-on pu utiliser pour concevoir la mme fonctionnalit ?

On aurait pu implanter ce circuit directement laide de portes logiques sans rutiliser
des composants prdfinis tel que nous lavons fait ici. La rutilisation permet de
simplifier la conception des circuits en crant es hirarchies de composants.

2) Recopier, compiler, crire le testbench et simuler le code du composant dcrit
ci-dessous :
----------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity addN is
generic(N: integer := 4);
port (
a,b: in std_logic_vector ( N-1 downto 0);
s: out std_logic_vector (N-1 downto 0));
end addN;
architecture archi of addN is
begin
--process(a,b)
--begin
s <= a + b ;
--end process ;
end archi;
----------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity addN_tb is
generic( N: integer:=3);
end addN_tb;
architecture archi of addN_tb is
signal entree1, entree2, sortie: std_logic_vector(N-1 downto 0);
component addN
generic(N: integer := 4);
port (a,b: in std_logic_vector ( N-1 downto 0);
s: out std_logic_vector (N-1 downto 0));
end component;
begin

uut:

addN generic map (N => N) port map (a=> entree1, b => entree2, s => sortie);

stimuli_entree1: process
begin
entree1 <= (others => '0');
wait for 50 ns;
loop
entree1 <= entree1 + 1;
wait for 50 ns;
end loop;
end process;
stimuli_entree2: process
variable temp: integer;
begin
temp:=1;
for i in 1 to N loop
temp:= temp * 2;
end loop;
for i in 0 to temp-1 loop
entree2 <= (others => '0');
wait for 50 ns;
end loop;
loop
entree2 <= entree2 + 1;
for i in 0 to temp-1 loop
wait for 50 ns;
end loop;
end loop;
end process;
end archi;
-----------------------------------

- Quelles sont les diffrences entre cette description et celle du 1) ?



Les entres/sortie sont sur le mme nombre de bits. Par consquent on perd la notion
de retenue ( carry ).
Au lieu dinstancier des blocs contenant des portes logiques, on ralise directement
laddition arithmtique entre les 2 vecteurs de bits.

- Supprimer les -- des 3 lignes en commentaire et simuler votre design : quest-
ce que vous observez ?

On observe exactement les mmes rsultats.

- La liste des signaux entre parenthses aprs process sappelle la liste de
sensibilit : enlever a ou b de cette liste et simulez votre circuit. Que peut signifier
alors liste de sensibilit ?

Si on enlve a par exemple, le process ne se dclenche plus lorsquil y a un vnement
(changement de valeur) qui se produit sur ce port.
La liste de sensibilit, cest la liste des signaux (et/ou ports) auxquels le process doit
ragir lorsquil y a un vnement.

- Modifiez la valeur de N et expliquez lintrt de generic ?

Ce terme, ajout une interface de composant, permet de rendre une description


paramtrable. Dans le cas de ladditionneur, le paramtre est N, la largeur des bus
dentres/sortie (nombre de bits).
Dans le testbench, on a ajout galement un paramtre gnrique qui va permettre de
fixer la taille de tous les signaux utiliss.
Un generic map est galement ajout linstanciation de addN afin de connecter
le N du testbench au N de addN. En modifiant simplement la valeur de N dans le
testbench, on peut passer dun additionneur 3 bits un additionneur 16 bits.
Notez galement les 2 process de gestion des stimuli sur les signaux entree1 et
entree2 ...

3) Recopier, compiler, crire le testbench et simuler le code du composant dcrit
ci-dessous :
-------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
entity sig_var is
port( d1, d2, d3:
res1, res2:
end sig_var;

in std_logic;
out std_logic);

architecture behv of sig_var is


signal sig_s1: std_logic;
begin
proc1: process(d1,d2,d3)
variable var_s1: std_logic;
begin
var_s1 := d1 and d2;
res1 <= var_s1 xor d3;
end process;
proc2: process(d1,d2,d3)
begin
sig_s1 <= d1 and d2;
res2 <= sig_s1 xor d3;
end process;
end behv;
--------------------------------------------------------

Question:

- Quelle est la diffrence entre un signal et une variable en VHDL ?
- un signal peut sutiliser hors ou dans un process
- une variable ne sutilise que dans un process
- lintrt dune variable est de stocker des rsultats de calculs temporaires que
lon veut rinjecter dans dautres calculs
- Laffectation dune valeur une variable est immdiate alors que laffectation
dune valeur un signal ne seffectue, dans un process, que lorsque celui-ci est
suspendu (cest dire lorsquil arrive un wait ou end process )

Dans lexemple du composant sig_var, on observe effectivement que les sorties res1
et res2 sont diffrentes, alors que ce sont les mmes calculs qui sont effectus. Dans le
cas du 2me process, sortie2 est le rsultat dun xor entre sig_s1 et d3. Le signal sig_s1

ntant affect que lorsque le process est suspendu, la sortie res2 prend la valeur de
sig_s1 retarde dun cycle dexcution.


4) Recopier, compiler, crire le testbench et simuler le code du composant dcrit
ci-dessous :
-------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity adder is
port( a,b: in std_logic_vector ( 3 downto 0);
s: out std_logic_vector ( 3 downto 0);
cf, ovf: out std_logic);
end adder;
architecture archi of adder is
begin
process(a,b)
variable temp: std_logic_vector(4 downto 0);
begin
temp := ( 0 & a ) + ( 0 & b ) ;
s <= temp (3 downto 0) ;
cf <= temp(4) ;
ovf <= temp(3) xor a(3) xor b(3) xor temp(4) ;
end process;
end archi;
--------------------------------------------------------

- Quelles sont les diffrences entre cette description, celle du 1) et celle du 2) ?



Il sagit dun additionneur qui utilise loprateur arithmtique + utilis dans lexercice 2,
la diffrence prs quon rcupre ici un bit de carry et un bit overflow .
Pour cela, on concatne aux 2 ports dentre a et b un 0 (on ajoute en interne 2 fils
connects la masse, soit 0 logique).

Le rsultat de laddition des 2 vecteurs ainsi obtenus est stock dans une variable sur 5
bits. Le bit de poids fort est directement utilis pour la retenue ( carry ).

Pour loverflow , on sait quil est gal la carry interne c(3) xor c(4). Comme il sagit
dune description dans laquelle on na pas directement accs la carry interne c(3), mais
que c(3) = s(3) xor a(3) xor b(3), on en dduit ainsi ovf est tel quil est crit ci-dessus.



- Quel est lintrt des flags cf et ovf ?



Carry Flag, ou CF, ou retenue, est positionn 1 lorsquil y a dpassement de capacit
pour une addition non-signe. Par exemple, pour des vecteurs de 4 bits, lorsque la
somme des 2 vecteurs est suprieure 15, CF est mis 1.

Overflow, ou OVF, ou dpassement de capacit, est positionn 1 lorsquil y a
dpassement de capacit pour une addition signe. Pour des vecteurs sur 4 bits signs,
lintervalle de dfinition est compris entre -8 et 7. Tout calcul entre 2 vecteurs qui
impliquerait un rsultat en dehors de cet intervalle entrainera un positionnement du
flag OVF 1.

NB : la reprsentation des nombres est faite en complment 2. Pour obtenir la
reprsentation ngative dun entier positif, on inverse tous les bits et on ajoute 1. Une
astuce consiste prendre le 1er bit 1 en partant de la droite et inverser tous les bits
qui suivent.


- Modifiez le format daffichage de vos signaux dans la fentre waveform et essayez
dinterprter ce que vous visualisez.
Affichage des signaux en Decimal (nombres signs)

Affichage des signaux en Unsigned (nombres non-signs)

Vous aimerez peut-être aussi