Sunteți pe pagina 1din 23

1

INSTRUCIUNI CONCURENTE N LIMBAJUL VHDL

Operaiile din sistemele reale se execut n mod concurent. Limbajul VHDL mod eleaz sistemele reale sub forma unui set de subsisteme care funcioneaz n mod concurent. Fiecare din aceste subsisteme poate fi specificat sub forma unui proces separat, iar comunicaia dintre procese se poate realiza prin semnale. Complexitatea diferitelor procese poate fi foarte variat, de la o simpl poart logic pn la un procesor. Modelarea sistemelor reale sub aceast form poate fi realizat cu ajutorul instruciunilor concurente. n prima parte, aceast lucrare de laborator prezint formatul, utilizarea i sinteza principalelor instruciuni concurente. n partea a doua, lucrarea de laborator descrie unele circuite combinaionale i secveniale de baz: multiplexoare, decodificatoare, codificatoare prioritare, circuite de deplasare combinaional, bistabile, registre, registre de deplasare i numrtoare. n seciunile urmtoare se prezint mai nti structura i execuia unei arhitecturi, iar apoi sunt descrise principalele instruciuni concurente ale limbajului VHDL. Cea mai impo rtant instruciune concurent este declaraia unui proces. Procesele au fost prezentate n lucrarea dedicat instruciunilor secveniale, astfel nct n aceast lucrare de laborator vor fi prezentate doar principalele caracteristici ale proceselor. Alte instruciuni concurente sunt instruciunea concurent de asignare a semnalelor, instruciunea block, instruciunea concurent de apel a unei proceduri, instanierea unei componente i instruciunea generate. Instanierea unei componente i instruciunea generate vor fi descrise n lucrarea de laborator dedicat proiectrii structurale.

1. Sintaxa i utilizarea instruciunilor concurente


1.1. Structura i execuia unei arhitecturi
Definiia unei arhitecturi are dou pri: o parte declarativ i o parte descriptiv. n partea declarativ se pot declara obiecte care sunt interne arhitecturii. Partea descriptiv co nine instruciuni concurente. Acestea definesc procesele sau blocurile interconectate care de scriu funcionarea sau structura global a sistemului.

Figura 1. Schema unui sumator de 1 bit.

Toate procesele dintr-o arhitectur se execut n paralel unele fa de altele, dar i nstruciunile din cadrul unui anumit proces se execut secvenial. Un proces suspendat este activat din nou atunci cnd unul din semnalele din lista sa de sensibilitate i modific valoarea. Atunci cnd exist mai multe procese ntr-o arhitectur, la modificarea valorii unui semnal

Structura sistemelor de calcul

sunt activate toate procesele care conin acest semnal n lista lor de sensibilitate. Instruciunile din cadrul proceselor activate sunt executate secvenial, dar independent de instruciunile din alte procese. Figura 1 prezint schema unui sumator de 1 bit. n Exemplul 1 fiecare poart din aceast schem este descris printr-un proces separat care se execut n mod concurent cu celelalte procese.

Exemplul 1
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 procese of add_1 is signal s1, s2, s3, s4: std_logic; begin p1: process (b, cin) begin s1 <= b xor cin; end process p1; p2: process (a, b) begin s2 <= a and b; end process p2; p3: process (a, cin) begin s3 <= a and cin; end process p3; p4: process (b, cin) begin s4 <= b and cin; end process p4; p5: process (a, s1) begin s <= a xor s1; end process p5; p6: process (s2, s3, s4) begin cout <= s2 or s3 or s4; end process p6; end procese;

Comunicaia ntre procese poate fi realizat cu ajutorul instruciunilor de asignare a semnalelor. Acestea se pot utiliza att pentru activarea proceselor, ct i pentru sincronizarea ntre procese. Astfel, un semnal poate atepta un eveniment asupra unui semnal de intrare, semnal care este asignat ntr-un alt proces. Acest semnal este declarat n partea declarativ a arhitecturii, i astfel este vizibil pentru toate procesele din cadrul arhitecturii.

Instruciuni concurente n limbajul VHDL

Observaie
Pentru comunicaia ntre procese se pot utiliza doar semnale, nu i variabile, deoarece acestea sunt obiecte locale n procesul n care sunt declarate.

1.2. Procese
Procesele sunt compuse din instruciuni secveniale, dar declaraiile proceselor reprezint instruciuni concurente. Declaraia unui proces a fost prezentat n lucrarea de laborator dedicat instruciunilor secveniale. Se pot formula urmtoarele caracteristici ale unui proces: Se execut n paralel cu alte procese; Nu poate conine instruciuni concurente; Definete o regiune a arhitecturii unde instruciunile se execut secvenial; Trebuie s conin o list de sensibilitate explicit sau o instruciune wait; Permite descrieri funcionale, asemntoare limbajelor de programare; Permite accesul la semnalele definite n arhitectura n care apare procesul i la cele definite n entitatea cu care este asociat arhitectura.

1.3. Instruciuni concurente de asignare a semnalelor


O instruciune concurent de asignare a valorii unui semnal este echivalent cu un proces coninnd acea instruciune. O asemenea instruciune este executat n paralel cu alte instruciuni concurente sau alte procese. Exist trei tipuri ale instruciunilor concurente de asignare a semnalelor: instruciunea de asignare simpl, instruciunea de asignare condiional i instruciunea de asignare selectiv. Acestea sunt prezentate n continuare.

1.3.1. Instruciunea de asignare simpl


Instruciunea de asignare simpl este versiunea concurent a instruciunii secveniale de asignare a semnalelor, avnd aceeai form cu aceasta. Ca i n cazul versiunii secveniale, asignarea concurent definete un nou driver pentru semnalul asignat. Deosebirea fa de ve rsiunea secvenial este c instruciunea concurent de asignare apare n afara unui proces, n cadrul unei arhitecturi. O instruciune concurent de asignare reprezint o form simplificat de scriere a unui proces, fiind echivalent cu un proces care conine o singur instruciune secvenial de asignare. Descrierea sumatorului de 1 bit din Exemplul 1 poate fi simplificat prin utilizarea instruciunilor concurente de asignare, dup cum se arat n Exemplul 2.

Exemplul 2
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 concurent of add_1 is signal s1, s2, s3, s4: std_logic; begin s1 <= b xor cin; s2 <= a and b; s3 <= a and cin; s4 <= b and cin; s <= a xor s1;

