Sunteți pe pagina 1din 24

1

INSTRUCIUNI SECVENIALE N LIMBAJUL VHDL

O descriere n limbajul VHDL are dou domenii: un domeniu secvenial i un domeniu concurent. Domeniul secvenial este reprezentat de un proces sau subprogram care conine instruciuni secveniale. Aceste instruciuni sunt executate n ordinea n care apar n cadrul procesului sau subprogramului, ca i n cazul limbajelor de programare. Domeniul concurent este reprezentat de o arhitectur, care conine procese, apeluri concurente de proceduri, asi gnri concurente ale semnalelor i instanieri de componente. Toate activitile descrise de acestea au loc simultan. n aceast lucrare se descrie formatul i modul de utilizare al unor instruciuni secveniale. Sunt prezentate unele probleme legate de sinteza logic a instruciunilor secveniale i sunt ilustrate circuitele sintetizate din aceste instruciuni. n seciunile urmtoare se descriu mai nti unele aspecte legate de procese, cum sunt modul de specificare al unui proces, execuia unui proces, instruciunea wait i deosebirea dintre procesele combinaionale i cele secveniale. Sunt prezentate apoi instruciunile secve niale care pot apare ntr-un proces sau subprogram: asignarea secvenial a semnalelor, asignarea variabilelor, instruciunea if, instruciunea case i instruciunile de buclare. Pe lng acestea, alte instruciuni secveniale sunt instruciunea de apel a unei proceduri i instruciunea de revenire dintr-o procedur sau funcie.

1. Sintaxa i utilizarea instruciunilor secveniale


1.1. Procese
Un proces este o secven de instruciuni care sunt executate n ordinea specificat. Declaraia unui proces delimiteaz un domeniu secvenial al arhitecturii n care apare declar aia. Procesele se utilizeaz pentru descrieri funcionale.

1.1.1. Structura i execuia unui proces


Un proces poate apare oriunde n corpul unei arhitecturi (partea care ncepe dup c uvntul cheie begin). Structura de baz a declaraiei unui proces este urmtoarea:
[nume:] process [(list_de_sensibilitate)] [declaraii_de_tipuri] [declaraii_de_constante] [declaraii_de_variabile] [declaraii_de_subprograme] begin instruciuni_secveniale end process [nume];

Declaraia unui proces este cuprins ntre cuvintele cheie process i end process. Unui proces i se poate asigna n mod opional un nume pentru identificarea mai uoar a pr ocesului n textul surs. Numele este un identificator i trebuie urmat de caracterul ':' (cu rol de etichet). Acest nume este util i pentru simulare, de exemplu, pentru setarea u nui punct de ntrerupere a execuiei simulrii. Numele poate fi repetat la sfritul declaraiei, dup cuvint ele cheie end process. Lista de sensibilitate (opional) este lista semnalelor la a cror modificare procesul este sensibil. Producerea unui eveniment asupra unuia din semnalele specificate n lista de sensibilitate va determina execuia instruciunilor secveniale din cadrul procesului, similar cu

Structura sistemelor de calcul

instruciunile dintr-un program obinuit. Spre deosebire de un limbaj de programare, n limbajul VHDL clauza end process nu specific terminarea execuiei procesului. Procesul va fi executat ntr-un ciclu infinit, iar n cazul n care se specific o list de sensibilitate, procesul va fi doar suspendat dup execuia ultimei instruciuni, pn la producerea unui nou eveniment asupra semnalelor din list. Se menioneaz c un eveniment are loc numai la modific area valorii unui semnal. Astfel, asignarea aceleiai valori la un semnal nu reprezint un ev eniment. n cazul n care lista de sensibilitate lipsete, procesul va fi executat n mod continuu. n acest caz, procesul trebuie s conin o instruciune wait pentru a determina suspendarea procesului i activarea acestuia la apariia unui eveniment sau ndeplinirea unei condiii. n cazul n care lista de sensibilitate este prezent, procesul nu poate conine instruciuni wait. Instruciunea wait este prezentat n seciunea 1.1.2. Partea declarativ a procesului este cuprins ntre cuvintele cheie process i begin. n aceast parte se pot declara tipuri, constante, variabile i subprograme (proceduri i funcii) care sunt locale procesului. Elementele declarate se pot utiliza deci numai n interiorul procesului.

Observaie
n interiorul unui proces nu pot fi declarate semnale, ci numai constante i variabile. Partea de instruciuni a procesului ncepe dup cuvntul cheie begin. Aceast parte conine instruciunile care vor fi executate la fiecare activare a procesului. Nu este permis utilizarea instruciunilor concurente n interiorul unui proces. n Exemplul 1 se prezint declaraia unui proces simplu format dintr -o singur instruciune de asignare secvenial.

Exemplul 1
proc1: process (a, b, c) begin x <= a and b and c; end process proc1;

1.1.2. Instruciunea wait


n locul unei liste de sensibilitate, un proces poate conine o instruciune wait. Utilizarea unei instruciuni wait are dou scopuri: Suspendarea execuiei unui proces; Specificarea condiiei care va determina activarea procesului suspendat. La ntlnirea unei instruciuni wait, procesul n care apare aceast instruciune este suspendat. Atunci cnd se ndeplinete condiia specificat n cadrul instruciunii wait, procesul este activat i se execut instruciunile acestuia pn cnd se ntlnete din nou instru ciunea wait. Limbajul VHDL permite ca un proces s conin mai multe instruciuni wait. Atunci cnd se utilizeaz pentru modelarea logicii combinaionale n vederea sintezei, un pr oces poate conine ns o singur instruciune wait. Dac un proces conine o instruciune wait, nu poate conine o list de sensibilitate. Procesul din Exemplul 2, care conine o instruciune wait explicit, este echivalent cu procesul din Exemplul 1, care conine o list de sensibilitate. Ambele procese se vor executa atunci cnd apare o modificare a valorii semnalelor a, b sau c.

Instruciuni secveniale n limbajul VHDL

Exemplul 2
proc2: process begin x <= a and b and c; wait on a, b, c; end process proc2;

Formele instruciunii wait


Exist trei forme ale instruciunii wait:
wait on list_de_sensibilitate; wait until expresie_condiional; wait for expresie_de_timp;

Instruciunea wait on a fost ilustrat n exemplele precedente. Instruciunea wait until suspend un proces pn cnd condiia specificat devine adevrat datorit modificrii unuia din semnalele care apar n expresia condiional. Se menioneaz c dac nici un semnal din aceast expresie nu se modific, procesul nu va fi activat, chiar dac expresia condiional este adevrat. Exemplele urmtoare prezint mai multe forme ale instruciunii wait until:
wait until semnal = valoare; wait until semnalevent and semnal = valoare; wait until not semnalstable and semnal = valoare;

unde semnal este numele unui semnal, iar valoare este valoarea care se testeaz. Dac semnalul este de tip bit, atunci pentru valoarea '1' se ateapt frontul cresctor al semnalului, iar pentru '0' frontul descresctor. Instruciunea wait until se poate utiliza pentru implementarea unei funcionri sincrone. n mod obinuit, semnalul testat este un semnal de ceas. De exemplu, ateptarea frontului cresctor al unui semnal de ceas se poate exprima n urmtoarele moduri:
wait until clk = '1'; wait until clk'event and clk = '1'; wait until not clk'stable and clk = '1';

