5.Subprograme si pachete

Subprogramele VHDL pot fi proceduri sau functii. Exista si modalitati de incapsulare a datelor in package-uri(engl.pachet).

a)Proceduri si functii:

Sintaxa este:

subprogram::=specificare-subprogram;

specificare_subprogram::= procedure nume[(lista parametrii formali)] function nume[lista parametrii-formali)] return marcaj tip

Aceste declaratii de subprograme sint folosite de obicei in specificatii de package, unde corpul subprogramului este dat in corpul package-ului.

lista_parametrii_formali::=lista-interfata parametrii

lista_interfata::=element_interfata{;element interfata}

element_interfata::=declaratie_interfata

declaratie_interfata::=declaratie_constante_interfata declaratie -semnale_interfata declaratie variabile interfata

declaratie_constante_interfata::=

[constant]lista_identificatori:in subtip[:=expresie_statica]

declaratie variabile interfata::=

[variable]lista_identificatori:[mod]subtip[:=expresie_statica]

Exemple:

1) procedure reset;

rest; --apel procedura

2) procedure increment_reg ( variable reg : inout word_32;

constant incr : in integer := 1 );

In al 2-lea exemplu, procedura are 2 parametrii: 'reg' si 'incr'. Modul lui 'reg' este INOUT, ceea ce inseamna ca 'reg' poate fi citit si asignat. Alte moduri posibile sint: IN (parametrul poate fi numai citit) si OUT, parametrul nu poate fi decat asignat. Daca modul este INOUT sau OUT, atunci cuvintul VARIABLE poate lipsi, fiind subinteles. Daca modul este IN, atunci CONSTANT poate lipsi. Un apel de procedura contine lista parametrilor actuali, data sub aceiasi forma ca la vectori.

Exemple:

increment reg ( index_reg , offset-2 ); --adaug o

valoare

increment reg ( prog counter ); -

incrementez(1=implicit)

sau

increment_reg ( incr => offset-2 , reg => index_reg );

increment_reg ( reg => prog_counter );

Exemplu de functie:

function byte_to_int ( byte : word-8 ) return integer;

Pentru functii, modul trebuie sa fie IN, si nu mai trebuie specificat. Daca nu se specifica clasa parametrului, se considera implicit CONSTANT.

Sintaxa pentru corpul unui subprogram este:

corp_subprogram::=

subprogram is

declaratii subprogram

begin

instructiuni_subprogram

end [nume];

declaratii_subprogram::={declaratie subprogram}

instructiuni_subprogram::={instructiune secventiala}

declaratie-subprogram::=subprogram

corp_subprogram

tip

subtip

constanta

variabila

alias

Numele listate dupa partea declarativa a subprogramului sint locale si nu sint vizibile in afara subprogramului. Ele chiar "ascund" semnificatia celor declarate in afara. Dupa apel, se executa instructiunile subprogramului pina se ajunge la sfirsit sau la un RETURN:

insructiunea-return::=RETURN[expresie];

Functiile nu trebuie sa aiba efecte laterale. O consecinta importanta a acestei reguli este ca functiile pot fi apelate fara sa aiba efect asupra mediului apelant.

Exemplu corp functie:

function byte_to_int ( byte : word_8 ) return integer is variable result : integer := 0

begin

for index in 0 to 7 loop

result := result * 2 + bit'pos ( byte ( index) );

end loop;

return result;

end byte to_int;

REDENUMIRE: exista posibilitatea ca 2 subprograme sa aiba acelasi nume, diferentiindu-se prin numarul sau tipul parametrilor.

Exemple:

function check limit ( value : integer ) return boolean;

function check-limit ( value : word-32 ) return boolean;

testl := check-limit ( 4095 ) -- apel prima functie

test2 := check-limit ( X"0000_OFFF") --apel a doua functie

Numele subprogramului poate fi simbol de operator. Se pot redefini astfel operatori pentru tipuri not de operanzi.

Exemple:

function "+"(a,b : word_32) return word_32 is

begin

return inttoword_32(word_32_to_int(a) + word-32 to int(b));

end "+";

X"1000_0010" + X"0000_FFDO" --e apelat noul operator

"+"(X"1000_0010",X"0000_FFDO") --notatie echivalenta

 

b)Package-uri si declaratia corpului pentru package

Un package - pachet - este o colectie de tipuri, constante, subprograme si eventual alte constructii care se folosesc de obicei pentru a implementa un anumit serviciu sau pentru a izola un anume grup de elemente intre care exista o legatura. Mai mult decit atit, detaliile implementarii unui package pot fi "ascunse" fata de utilizatorii acestuia, lasind vizibila pentru restul lumii numai partea de interfata.

Un package poate fi impartit in doua parti: partea de declaratii - care defineste interfata package-ului - si corpul package-ului, in care se define celelalte detalii. Corpul poate fi omis daca nu sint alte detalii nespecificate in partea de declaratii. Sintaxa declararii unui package este urmatoarea:

declaratie_package ::=

package identificator is

partea_declarativa_package

end [ nume-simplu package ] ;

partea_declarativa_package ::=[ element_parte_declarativa ]

element_parte_declarativa ::=declaratie subprogram

declaratie_tip

declaratie_subtip

declaratie_constanta

declaratie_alias

clauza_use

Declaratiile definesc acele elemente care vor fi vizibile pentru utilizatorii packageului si totodata in interiorul corpului package-ului. Trebuie notat de asemenea ca mai sint si alte tipuri de declaratii ce mai pot fi incluse, dar nu vor fi discutate aici.

Exemple:

package data_types is

subtype address is bit_vector(24 downto 0);

subtype data is bit _vector(15 downto 0);

constant vector_table_loc : address;

function data _to_int(value : data) return integer;

function int_to_data(value : integer) return data;

end data_types;

In acest exemplu, declararea valorii constantei vector table precum si corpurile celor doua functii sint aminate, drept pentru care este necesar si corpul package-ului.

Sintaxa pentru corpul unui package este:

corp_package ::=

package body nume_simplu package is

parte declarativa_corp_package

end [ nume-simplu package ] ;

parte declarativa_corp package ::= [element corp package ]

element_package ::=

declaratie subprogram

corp_subprogram

declaratie_subtip

declaratie_constanta

declaratie_alias

clauza_use

 

In corpul package-ului poate fi inclus corpul unui subprogram, in timp ce in interfata package-ului nu poate fi inclusa decit partea declarativa a unui subprogram.

Exemple:

package body data types is

constant vector_table_loc : address = X"FFFFF00";

function data_to_int(value : data) return integer is corpul functiei data_to_int

end data_to_int;

function int_to_data(value : integer) return data is corpul functiei int_to_data;

end int_to_data;

end data_types;

In corpul package-ului se specifica valoarea pentru constante si sint date corpurile functiilor. Declaratife de subtip nu sint repetate deoarece cele facute in partea declarativa a package-ului sint vizibile si in corpul package-ului.

Odata package-ul declarat, elementele sale pot fi referite prin prefixarea numelui for cu numele package-ului. Pentru exemplele anterioare:

variable PC : data_types.address;

int_vector_loc := data_types.vector_table_loc * 4 int_level;

offset := data types.data to int(offset reg);

Adeseori este convenabil sa poti referi elementele dintr-un package fara a le mai prefixa cu numele acestuia. Pentru aceasta se foloseste clauza use intr-o parte declarativa. Sintaxa acesteia este:

clauza_use ::= use nume selectat { , nume_selectat } ;

nume selectat ::= prefix . sufix

Efectul utilizarii acestei clauze este ca toate numele listate pot fi folosite apoi fara a mai fi nevoie sa le, prefixam cu numele package-ului. Se poate folosi sufixul *all* pentru referirea neprefixata la toate elementele declarate intr-un package.

Exemple:

use data types.all;