Structura sistemelor de calcul

cout <= s2 or s3 or s4; end concurent;

Dup cum se observ din exemplul anterior, instruciunile concurente de asignare apar direct n cadrul arhitecturii i nu n interiorul unui proces. Ordinea n care sunt scrise instruciunile nu are importan. La simulare toate instruciunile se execut n acelai ciclu de simulare. Activarea execuiei proceselor este determinat de modificarea valorii unui semnal din lista de sensibilitate a acestora sau de ntlnirea unei instruciuni wait. n cazul instruciunilor concurente de asignare, modificarea valorii unuia din semnalele care apar n partea dreapt a asignrii activeaz execuia asignrii, fr s se specifice n mod explicit o list de sensibilitate. Activarea unei instruciuni de asignare este independent de activarea altor i nstruciuni concurente din cadrul arhitecturii. Instruciunile concurente de asignare se utilizeaz pentru descrieri de tipul fluxului de date. Prin sinteza acestor instruciuni se genereaz circuite combinaionale.

Observaie
Dac ntr-o arhitectur exist mai multe asignri concurente la acelai semnal, vor fi create drivere multiple pentru acel semnal. n asemenea cazuri, trebuie s existe o funcie de rezoluie predefinit sau definit de utilizator pentru tipul semnalului respectiv. Spre deosebire de asignrile concurente, dac ntr-un proces exist mai multe asignri secveniale la acelai semnal, va avea efect doar ultima dintre acestea.

1.3.2. Instruciunea de asignare condiional


Instruciunea de asignare condiional este echivalent funcional cu instruciunea condiional if, avnd sintaxa urmtoare:
semnal <= [expresie when condiie else ...] expresie;

Valoarea uneia din expresiile surs se atribuie semnalului destinaie. Expresia atribuit va fi prima a crei condiie boolean asociat este adevrat. La execuia unei instruciuni de asignare condiional, condiiile sunt testate n ordinea n care ele sunt scrise. La nt lnirea primei condiii care se evalueaz la valoarea boolean TRUE, expresia corespunztoare acesteia se asigneaz semnalului destinaie. Dac nici o condiie nu se evalueaz la valoarea TRUE, semnalului destinaie i se asigneaz ultima expresie, cea a ultimei clauze else. Dac exist dou sau mai multe condiii care se evalueaz la valoarea TRUE, va fi luat n considerare doar prima condiie. Deosebirile dintre instruciunea de asignare condiional i instruciunea condiional if sunt urmtoarele: Instruciunea de asignare condiional este o instruciune concurent, deci poate fi utilizat ntr-o arhitectur, n timp ce instruciunea if este secvenial, astfel c poate fi utilizat numai n interiorul unui proces. Instruciunea de asignare condiional poate fi utilizat numai pentru asignarea valorii unor semnale, n timp ce instruciunea if poate fi utilizat pentru execuia oricrei instruciuni secveniale. Exemplul 3 definete o entitate i dou arhitecturi pentru o poart SAU EXCLUSIV cu dou intrri. Prima arhitectur utilizeaz o instruciune de asignare condiional, iar a doua utilizeaz o instruciune if echivalent.

Exemplul 3
library ieee; use ieee.std_logic_1164.all;

Instruciuni concurente n limbajul VHDL

entity xor2 is port (a, b: in std_logic; x: out std_logic); end xor2; architecture arh1_xor2 of xor2 is begin x <= '0' when a = b else '1'; end arh1_xor2; architecture arh2_xor2 of xor2 is begin process (a, b) begin if a = b then x <= '0'; else x <= '1'; end if; end process; end arh2_xor2;

Instruciunea de asignare condiional este implementat printr-un multiplexor care selecteaz una din expresiile surs. Figura 2 ilustreaz circuitul rezultat pentru urmtoarea instruciune:
s <= a xor b when c = '1' else not (a xor b);

Circuitul din figura 2 este cel generat iniial de utilitarul de sintez, dar operatorul de egalitate va fi minimizat ulterior la o simpl conexiune, astfel nct semnalul c s controleze multiplexorul n mod direct.

Figura 2. Implementarea unei instruciuni de asignare condiional.

Exemplul anterior reprezint forma cea mai simpl a unei instruciuni de asignare condiional, n care exist o singur condiie testat. Un alt exemplu n care exist dou condiii testate este urmtorul:
z <= a when s0 = '1' else b when s1 = '1' else c;

Condiiile sunt evaluate n ordinea n care sunt scrise, fiind selectat pentru asignare prima expresie a crei condiie este adevrat. Aceasta echivaleaz din punct de vedere hardware cu o serie de multiplexoare cu dou ci, prima condiie controlnd multiplexorul cel mai apropiat de ieire. Circuitul rezultat pentru acest exemplu este prezentat n figura 3. Pentru acest circuit, condiiile au fost deja optimizate, astfel nct semnalele s0 i s1 controleaz multiplexoarele n mod direct. Din acest circuit se poate observa c atunci cnd s0 este '1', este selectat semnalul a indiferent de valoarea semnalului s1. Dac s0 este '0', atunci s1 selecteaz ntre intrrile b i c.

Structura sistemelor de calcul

Figura 3. Implementarea unei instruciuni de asignare condiional cu dou condiii.

Dac exist un numr mare de ramuri ale instruciunii, la implementare rezult un ir lung de multiplexoare. De acest aspect trebuie s se in cont la proiectare: cu ct o expresie surs apare mai trziu n lista de selecie, cu att semnalele din aceast expresie vor traversa mai multe multiplexoare n circuitul rezultat la sintez. La implementare, se consider c fiecare condiie dintr-o instruciune de asignare condiional este independent de celelalte. Aceasta nseamn c, n cazul n care condiiile sunt dependente (de exemplu, se bazeaz pe acelai semnal), este posibil s nu se realizeze nici o optimizare. De exemplu:
z <= a when sel = '1' else b when sel = '0' else c;

n acest exemplu, a doua condiie este dependent de prima. De fapt, n a doua ramur, semnalul sel poate fi numai '0'. De aceea, a doua condiie este redundant, iar ultima r amur else nu poate fi atins. La sintez, aceast instruciune de asignare condiional va fi implementat totui prin dou multiplexoare, dup cum se ilustreaz n figura 4.

Figura 4. Implementarea unei instruciuni de asignare condiional cu o ramur redundant.