Pentru descrierile destinate sintezei, instruciunea wait until trebuie s fie prima din cadrul procesului. Din aceast cauz, logica sincron descris cu o instruciune wait until nu poate fi resetat n mod asincron. Instruciunea wait for permite suspendarea execuiei unui proces pentru un timp specificat, de exemplu:
wait for 10 ns;

Observaie
Forma wait for expresie_de_timp a instruciunii wait nu se poate utiliza pentru sintez. Se pot combina mai multe condiii ale instruciunii wait ntr-o condiie mixt. n Exemplul 3, procesul proc3 va fi activat la modificarea valorii unuia din semnalele a sau b, dar numai atunci cnd valoarea semnalului clk este '1'.

Exemplul 3
proc3: process begin wait on a, b until clk = '1'; ... end process proc3;

Structura sistemelor de calcul

Poziia instruciunii wait


De obicei, instruciunea wait apare fie la nceputul unui proces, fie la sfritul acestuia. n Exemplul 2, instruciunea wait apare la sfritul procesului. Aceast form a procesului este echivalent cu forma care conine o list de sensibilitate. Aceast echivalen se dat oreaz modului n care se execut simularea unui model. n faza de iniializare a simulrii, se execut toate procesele modelului. Dac procesul conine o list de sensibilitate, toate instru ciunile procesului vor fi executate o singur dat. n forma procesului care conine o instruciune wait i aceasta apare la sfrit, n faza de iniializare se execut o singur dat toate i nstruciunile pn la instruciunea wait, ca i n cazul formei care conine o list de sensibilitate. n cazul n care instruciunea wait apare la nceputul procesului, simularea se va executa n mod diferit, deoarece n faza de iniializare procesul va fi suspendat fr a se executa nici o instruciune a acestuia. Deci, un proces cu instruciunea wait plasat la nceput nu este echivalent cu un proces care conine o list de sensibilitate. Deoarece faza de iniializare a simulrii nu are echivalent hardware, nu vor exista diferene la sinteza celor dou procese cu instruciunea wait plasat la sfrit, respectiv la nceput. Totui, din cauza diferenei ntre simulare i sintez n ceea ce privete faza de inii alizare a simulrii, pot exista diferene ntre funcionarea modelului la simulare i funcionarea circuitului rezultat prin sintez. Este posibil ca modelul care funcioneaz corect la si mulare s fie sintetizat ntr-un circuit a crui funcionare este eronat.

1.2. Instruciunea secvenial de asignare a semnalelor


Semnalele reprezint interfaa dintre domeniul concurent al unui model n limbajul VHDL i domeniul secvenial din cadrul unui proces. Un model VHDL este format dintr-un numr de procese care comunic ntre ele prin intermediul semnalelor. La simulare, ntreaga ierarhie din cadrul modelului este eliminat, rmnnd numai procesele i semnalele. Simul atorul execut n mod alternativ actualizarea valorii unor semnale i rularea proceselor activate de modificarea valorii semnalelor aflate n listele lor de sensibilitate. Asignarea valorilor la semnale se poate realiza printr-o instruciune secvenial sau o instruciune concurent. Instruciunea secvenial poate apare doar n interiorul unui proces, iar cea concurent poate apare doar n exteriorul proceselor. Instruciunea secvenial de asi gnare are o singur form, cea simpl, care este o asignare necondiionat. Instruciunea concurent are, pe lng forma sa simpl, nc dou forme: asignarea condiional i asignarea selectiv. Instruciunea secvenial de asignare a unui semnal are sintaxa urmtoare:
semnal <= expresie [after ntrziere];

Ca rezultat al execuiei acestei instruciuni ntr-un proces, se evalueaz expresia din dreapta simbolului de asignare i se planific un eveniment care const din modificarea val orii semnalului. Simulatorul va modifica ns valoarea semnalului doar n momentul n care procesul va fi suspendat, iar n cazul n care se utilizeaz clauza after, dup ntrzierea specificat din acest moment. Deci, ntr-un proces semnalele vor fi actualizate doar dup execuia tuturor instruciunilor din cadrul procesului sau la ntlnirea unei instruciuni wait. n mod tipic, sistemele de sintez nu permit utilizarea clauzelor after, sau ignor aceste clauze. Clauzele after sunt ignorate nu numai deoarece interpretarea lor pentru sintez nu este specificat de standarde, ci i pentru c ar fi dificil garanta rea rezultatelor unor asemenea ntrzieri. De exemplu, nu este clar dac ntrzierea ar trebui interpretat ca o nt rziere de propagare minim sau maxim. De asemenea, nu este clar cum trebuie s procedeze programul de sintez dac o ntrziere specificat n codul surs nu poate fi asigurat. O consecin a modului n care se execut asignarea semnalelor n cadrul proceselor este c n cazul n care exist mai multe asignri a unor valori diferite la acelai semnal, va avea efect doar ultima asignare. Astfel, cele dou procese din Exemplul 4 sunt echivalente.

Instruciuni secveniale n limbajul VHDL

Exemplul 4
proc4: process (a) begin z <= '0'; z <= a; end process proc4; proc5: process (a) begin z <= a; end process proc5;

n concluzie, trebuie s se in cont de urmtoarele aspecte importante la utilizarea instruciunilor de asignare a semnalelor n interiorul proceselor: Orice asignare a unei valori la un semnal devine efectiv numai atunci cnd procesul este suspendat. Pn n acel moment, toate semnalele i pstreaz vechea valoare. Numai ultima asignare a unei valori la un semnal va fi executat efectiv. Deci, nu are sens s se asigneze mai mult de o valoare la un semnal n acelai proces.

1.3. Variabile
Restriciile impuse asupra semnalelor reduc posibilitile de utilizare ale acestora. Deoarece semnalele pot pstra numai ultima valoare asignat, ele nu pot fi utilizate pentru memorarea rezultatelor intermediare sau temporare n cadrul unui proces. Un alt inconvenient este c noile valori sunt asignate semnalelor nu n momentul execuiei instruciunii de asignare, ci dup suspendarea execuiei procesului. Aceasta determin ca analiza unei descrieri s fie dificil. Spre deosebire de semnale, variabilele pot fi declarate n interiorul unui proces i se pot utiliza pentru memorarea rezultatelor intermediare. Variabilele pot fi utilizate ns numai n domeniul secvenial al limbajului VHDL, deci n interiorul proceselor sau subprogramelor, i nu pot fi declarate sau utilizate direct ntr-o arhitectur. Ele sunt deci locale procesului sau subprogramului respectiv.

1.3.1. Declararea i iniializarea variabilelor


Ca i semnalele, variabilele trebuie declarate nainte de a fi utilizate. Declaraia unei variabile este similar cu cea a unui semnal, cu deosebirea c se utilizeaz cuvntul cheie variable. Aceast declaraie specific tipul variabilei. n mod opional, n cazul variabilelor scalare se poate specifica un domeniu restrns, iar n cazul variabilelor de tip tablou se poate specifica un index restrns. Pentru ambele tipuri de variabile, se poate specifica o valoare iniial. Exemplul 5 ilustreaz declararea i iniializarea variabilelor.

Exemplul 5
variable variable variable variable variable a, b, c: bit; x, y: integer; index integer range 1 to 10 := 1; t_ciclu: time range 10 ns to 50 ns := 10 ns; mem: bit_vector (0 to 15);

Unei variabile i se atribuie o valoare iniial n faza de iniializare a simulrii. Aceast valoare iniial este fie cea specificat n mod explicit la declararea variabilei, fie o valoare implicit, care este valoarea cea mai din stnga a tipului. De exemplu, pentru tipul bit valoarea iniial implicit este '0', iar pentru tipul integer aceast valoare este -2.147.483.647.

