7. Comportamente VHDL

Comportamentul unui sistem digital poate fi descris in termenii unui limbaj de programare. Aspectele legate de paradigma secventiala a VHDL ca limbajj de programare au detaliate in capitolul 2. In acest capitol vom incerca sa descriem modul in care aceste caracteristici ale VHDL sint extinse pentru a include instructiuni ce permit modificarea valorilor unor semnale si mijloace de a raspunde la modificarea valorilor unor semnale.

a)Atribuiri pentru semnale

Sintaxa este:

instructiune_atribuire_semnal ::=

destinatie <= [ transport ] forma unda ;

destinatie ::= nume | nume-compus

forma unda ::= element forma unda {, element forma unda }

element_forma_unda::= valoare_expresie [ after expresie_timp | null [ after expresie time ]

Destinatia trebuie sa reprezinte un semnal sau un grup de semnale. Daca expresie timp ce corespunde intirzierii este omisa, atunci se va considera valoarea implicita de 0 fs. Aceasta inseamna ca se va considera ca tranzactia a avut loc simultan cu executia operatiei de atribuire.

Asociem fiecarui semnal valoarea prevazuta a formei sale de unda. Atribuirile introduc tranzitii in aceasta forma de unda. De exemplu:

s <= 0' after 10 ns;

Aceasta atribuire va avea ca efect trecerea la '0' a valorii semnalului s la 10 ns dupa executia acesteia. Putem reprezenta valorile prevazute ale unui semnal dat, desenind tranzitiile care apar de-a lungul unei axe pe care consideram timpul. Spre exemplu, daca atribuirea de mai sus ar fi executata la momentul t=5 ns, atunci reprezentarea grafica ar fi cea de mai sus:

Cind simularea a atins momentul de timp t=15ns, tranzitia corespunzatoare va fi procesata si valoarea semnalului va fi modificata. Sa presupunem in continuare ca la momentul de timp t=16 ns, executam atribuirea urmatoare:

s <= 1' after 4 ns, '0' after 20 ns;

Vor apare astfel doua not tranzitii. Trebuie notat faptul ca atunci cind intr-o atribuire sint prezente mai multe tranzitii, momentele de timp ce specifica intirzierea trebuiesc sa fie in ordine crescatoare.

Este interesant de notat ce se intimpla in cazul executiei unor atribuiri de valori pentru semnale pentru care existau si alte atribuiri anterioare. Aici distingem doua cazuri, dupa cum cuvintul rezervat *transport* este sau nu inclus in instructiunea de atribuire. A stfel

daca *transport* apare, atunci intirzierea se numeste intirziere de transport.In aceasta situatie, orice alte tranzitii anterioare tranzitiei cauzate de executia atribuirii curente vor fi sterse. Este ca si cum tranzitiile anterioare ar fi suprascrise de tranzitia cauzata de atribuirea curenta.

daca nu se foloseste transport, atunci vom avea de-a face cu al doilea tip de intirziere ce se numeste intirziere inertiala. Acest tip de atribuire a valorii unui semnal corespunde dispozitivelor fizice care nu prezinta un raspuns la excitarea cu un impuls de durata mai mica decit intirzierea pe care o necesita propagarea semnalului de excitatie pina la iesire. In aceasta situatie, vor fi sterse toate acele tranzitii care ar fi trebuit sa aiba loc inainte de tranzitia nou introdusa si vor ramine numai cele care vor avea loc in timp de la momentul de timp corespunzator tranzitiei nou introduse inainte.

Cind se executa o atribuire a valorii unui semnal in care se specifica mai multe tranzitii, prima tranzitie va fi considerata de tip inertial, iar restul de tip intirziere de transport.

b)Procese. Instructiunea wait

Unitatea de baza intr-o descriere comportamentala de tip VHDL este procesul. Un proces este un corp de cod cu executie secventiala ce poate fi activat ca raspuns la o schimbare de stare. Atunci cind se executa mai mult de un proces la un moment dat, executia va avea loc concurent. Procesele sint specificate conform sintaxei urmatoare:

instructiune_proces ::= [ eticheta proces : ]

process [ ( lista semnale ) ]

parte declarativa proces

begin

instructiuni_proces

end process [ eticheta proces ] ;

parte_declarativa_proces :.= { element declaratie proces }

element_declaratie_proces ::= declarare subprogram

corp_subprogram

declarare_tip

declarare_subtip

declarare_constante

declarare_variabile

declarare_alias

clauza_use

instructiuni proces ::= { instructiune_secventiala }

instructiune secventiala ::= {instructiune wait

instructiune_atribuire

instructiune_atribuire_semnal

instructiune_atribuire_variabile

instructiune_if

apel_procedura

instructiune_case

instructiune_loop

instructiune_next

instructiune_exit

instructiune_return

instructiune_nula

O instructiune de tip proces este o instructiune concurenta ce poate fi folosita in corpul unei arhitecturi sau al unui bloc. Partea declarativa defineste elementele ce pot fi folosite local in cadrul procesului. Trebuie notat ca variabilele definite intr-un proces pot fi folosite la pastrarea starii in cadrul unui model.

Un proces poate contine instructiuni de atribuire a valorilor unui semnal dat. Aceste instructiuni de atribuire formeaza impreuna ceea ce se numeste un driver pentru acel semnal. In mod normal ar trebui sa existe un singur driver pentru orice semnal considerat, astfel incit codul ce defineste valorile pe care le poate avea un semnal sa fie restrins in interiorul unui singur proces.

Un proces este activat initial in cadrul fazei de initializare a simularii. Procesul va executa toate instructiunile secventiale si apoi va relua executia de la inceput. Eventual, procesul va fi blocat in executia unei instructiuni de tip wait. Aceasta instructiune are urmatoarea sintaxa:

instructiune wait wait [ clauza-semnale ] [ clauza-conditii ] [clauza timeout];

clauza_semnale::=on lista_semnale

lista_semnale::= nume_semnal {, nume-semnal}

clauza_conditii::= until conditie

clauza_timeout::= for expresie_timp

Lista de semnale a unei instructiuni de tip wait specifica un set de semnale fata de care procesul respectiv este sensibil in timpul perioadei in care este blocat. Atunci cind se petrece un eveniment ce afecteaza oricare din aceste semnale - adica se schimba valoarea semnalului - procesul respectiv va iesi din blocare si va reevalua conditia. Daca conditia este adevarata, sau daca conditia este omisa, atunci executia va continua cu urmatoarea instructiune, altfel procesul se va reintoarce in starea de blocare in care se afla anterior.

Daca lista de semnale este omisa, atunci procesul respectiv este sensibil la valoarea tuturor semnalelor ce apar in expresia conditiei. Cu alte cuvinte, o modificare a valorii unui semnal dih expresia conditiei va duce la "trezirea" procesului respectiv si la reevaluarea conditiei. In cazul in care si lista de semnale si conditia sint omise dintr-un proces, este posibil ca acesta sa ramina blocat un timp nedefinit.

Daca lista de semnale apare explicit in antetul unui proces, atunci se presupune ca acel proces va contine ca ultima instructiune o instructiune de tip wait a carei lista de semnale este identica cu lista specificata in antet. In acest caz este posibil ca procesul sa nu mai contina nici o alta instructiune de tip wait explicita.

Iata in continuare un exemplu:

process (reset, clock)

variable state : bit := false;

begin

if reset then state := false;

elsif clock = true then state := not state;

end if q <= state after prop_delay; -- wait implicit pentru modificarea valorii semnalelor reset si clock.

end process;

In faza de initializare a simularii procesul este activat si se executa atribuirea valorii initiale a semnalului q. Apoi procesul se va bloca la executia instructiunii wait implicite indicate in comentariu. La orice modificare a valorii unuia dintre semnalele reset sau clock, procesul va fi "trezit" si se va reevalua valoarea semnalului q.

Urmatorul exemplu descrie comportarea unui circuit de sincronizare numit "Muller _C". Acest dispozitiv se foloseste in construirea circuitelor logice asincrone. Iesirea dispozitivului este initial '0' si ramine la aceasta valoare pina cind ambele intrari ale circuitului sint ' 1'. In acest moment iesirea devine ' 1' si ramine la aceasta valoare pina cind ambele intrari ale circuitului devin '0', moment in care va lua valoarea '0' din nou. Descrierea VHDL este urmatoarea:

muller_c_2: process

begin

wait until a='1' and b='1';

q<='1';

wait until a='0' and b='0';

q<=0;

end process muller_c_2;

Din cauza ca acest proces nu contine o lista de semnale este necesara folosirea explicita a instructiunilor de tip wait. In ambele instructiuni wait, lista semnalelor este formata din a si b, derivate din conditia testata.

c)Instructiuni concurente de atribuire a valorilor unui semnal.

