Documente Academic
Documente Profesional
Documente Cultură
VHDL Cap6
VHDL Cap6
Tehnici de bază
în modelarea VHDL
X 1 4 5 5 3
Y 2 2 2 3 2
Z 0 3 2 2 2
t1 t1+2 t1+4 t1+6
6.1 Modelarea întârzierilor (cont.)
Modelul din Figura 6.2 satisface toate restricţiile discutate mai sus.
După cum am discutat în Capitolul 4, instrucţiunile dintr-un proces
sunt întotdeauna executate în ordinea în care sunt scrise. Adică,
aceste instrucţiuni sunt instrucţiuni secvenţiale. Instrucţiunile de
asignare de semnale din procesul PROP_DELAY şi cele de asignare
de variabile din procesul INSTANTANEOUS sunt secvenţiale.
entity STATEMENTS is
port(X,Y,Z: in INTEGER; -- Porturile entitatii sunt
B: out INTEGER); -- intotdeauna semnale
end entity STATEMENTS;
architecture PROP_DELAY of STATEMENTS is
signal AS: INTEGER;
begin
process (X,Y,Z)
begin
AS <= X*Y after 2 ns; --Instructiunea (1)
B <= AS+Z after 2 ns; --Instructiunea (2)
end process;
end architecture PROP_DELAY;
6.1 Modelarea întârzierilor (cont.)
Întârziere şi concurenţă
Pentru că semnalele logice se transmit în paralel, modelele VHDL
pentru circuite logice trebuie să includă posibilitatea de concurenţă a
execuţiei. Fig. 6.3 ilustrează acest concept, folosind trei blocuri logice.
Dacă se presupune că setul de intrare 1 şi setul de intrare 2 sunt
activate simultan,blocurile logice 1 şi 2 vor fi activate în paralel. Blocul
logic 3 va fi activat de îndată ce oricare dintre ieşirile din blocul 1 (Z1)
sau din blocul 2 (Z2) se modifică. În timp ce semnalele se propagă
prin blocul logic 3, noi schimbări în semnalele de intrare se pot
propaga prin blocurile 1 şi 2. Deci, transmisia semnalelor poate avea
loc prin toate cele trei blocuri simultan.
Fig. 6.3 Transformarea
blocurilor
Set de
logice în procese.
intrare 1 Bloc logic
Z1
1
Bloc logic Ieşire
3
Set de
intrare 2 Bloc logic Z2
2
6.1 Modelarea întârzierilor (cont.)
AS <= X * Y; -- Instrucţiunea S1
BS <= AS + Z; -- Instrucţiunea S2
entity STATEMENTS is
port(X,Y,Z: in INTEGER; -- Toate porturile
-- entitatii
BS: out INTEGER); -- sunt intotdeauna
-- semnale
end entity STATEMENTS;
mecanism_de_întârziere
<= transport | [ reject expresie_time ] inertial
line_out
1000 ps
'0'
Exemplu
Figura 6.13 prezintă un proces care descrie comportarea unui
element cu întârziere asimetrică, cu timpi de întârziere diferiţi pentru
tranziţiile pozitive şi negative. Întârzierea pentru tranziţiile pozitive
este de 800 ps iar pentru cele negative este de 500 ps.
entity assym_delay is
end entity assym_delay;
architecture test of assym_delay is
signal a, z : bit;
begin
asym_delay : process (a) is
constant Tpd_01 : time := 800 ps;
constant Tpd_10 : time := 500 ps;
begin
if a = '1' then
z <= transport a after Tpd_01;
else -- a = '0'
z <= transport a after Tpd_10;
end if;
end process asym_delay;
end architecture test;
6.1 Modelarea întârzierilor (cont.)
z '0'
1000 ps
'1'
a a
y y
2 4 6 8 10 12 14 16 18 20 22 ns
2 4 6 8 10 ns
11 ns 12 ns 14 ns 15 ns 16 ns 17 ns 20 ns 25 ns
'1' 'X' '1' '0' '1' '1' '1' '0'
11 ns 12 ns 16 ns 17 ns 18 ns tranzacţie nouă
'1' 'X' '1' '1' '1'
Fig. 6.16 Tranzacţiile înainte (sus) şi după (jos) o asignare de semnal cu întârziere inerţială.
Tranzacţiile de la 20 şi 25 ns sunt şterse deoarece ele sunt planificate mai târziu decât noua
tranzacţie. Cele de la 11 şi 12 ns sunt reţinute pentru că sunt înainte de intervalul de rejecţie a
pulsului. Tranzacţiile de la 16 şi 17 ns sunt în interiorul intarvalului de rejecţie şi sunt de asemenea
reţinute. Celelalte tranzacţii din intervalul de rejecţie sunt şterse.
6.2 Modelarea circuitelor
combinaţionale şi secvenţiale
VHDL posedă elementele necesare pentru modelarea circuitelor
logice de tip combinaţional şi de tip secvenţial. În Figura 6.18
sunt reprezentate cele două cazuri: în (a) este prezentat un circuit
combinaţional la care ieşirea Z este o funcţie numai de intrarea X şi
care răspunde la schimbările lui X după o întârziere DEL.
DEL DEL
X Z X Z
(a) (b)
X(0) Z X(0) Z
X(1) MAJ3 X(1) MAJ3
X(2)
Poartă AND
Porţile logice sunt primitivele combinaţionale de bază în VHDL. În
Figura 6.21 este dezvoltat modelul pentru o poartă NAND cu două
intrări. Modelul calculează funcţia logică NAND între două semnale
de intrare şi copiază rezultatul la ieşirea O după întârzierea
generică DEL. Modelele primitive pentru celelalte porţi de bază sunt
lăsate ca exerciţii pentru cititor.
entity NAND2 is
generic(DEL: TIME);
port(I1,I2: in BIT; O: out BIT);
end entity NAND2;
architecture DF of NAND2 is
begin
O <= not(I1 and I2) after DEL;
end architecture DF;
Primitive logice (cont.)
Buffer
Primitivele buffer copiază transferă I la ieşirea O, cu condiţia
casemnalul de validare (enable) E să fie activ (în exemplul nostru '1').
Dacă intrarea E este '0', ieşirea bufferului este în starea de înaltă
impedanţă. Condiţia de înaltă impedanţă la ieşire este modelată
printr-un 1 logic. Deci, ieşirea acestui buffer poate fi conectată direct
cu ieşirea altui buffer folosind un operator AND cablat. Pentru multe
situaţii acesta este un model suficient de exact. Au fost folosite
entity BUF is
întârzieri diferite pentru validarea şi invalidarea ieşirii bufferului.
generic(DATA_DEL,Z_DEL: TIME);
port(I,EN: in BIT; O: out BIT);
end entity BUF;
architecture ALG of BUF is
begin
process(I,EN)
begin
if EN = '1' then
O <= I after DATA_DEL;
else
O <= '1' after Z_DEL;
end if;
end process;
Primitive logice (cont.)
Sumator
Primitiva de bază este reprezentată de sumatorul complet, care adună
doi biţi de date şi o intrare de transport (carry) pentru a forma o ieşire
de date şi una de transport. În Figura 6.23 este prezentat modelul flux
de date pentru un sumator complet de doi biţi. Ieşirea SUM este
funcţia paritate impară aplicată celor trei biţi de intrare. Ieşirea de
transport COUT este funcţia de decizie majoritară aplicată celor trei
intrări. Pentru modelare au fost folosite întârzieri generice diferite.
entity FULL_ADDER is
generic(SUM_DEL,CARRY_DEL:TIME);
port(A,B,CI: in BIT; SUM,COUT: out BIT);
end entity FULL_ADDER;
architecture DF of FULL_ADDER is
begin
SUM <= A xor B xor CI after SUM_DEL;
COUT <= (A and B) or (A and CI) or (B and CI)
after CARRY_DEL;
end architecture DF;
Primitive logice (cont.)
A B CI A B CI A B CI A B CI
COUT S3 S2 S1 S0
Primitive logice (cont.)
Multiplexor
De multe ori este necesar să se selecteze datele din mai multe surse
posibile. În general, numărul surselor este 2N, iar selecţia se
realizează cu ajutorul unui multiplexor 2N:1. În alte situaţii, se
multiplexează vectori de B biţi. În Figura 6.25 este prezentat modelul
VHDL pentru un multiplexor 4:1 pentru cuvinte de câte 4 biţi. Acest
multiplexor este modelat compact folosind o asignare condiţionată.
entity FOUR_TO_1_MUX is
generic(DEL: TIME);
port(IN0,IN1,IN2,IN3: in BIT_VECTOR(3 downto 0);
SEL: in BIT_VECTOR(1 downto 0);
O: out BIT_VECTOR(3 downto 0));
end entity FOUR_TO_1_MUX;
architecture DF of FOUR_TO_1_MUX is
begin
O <= IN0 after DEL when SEL = "00" else
IN1 after DEL when SEL = "01" else
IN2 after DEL when SEL = "10" else
IN3 after DEL;
end architecture DF;
Primitive logice (cont.)
Decodificator
Decodificatoarele acceptă la intrare N biţi şi activează una din cele 2 N
ieşiri. Numărul i activat la ieşire este egal cu echivalentul zecimal al
codului binar prezentat la cei N biţi de intrare. În acest sens,
decodificatorul funcţionează ca un convertor binar - zecimal.
Decodificatoarele se folosesc pentru a converti semnale care
corespund unor adrese în semnale de selecţie a unei singure linii, care
se pot folosi pentru a activa ieşirile unui singur dispozitiv. Sunt folosite
de asemenea pentru a interpreta intrări standard din câmpul cod
operaţie al instrucţiunilor sistemelor microprogramate. În Figura 6.26
este prezentat modelul VHDL pentru un decodificator cu două intrări şi
patru ieşiri.
Primitive logice (cont.)
entity TWO_TO_4_DEC is
generic(DEL: TIME);
port(I: in BIT_VECTOR(1 downto 0);
O: out BIT_VECTOR(3 downto 0));
end entity TWO_TO_4_DEC;
Registru de deplasare
Deplasările sunt operaţii importante efectuate asupra bit vectorilor
pentru că, în anumite condiţii, deplasarea la dreapta reprezintă o
împărţire la doi iar deplasarea la stânga reprezintă o înmulţire cu doi.
Într-un sens pur logic, deplasarea corespunde unei permutări a unui
cuvânt binar. În Figura 6.28 este prezentat modelul VHDL pentru un
registru de deplasare care deplasează cuvântul de intrare spre
dreapta cu o poziţie dacă SR = '1' şi SR = '0', cuvântul de
intrare este deplasat spre stânga cu o poziţie dacă SR = '0' şi SL
= '1'. Pentru celelalte două combinaţii SR SL, intrarea se transferă
neschimbată la ieşire. IL şi IR sunt valorile care se introduc în partea
stângă, respectiv dreaptă, a ieşirii deplasate. Se foloseşte operaţia de
concatenare pentru a modela deplasările.
Primitive logice (cont.)
entity SHIFTER is
generic(DEL: TIME);
port(DATA_IN: in BIT_VECTOR(3 downto 0);
SR,SL: in BIT; IL,IR: in BIT;
DATA_OUT: out BIT_VECTOR(3 downto 0));
end entity SHIFTER;
architecture ALG of SHIFTER is
begin
process(SR,SL,DATA_IN,IL,IR)
variable CON: BIT_VECTOR(0 to 1);
begin
CON := SR&SL;
case CON is
when "00" => DATA_OUT <= DATA_IN after DEL;
when "01" => DATA_OUT <= DATA_IN(2 downto 0) & IL
after DEL;
when "10" => DATA_OUT <= IR & DATA_IN(3 downto 1)
after DEL;
when "11" => DATA_OUT <= DATA_IN after DEL;
end case;
end process;
end architecture ALG;
Primitive logice (cont.)
Flip-flop
Circuitele bistabile (flip-flop) reprezintă primitivele secvenţiale de
bază. În Figura 6.34 se prezintă modelul algoritmic al unui flip-flop de
tip JK. Setarea şi resetarea sunt operaţii prioritare faţă de operarea
normală prin intermediul semnalului de ceas. Dacă R = S = 1, nu
se întâmplă nimic. Pentru că aceasta este o condiţie ilegală, ieşirea,
în general, nu se specifică. Deci, modul de funcţionare "nu se
întâmplă nimic" este consistent cu specificaţia.
Registru
Registrele se pot folosi pentru a memora date. Deşi pot fi construite
modele structurale ale registrelor pornind de la primitive cum sunt
bistabile şi porţi logice, vom elabora un model comportamental pentru
un astfel de registru (Figura 6.35). Registrul este în întregime sincron,
adică atât funcţia de reset cât şi aceea de încărcare paralelă (load)
sunt sincrone, având prioritate reset. Alte modele pot considera
reset ca fiind asincron în raport cu semnalul de ceas. Folosirea
registrelor care sunt total sincrone conduce la evitarea erorilor de
temporizare. Registrul prezentat este un registru controlat, adică va fi
încărcat numai atunci când LOAD = '1', pe frontul activ (crescător)
al semnalului de ceas. Se foloseşte un bloc gardat (vezi paragraful
următor). Având un semnal de control (LOAD) registrul este mai uşor
de controlat cu semnale generate de o unitate de control (Capitolul 8).
Primitive logice (cont.)
entity REG is
generic(DEL: TIME);
port(RESET,LOAD,CLK: in BIT;
DATA_IN: in BIT_VECTOR(3 downto 0);
Q: inout BIT_VECTOR(3 downto 0));
end entity REG;
architecture DF of REG is
begin
REG: block(not CLK'STABLE and CLK ='1')
begin
Q <= guarded "0000" after DEL when RESET ='1' else
DATA_IN after DEL when LOAD ='1' else
Q;
end block REG;
end architecture DF;
Primitive logice (cont.)
Latch
Registrul de mai sus, comandat de un semnal de ceas, preia
eşantioane ale intrărilor şi actualizează ieşirile în momentul când
apare o tranziţie pozitivă în semnalul de ceas. O altă formă a unui
element de memorare, similar unui registru, este latch-ul, a cărui ieşire
preia valoarea de la intrare atunci când ceasul este activ; el
memorează valoarea intrării atunci când semnalul de ceas este
dezactivat. Deci, când ceasul este valid, un latch acţionează ca un
buffer logic, iar după următoarea tranziţie el funcţionează ca un
element de memorie. Latchurile au un avantaj important faţă de
elementele de memorie acţionate pe front: noile valori apar mai
devreme, aşa încât se reduc întârzierile în propagare. În Figura 6.36
am prezentat descrierea VHDL pentru un latch.
Primitive logice (cont.)
Atunci când garda (CLK) pentru blocul LATCH trece în '1', valoarea lui D este
transferată la LOUT, după LATCH_DEL şi oricare schimbare ulterioară în D se
va transfera la LOUT atâta timp cât CLK este '1'. Când CLK devine zero,
instrucţiunea gardată este dezactivată iar semnalul LOUT îşi menţine ultima
valoare obţinută pe durata cât CLK a fost '1'. În Figura 6.37 am prezentat
formele de undă explicative pentru funcţionarea unui latch, pentru care
LATCH_DEL = 10 ns.
entity LATCH is
generic(LATCH_DEL:TIME);
port(D: in BIT_VECTOR(7 downto 0);
CLK: in BIT; LOUT: out BIT_VECTOR(7 downto 0));
end entity LATCH;
architecture DFLOW of LATCH is
begin
LATCH: block(CLK = '1')
begin
LOUT <= guarded D after LATCH_DEL;
end block LATCH;
end architecture DFLOW;
Primitive logice (cont.)
CLK
LOUT
Registru de deplasare
Registrele de deplasare sunt elemente importante pentru efectuarea
operaţiilor asupra datelor. În Figura 6.38 se prezintă un model pentru
această primitivă. Se observă că elementul poate fi încărcat (LOAD = '1'),
conţinutul lui se poate deplasa la dreapta (SR = '1' şi SL = '0') sau se poate
deplasa la stâng (SR = '0' şi SL = '1'). IR şi IL sunt intrări seriale pentru
deplasarea la dreapta/stânga. Încărcarea paralelă are prioritate faţă de
deplasare.
entity SHIFTREG is
generic(DEL: TIME);
port(DATA_IN: in BIT_VECTOR(3 downto 0);
CLK,LOAD,SR,SL: in BIT; IL,IR: in BIT;
Q: inout BIT_VECTOR(3 downto 0));
end entity SHIFTREG;
architecture DF of SHIFTREG is
begin
SH:block(not CLK'STABLE and CLK ='1')
begin
Q <= guarded DATA_IN after DEL when LOAD= '1' else
Q(2 downto 0) & IL after DEL when SL='1' and SR='0' else
IR & Q(3 downto 1) after DEL when SL='0' and SR='1' else
Q;
end block SH;
end architecture DF;