n cazul unui exemplu simplu cum este cel anterior, este probabil ca utilitarul de sintez s elimine multiplexorul redundant, dar n cazul unor exemple mai complexe aceast eliminare nu poate fi garantat. Motivul pentru care nu se obine o implementare optimizat este c, n cazul general, detectarea unui cod VHDL la care nu se poate ajunge nu este o pr oblem trivial. n cazul n care condiiile sunt dependente unele de altele, este mai avantajoas utilizarea unei instruciuni de asignare selectiv.

1.3.3. Instruciunea de asignare selectiv


Ca i instruciunea de asignare condiional, instruciunea de asignare selectiv pe rmite selectarea unei expresii surs pe baza unei condiii. Deosebirea const n faptul c i nstruciunea de asignare selectiv utilizeaz o singur condiie pentru selecia dintre diferite opiuni. Aceast instruciune este echivalent funcional cu instruciunea secvenial case. Sintaxa este urmtoarea:
with expresie_de_selecie select semnal <= expresie_1 when opiuni_1, ... expresie_n when opiuni_n, [expresie when others];

Instruciuni concurente n limbajul VHDL

Semnalului destinaie i se atribuie valoarea uneia din expresii. Expresia selectat este prima dintre cele ale cror opiuni includ valoarea expresiei de selecie. Sintaxa opiunilor este aceeai ca i n cazul instruciunii case. Astfel, fiecare opiune poate fi reprezentat de o valoare individual sau de un set de valori. n cazul n care o opiune este reprezentat de un set de valori, se pot specifica fie valorile individuale din set separate prin simbolul |, fie domeniul valorilor, fie o combinaie a acestora. Tipul expresiei de selecie determin tipul fiecrei opiuni. Fiecare valoare din domeniul expresiei de selecie trebuie s fie acoperit de o opi une. Ultima opiune poate fi indicat prin cuvntul cheie others, care specific toate valorile din domeniul expresiei de selecie rmase neacoperite de opiunile anterioare. Exist urmtoarele restricii pentru diferitele opiuni: Valorile din cadrul opiunilor nu se pot suprapune. Dac opiunea others nu este prezent, toate valorile posibile ale expresiei de selecie trebuie acoperite de setul de opiuni.

Observaie
Opiunile din cadrul instruciunii de asignare selectiv sunt separate prin virgule. n Exemplul 4 se reia definiia porii SAU EXCLUSIV cu dou intrri, dar n cadrul arhitecturii se utilizeaz o instruciune de asignare selectiv.

Exemplul 4
library ieee; use ieee.std_logic_1164.all; entity xor2 is port (a, b: in std_logic; x: out std_logic); end xor2; architecture arh_xor2 of xor2 is signal tmp: std_logic_vector (1 downto 0); begin tmp <= a & b; with tmp select x <= '0' when "00", '1' when "01", '1' when "10", '0' when "11"; end arh_xor2;

1.4. Instruciunea block


O instruciune block definete un grup de instruciuni concurente. Aceast instruc iune este util pentru organizarea instruciunilor concurente n mod ierarhic sau pentru parti ionarea unei liste de conexiuni structurale n scopul creterii lizibilitii descrierii. Sintaxa instruciunii block este urmtoarea:
etichet: block [(expresie_de_gard)] [declaraii] begin instruciuni_concurente end block [etichet];

Eticheta obligatorie denumete blocul. n partea de declaraii se pot declara obiecte locale blocului. Declaraiile posibile sunt cele care pot apare i n partea declarativ a unei arhitecturi, i anume:

Structura sistemelor de calcul

Clauze use; Declaraii de porturi i generice, ca i declaraii pentru maparea acestora; Declaraii i corpuri de subprograme; Declaraii de tipuri i subtipuri; Declaraii de constante, variabile i semnale; Declaraii de componente; Declaraii de fiiere, atribute i configuraii. Ordinea instruciunilor concurente dintr-un bloc nu este semnificativ, deoarece toate instruciunile sunt ntotdeauna active. ntr-un bloc pot fi declarate alte blocuri, pe mai multe nivele ierarhice. Obiectele declarate ntr-un bloc sunt vizibile n acel bloc i n toate blocurile interioare. Atunci cnd ntr-un bloc interior se declar un obiect cu acelai nume ca i un obiect dintr-un bloc exterior, este valabil declaraia din blocul interior. Exemplul 5 ilustreaz utilizarea blocurilor pe mai multe nivele ierarhice.

Exemplul 5
B1: block signal s: std_logic; begin s <= a and b; B2: block signal s: std_logic; begin s <= c and d; B3: block begin x <= s; end block B3; end block B2; y <= s; end block B1; -- declaratia "s" in blocul B1 -- "s" din blocul B1 -- declaratia "s" in blocul B2 -- "s" din blocul B2 -- "s" din blocul B2 -- "s" din blocul B1

Introducerea blocurilor n cadrul unei descrieri nu afecteaz execuia unui model la simulare, ci are doar rol de organizare a descrierii. La declararea unui bloc se poate specifica o expresie boolean, numit expresie de gard. Aceast expresie, specificat n paranteze dup cuvntul cheie block, creeaz n mod implicit un semnal boolean numit guard, care se poate utiliza pentru controlul unor operaii din cadrul blocului. Acest semnal poate fi citit ca orice alt semnal din cadrul instruciunii block, dar nu poate fi actualizat printr-o instruciune de asignare. De fiecare dat cnd apare o tranzacie asupra unuia din semnalele dintr-o expresie de gard, expresia este evaluat i semnalul guard este actualizat imediat. Acest semnal ia valoarea TRUE dac valoarea expresiei de gard este adevrat i FALSE n caz contrar. Semnalul guard poate fi declarat i n mod explicit ca un semnal de tip boolean n cadrul instruciunii block. Avantajul acestei declarri explicite este c se poate utiliza un a lgoritm mai complex pentru controlul semnalului guard dect cel permis de o expresie boolean. n particular, se poate utiliza un proces separat pentru controlul acestui semnal. Dac ntr-un bloc nu se specific o expresie de gard i semnalul guard nu este declarat n mod explicit, atunci acest semnal are ntotdeauna valoarea TRUE. Semnalul guard poate fi utilizat pentru controlul instruciunilor de asignare a semnalelor din cadrul blocului. O asemenea instruciune de asignare conine cuvntul cheie guarded dup simbolul de asignare, care determin ca execuia instruciunii de asignare s fie condiional:
semnal <= guarded expresie;