Adesea, un proces ce descrie un driver pentru un semnal contine o singura instructiune de atribuire a valorii acelui semnal. Limbajul VHDL ofera posibilitatea de a folosi o notatie scurta pentru acest lucru. Aceasta notatie poarta numele de instructiune concurenta de atribuire a valorilor unui semnal. Sintaxa este:

instructiune_concurenta_semnal ::=

[eticheta : ] atribuire_conditionala_semnal | [ eticheta : ] atribuire_selectiva_semnal

Pentru fiecare tip de atribuire concurenta a valorii unui semnal exista o varianta corespunzatoare cu lists de semnale in antetul unui proces.

a)Atribuire conditionala

Acest tip de atribuire a valorii unui semnal corespunde situatiei in care in cadrul unui proces se face atribuirea de valori unui semnal in interiorul unei instructiuni if. Sintaxa este:

atribuire_conditionals_semnal ::= destinatie <= optiuni forma_unda_conditionala ;

optiuni ::= [ guarded ] [ transport ]

forma_unda_conditionala :.= { forma_unda when conditie else } forma_unda

Daca se include cuvintul cheie *transport*, atunci atribuirile corespunzatoare din proces vor fi facute cu intirziere de tip transport.

b)Atribuire selectiva

O instructiune de atribuire selectiva a valorii unui semnal corespunde unei instructiuni de atribuire ce se executa in interiorul unei instructiuni de tip case. Sintaxa este:

atribuire_selectiva ::= with expresie select

destinatie <= optiuni forma_unda_selectie;

forma_unda_selectie ::= { forma_unda when posibilitati ,} forma_unda when posibilitati

posibilitati ::= posibilitate { I posibilitate }

Optiunile sint aceleasi ca si pentru atribuirea conditionala. Cu alte cuvinte, daca cuvintul rezervat *transport* apare, atunci atribuirile corespunzatoare din proces vor fi facute cu intirziere de tip transport.

Lista de semnale pentru instructiunea wait se determina in felul urmator: daca in instructiunea de atribuire selectiva nu apare nici o referinta explicita la vreun semnal, atunci lista de semnale pentru acea instructiune wait va fi vida. In caz contrar, lista de semnale a instructiunii wait va contine acele semnale care au fost referite in interiorul instructiunii de atribuire selectiva.

Iata in continuare un exemplu de instructiune de atribuire selectiva:

with alu_function select

alu-result <= op1 + opt2 when alu_add I alu-incr,

opl - op2 when alu_substract,

opl and opt when alu_and,

opl or opt when alu_or,

opt and not opt alu mask;

In acest exemplu, valoarea semnalului alu function este folosita pentru a selecta care dintre instructiunile de atribuire se va executa. Instructiunea contine in lista ei de semnale urmatoarele semnale alu function, op 1, opt, astfel incit oricare dintre aceste trei semnale isi va schimba valoarea, instructiunea de atribuire selectiva isi va relua executia.