Sunteți pe pagina 1din 22

Subprograme

Capitolul 6
Subprograme
• Un subrogram defineste (reprezinta) un algoritm
secvential care face anumite calcule.
• Subprogramele pot fi:
– 1. functii
– 2. proceduri
• Functii:
– Calculeaza in mod normal o singura valoare
– Se executa in timp de simulare 0 => nu contin instructiuni
WAIT.
• Proceduri:
– Pot returna zero sau mai multe valori
– Pot contine instructiuni WAIT (caz in care nu se executa in timp
de simulare 0).
– Pot fi apelate secvential sau concurent.
Subprograme: specificare
Specificarea unui subprogram (subprogram body):
subprogram-specification IS
subprogram-item-declarations
BEGIN
subprogram-statements
END [FUNCTION | PROCEDURE] [subprogram-name];
Subprogram-specification:
- precizeaza numele subprogramului
- defineste interfata subprogramului, adica parametrii formali.
Subprogram-item-declarations: declaratiile din subprograme
Subprogram-statements: sint instructiuni secventiale si instructiunea RETURN
Subprogram-name de la sfirsit: daca apare, e acelasi ca si numele din
subprogram-specification
Simbolul ; de la sfirsit e obligatoriu.
Specificare: parametri
• Parametrii formali au:
– nume
– Tip
– clasa: constante, variable, semnale, fisiere (FILE)
– mod: IN, OUT, INOUT
• Modul parametrilor formali:
– IN - se pot doar citi, dar nu pot fi modificati
– OUT -pot fi modificati, dar nu si cititi
– INOUT: pot fi atit cititi, cit si modificati
– Fisierele nu au mod, ele pot fi citite sau scrise, depinzind de felul
cum au fost deschise.
– Functiile pot avea doar parametri de mod IN, procedurile pot
avea parametri de orice mod.
Parametrii subprogramelor
• La apelarea subprogramelor se folosesc parametri actuali.
• Asocieri:
– Unui parametru formal semnal i se poate asocia ca actual doar un
parametru semnal.
– Analog pentru parametri formali VARIABLE sau FILE
– Unui parametru formal constanta i se poate asocia si o expresie.
– Trebuie sa corespunda tipul parametrului formal si al celui actual
– Daca un parametru formal e unconstrained array, atunci dimensiunea lui
va fi data de dimensiunea parametrului actual.
• Semnale:
– In interiorul functiilor NU se pot asigna valori semnalelor
– Daca intr-o procedura se asigneaza valori unui semnal, atunci driverul
semnalului este afectat imediat si indiferent daca procedura se termina
sau nu.
– Nu se permite utilizarea in proceduri a atributelor care genereaza noi
semnale: ‘STABLE, ‘QUIET, ‘TRANSACTION, ‘DELAYED (nici in functii)
Subprograme: declaratii
• Subprogram-item-declarations (declaratiile din
subprograme):
– Pot fi declaratii de tipuri sau obiecte (constante,
variabile, dar NU semnale!)
– Nu pot fi declaratii de componente !
– Aceste declaratii sint vizibile doar in interiorul
subprogramelor si devin efective doar la apelul
subprogramului.
– Astfel, o variabila declarata intr-un subprogram
• este initializata la fiecare apel al subprogramului si
• Exista doar pe durata executiei subprogramului.
• (o variabila declarata intr-un proces e initializata la inceputul
simularii, exista pe toata durata simularii si isi pastreaza
valoarea de la o executie la alta a procesului)
Specificare: instructiuni
• Instructiunile din subprograme pot fi
– instructiuni secventiale (ca si in procese)
– Instructiunea RETURN:
• Sintaxa: RETURN [expression];
• Este permisa doar in subprograme
• La executia ei se termina subprogramul si controlul este redat
programului care a apelat subprogramul.
• Orice functie trebuie sa contina RETURN expresie;
– Valoarea expresiei este returnata programului care a apleat functia
• La proceduri si parametrii OUT si INOUT returneaza valori.
• Procedurile pot avea efecte secundare (‘side effects’),
adica pot afecta valoarea unor obiecte care sint declarate
global fata de procedura -> NU se recomanda !!
Proceduri
Procedurile permit descompunerea unor secvente de cod lungi in sectiuni. Spre
deosebire de o functie, o procedura poate returna zero sau mai multe valori.
Sintaxa pentru specificarea unei proceduri:
PROCEDURE procedure_name(parameter_list)
unde parameter_list specifica lista parametrilor formali.
Clasele parametrilor: constante, variabile, semnale (si fisiere)
Modul parametrilor: IN, OUT, INOUT.
Daca nu se specifica clasa parametrilor, atunci aceasta este constanta pt
parametrii de mod IN si variabila pt parametrii de mod OUT sau INOUT.
Daca nu se specifica modul unui parametru, atunci implicit este IN.
Exemplu de procedura:
TYPE op_code IS (add, sub, mul, div, lt, le, eq);