Aceast asignare se execut numai dac semnalul guard al blocului care conine expresia de gard are valoarea TRUE.

Instruciuni concurente n limbajul VHDL

n Exemplul 6, semnalului out1 i se va asigna valoarea not in1 numai dac valoarea expresiei clk'event and clk = '1' va fi adevrat.

Exemplul 6
front_crescator: block (clk'event and clk = '1') begin out1 <= guarded not in1 after 5 ns; ... end block front_crescator;

n Exemplul 7, semnalul guard este declarat in mod explicit, astfel nct i se poate asigna o valoare ca i oricrui alt semnal.

Exemplul 7
UAL: block signal guard: boolean := FALSE; begin out1 <= guarded not in1 after 5 ns; ... p1: process begin guard <= TRUE; ... end process p1; end block UAL;

Observaii
n general, utilitarele de sintez nu permit utilizarea blocurilor cu expresii de gard. Un asemenea bloc este echivalent cu un proces cu o list de sensibilitate care conine instruciuni condiionale. Se poate utiliza un asemenea proces n locul unui bloc cu o expresie de gard. De obicei, blocurile simple sunt ignorate de utilitarele de sintez. Dei blocurile se pot utiliza pentru partiionarea descrierilor, limbajul VHDL permite utilizarea unui mecanism mai puternic pentru partiionare, i anume instanierea componentelor.

2. Descrierea unor circuite combinaionale


2.1. Multiplexoare
Pentru descrierea multiplexoarelor se pot utiliza diferite metode. Exemplul 8 prezint descrierea multiplexorului 4:1 pentru magistrale de 4 bii din figura 5 utiliznd o instruciune de asignare selectiv.

Figura 5. Schema unui multiplexor 4:1 pentru magistrale de 4 bii.

10

Structura sistemelor de calcul

Exemplul 8
library ieee; use ieee.std_logic_1164.all; entity mux is port (a, b, c, d: in std_logic_vector (3 downto 0); s: in std_logic_vector (1 downto 0); x: out std_logic_vector (3 downto 0)); end mux; architecture arh_mux of mux is begin with s select x <= a when "00", b when "01", c when "10", d when "11", d when others; end arh_mux;

Motivul pentru care se utilizeaz cuvntul cheie others este c semnalul de selecie s este de tip std_logic_vector i exist nou valori posibile ale unui obiect de acest tip. Toate valorile posibile ale semnalului de selecie trebuie acoperite. n cazul n care nu s -ar fi utilizat opiunea others, doar patru din cele 81 de valori posibile ar fi acoperite de setul de opiuni. Alte valori posibile ale semnalului s sunt, de exemplu, "1X", "UX", "Z0", "U-". Pentru sintez "11" este singura valoare util, ns pentru simulare semnalul s poate avea alte 77 de valori posibile. Se poate utiliza i valoarea metalogic "--" pentru asignarea unei valori indiferente semnalului x. Multiplexorul 4:1 poate fi descris cu ajutorul unei instruciuni if n modul indicat n Exemplul 9.

Exemplul 9
architecture arh_mux of mux is begin mux4_1: process (a, b, c, d, s) begin if s = "00" then x <= a; elsif s = "01" then x <= b; elsif s = "10" then x <= c; else x <= d; end if; end process mux4_1; end arh_mux;

Deoarece condiiile implic valori mutual exclusive ale semnalului s, prin sinteza acestei descrieri se genereaz acelai circuit ca i n cazul utilizrii unei instruciuni de asignare selectiv. ns, deoarece condiiile conin o prioritate, instruciunea if nu este avantajoas atunci cnd condiiile implic semnale multiple care sunt mutual exclusive. Utilizarea unei instruciuni if n aceste cazuri poate determina generarea unei logici suplimentare pentru a asigura faptul c precedentele condiii nu sunt adevrate. n locul unei instruciuni if, este mai avantajoas utilizarea unei ecuaii booleene sau a unei instruciuni case.

Instruciuni concurente n limbajul VHDL

11

2.2. Decodificatoare
Un decodificator este un circuit combinaional care identific un cod de intrare prin activarea unei singure linii de ieire, corespunztoare codului de intrare. Un decodificator cu n linii de intrare are, n general, 2n linii de ieire i se noteaz cu DCD n:2n. Exemplul 10 descrie un decodificator 1:8 pentru care liniile de ieire sunt active n starea 1 logic. Pentru descriere se utilizeaz o instruciune de asignare condiional.

Exemplul 10
library ieee; use ieee.std_logic_1164.all; entity decodif_1_8 is port (a: in std_logic_vector (2 downto 0); y: out std_logic_vector (7 downto 0)); end decodif_1_8; architecture decod of decodif_1_8 begin y <= "00000001" when a = "000" "00000010" when a = "001" "00000100" when a = "010" "00001000" when a = "011" "00010000" when a = "100" "00100000" when a = "101" "01000000" when a = "110" "10000000"; end decod; is else else else else else else else

Atunci cnd se utilizeaz programul de sintez XST, pentru a se genera un decodificator din descrierea HDL trebuie s se specifice toate combinaiile intrrilor i trebuie utilizate toate ieirile (de exemplu, nu trebuie specificate valori 'X' pentru liniile de ieire).

2.3. Codificatoare prioritare


Un exemplu de codificator prioritar este prezentat n figura 6.

Figura 6. Schema unui codificator prioritar.

Acest codificator prioritar poate fi descris n mod concis cu ajutorul unei instruciuni de asignare condiional, ca n Exemplul 11.

Exemplul 11
library ieee; use ieee.std_logic_1164.all; entity codif_prioritar is port (a, b, c, d: in std_logic;

12

Structura sistemelor de calcul

w, x, y, z: in std_logic; j: out std_logic); end codif_prioritar; architecture prioritar begin j <= w when a = '1' x when b = '1' y when c = '1' z when d = '1' '0'; end prioritar; of codif_prioritar is else else else else

Instruciunea when-else din exemplul precedent indic faptul c semnalului j i se asigneaz valoarea semnalului w atunci cnd a este '1', chiar dac b, c sau d sunt '1'. Semnalul b este prioritar fa de semnalele c i d, iar semnalul c este prioritar fa de semnalul d. Dac semnalele a, b, c i d sunt mutual exclusive (deci, se cunoate c numai unul din acestea va fi activ la un moment dat), atunci este mai avantajoas descrierea din Exemplul 12.

Exemplul 12
library ieee; use ieee.std_logic_1164.all; entity fara_prioritate is port (a, b, c, d: in std_logic; w, x, y, z: in std_logic; j: out std_logic); end fara_prioritate; architecture fara_prioritate of fara_prioritate is begin j <= (a and w) or (b and x) or (c and y) or (d and z); end fara_prioritate;

Logica generat prin sinteza descrierii din Exemplul 12 necesit pori I cu doar dou intrri. Dei n cazul circuitelor CPLD porile I cu un numr mai mare de intrri nu necesit, de obicei, resurse suplimentare, n cazul circuitelor FPGA aceste pori pot necesita celule l ogice i nivele logice suplimentare. Descrierile din Exemplul 11 i Exemplul 12 nu sunt echivalente funcional, aceast echivalen existnd doar n cazul n care semnalele a, b, c i d sunt mutual exclusive. n acest caz, descrierea din Exemplul 12 genereaz o logic echivalent cu un numr mai redus de resurse.

2.4. Circuite combinaionale de deplasare


Un circuit combinaional de deplasare realizeaz o operaie de deplasare logic sau aritmetic asupra datelor de intrare. Intrrile circuitului de deplasare sunt datele care trebuie deplasate i selectorul a crui valoare binar specific distana de deplasare. Ieirea circuitului de deplasare este rezultatul operaiei de deplasare. Atunci cnd se utilizeaz programul de sintez XST, exist urmtoarele restricii pentru a se genera un circuit combinaional de deplasare din descrierea HDL: Se pot utiliza numai operatori de deplasare logic (sll, srl), deplasare aritmetic (sla, sra), rotire (rol, ror) i concatenare (&). Operaiile de deplasare care completeaz poziiile eliberate cu valori dintr-un alt semnal nu sunt recunoscute. Pentru un circuit de deplasare se poate utiliza un singur tip de operaie de deplasare. Valoarea care specific distana de deplasare n operaia de deplasare trebuie s fie pozitiv i trebuie incrementat sau decrementat numai cu 1 pentru fiecare valoare binar consecutiv a selectorului.

Instruciuni concurente n limbajul VHDL

13

Trebuie s fie prezente toate valorile selectorului. Exemplul 13 descrie un circuit combinaional de deplasare pentru vectori de 8 bii care pot fi deplasai la stnga cu una, dou sau trei poziii. Pentru descrierea circuitului de deplasare se utilizeaz o instruciune de asignare selectiv.

Exemplul 13
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity depl_stanga is port (din: in unsigned (7 downto 0); sel: in unsigned (1 downto 0); dout: out unsigned (7 downto 0)); end depl_stanga; architecture arch_depl of depl_stanga is begin with sel select dout <= din when "00", din sll 1 when "01", din sll 2 when "10", din sll 3 when others; end arch_depl;

3. Descrierea unor circuite secveniale


3.1. Circuite secveniale sincrone i asincrone
Circuitele secveniale reprezint acea categorie de circuite logice care cuprind elemente de memorare. Efectul de memorare se datoreaz unor legturi inverse (bucle de reacie) prezente n schemele logice ale acestor circuite. Semnalele generate la ieirile unui circuit secvenial depind att de semnalele de intrare, ct i de starea circuitului. Starea prezent a circuitului este determinat de o stare anterioar i de valorile se mnalelor de intrare. n cazul circuitelor secveniale sincrone, modificarea strii se poate realiza la momente bine definite de timp sub controlul unui semnal de ceas. n cazul circuitelor secveniale asincrone, modificarea strii poate fi cauzat de schimbarea aleatoare n timp a val orii unui semnal de intrare. Comportamentul unui circuit asincron este mai puin sigur, evoluia strii fiind influenat i de timpii de ntrziere ai componentelor circuitului. Trecerea ntre dou stri stabile se poate realiza printr-o succesiune de stri instabile, aleatoare. Circuitele secveniale sincrone sunt mai fiabile i au un comportament predictiv. Toate elementele de memorare ale unui circuit sincron i modific simultan starea, ceea ce elimin apariia unor stri intermediare instabile. Prin testarea semnalelor de intrare la momente bine definite de timp se reduce influena ntrzierilor i a eventualelor zgomote. Exist dou tehnici de proiectare a circuitelor secveniale: Mealy i Moore. n cazul circuitelor secveniale Mealy, semnalele de ieire depind att de starea curent, ct i de intrrile prezente. n cazul circuitelor secveniale Moore, ieirile sunt dependente numai de starea curent, fr s depind n mod direct de intrri. Metoda Mealy permite implementarea unui anumit circuit printr-un numr minim de elemente de memorare (bistabile), ns eventualele variaii necontrolate ale semnalelor de intrare se pot transmite semnalelor de ieire. Proiectarea prin metoda Moore necesit mai multe elemente de memorare pentru acelai tip de co mportament, dar funcionarea circuitului este mai sigur.

3.2. Bistabile
Exemplul 14 descrie un bistabil sincron de tip D acionat pe frontul cresctor al semnalului de ceas (figura 7).

14

Structura sistemelor de calcul

Figura 7. Simbolul unui bistabil de tip D.

Exemplul 14
library ieee; use ieee.std_logic_1164.all; entity bist_d is port (clk: in std_logic; d: in std_logic; q: out std_logic); end bist_d; architecture exemplu of bist_d is begin process (clk) begin if (clk'event and clk = '1') then q <= d; end if; end process; end exemplu;

Procesul utilizat pentru descrierea bistabilului este sensibil numai la modificrile semnalului de ceas clk. Tranziia semnalului de intrare d nu determin activarea procesului. Expresia clk'event i lista de sensibilitate sunt redundante, deoarece ambele detecteaz modificarea semnalului de ceas. Unele utilitare de sintez ignor ns lista de sensibilitate a procesului, motiv pentru care trebuie inclus expresia clk'event pentru descrierea evenimentelor acionate pe frontul semnalului de ceas. Pentru descrierea unui circuit latch acionat pe nivel (figura 8), se elimin condiia clk'event i se insereaz intrarea de date d n lista de sensibilitate a procesului, dup cum se arat n Exemplul 15.

Figura 8. Simbolul unui circuit latch de tip D.

Exemplul 15
architecture exemplu of latch_d is begin process (clk, d) begin if (clk = '1') then q <= d; end if; end process; end exemplu;

n exemplele 14 i 15 nu exist o condiie else. Fr aceast condiie, este specificat n mod implicit un element de memorie (care va pstra valoarea semnalului q). Cu alte cuvinte, urmtorul fragment:

Instruciuni concurente n limbajul VHDL

15

if (clk'event and clk = '1') then q <= d; end if;

are aceeai semnificaie pentru simulare ca i fragmentul:


if (clk'event and clk = '1') then q <= d; else q <= q; end if;

Aceasta este n concordan cu modul n care funcioneaz un bistabil de tip D. Cele mai multe utilitare de sintez nu permit utilizarea unei expresii else dup condiia if (clk'event and clk = '1'), deoarece implementarea unei asemenea descrieri poate fi ambigu.

3.3. Registre
Exemplul 16 descrie un registru de 8 bii printr-un proces similar celui din Exemplul 14, cu deosebirea c d i q sunt vectori. n plus, acest registru are un semnal de validare a ceasului (ce).

Exemplul 16
library ieee; use ieee.std_logic_1164.all; entity reg8 is port (clk: in std_logic; ce: in std_logic; d: in std_logic_vector (7 downto 0); q: out std_logic_vector (7 downto 0)); end reg8; architecture ex_reg of reg8 is begin process (clk) begin if (clk'event and clk = '1') then if (ce = '1') then q <= d; end if; end if; end process; end ex_reg;

3.4. Registre de deplasare


Un registru de deplasare este un circuit secvenial care deplaseaz la stnga sau la dreapta coninutul registrului cu o poziie n fiecare ciclu de ceas. De obicei, intrrile unui registru de deplasare sunt reprezentate de semnalul de ceas, o intrare serial de date, un semnal de setare/resetare sincron sau asincron i un semnal de validare a ceasului . n plus, un registru de deplasare poate avea semnale de control i de date pentru ncrcarea paralel sincron sau asincron. Datele de ieire ale unui registru de deplasare pot fi accesate fie serial, atunci cnd este accesibil numai coninutul ultimului bistabil pentru restul circuitului, fie n paralel, atunci cnd este accesibil coninutul mai multor bistabile. Circuitele FPGA Xilinx conin resurse dedicate (primitivele SRL16 i SRL32) care permit o implementare eficient a registrelor de deplasare fr utilizarea unor bistabile suplimentare. Totui, aceste resurse permit numai operaii de deplasare la stnga i au un numr limitat de semnale de intrare/ieire: ceas, validarea ceasului, intrare serial de date i ieire

16

Structura sistemelor de calcul

serial de date. n primitivele SRL nu sunt disponibile semnale de setare/resetare sincron sau asincron. De aceea, dac n descriere se utilizeaz orice logic de setare, resetare sau de ncrcare paralel, este posibil ca utilitarul de sintez XST s nu poat beneficia de avantajul primitivelor dedicate pentru o implementare eficient. Exist mai multe posibiliti pentru descrierea registrelor de deplasare n limbajul VHDL: Utilizarea operatorului de concatenare:
reg <= reg (6 downto 0) & si;

Utilizarea construciilor for loop; Utilizarea operatorilor de deplasare predefinii (sll, srl, sla, sra). Exemplul 17 descrie un registru de deplasare la stnga de 8 bii cu semnale de validare a ceasului, intrare serial i ieire serial. Pentru descrierea registrului de deplasare se utilizeaz o construcie for loop.

Example 17
library ieee; use ieee.std_logic_1164.all; entity reg8_depl is port (clk: in std_logic; ce: in std_logic; si: in std_logic; so: out std_logic); end reg8_depl; architecture reg_depl of reg8_depl is signal tmp: std_logic_vector (7 downto 0); begin process (clk) begin if (clk'event and clk = '1') then if (ce = '1') then for i in 0 to 6 loop tmp(i+1) <= tmp(i); end loop; tmp(0) <= si; end if; end if; end process; so <= tmp(7); end reg_depl;

3.5. Numrtoare
Exemplul 18 descrie un numrtor de 3 bii.

Exemplul 18
library ieee; use ieee.std_logic_1164.all; entity num3 is port (clk: in std_logic; num: out integer range 0 to 7); end num3; architecture num3_integer of num3 is signal tmp: integer range 0 to 7; begin

Instruciuni concurente n limbajul VHDL

17

cnt: process (clk) begin if (clk'event and clk = '1') then tmp <= tmp + 1; end if; end process cnt; num <= tmp; end num3_integer;

n exemplul anterior, pentru semnalul num, care este de tip integer, se utilizeaz operatorul de adunare. Majoritatea utilitarelor de sintez permit aceast utilizare, convertind tipul integer la tipul bit_vector sau std_logic_vector. Utilizarea tipului integer pentru porturi pune ns unele probleme: 1) Pentru a utiliza valoarea num ntr-o alt poriune a proiectului pentru care interfaa are porturi de tip std_logic, trebuie efectuat o conversie de tip. 2) Vectorii aplicai n timpul simulrii codului surs nu pot fi utilizai pentru simularea modelului generat n urma sintezei. Pentru codul surs, vectorii trebuie s fie valori ntregi. Modelul generat n urma sintezei necesit vectori de tip std_logic. Deoarece operatorul nativ + al limbajului VHDL nu este definit pentru tipurile bit sau std_logic, acest operator trebuie redefinit nainte de adunarea operanzilor care au aceste tipuri. Standardul IEEE 1076.3 definete funcii pentru redefinirea operatorului + pentru urmtoarele perechi de operanzi: (unsigned, unsigned), (unsigned, integer), (signed, signed) i (signed, integer). Aceste funcii sunt definite n pachetul numeric_std al standardului 1076.3. Exemplul 19 reprezint Exemplul 18 modificat pentru a se utiliza tipul unsigned pentru ieirea numrtorului.

Exemplul 19
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity num3 is port (clk: in std_logic; num: out unsigned (2 downto 0)); end num3; architecture num3_unsigned of num3 is signal tmp: unsigned (2 downto 0); begin cnt: process (clk) begin if (clk'event and clk = '1') then tmp <= tmp + 1; end if; end process cnt; num <= tmp; end num3_unsigned;

De obicei, utilitarele de sintez pun la dispoziie pachete suplimentare care redefinesc operatorii pentru tipul std_logic. Dei acestea nu sunt pachete standard, ele se utilizeaz adesea de ctre proiectani, deoarece permit operaii aritmetice i relaionale cu tipul std_logic, din acest punct de vedere fiind chiar mai utile dect pachetul numeric_std. De asemenea, aceste pachete nu necesit utilizarea a dou tipuri suplimentare ( signed, unsigned) n plus fa de tipul std_logic_vector i nici a funciilor necesare conversiei ntre aceste tipuri. La utilizarea unuia din aceste pachete pentru operaiile aritmetice, utilitarul

18

Structura sistemelor de calcul

de sintez va utiliza pentru tipul std_logic_vector o reprezentare fr semn sau una cu semn (n complement fa de 2) i va genera componentele aritmetice corespunztoare. Exemplul 20 prezint descrierea modificat a numrtorului din exemplele precedente pentru a se utiliza pachetul std_logic_unsigned i tipul std_logic_vector pentru ieirea numrtorului.

Exemplul 20
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity num3 is port (clk: in std_logic; num: out std_logic_vector (2 downto 0)); end num3; architecture num3_std_logic of num3 is signal tmp: std_logic_vector (2 downto 0); begin cnt: process (clk) begin if (clk'event and clk = '1') then tmp <= tmp + 1; end if; end process cnt; num <= tmp; end num3_std_logic;

3.5. Resetarea componentelor sincrone


Exemplele anterioare nu fac referire la resetarea componentelor descrise sau la condiiile iniiale. Standardul VHDL nu specific faptul c un circuit trebuie resetat sau iniializat. Pentru simulare, standardul specific faptul c, dac un semnal nu este iniializat explicit, acesta va fi iniializat cu valoarea avnd atributul 'left a tipului semnalului respectiv. Pentru ca circuitele reale s fie aduse ntr-o stare cunoscut la iniializare, trebuie utilizate semnale de resetare i setare (preset). Figura 9 ilustreaz un bistabil de tip D cu un semnal de resetare asincron. Acest bistabil poate fi descris n modul prezentat n Exemplul 21.

Figura 9. Simbolul unui bistabil de tip D cu un semnal de resetare asincron.

Exemplul 21
architecture exemplu_r of bist_d is begin process (clk, rst) begin if (rst = '1') then q <= '0'; elsif rising_edge (clk) then q <= d; end if; end process; end exemplu_r; -- 1 -- 2 -- 3 -- 4 -- 5 -- 6 -- 7 -- 8 -- 9 -- 10 -- 11

Instruciuni concurente n limbajul VHDL

19

Dac semnalul rst este activat, semnalul q va fi setat la '0', indiferent de valoarea semnalului de ceas. Funcia rising_edge este definit n pachetul std_logic_1164, avnd rolul de a detecta frontul cresctor al unui semnal. Aceast funcie se poate utiliza n locul expresiei (clk'event and clk = '1'), dac semnalul clk este de tip std_logic. n acelai pachet este definit i funcia falling_edge, care detecteaz fronturile descresctoare ale semnalelor. Aceste funcii sunt preferate de ctre unii proiectani deoarece la simulare funcia rising_edge, de exemplu, va asigura c tranziia este de la '0' la '1' i nu va ine cont de alte tranziii, cum este cea de la 'U' la '1'. Pentru a descrie un bistabil cu un semnal de setare asincron, liniile 5-7 din exemplul anterior se modific astfel:
if (set = '1') then q <= '1'; elsif rising_edge (clk) then ---5 6 7

De obicei, circuitele FPGA au semnale dedicate de resetare sau setare. De exemplu, circuitele FPGA Xilinx au un semnal dedicat de resetare asincron numit Global Set/Reset (GSR). Acest semnal este activat n mod automat la sfritul configurrii circuitului FPGA. Pentru simularea la nivelul porilor logice, n modelul generat pentru simulare este inserat i semnalul GSR pentru a permite simularea cu acuratee a proiectului iniializat. Atunci cnd este disponibil un semnal dedicat de resetare asincron, utilizarea unui semnal de resetare asincron ntr-un proiect nu este recomandat din urmtoarele motive: Semnalul dubleaz doar semnalul de resetare dedicat; Analiza temporal este mai dificil; Circuitul sintetizat de utilitarul de sintez este mai puin optim. Se pot utiliza semnale de resetare (sau de setare) sincrone prin includerea condiiei respective n interiorul poriunii procesului care este sincron cu ceasul, dup cum se indic n Exemplul 22.

Exemplul 22
architecture exemplu_r_sinc of bist_d is begin process (clk) begin if rising_edge (clk) then if (rst = '1') then q <= '0'; else q <= d; end if; end if; end process; end exemplu_r_sinc;

Execuia procesului din exemplul anterior depinde numai de modificrile semnalului de ceas. n urma sintezei se genereaz un bistabil D care resetat n mod sincron atunci cnd semnalul rst este activ i apare un front cresctor al semnalului de ceas. Deoar ece bistabilele circuitelor CPLD nu dispun, de obicei, de intrri de setare sau resetare sincron, implementarea acestor intrri necesit utilizarea unor resurse logice suplimentare (figura 10).

Figura 10. Resurse logice suplimentare necesare pentru un semnal de resetare sincron.

20

Structura sistemelor de calcul

Se pot utiliza i combinaii de semnale sincrone i asincrone de resetare (sau setare). Uneori sunt necesare dou semnale asincrone: att un semnal de resetare, ct i unul de se tare. Exemplul 23 prezint un numrtor de 8 bii cu semnale asincrone de resetare i setare.

Exemplul 23
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity num8 is port (clk: in std_logic; rst, set: in std_logic; en, load: in std_logic; data: in std_logic_vector (7 downto 0); num: out std_logic_vector (7 downto 0)); end num8; architecture arh_num8 of num8 is signal tmp: std_logic_vector (7 downto 0); begin cnt: process (rst, set, clk) begin if (rst = '1') then tmp <= (others => '0'); elsif (set = '1') then tmp <= (others => '1'); elsif (clk'event and clk = '1') then if (load = '1') then tmp <= data; elsif (en = '1') then tmp <= tmp + 1; end if; end if; end process cnt; num <= tmp; end arh_num8;

n exemplul anterior, ambele semnale rst i set sunt utilizate pentru asignarea asincron a unor valori la registrele numrtorului. Combinaia de semnale de resetare i setare din acest exemplu ridic o problem legat de sintez. Construcia if-then-else utilizat n cadrul procesului implic o preceden faptul c numrtorului trebuie s i se asigneze valoarea "11111111" numai atunci cnd semnalul set este activ i semnalul rst nu este activ. Logica din figura 11 (a) asigur aceast condiie.

Figura 11. Rezultatul sintezei descrierii din Exemplul 20: (a) logica suplimentar asigur ca semnalul rst s fie dominant; (b) rezultatul dac se presupune c semnalul rst este dominant.

Exist posibilitatea ca aceasta s nu reprezinte comportarea dorit. Unele utilitare de sintez pot recunoate faptul c acesta nu reprezint efectul dorit i c prin construcia bistabilelor este dominant fie semnalul rst, fie semnalul set. Astfel, n funcie de algoritmul utilizat de programul de sintez, descrierea din Exemplul 23 va genera fie logica din figura 11

Instruciuni concurente n limbajul VHDL

21

(a), fie cea din figura 11 (b). Multe circuite CPLD care permit resetarea sau setarea prin termeni produs pot implementa ambele variante. n timp ce majoritatea circuitelor FPGA permit resetarea sau setarea eficient prin semnale globale, de obicei acestea nu dispun de resurse pentru resetarea sau setarea eficient prin termeni produs, caz n care implementarea din figura 11 (b) este preferat. n toate exemplele anterioare n care exist semnale de resetare sau setare s -a utilizat instruciunea if sau funcia rising_edge pentru descrierea circuitelor sincrone. Pentru descrierea acestor circuite se poate utiliza i instruciunea wait until, dar n acest caz semnalele de resetare i setare trebuie s fie sincrone. Aceasta deoarece pentru descrierile destinate sintezei instruciunea wait trebuie s fie prima din cadrul unui proces, astfel nct toate instruciunile care urmeaz vor descrie o logic sincron.

3.6. Buffere cu trei stri i semnale bidirecionale


Majoritatea circuitelor programabile dispun de ieiri cu trei stri sau semnale bidire cionale de I/E. n plus, anumite circuite dispun de buffere interne cu trei stri. Un semnal cu trei stri poate avea valorile '0', '1' i 'Z', toate acestea fiind permise de tipul std_logic. Exemplul 24 prezint descrierea modificat a numrtorului din Exemplul 23 pentru a utiliza ieiri cu trei stri. Acest numrtor nu dispune de un semnal de setare asincron.

Exemplul 24
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity num8 is port (clk, rst: in std_logic; en, load: in std_logic; oe: in std_logic; data: in std_logic_vector (7 downto 0); num: out std_logic_vector (7 downto 0)); end num8; architecture arh_num8 of num8 is signal tmp: std_logic_vector (7 downto 0); begin cnt: process (rst, clk) begin if (rst = '1') then tmp <= (others => '0'); elsif rising_edge (clk) then if (load = '1') then tmp <= data; elsif (en = '1') then tmp <= tmp + 1; end if; end if; end process cnt; oep: process (oe, tmp) begin if (oe = '0') then num <= (others => 'Z'); else num <= tmp; end if; end process oep; end arh_num8;

22

Structura sistemelor de calcul

Comparativ cu descrierea din Exemplul 23, n aceast descriere se utilizeaz un semnal suplimentar oe pentru controlul ieirilor cu trei stri. Procesul etichetat cu oep descrie ieirile cu trei stri ale numrtorului. Dac semnalul oe nu este activat, ieirile sunt trecute n starea de nalt impedan. Descrierea procesului oep este n concordan cu funcionarea unui buffer cu trei stri (figura 12).

Figura 12. Buffer cu trei stri.

Numrtorul din exemplele precedente poate fi modificat astfel nct pentru ieirile acestuia s se utilizeze semnale bidirecionale. n acest caz, numrtorul poate fi ncrcat cu valoarea curent a ieirilor acestuia, ceea ce nseamn c valoarea ncrcat atunci cnd se mnalul load este activ va fi valoarea precedent a numrtorului sau o valoare aplicat din e xterior, n funcie de starea semnalului oe. n Exemplul 25, semnalul de validare a ieirilor unui buffer cu trei stri este definit n mod implicit.

Exemplul 25
mux: process (adr_lin, adr_col, stare_prez) begin if (stare_prez = linie or stare_prez = RAS) then dram <= adr_lin; elsif (stare_prez = coloana or stare_prez = CAS) then dram <= adr_col; else dram <= (others => 'Z'); end if; end process mux;

Bufferele cu trei stri ale semnalului dram sunt validate dac valoarea semnalului stare_prez este linie, RAS, coloana sau CAS. Pentru orice alt valoare a acestui semnal, bufferele de ieire nu sunt validate. n exemplele anterioare, pentru bufferele cu trei stri s-au utilizat descrieri funcionale. Pentru generarea acestor buffere se pot utiliza i descrieri structurale, cum este construcia for generate. Aceast construcie va fi descris n lucrarea de laborator dedicat proiectrii structurale.

4. Aplicaii
4.1. Modificai urmtoarea secven pentru a utiliza o instruciune de asignare cond iional:
process (a, b, j, k) begin if a = '1' and b = '0' then pas <= "0100"; elsif a = '1' then pas <= j; elsif b = '1' then pas <= k; else pas <= "----"; end if; end process;

4.2. Transformai urmtoarea secven ntr-o instruciune case:

Instruciuni concurente n limbajul VHDL

23

with stare select data <= "0000" when "1111" when "1010" when "0101" when "----" when

inactiv | terminat, creste, mentine, scade, others;

4.3. Transformai urmtoarea secven n dou instruciuni de asignare selectiv:


case stare is when inactiv => a <= "11"; b <= "00"; when terminat | creste => a <= "01"; b <= "--"; when mentine | scade => a <= "10"; b <= "11"; when others => a <= "11"; b <= "01"; end case;

4.4. Rescriei urmtoarea secven utiliznd o instruciune condiional if:


iesire <= a when stare = inactiv else b when stare = receptie else c when stare = transmisie else d;

4.5. Implementai memoria FIFO pe o plac de dezvoltare, urmrind etapele descrise n documentul Aplicatie-FIFO.pdf.

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