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)