Structura sistemelor de calcul

1.3.2. Instruciunea de asignare a variabilelor


O instruciune de asignare a unei variabile nlocuiete valoarea curent a variabilei cu o nou valoare specificat de o expresie. Expresia poate conine variabile, semnale i literale. Variabila i rezultatul evalurii expresiei trebuie s fie de acelai tip. Instruciunea de asignare a unei variabile are sintaxa urmtoare:
variabil := expresie;

Aceast instruciune este similar cu asignrile din majoritatea limbajelor de progr amare. Spre deosebire de o instruciune secvenial de asignare a semnalelor, asignarea unei variabile este executat instantaneu, deci ntr-un timp de simulare zero. Exist urmtoarele deosebiri principale ntre asignarea semnalelor i a variabilelor: n cazul asignrii semnalelor, se planific un eveniment pentru actualizarea valorii acestora, iar actualizarea se execut numai la suspendarea procesului, n timp ce pe ntru asignarea variabilelor nu se planific un eveniment, iar actualizarea se execut i nstantaneu. La asignarea semnalelor se poate specifica o ntrziere (numai pentru simulare), n timp ce asignarea variabilelor nu poate fi ntrziat. ntr-un proces, doar ultima asignare a unei valori la un semnal este efectiv. n schimb, pot exista numeroase asignri la o variabil n acelai proces, toate fiind efective. Exemplul 6 ilustreaz utilizarea variabilelor pentru memorarea rezultatelor intermediare.

Exemplul 6
library ieee; use ieee.std_logic_1164.all; entity add_1 is port (a, b, cin: in std_logic; s, cout: out std_logic); end add_1; architecture functional of add_1 is begin process (a, b, cin) variable s1, s2, c1, c2: std_logic; begin s1 := a xor b; c1 := a and b; s2 := s1 xor cin; c2 := s1 and cin; s <= s2; cout <= c1 or c2; end process; end functional;

Exemplul anterior descrie un sumator elementar. Acesta nu este modul optim de a descrie un sumator elementar, dar ilustreaz utilizarea variabilelor. Rezultatul se genereaz prin crearea a dou semisumatoare, primul genernd ieirile s1 i c1, iar al doilea genernd ieirile s2 i c2. n final, ieirile sunt asignate celor dou porturi de ieire s i cout prin instruciuni de asignare a semnalelor, deoarece porturile sunt semnale.

Instruciuni secveniale n limbajul VHDL

1.4. Instruciunea if
Instruciunea if selecteaz pentru execuie una sau mai multe secvene de instruciuni, n funcie de valoarea unei condiii corespunztoare secvenei respective. Sintaxa acestei instruciuni este urmtoarea:
if condiie then secven_de_instruciuni [elsif condiie then secven_de_instruciuni ...] [else secven_de_instruciuni] end if;

Fiecare condiie este o expresie boolean, care se evalueaz la valoarea TRUE sau FALSE. Pot exista mai multe clauze elsif, dar poate exista o singur clauz else. Se evalueaz mai nti condiia de dup cuvntul cheie if, i dac este adevrat, se execut secvena de instruciuni corespunztoare. n caz contrar, dac este prezent clauza elsif, se evalueaz condiia de dup aceast clauz i dac aceast condiie este adevrat, se execut secvena de instruciuni corespunztoare. n caz contrar, dac sunt prezente alte clauze elsif, se continu cu evaluarea condiiei acestor clauze. Dac nici o condiie evaluat nu este adevrat, se ex ecut secvena de instruciuni corespunztoare clauzei else, dac aceasta este prezent.

Exemplul 7
process (a, b) begin if a = b then rez <= 0; elsif a < b then rez <= -1; else rez <= 1; end if; end process;

1.5. Instruciunea case


Ca i instruciunea if, instruciunea case selecteaz pentru execuie una din mai multe secvene alternative de instruciuni pe baza valorii unei expresii. Spre deosebire de i nstruciunea if, n cazul instruciunii case expresia nu trebuie s fie boolean, ci poate fi reprezentat de un semnal, o variabil sau o expresie de orice tip discret (un tip enumerat sau ntreg) sau un tablou unidimensional de caractere (inclusiv bit_vector sau std_logic_vector). Instruciunea case se utilizeaz atunci cnd exist un numr mare de alternative posibile. Aceast instruciune este mai lizibil dect o instruciune if cu un numr mare de ramuri, permind identificarea uoar a unei valori i a secvenei de instruciuni as ociate. Sintaxa instruciunii case este urmtoarea:
case expresie is when opiuni_1 => secven_de_instruciuni ... when opiuni_n => secven_de_instruciuni [when others => secven_de_instruciuni] end case;

Instruciunea case conine mai multe clauze when, fiecare specificnd una sau mai multe opiuni. Opiunile reprezint fie o valoare individual, fie un set de valori cu care se compar expresia instruciunii case. n cazul n care expresia este egal cu valoarea individual sau cu una din valorile setului, se execut secvena de instruciuni specificat dup simb o-

Structura sistemelor de calcul

lul =>. O secven de instruciuni poate fi format i din instruciunea nul, null. Spre deosebire de anumite limbaje de programare, instruciunile dintr-o secven nu trebuie incluse ntre cuvintele cheie begin i end. Clauza others se poate utiliza pentru a specifica execuia unei secvene de instruciuni n cazul n care valoarea expresiei nu este egal cu nici una din valorile specificate n clauzele when. n cazul n care o opiune este reprezentat de un set de valori, se pot specifica fie valorile individuale din set, separate prin simbolul | avnd semnificaia sau, fie domeniul valorilor, fie o combinaie a acestora, dup cum se arat n exemplul urmtor.
case expresie is when val => secven_de_instruciuni when val1 | val2 | ... | valn => secven_de_instruciuni when val3 to val4 => secven_de_instruciuni when val5 to val6 | val7 to val8 => secven_de_instruciuni ... when others => secven_de_instruciuni end case;

Observaii
ntr-o instruciune case trebuie enumerate toate valorile posibile pe care le poate avea expresia de selecie, innd cont de tipul sau subtipul acesteia. De exemplu, dac expresia de selecie este de tip std_logic_vector de doi bii, trebuie enumerate 81 de valori, deoarece pentru un singur bit pot exista nou valori posibile. Dac nu sunt enumerate toate valorile, trebuie utilizat clauza others. Clauza others trebuie s fie ultima dintre toate opiunile. Exemplul 8 prezint un proces pentru secvenierea valorilor unui tip enumerat reprezentnd strile unui semafor. Procesul este descris cu ajutorul unei instruciuni case.

Exemplul 8
type tip_culoare is (rosu, galben, verde); signal culoare, culoare_urm: tip_culoare; process (culoare) case culoare is when rosu => culoare_urm <= verde; when galben => culoare_urm <= rosu; when verde => culoare_urm <= galben; end case; end process;

Exemplul 9 definete o entitate i o arhitectur pentru o poart SAU EXCLUSIV cu dou intrri. Poarta este descris n mod funcional cu ajutorul unui proces care conine o i nstruciune case.