Proceduri
PROCEDURE alu_proc IS (a,b: IN INTEGER; op: op_code; z:
OUT INTEGER; zcomp: OUT BOOLEAN) IS
BEGIN
CASE op IS
WHEN add => z:=a+b;
WHEN sub=> z:=a-b;
WHEN mul=> z:=a*b;
WHEN div=> z:=a/b;
WHEN lt=> zcomp := a<b;
WHEN le=> zcomp:= a<=b;
WHEN eq=> zcomp:=a=b;
END CASE;
END PROCEDURE alu_proc;
Proceduri
Apelul procedurilor poate fi secvential sau concurent. Sintaxa:
[label:] procedure_name(list_of_actuals);
Apelul concurent este echivalent cu un proces ce contine apelul secvential si are
in lista de senzitivitate parametrii apartinind clasei semnal si avind modul IN sau
INOUT.
Parametrii actuali pot fi precizati prin asociere pozitionala sau dupa nume.
Exemplu:
alu_proc(d1,d2,add, sum, comp); -- pozitional
alu_proc(z=>sum, b=>d2, a=>d1, op=>add, zcomp=>comp);-- dupa nume
Daca o procedura contine instructiuni WAIT, atunci nu poate fi aplelata dintr-un
proces ce are lista de senzitivitate.
O procedura poate fi si aminata (postponed) fiind declarata ca atare:
POSTPONED PROCEDURE o_procedura(lista_de_parametri) IS

Declarare vs specificare
Se poate face si numai declararea unei proceduri, fara a specifica si corpul
ei. Analog pentru functii:
-de exemplu in PACKAGE DECLARATION
-este util la apelul recursiv (a se vedea exemplul)
Sintaxa unei declaratii de subprogram este:
subprogram_specification
Exemplu cu 2 proceduri:
PROCEDURE p(…) IS
VARIABLE a, b:…
BEGIN
a:=q(b);

END p;
Declarare vs specificare
FUNCTION q(…)
BEGIN

p();

END q;
Exemplul nu e corect, nu se compileaza.
Corect ar fi:
PROCEDURE p();
FUNCTION q();
PROCEDURE p() IS

END p;
FUNCTION q() IS

END FUNCTION q;
Functii
Specificare:
[PURE|IMPURE] FUNCTION function_name (parameter_list)
RETURN return_type
O functie este pura daca returneaza de fiecare data aceeasi valoare atunci cind
este apleata cu acelasi set de parametri actuali.
O functie impura poate returna valori diferite atunci cind este apleata cu acelasi
set de parametri actuali.
In mod implicit o functie este pura. Exemple de functii impure:
- functii care genereaza numere aleatoare
- functia NOW (returneaza timpul de simulare curent).
Lista de parametri (parameter_list) descrie lista parametrilor formali ai functiei.
Acestia pot avea doar modul IN si pot apartine clasei constantelor sau
semnalelor, fiind in mod implicit constante.
Apelul functiilor se face doar in expresii conform sintaxei:
function_name(list_of_actuals)
Functii
Pentru o constanta parametrul actual poate fi si o expresie, iar pt un semnal,
poate fi doar semnal.
Asocierea parametrilor formali cu cei actuali poate fi facuta pozitional sau dupa
nume.
Functiile NU pot contine instructiuni WAIT si nu pot asigna valori unor semnale.
In general functiile nu au efecte laterale (secundare).
Exemplu de functie care detecteaza frontul crescator al unui semnal:
FUNCTION front_crescator (SIGNAL s: BIT) RETURN BOOLEAN IS
BEGIN
RETURN (s=‘1’ AND s’EVENT AND s’LAST_VALUE=‘0’);
END FUNCTION front_crescator;
Cele mai frecvente utilizari ale functiilor:
-pt conversii
-ca functii de rezolutie
Functii de conversie
In VHDL se pot face putine conversii de tip cast de tipul (INTEGER) x sau
(REAL) y, in general se folosesc functii de conversie.
Exemplu:
TYPE mvl IS (‘X’, ‘0’, ‘1’, ‘Z’);
TYPE fourval IS (X, L, H, Z);
FUNCTION mvl_to_fourval(v: mvl) RETURN fourval IS
BEGIN
CASE v IS
WHEN ‘X’ => RETURN X;
WHEN ‘0’ => RETURN L;
WHEN ‘1’ => RETURN H;
WHEN ‘Z’ => RETURN Z;
END CASE;
END FUNCTION;
Exemplu de conversie cu look-up table
Conversia e mai eficienta daca se foloseste look-up table in locul functiei de conversie, ca in
exemplul urmator:

entity look_up_table_2 is
generic (tp: time:=5ns);
end;
architecture a of look_up_table_2 is
type mvl is ('Z', '0', '1', 'X');
type fourval is (Z, L, H, X);
type look_up is array(mvl) of fourval;

CONSTANT to_fourval: look_up:=('Z'=>Z, '0'=>L,'1'=>H,'X'=>X);

SIGNAL fv0,fv1,fv2: fourval;


SIGNAL mvl1,mvl2: mvl;

SIGNAL s1, s2: look_up;


BEGIN
Process(mvl1)
Begin
fv1 <= to_fourval(mvl1) after 1ns;
end process;
Exemplu de conversie cu look-up table
process(mvl2)
begin
fv2<= to_fourval(mvl2) after 1ns;
end process;

fv0 <= to_fourval(mvl'('Z')) after tp, to_fourval('0') after 2*tp,


to_fourval('1') after 3*tp, to_fourval('X') after 4*tp;

mvl1 <= 'X' after 20ns, '1' after 30ns, '0' after 40ns, 'Z' after 50ns;
mvl2 <= '0' after 40ns, '1' after 70ns;

s1 <= ('X'=>X, '1'=>H, '0'=>L, 'Z'=> Z) after tp, ('X'=>Z, 'Z'=>X,


'0'=>H, others=>L) after 2*tp;

s2 <= (others=>L) after tp, (L,H,X,Z) after 2*tp;

end architecture;
Diagrama de semnale:

Fig 10. Diagrama de semnale pentru exemplul de conversie cu look-up table.


Functii de rezolutie
• Se utilizeaza pentru a rezolva valoarea unui semnal
atunci cind semnalul are mai multe drivere (surse)
• In VHDL este ilegal ca un semnal cu mai multe drivere
sa nu fie rezolvat
• Functia de rezolutie:
– Se scrie de catre programator
– Se apeleaza de catre simulator:
• Atunci cind cel putin unul din driverele semnalului are un eveniment.
• La aparitia acelui eveniment se executa functia care va returna o
valoare obtinuta din valorile tuturor driverelor semnalului.
• Spre deosebire de alte HDL in VHDL nu exista functii de
rezolutie predefinite.
Overloading (supraincarcare)
• Uneori dorim sa avem doua subprograme cu acelasi
nume, caz in care se spune ca subprogramele sint
supraincarcate
– De exemplu un subprogram denumit count care numara biti si un
altul, denumit tot count, care numara intregi
• Un apel catre astfel de subprograme este ambiguu si
deci eronat daca nu poate fi identificat subprogramul
apelat.
• Identificarea se poate face pe baza:
– Numelui subprogramelor
– Numarului de parametri actuali
– Tipul si ordinea parametrilor actuali
– Numele parametrilor formali (daca se foloseste asocierea
dupa nume la apel)
– Tipul rezultatului (la functii)
Overloading la operatori
• Cind un operator standard al limbajului
este facut sa se comporte diferit se spune
ca avem operator overloading
– De obicei dorim sa extindem operatorul si
asupra unor operanzi avind alt tip decit pentru
operatorul standard
– La declararea noului operator, numele
acestuia se pune in ghilimele, pentru a-l putea
apela sub forma unui operator
• Operatorul poate fi apelat si ca o functie.
Exemplu de operator overloading
--definirea operatorilor
FUNCTION “+” (op1, op2: BIT_VECTOR) RETURN BIT_VECTOR;
FUNCTION “-” (op1, op2: BIT_VECTOR) RETURN BIT_VECTOR;
TYPE mvl IS (X, L, H, Z);
FUNCTION “OR”(l, r: mvl) RETURN mvl;
FUNCTION “AND”(l, r: mvl) RETURN mvl;

--Apelul operatorilor
VARIABLE x,y,z1,z2: BIT_VECTOR(3 DOWNTO 0);
VARIABLE a1, b1, c1,c2: mvl;
z1:=x+y;--notatie standard pt operatori
z2:=“-”(x,y);--notatie standard pt functii
c1:=a1 AND b1;--notatie standard pt operatori
c2:= “OR”(a1,b1);--notatie standard pt functii