Exemplul 9
library ieee; use ieee.std_logic_1164.all; entity xor_2 is port (a, b: in std_logic;

Instruciuni secveniale n limbajul VHDL

x: out std_logic); end xor_2; architecture arh_xor_2 of xor_2 is begin process (a, b) variable tmp: std_logic_vector (1 downto 0); begin tmp := a & b; case tmp is when "00" => x <= '0'; when "01" => x <= '1'; when "10" => x <= '1'; when "11" => x <= '0'; when others => x <= '0'; end case; end process; end arh_xor_2;

1.6. Instruciuni de buclare


Instruciunile de buclare permit execuia repetat a unei secvene de instruciuni, de exemplu, prelucrarea fiecrui element al unui tablou n acelai mod. n limbajul VHDL, exist trei tipuri de instruciuni de buclare: instruciunea de buclare simpl loop, instruciunea while loop i instruciunea for loop. Instruciunea de buclare simpl loop specific repetarea unor instruciuni n mod nedefinit. n cazul instruciunii while loop, instruciunile care formeaz corpul buclei sunt repetate ct timp condiia specificat este adevrat, iar n cazul instruciunii for loop instruciunile din corpul buclei sunt repetate de un numr de ori specificat de un contor.

Observaie
Singura instruciune de buclare care poate fi utilizat pentru sinteza logic este instruciunea for loop, deoarece la aceasta numrul de iteraii este fix.

1.6.1. Instruciunea loop


Instruciunea de buclare simpl loop are sintaxa urmtoare:
[etichet:] loop secven_de_instruciuni end loop [etichet];

Instruciunea are o etichet opional, care poate fi utilizat pentru identificarea i nstruciunii. Instruciunea loop are ca efect repetarea instruciunilor din corpul buclei de un numr nelimitat de ori. n cazul acestei instruciuni, singura posibilitate de terminare a execuiei este utilizarea unei instruciuni exit (prezentat n seciunea 1.6.5).

1.6.2. Instruciunea while loop


Instruciunea while loop este o instruciune de buclare condiionat. Sintaxa acestei instruciuni este urmtoarea:
[etichet:] while condiie loop secven_de_instruciuni end loop [etichet];

Condiia este testat naintea fiecrei execuii a buclei. Dac aceast condiie este adevrat, se execut secvena de instruciuni din corpul buclei, dup care controlul este tran s-

10

Structura sistemelor de calcul

ferat la nceputul buclei. Execuia buclei se termin atunci cnd condiia testat devine fals, caz n care se execut instruciunea care urmeaz dup clauza end loop.

Exemplul 10
process variable contor: integer := 0; begin wait until clk = '1'; while nivel = '1' loop contor := contor + 1; wait until clk = '0'; end loop; end process;

n procesul din Exemplul 10 se numr fronturile cresctoare ale semnalului de ceas


clk att timp ct semnalul nivel are valoarea '1'. Stabilitatea semnalului nivel nu este tes-

tat. Se testeaz doar dac acest semnal are valoarea '1' la detectarea unui front cresctor al semnalului clk, i nu se testeaz dac valoarea semnalului nivel s-a modificat de la testarea anterioar. Instruciunile de buclare pot fi imbricate pe mai multe nivele. Deci, corpul buclei unei instruciuni while loop poate conine o alt instruciune de buclare, n particular o instruc iune while loop, dup cum se arat n exemplul urmtor.
E1: E2: while i < 10 loop while j < 20 loop ... end loop E2; end loop E1;

1.6.3. Instruciunea for loop


Pentru execuia repetat a unei secvene de instruciuni de un numr de ori specificat se poate utiliza instruciunea for loop. Sintaxa acestei instruciuni este urmtoarea:
[etichet:] for contor in domeniu loop secven_de_instruciuni end loop [etichet];

ntr-o instruciune for loop se specific un contor de iteraii i un domeniu. Instruciunile din corpul buclei sunt executate ct timp contorul se afl n domeniul specificat. Dup terminarea unei iteraii, contorului i se asigneaz urmtoarea valoare din domeniu. Domeniul poate fi unul cresctor, specificat prin cuvntul cheie to, sau descresctor, specificat prin cuvntul cheie downto. Acest domeniu poate fi specificat i sub forma unui tip enumerat sau subtip, caz n care nu se specific n mod explicit limitele domeniului n cadrul instruciunii for loop. Limitele domeniului vor fi determinate de compilator din declaraia tipului sau subtipului respectiv. Instruciunea for loop din Exemplul 11 calculeaz ptratele valorilor ntregi cuprinse ntre 1 i 10, pe care le depune n tabloul i_patrat.

Exemplul 11
for i in 1 to 10 loop i_patrat (i) <= i * i; end loop;

Contorul de iteraii din acest exemplu este n mod implicit de tip integer, deoarece tipul acestuia nu a fost definit n mod explicit. Forma complet a declaraiei domeniului pe ntru contorul de iteraii este similar cu cea a unui tip. Pentru exemplul anterior, clauza for poate fi scris i sub forma urmtoare:

Instruciuni secveniale n limbajul VHDL

11

for i in integer range 1 to 10 loop

n unele limbaje de programare, n cadrul buclei se poate asigna o valoare contorului de iteraii (n exemplul anterior, i) pentru a-i modifica valoarea. Limbajul VHDL nu permite ns asignarea unei valori contorului de iteraii sau utilizarea acestuia ca parametru de intrare sau de ieire al unei proceduri. Contorul poate fi utilizat ns ntr -o expresie, cu condiia s nu i se modifice valoarea. Un alt aspect legat de contorul de iteraii este c acesta n u trebuie declarat n mod explicit n cadrul procesului. Acest contor este declarat n mod implicit ca o variabil local a instruciunii de buclare prin specificarea sa dup cuvntul cheie for. Dac exist o alt variabil cu acelai nume n cadrul procesului, cele dou vor fi tratate ca variabile separate. Din cauza interpretrii sintezei instruciunii for loop (descris n seciunea 2.8), limitele domeniului buclei trebuie s fie constante. Aceasta nseamn c limitele nu pot fi def inite utiliznd valoarea unei variabile sau semnal. Aceast restricie determin ca descrierea unor circuite s fie dificil. De exemplu, considerm cazul n care trebuie contorizat numrul de zerouri de la nceputul unei valori ntregi, i deci numrul de iteraii necesar nu este cunoscut dinainte. Descrierea unor asemenea circuite cu ajutorul instruciunilor de buclare este facilitat prin utilizarea instruciunilor next i exit.

1.6.4. Instruciunea next


Exist situaii n care este necesar oprirea execuiei instruciunilor dintr-o bucl n iteraia curent i trecerea la urmtoarea iteraie. Pentru aceasta se poate utiliza instruciunea next. Sintaxa acestei instruciuni este urmtoarea:
next [etichet] [when condiie];

La ntlnirea unei instruciuni next n cadrul corpului unei bucle, execuia iteraiei curente este oprit i controlul este transferat la nceputul instruciunii de buclare, fie necondiionat, dac clauza when nu este prezent, fie condiionat, dac aceast clauz este prezent. Contorul de iteraii va fi actualizat, iar dac limita domeniului nu a fost atins, execuia va continua cu prima instruciune din corpul buclei. n caz contrar, execuia instruciunii de b uclare se va termina. n cazul n care exist mai multe nivele de instruciuni de buclare (o bucl coninut ntr-o alt bucl), n cadrul instruciunii next se poate specifica o etichet, aceasta fiind eticheta instruciunii de buclare de nivel imediat superior n care este cuprins instruciunea next. Aceast etichet are doar rolul de a crete claritatea descrierii i nu poate fi diferit de cea a instruciunii de buclare curente. O instruciune next se poate utiliza n locul unei instruciuni if pentru execuia condiionat a unui grup de instruciuni. Utilizarea instruciunii next este ilustrat n seciunea 2.9.

1.6.5. Instruciunea exit


Exist situaii n care execuia unei instruciuni de buclare trebuie oprit complet, fie datorit apariiei unei erori n timpul execuiei unui model, fie datorit faptului c prelucrarea trebuie terminat naintea depirii domeniului de ctre contorul de iteraii. n asemenea situaii, se poate utiliza instruciunea exit. Sintaxa acestei instruciuni este urmtoarea:
exit [etichet] [when condiie];

Exist trei forme ale instruciunii exit. Prima este cea n care nu apare o etichet i nici o condiie specificat printr-o clauz when. n acest caz, se va opri n mod necondiionat execuia instruciunii curente de buclare. n cazul n care instruciunea exit apare ntr-o instruciune de buclare aflat n interiorul unei alte instruciuni de buclare, va fi oprit doar ex ecuia instruciunii interioare de buclare, dar execuia instruciunii exterioare de buclare va continua.

12

Structura sistemelor de calcul

Dac n instruciunea exit se specific o etichet a unei instruciuni de buclare, la ntlnirea instruciunii exit controlul va fi transferat la eticheta specificat. Dac instruciunea exit conine o clauz when, execuia instruciunii de buclare va fi oprit numai n cazul n care condiia specificat de aceast clauz este adevrat. Urmtoarea instruciune executat depinde de prezena sau absena unei etichete n cadrul instruciunii. Dac se specific o etichet a unei instruciuni de buclare, urmtoarea instruciune executat va fi prima din instruciunea de buclare specificat de acea etichet. Dac nu se specific o etichet, urmtoarea instruciune executat va fi cea de dup clauza end loop a instruciunii de buclare curente. Instruciunea exit se poate utiliza pentru a termina execuia unei instruciuni loop simple, dup cum se arat n Exemplul 12.

Exemplul 12
E3: loop a := a + 1; exit E3 when a > 10; end loop E3;

2. Sinteza instruciunilor secveniale


2.1. Procese cu liste de sensibilitate incomplete
Unele programe utilitare de sintez nu verific listele de sensibilitate ale proceselor. Aceste utilitare presupun c toate semnalele din partea dreapt a asignrilor secveniale la semnale se afl n lista de sensibilitate. Astfel, aceste utilitare vor interpreta cele dou procese din Exemplul 13 ca fiind identice.

Exemplul 13
proc6: process (a, b, c) begin x <= a and b and c; end process proc6; proc7: process (a, b) begin x <= a and b and c; end process proc7;

Toate utilitarele de sintez vor interpreta procesul proc6 ca o poart I cu 3 intrri. Unele utilitare de sintez vor interpreta procesul proc7 de asemenea ca o poart I cu 3 intrri, chiar dac la simularea acestui cod procesul nu se va comporta ca atare. La simulare, o modificare a valorii semnalului a sau b va determina execuia procesului, iar valoarea funciei I logic ntre semnalele a, b i c se va asigna semnalului x. Totui, dac se modific valoarea semnalului c, procesul nu este executat, iar semnalul x nu este actualizat. Deoarece nu este clar modul n care un utilitar de sintez ar trebui s genereze un circuit pentru care o tranziie a semnalului c nu determin o modificare a semnalului x, dar o modificare a semnalelor a sau b determin actualizarea semnalului x cu valoarea funciei I logic ntre semnalele a, b i c, exist urmtoarele alternative pentru programele de sintez: Interpretarea procesului proc7 n mod identic cu procesul proc6 (cu o list de sensibilitate care cuprinde toate semnalele din partea dreapt a instruciunilor de asignare a semnalelor din cadrul procesului); Indicarea unei erori la compilare, specificnd faptul c nu se poate realiza sinteza pr ocesului fr o list de sensibilitate complet.

Instruciuni secveniale n limbajul VHDL

13

A doua variant este preferabil, deoarece proiectantul va trebui s modifice codul surs astfel nct funcionarea circuitului generat s fie aceeai cu rezultatul simulrii funci onale a codului surs. Dei din punct de vedere sintactic procesele pot fi declarate fr o list de sensibilitate i fr o instruciune wait, asemenea procese nu vor fi suspendate niciodat. De aceea, dac se va simula un asemenea proces, timpul de simulare nu va avansa, deoarece faza de iniial izare, n care toate procesele sunt executate pn cnd acestea sunt suspendate, nu se va termina niciodat.

2.2. Procese combinaionale i procese secveniale


Att procesele combinaionale, ct i procesele secveniale sunt interpretate n acelai fel la sintez, singura deosebire dintre acestea fiind c la procesele secveniale semnalele de ieire se nscriu n bistabile. Un proces combinaional simplu este prezentat n Exemplul 14.

Exemplul 14
proc8: process begin wait on a, b; z <= a and b; end process proc8;

Acest proces va fi implementat prin sintez ca o simpl poart I cu dou intrri. Pentru ca un proces s modeleze un circuit combinaional, acesta trebuie s conin n lista de sensibilitate toate semnalele care sunt intrri ale procesului. Cu alte cuvinte, procesul trebuie reevaluat de fiecare dat cnd una din intrrile circuitului pe care l modeleaz se modific. n acest fel se modeleaz n mod corect un circuit combinaional. Dac un proces nu este sensibil la toate intrrile sale i nu este un proces secvenial, atunci nu poate fi sintetizat, deoarece nu exist un echivalent hardware al unui asemenea proces. Nu toate utilitarele de sintez impun o asemenea regul, astfel nct trebuie acordat atenie la scrierea proceselor combinaionale pentru a nu introduce erori. Asemenea erori vor avea ca efect diferene subtile ntre modelul simulat i circuitul obinut prin sintez, deoarece un proces non-combinaional este interpretat de utilitarul de sintez ca un circuit combinaional. Dac un proces conine o instruciune wait until sau o instruciune if semnal'event, procesul va fi interpretat ca un proces secvenial. Astfel, procesul din Exemplul 15 va fi interpretat ca un proces secvenial.

Exemplul 15
proc9: process begin wait until clk = '1'; z <= a and b; end process proc9;

Prin sinteza acestui proces, rezult circuitul din Figura 1, unde s-a adugat un bistabil la ieire.

Figura 1. Rezultatul sintezei unui proces secvenial.

14

Structura sistemelor de calcul

2.3. Reacii inverse la asignarea semnalelor


O consecin a modului n care se execut asignarea semnalelor este c prin citirea unui semnal cruia i se asigneaz o valoare n acelai proces se va obine valoarea care i -a fost asignat semnalului la execuia precedent a procesului. Citirea unui semnal i asignarea unei valori la acel semnal n acelai proces este echivalent cu o reacie invers. ntr-un proces combinaional, valoarea precedent este o ieire a logicii combinaionale, astfel nct reacia este asincron. ntr-un proces secvenial, valoarea precedent este valoarea memorat ntr -un bistabil sau registru, astfel nct reacia este sincron. n Exemplul 16 se prezint un proces n care se utilizeaz reacia invers sincron. Procesul descrie un numrtor de 4 bii, semnalul num fiind de tip unsigned, tip care este declarat n pachetul numeric_std. De observat c semnalul num este declarat n afara procesului.

Exemplul 16
library ieee; use ieee.numeric_std.all; signal num: unsigned (3 downto 0); process (clk) begin if (clk'event and clk = '1') then if rst = '1' then num <= "0000"; else num <= num + "0001"; end if; end if; end process;

Circuitul rezultat n urma sintezei procesului din exemplul anterior este prezentat n Figura 2.

Figura 2. Exemplu de reacie invers sincron.

2.4. Sinteza instruciunilor if


O instruciune if poate fi implementat printr-un multiplexor. Considerm mai nti forma instruciunii if fr nici o ramur elsif. Exemplul 17 prezint utilizarea unei asemenea instruciuni pentru descrierea unui comparator.

Exemplul 17
library ieee; use ieee.std_logic_1164.all; entity comp is port (a, b: in std_logic_vector (7 downto 0); egal: out std_logic); end comp; architecture functional of comp is begin

Instruciuni secveniale n limbajul VHDL

15

process (a, b) begin if a = b then egal <= '1'; else egal <= '0'; end if; end process; end functional;

n exemplul anterior, se testeaz egalitatea a dou semnale std_logic_vector, reprezentnd doi vectori de cte 8 bii, rezultnd o valoare de tip std_logic. Circuitul rezultat este prezentat n Figura 3. De notat c, la fel ca i n cazul altor exemple, n practic utilitarul de sintez va elimina ineficienele din circuit (n acest caz, intrrile constante la multiplexor) pentru a rezulta o soluie minimal.

Figura 3. Implementarea unei instruciuni if.

O instruciune if cu ramuri multiple, n care apare cel puin o clauz elsif, este implementat prin mai multe etaje de multiplexoare. Considerm instruciunea if din Exemplul 18.

Exemplul 18
process (a, b, c, s0, s1) begin if s0 = '1' then z <= a; elsif s1 = '1' then z <= b; else z <= c; end if; end process;

Rezultatul implementrii instruciunii if din exemplul anterior este prezentat n Figura 4. Acest circuit este echivalent cu cel rezultat prin implementarea unei instruciuni de asi gnare condiional, care este o instruciune concurent.

Figura 4. Implementarea unei instruciuni if cu ramuri multiple.

Condiiile din ramurile succesive ale unei instruciuni if sunt evaluate independent. n exemplul anterior, condiiile implic cele dou semnale s0 i s1. Pot exista oricte condiii, fiecare din acestea fiind independent de celelalte. Structura instruciunii if asigur faptul c primele condiii vor fi testate naintea celorlalte. n acest exemplu, semnalul s0 a fost testat naintea semnalului s1. Aceast prioritate se reflect n circuitul rezultat, n care multiplex o-

16

Structura sistemelor de calcul

rul controlat de semnalul s0 este mai apropiat de ieire dect multiplexorul controlat de semnalul s1. Este important s se rein existena acestei prioriti cu care se testeaz condiiile, astfel nct s fie eliminate condiiile redundante. Considerm instruciunea if din Exemplul 19, care este echivalent cu instruciunea if din Exemplul 18.

Exemplul 19
process (a, b, c, s0, s1) begin if s0 = '1' then z <= a; elsif s0 = '0' and s1 = '1' then z <= b; else z <= c; end if; end process;

Condiia suplimentar s0 = '0' este redundant, deoarece ea va fi testat numai dac prima condiie a instruciunii if este fals. Se recomand evitarea unor asemenea redundane, deoarece nu exist garania c ele vor fi detectate i eliminate de ctre utilitarul de sintez. n cazul instruciunilor if cu ramuri multiple, n mod normal fiecare condiie va fi dependent de semnale i variabile diferite. Dac fiecare ramur este dependent de acelai semnal, atunci este mai avantajos s se utilizeze o instruciune case.

2.5. Instruciuni if incomplete


n exemplele prezentate pn acum, toate instruciunile if au fost complete. Cu alte cuvinte, semnalului destinaie i s-a asignat o valoare n toate condiiile posibile. Sunt posibile ns dou situaii n care unui semnal nu i se asigneaz o valoare: atunci cnd lipsete clauza else a instruciunii if sau atunci cnd unui semnal nu i se asigneaz o valoare ntr-o ramur a instruciunii if. n ambele cazuri, interpretarea este aceeai. n situaiile n care unui semnal nu i se asigneaz o valoare, semnalul i pstreaz valoarea precedent. Se pune ns problema care este valoarea precedent a semnalului. Dac exist o i nstruciune anterioar de asignare n care semnalul apare ca destinaie, valoarea precedent provine de la acea instruciune de asignare. n caz contrar, valoarea provine din execuia pr ecedent a procesului, ceea ce conduce la existena unei reacii inverse n cadrul circuitului. Primul caz este ilustrat prin Exemplul 20.

Exemplul 20
process (a, b, en) begin z <= a; if en = '1' then z <= b; end if; end process;

n acest caz, instruciunea if este incomplet deoarece lipsete clauza else. n instruciunea if, semnalul z primete o valoare n cazul n care condiia en = '1' este adevrat, dar rmne la valoarea precedent n cazul n care condiia este fals. Valoarea precedent provine din instruciunea de asignare aflat naintea instruciunii if. Instruciunea if din Exemplul 20 este echivalent cu instruciunea if din Exemplul 21.

Instruciuni secveniale n limbajul VHDL

17

Exemplul 21
process (a, b, en) begin if en = '1' then z <= b; else z <= a; end if; end process;

n cazul n care instruciunea if este incomplet i nu exist o instruciune anterioar de asignare, se va insera un circuit latch la ieire i va exista o reacie invers de la ieirea circuitului la intrare. Aceasta deoarece valoarea semnalului de la execuia precedent a proces ului este pstrat i aceasta devine valoarea semnalului la execuia curent a procesului. O asemenea form a instruciunii if este utilizat pentru a descrie un bistabil sau un registru cu o intrare de validare, ca n Exemplul 22.

Exemplul 22
process (clk) begin if (clkevent and clk = '1') then if en = '1' then q <= d; end if; end if; end process;

Semnalul q este actualizat cu noua valoare a semnalului d n cazul n care condiia este adevrat, dar nu este actualizat n cazul n care condiia este fals. n acest caz, valoarea precedent a semnalului q este pstrat prin reacia invers secvenial a semnalului q. Circuitul rezultat este prezentat n Figura 5.

Figura 5. Implementarea unei instruciuni if incomplete.

Instruciunea if din Exemplul 22 este echivalent cu instruciunea if complet din Exemplul 23.

Exemplul 23
process (clk) begin if (clkevent and clk = '1') then if en = '1' then q <= d; else q <= q; end if; end if; end process;

n cazul n care condiia este fals, se asigneaz semnalului q valoarea anterioar a acestuia, ceea ce este echivalent cu pstrarea valorii sale anterioare.

18

Structura sistemelor de calcul

Una din cele mai obinuite erori ntlnite n descrierile VHDL destinate sintezei logice este introducerea neintenionat a reaciei inverse n circuit datorit unei instruciuni if incomplete. Aceasta va insera circuite latch n proiectul sintetizat, ceea ce poate fi problematic pentru circuitele FPGA deoarece ntrzierile pentru cile care conin circuite latch sunt dificil de analizat. Utilitarele de sintez raporteaz, de obicei, inserarea unui circuit latch. Pentru a se evita inserarea unor circuite latch, proiectantul trebuie s se asigure c fiecare semnal cruia i se asigneaz o valoare ntr-un proces combinaional (care este deci un semnal de ieire din proces) primete o valoare n fiecare combinaie posibil a condiiilor. n practic, exist dou posibiliti pentru aceasta: asignarea unei valori unui semnal de ieire n fiecare ramur a instruciunii if i includerea clauzei else, sau iniializarea semnalului printr-o instruciune de asignare necondiionat naintea instruciunii if. n exemplul urmtor, dei instruciunea if pare complet, n cele dou ramuri ale instruciunii asignrile se efectueaz la semnale diferite. De aceea, ambele semnal e z i y vor avea o reacie invers asincron.

Exemplul 24
process (a, b, c) begin if c = '1' then z <= a; else y <= b; end if; end process;

Un alt exemplu este cel n care exist un test redundant al unei condiii care trebuie s fie adevrat (Exemplul 25).

Exemplul 25
process (a, b, c) begin if c = '1' then z <= a; elsif c = '0' then z <= b; end if; end process;

n acest caz, dei instruciunea if pare complet (presupunnd c semnalul c este de tip bit), deoarece pentru fiecare condiie testat sinteza se realizeaz n mod independent, este posibil ca sistemul de sintez s nu detecteze faptul c a doua condiie este redundant. n acest caz, instruciunea if va fi implementat printr-un multiplexor cu trei ci, a treia intrare fiind condiia ramurii else care lipsete, aceasta fiind reacia invers a valorii anterioare. Circuitul implementat pentru acest exemplu este prezentat n Figura 6.

Figura 6. Implementarea unei instruciuni if cu o condiie redundant.

Instruciuni secveniale n limbajul VHDL

19

2.6. Instruciuni if n care apar variabile


Pn acum, n instruciunile if au fost utilizate doar semnale. Aceleai reguli se aplic i n cazul utilizrii variabilelor, cu o singur diferen. Ca i n cazul unui semnal, dac unei variabile i se asigneaz valori numai n anumite ramuri ale instruciunii if, se pstreaz valoarea anterioar a variabilei prin reacie invers. Spre deosebire de cazul utilizrii unui semnal, citirea i scrierea unei variabile n acelai proces va determina o reacie invers numai dac citirea apare naintea scrierii. n acest caz, valoarea citit este valoarea precedent a var iabilei. n cazul citirii i scrierii n acelai proces a unui semnal, va rezulta ntotdeauna o rea cie invers. Aceast observaie se poate utiliza pentru a crea registre sau numrtoare utiliznd variabile. Reamintim c un proces secvenial este interpretat la sintez prin plasarea unui b istabil sau registru naintea ieirii fiecrui semnal cruia i s -a asignat o valoare n procesul respectiv. Aceasta nseamn c n mod normal variabilele nu sunt nscrise n bistabile sau regi stre. Dac exist ns o reacie invers a valorii precedente a unei variabile, aceast reacie se realizeaz printr-un bistabil sau registru pentru ca procesul s fie sincron. n Exemplul 26 se descrie un numrtor utiliznd tipul ntreg unsigned. La incrementarea unei valori de tip unsigned, dac valoarea este cea maxim a domeniului se obine valoarea minim a domeniului.

Exemplul 26
process (clk) variable num: unsigned (7 downto 0); begin if (clkevent and clk = '1') then if rst = '1' then num := "00000000"; else num := num + 1; end if; rez <= num; end if; end process;

n acest exemplu, n ramura else a instruciunii if se citete valoarea precedent a variabilei num pentru a calcula valoarea urmtoare. Rezult astfel o reacie invers. De notat c n acest exemplu se creeaz de fapt dou registre. Conform regulilor pe ntru reacia invers, variabila num va fi nscris ntr-un registru. Semnalul rez va fi de asemenea nscris ntr-un registru, deoarece toate semnalele crora li se asigneaz o valoare ntr -un proces secvenial vor fi nscrise n registre. Acest registru suplimentar va conine ntotdeauna aceeai valoare ca i registrul variabilei num. Utilitarul de sintez va elimina n mod normal acest registru redundant.

2.7. Sinteza instruciunilor case


O instruciune case este implementat printr-un multiplexor, asemntor instruciunii if. Deosebirea este c toate opiunile depind de aceeai intrare i sunt mutual exclusive. Aceasta permite anumite optimizri ale condiiilor de control comparativ cu o instruciune if cu ramuri multiple, la care nu se va presupune nici o dependen ntre diferitele condiii. Efectul este c vor fi necesare mai puine resurse i ntrzierea semnalelor va fi mai redus.

2.8. Sinteza instruciunilor for loop


Interpretarea sintezei unei instruciuni for loop este aceea c se realizeaz o nou copie a circuitului descris de coninutul instruciunii la fiecare iteraie a buclei. Utilizarea i nstruciunii for loop pentru generarea unui circuit este ilustrat n Exemplul 27.

20

Structura sistemelor de calcul

Exemplul 27
library ieee; use ieee.std_logic_1164.all; entity potrivire_biti is port (a, b: in std_logic_vector (7 downto 0); potriviri: std_logic_vector (7 downto 0)); end potrivire_biti; architecture functional of potrivire_biti is begin process (a, b) begin for i in 7 downto 0 loop potriviri (i) <= not (a(i) xor b(i)); end loop; end process; end functional;

Prin procesul din acest exemplu, se genereaz un set de comparatoare de cte un bit, care compar biii de acelai rang ai vectorilor a i b. Rezultatul este nscris n vectorul potriviri, care va conine '1' n poziiile n care biii celor doi vectori sunt identici i '0' n celelalte poziii. Procesul din exemplul anterior este echivalent cu urmtorul proces:
process (a, b) begin potriviri (7) potriviri (6) potriviri (5) potriviri (4) potriviri (3) potriviri (2) potriviri (1) potriviri (0) end process;

<= <= <= <= <= <= <= <=

not not not not not not not not

(a(7) (a(6) (a(5) (a(4) (a(3) (a(2) (a(1) (a(0)

xor xor xor xor xor xor xor xor

b(7)); b(6)); b(5)); b(4)); b(3)); b(2)); b(1)); b(0));

n acest caz, ordonarea domeniului contorului de iteraii nu are importan, deoarece nu exist conexiune ntre blocurile generate ale circuitului. Aceast ordonare devine impo rtant atunci cnd exist o conexiune ntre aceste blocuri. Aceast conexiune este creat de obicei de ctre o variabil care pstreaz o valoare ntr-o iteraie a buclei, valoare care este citit apoi ntr-o alt iteraie. De obicei, este necesar iniializarea unei asemenea variabile naintea intrrii n bucl. Exemplul 28 prezint un asemenea circuit.

Exemplul 28
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity contorizare_unu is port (v: in std_logic_vector (15 downto 0); num: out signed (3 downto 0)); end contorizare_unu; architecture functional of contorizare_unu is begin process (v) variable rez: signed (3 downto 0); begin rez := (others => '0'); for i in 15 downto 0 loop if v(i) = '1' then

Instruciuni secveniale n limbajul VHDL

21

rez := rez + 1; end if; end loop; num <= rez; end process; end functional;

Acest exemplu este un circuit combinaional care contorizeaz numrul biilor din vectorul v care sunt '1'. Rezultatul este acumulat pe parcursul execuiei procesului ntr-o variabil numit rez i este asignat apoi semnalului de ieire num la sfritul procesului. Corpul buclei o instruciune if coninnd o asignare a unei variabile reprezint un bloc format dintr-un multiplexor i un sumator, care va fi generat la sintez pentru fiecare iteraie a buclei. Ieirea unui bloc devine intrarea rez a urmtorului bloc. Figura 7 prezint circuitul generat.

Figura 7. Implementarea unei instruciuni for loop.

n Exemplul 28, domeniul contorului de iteraii al instruciunii for loop a fost specificat n mod explicit ca fiind 15 downto 0. n practic, aceast specificare explicit este utilizat foarte rar pentru accesarea tablourilor, fiind recomandat utili zarea atributelor pentru tablouri. Exist patru posibiliti, n funcie de domeniul cresctor sau descresctor al tablo ului sau de ordinea n care trebuie parcurse elementele tabloului. 1. Dac elementele unui tablou trebuie parcurse de la stnga la dreapta, indiferent de domeniul cresctor sau descresctor al tabloului, se utilizeaz atributul 'range:
for i in v'range loop

2. Dac elementele unui tablou trebuie parcurse de la dreapta la stnga, se utilizeaz atributul 'reverse_range:
for i in v'reverse_range loop

3. Dac elementele unui tablou trebuie parcurse de la indexul minim la cel maxim, ind iferent de domeniul cresctor sau descresctor al tabloului, se utilizeaz atributele 'low i 'high:
for i in v'low to v'high loop

4. n sfrit, dac elementele unui tablou trebuie parcurse de la indexul maxim la cel minim, se utilizeaz atributele 'high i 'low, cu specificarea cuvntului cheie downto:
for i in v'high downto v'low loop

La scrierea subprogramelor, n cazul n care nu se cunoate dinainte dac o variabil sau un semnal de tip tablou va avea un domeniu cresctor sau descresctor, devine foarte important alegerea limitelor corecte pentru instruciunile de buclare. Pentru tipurile tablou care reprezint valori ntregi, cum sunt tipurile signed i unsigned definite n pachetele numeric_std i std_logic_arith, convenia este c bitul din stnga reprezint bitul c.m.s. i bitul din dreapta reprezint bitul c.m.p.s., indiferent de domeniul tabloului. Aceasta nseamn c modul corect pentru accesul acestor tablouri este utilizarea atributului 'range sau 'reverse_range. Astfel, pentru accesul unui tablou n reprezentnd o valoare ntreag ncepnd de la bitul c.m.s. spre bitul c.m.p.s., se va utiliza atributul 'range:

22

Structura sistemelor de calcul

for i in n'range loop

Pentru accesul aceluiai tablou ncepnd de la bitul c.m.p.s. spre bitul c.m.s., se va utiliza atributul 'reverse_range:
for i in n'reverse_range loop

2.9. Sinteza instruciunilor next


Pentru sinteza unei instruciuni next sunt necesare aceleai circuite ca i cele necesare pentru sinteza unei instruciuni if. Alegerea uneia din cele dou instruciuni rmne la latitudinea proiectantului. Ca un exemplu, considerm acelai circuit care contorizeaz numrul biilor de '1' dintr-un vector. Exemplul 29 prezint descrierea modificat a acestui circuit. n locul instruciunii if se utilizeaz o instruciune next, prin care se abandoneaz o iteraie n cazul n care valoarea elementului curent este '0', astfel c nu se execut incrementarea contorului.

Exemplul 29
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity contorizare_unu is port (v: in std_logic_vector (15 downto 0); num: out signed (3 downto 0)); end contorizare_unu; architecture functional of contorizare_unu is begin process (v) variable rez: signed (3 downto 0); begin rez := (others => '0'); for i in v'range loop next when v(i) = '0'; rez := rez + 1; end loop; num <= rez; end process; end functional;

Figura 8. Implementarea unei instruciuni for loop care conine o instruciune next.

Figura 8 prezint circuitul generat prin sinteza descrierii din exemplul anterior. Singura diferen dintre acest circuit i cel din Figura 7 este c este inversat logica de control a multiplexoarelor. Cele dou circuite sunt ns echivalente funcional.

2.10. Sinteza instruciunilor exit


Exemplul 30 prezint descrierea unui circuit pentru contorizarea numrului de zerouri de la sfritul unui vector de bii. Se testeaz fiecare element al vectorului reprezentnd o valoare ntreag, iar dac un element este '1', bucla se termin cu ajutorul unei instruciuni exit.

Instruciuni secveniale n limbajul VHDL

23

Exemplul 30
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity contorizare_zero is port (v: in std_logic_vector (15 downto 0); num: out signed (3 downto 0)); end contorizare_zero; architecture functional of contorizare_zero is begin process (v) variable rez: signed (3 downto 0); begin rez := (others => '0'); for i in v'reverse_range loop exit when v(i) = '1'; rez := rez + 1; end loop; num <= rez; end process; end functional;

Figura 9. Implementarea unei instruciuni for loop care conine o instruciune exit.

Circuitul generat prin sinteza descrierii din exemplul anterior este prezentat n Figura 9. Instruciunea exit este implementat prin porile SAU care determin, pentru iteraia curent i toate iteraiile rmase, selectarea intrrii multiplexoarelor care nu conin circuitul de incrementare atunci cnd condiia instruciunii exit devine adevrat. Se poate observa c implementarea unei instruciuni exit dintr-o bucl este similar cu cea a unei instruciuni if dintr-o bucl.

3. Aplicaii
3.1. Rspundei la urmtoarele ntrebri: a. Care sunt deosebirile dintre asignarea semnalelor i a variabilelor? b. Care este deosebirea dintre instruciunile if cu semnale i instruciunile if cu variabile? c. Cnd este mai avantajoas utilizarea unei instruciuni case n locul unei instruciuni if i care este avantajul utilizrii unei instruciuni case? d. Care este problema utilizrii instruciunilor if incomplete n procesele combinaionale? 3.2. Identificai i corectai erorile din urmtoarea descriere:

24

Structura sistemelor de calcul

library ieee; use ieee.std_logic.all; entity t_c is port (clock, reset, enable: in bit; data: in std_logic_vector (7 downto 0); egal, term_cnt: out std_logic); end t_c; architecture t_c of t_c is signal num: std_logic_vector (7 downto 0); begin comp: process begin if data = num then egal = '1'; end if; end process; count: process (clk) begin if reset = '1' then num <= "111111111"; elsif rising_edge (clock) then num <= num + 1; end if; end process; term_cnt <= 'z' when enable = '0' else '1' when num = "1-------" else '0'; end t_c;

-------------------------------

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Utilizai sistemul de dezvoltare Xilinx ISE pentru compilarea cu succes a acestei descrieri. Corectai apoi erorile semantice ale descrierii. 3.3. Scriei o secven pentru setarea semnalului x la valoarea funciei I logic ntre toate liniile unei magistrale de 8 bii a_bus(7:0). 3.4. Descriei un multiplexor 4:1 de 8 bii utiliznd o instruciune case. Intrrile multiplexorului sunt a(7:0), b(7:0), c(7:0), d(7:0), s(1:0), iar ieirile sunt q(7:0). 3.5. Realizai un decodificator din codul BCD pentru afiajul cu 7 segmente. Intrrile decodificatorului sunt bcd(3:0), iar ieirile sunt led(6:0). 3.6. Descriei memoria FIFO ale crei specificaii i schem bloc sunt prezentate n seciunea 1 din documentul Aplicatie-FIFO.pdf, disponibil pe pagina laboratorului. Creai entitatea i arhitectura pentru modulul fifo8x8, dup cum se indic n seciunea 2 din acelai document.

S-ar putea să vă placă și