Aspecte avansate

33
Aspecte avansate (Advanced topics) Capitolul 7

description

Aspecte avansate. (Advanced topics) Capitolul 7. Cuprins. 7.1. Functii de rezolutie 7.2. Semnale gardate. Deconectare 7.3. Instructiunea GENERATE. 7.1.Functii de rezolutie. Se utilizeaza pentru a rezolva valoarea unui semnal atunci cind semnalul are mai multe drivere (surse) - PowerPoint PPT Presentation

Transcript of Aspecte avansate

Aspecte avansate

(Advanced topics)

Capitolul 7

Cuprins

• 7.1. Functii de rezolutie

• 7.2. Semnale gardate. Deconectare

• 7.3. Instructiunea GENERATE

7.1.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.

Functii de rezolutie

• O functie de rezolutie – are un singur parametru de intrare

• Care este intotdeauna un unconstrained array cu elemente de tipul semnalului

– si returneaza o singura valoare: • Valoarea are tipul semnalului si se numeste valoare

rezolvata– Parametrul de intrare este unconstrained array

deoarece atunci cind se scrie functia nu se cunoaste cite drivere va avea semnalul in momentul apelului functiei.

• Pentru un semnal rezolvat (declarat ca atare) se apeleaza functia de rezolutie chiar daca semnalul are un singur driver.

Declararea unui semnal rezolvatExemplu gresit:

TYPE fourval IS (X,L,H,Z);

SUBTYPE fourval_rez IS frez fourval;

-- frez este functia de rezolutie

-- Ex e gresit deoarece functia de rezolutie nu a fost specificata sau declarata.

In concluzie, pt declararea unui semnal rezolvat trebui respectata o succesiune stricta de pasi:

PACKAGE frezpack IS

TYPE fourval IS (X,L,H,Z);

TYPE fourval_vector IS ARRAY(NATURAL RANGE<>) OF fourval;

FUNCTION frez(t: fourval_vector) RETURN fourval;

SUBTYPE fourval_rez IS frez fourval;

END PACKAGE frezpack;

Declararea unui semnal rezolvatUn semnal rezolvat poate fi declarat in doua moduri:

1. ca subtip rezolvat

2. prin utilizarea functiei de rezolutie in declararea semnalului.

Exemplu (continuare):

USE WORK.frezpack.ALL;

ENTITY ex IS

END;

ARCHITECTURE ex_rezolvat OF ex IS

SIGNAL s1,s2: fourval_rez;--modul 1

SIGNAL s3: frez fourval;--modul 2

BEGIN

END ARCHITECTURE;

Functii de rezolutie: exempluIn mod normal o functie de rezolutie e asociativa si comutativa pentru ca rezultatul returnat sa nu depinda de ordinea in care se parcurg intrarile functiei (adica driverele semnalului) deoarece programatorul nu controleaza ordinea respectiva.

Exemplu de functie de rezolutie pentru tipul fourval:

Taria valorilor tipului fourval:

X

HL

Z

Scade taria

X inseamna valoare nedeterminata,

Z inseamna impedanta ridicata.

L si H au aceeasi tarie.

Atunci cind exista cel putin un driver L si cel putin unul H functia de rezolutie va returna X.

Functii de rezolutie: exemplu

Tabelul dupa care functioneaza functia:

X L H Z

X X X X X

L X L X L

H X X H H

Z X L H Z

Functii de rezolutie: exempluFunctia din exemplu:

PACKAGE BODY frezpack IS

FUNCTION frez(t: fourval_vector) RETURN fourval IS

VARIABLE result: fourval:=Z;--se initializeaza cu

--valoarea cea mai slaba a tipului fourval

BEGIN

FOR i IN t’RANGE LOOP --t’RANGE parcurge tot tabloul t

CASE t(i) IS

WHEN X => result:=X; RETURN result;

WHEN L=>

CASE result IS

WHEN X|H => result:=X;

RETURN result;

WHEN L|Z => result:=L;

END CASE;

WHEN H=>CASE result IS

WHEN X|L => result:=X; RETURN result;

WHEN H|Z => result:=H;END CASE;

WHEN Z => NULL;--result ramine neschimbatEND CASE;

END LOOP;RETURN result;END FUNCTION frez;END PACKAGE BODY;

Observatie: In acest caz functia s-ar fi putut implementa si cu IF in loc de CASE, dar cu CASE e o metoda mai generala.

Functii de rezolutie pentru magistrale

• Daca exista mai multe dispozitive conectate la o magistrala trebuie avut grija ca la un moment dat un singur dispozitiv sa controleze magistrala:– Trebuie tratata situatia cind mai multe dispozitive vor sa controleze

magistrala • => e conflict• Se semnaleaza printr-o valoare speciala “multiple drivers” returnata de

functia de rezolutie– Trebuie tratata si situatia cind nici un dispozitiv nu controleaza

magistrala:• Functia de rezolutie va returna o valoare speciala “not driven”• Aceasta valoare o are si un semnal ca sa arate ca dispozitivul respectiv nu

controleaza magistrala• Valorile speciale se pot lua dintre valorile neutilizate ale magistralei

(de ex valori negative de adrese) sau • Daca nu exista valori neutilizate atunci

– Se va transforma tipul magistralei intr-un record– se mai adauga inca un cimp la valorile normale ale magistralei

ExempluPresupunem ca avem o magistrala de date si adrese, iar valorile adreselor pot fi doar intregi nenegativi, deci se pot alege doua valori negative ca valori speciale.

PACKAGE busrez IS

TYPE xtype IS RECORD

addr: INTEGER;--are doar valori >=0

data: INTEGER;

--cimp_suplimentar: INTEGER;

END RECORD;

CONSTANT notdriven: xtype:=(-1,-1);

CONSTANT multipledrivers: xtype :=(-2,-2);

TYPE xtype_vector IS ARRAY(NATURAL RANGE <>) OF xtype;

FUNCTION xf(t:xtype_vector) RETURN xtype;

SUBTYPE xbus IS xf xtype;

END PACKAGE busrez;

PACKAGE BODY busrez IS

FUNCTION xf(t:xtype_vector) RETURN xtype IS

VARIABLE result: xtype:=notdriven;

VARIABLE count: INTEGER:=0;

BEGIN

IF t’LENGTH=0 THEN --’LENGTH atribut ce retunreaza lungimea unui tablou

result:=notdriven;

REPORT “nici un driver” SEVERITY WARNING;

END IF;-- situatia poate aparea doar pt semnale gardate, ale caror drivere se pot

--deconecta

FOR i IN t’RANGE LOOP

IF t(i) /= notdriven THEN

count := count +1;

result:=t(i);

END IF;

IF count>1 THEN

result:=multipledrivers;

REPORT “mai multe drivere !” SEVERITY ERROR;

RETURN result;

END IF;

END LOOP;

IF count=0 THEN

REPORT “nici un driver !” SEVERITY WARNING;

END IF;

RETURN result;

END xf;

END PACKAGE BODY busrez;

7.2. Semnale gardate•Declaratia de semnale are sintaxa:

SIGNAL list_of_signals: [resolution_function] signal_type [signal_kind] [:=expression];

unde signal_kind poate fi BUS sau REGISTER

•Definitie: semnalele gardate sint semnale speciale declarate a fi BUS sau REGISTER.

•Semnalele gardate trebuie sa fie semnale rezolvate si deci trebuie sa aiba functie de rezolutie.

•Semnalelor gardate li se pot asigna valori doar in interiorul unor blocuri gardate.

•Catre semnalele gardate se pot face

- asignari concurente gardate sau

- asignari secveniale, dar

- NU se pot face asignari concurente negardate.

Semnale gardate•In interiorul unui bloc gardat, atunci cind semnalul GURAD devine FALSE, va avea loc deconectarea driverului semnalului gardat

•Deconectarea are loc dupa o perioada de timp numita disconnect time.•Atunci cind garda este TRUE, driverul semnalului primeste valori conform instructiunii de asignare de semnal

•In cazul unui semnal negardat care are o asignare concurenta gardata, atunci cind garda devine FALSE nu se deconecteaza driverul semnalului, ci driverul isi mentine valorile anterioare, fara a lua in considerare noile valori care ar putea fi generate de instructiunea de asignare de semnal (am spus ca driverul se dezactiveaza)

•A se vedea exemplul.

• Timpul dupa care se face deconectarea unui semnal gardat poate fi specificat prin disconnect_specification (dupa declararea semnalului):

DISCONNECT nume_semnal_gardat: signal_type AFTER time_expression;

• Deconectarea unui driver este un eveniment, deci se va apela functia de rezolutie.

ExempluARCHITECTURE guarded_ex OF exemplu IS

SIGNAL semnal_gardat: wired_or BIT REGISTER;

SIGNAL semnal_negardat: wired_and BIT;--nu e nevoie sa fie semnal rezolvat

BEGIN

b: BLOCK(guard_expression)

BEGIN

semnal_gardat <= GUARDED expression1 AFTER time1;

semnal_negardat <= GUARDED expression2 AFTER time2;

END BLOCK b;

END ARCHITECTURE;

Exemplul este echivalent cu:

Exemplu (continuare)ARCHITECTURE guarded_ex OF exemplu ISSIGNAL semnal_gardat: wired_or BIT REGISTER;SIGNAL semnal_negardat: wired_and BIT;--nu e nevoie sa fie semnal rezolvatBEGINb: BLOCK(guard_expression)BEGIN

p1: PROCESS

BEGIN

IF GUARD THEN

semnal_gardat <= expression1 AFTER time1;

ELSE

semnal_gardat <= NULL; -- se deconecteaza

-- semnal<=NULL inseamna deconectarea driverului

END IF;

WAIT ON GUARD, signals_in_expression1;

END PROCESS p1;

p2: PROCESS

BEGIN

IF GUARD THEN

semnal_negardat <= expression2 AFTER time2;

END IF;

--nu are ELSE deoarece NU SE INTIMPLA NIMIC atunci cind

-- GUARD = FALSE

WAIT ON GUARD, signals_in_expression2;

END PROCESS p2;

END BLOCK b;

END ARCHITECTURE;

Diferentele intre BUS si REGISTER

• Dupa locul unde pot aparea:– Semnalele gardate BUS pot fi

• atit semnale declarate local intr-o arhitectura cit si • Porturi ale unei entitati

– Semnalele gardate REGISTER pot fi• Doar semnale declarate local.

• Dupa modul cum se face deconectarea ultimului driver:– La un semnal gardat BUS:

• Daca se deconecteaza toate driverele, trebuie specificata valoarea pe care sa o aiba semnalul

• Adica functia de rezolutie trebuie sa specifice o valoare pt cazul cind nici un driver nu este conectat.

– La un semnal gardat REGISTER:• Cind se deconecteaza ultimul driver, semnalul isi va pastra valoarea anerioara• Nu se apeleaza functia de rezolutie la deconectarea ultimului driver• => functia de rezolutie nu trebuie neaparat sa specifice o valoare pt acest caz.

Exemplu de multiplexor 4:1 cu semnale gardate

USE WORK.my_pack.ALL; -- my pack contine functia de rezolutie sau_cablat

ENTITY mux IS

GENERIC(mux_del: TIME:= 5ns);

PORT(din: IN BIT_VECTOR(3 DOWNTO 0);

sel: IN BIT_VECTOR(1 DOWNTO 0);

z: OUT BIT);

END mux;

ARCHITECTURE cu_semnale_gardate OF mux IS

SIGNAL temp: sau_cablat BIT BUS; -- in acest caz poate fi si REGISTER

BEGIN

b0: BLOCK (sel=“00”)

BEGIN

temp<= GUARDED din(0);

END BLOCK b0;b1: BLOCK (sel=“01”)BEGIN

temp<= GUARDED din(1);END BLOCK b1;b2: BLOCK (sel=“10”)BEGIN

temp<= GUARDED din(2);END BLOCK b2;b3: BLOCK (sel=“11”)BEGIN

temp<= GUARDED din(3);END BLOCK b3;z <= temp AFTER mux_del;END ARCHITECTURE;-- in acest caz nu are mare importanta cum e functia de rezolutie, deoarece -- semnalul temp va avea un singur driver la un moment dat, restul de 3 -- drivere fiind deconectate.

7.3. Instructiunea GENERATE

• Este utilizata in special pentru descrierea structurilor regulate

• reprezinta un mecanism de compliare conditionata in VHDL

• Sintaxa instructiunii este:label_id: generation_scheme GENERATE

concurrent_statements

END GENERATE [label_id];

GENERATE (continuare)

• Schema de generare poate fi de tip:– FOR : indexul utilizat nu trebuie declarat– IF : nu are ELSIF si nici ELSE– IF si FOR nu au nici o semantica de executie (nici

o legatura cu instructiunile secventiale IF si LOOP FOR)

• Instructiunile concurente din corpul lui GENERATE sunt in mod tipic (dar nu neaparat) instantieri de componente.

• Compilatorul expandeaza codul din interiorul lui GENERATE. – De exemplu daca se utilizeaza o schema de generare de tip

FOR cu 5 iteratii si in corpul lui GENERATE se utilizeaza o instructiune de instantiere de componenta, atunci vor aparea 5 instantieri de componenta in codul expandat.

ExempluDescriem un registru de deplasare pe 4 biti utilizind GENERATE.Registrul e alcatuit din 4 bistabile de tip D.

Descrierea bistabilului D:

ENTITY dff_1 IS GENERIC(tp: time:=1ns); PORT(d, clk, reset: IN BIT; q, qb: OUT BIT);END dff_1;

ARCHITECTURE behave OF dff_1 ISBEGINPROCESS(reset, clk, d)BEGIN IF(reset='0') AND reset'EVENT THEN q<='0' AFTER tp; qb<='1' AFTER tp; ELSIF(clk='1') AND clk'EVENT AND clk'LAST_VALUE='0‘ THEN

q<= d AFTER tp; qb<=NOT d AFTER tp; END IF;END PROCESS;END ARCHITECTURE;

CONFIGURATION dff_cfg OF dff_1 IS FOR behave END FOR;END CONFIGURATION;

-- registrul de deplasare:

ENTITY shift_reg IS GENERIC(len: NATURAL:=4); PORT(reset, clock, a: IN BIT; b:OUT BIT);END shift_reg;

D

D D D

clk clk clk clkQ Q Q Q

reset reset reset resetreset

clock

ba

z(0) z(1) z(2) z(3) z(4)

Registrul de deplasare

shift_reg

Fig 11. Registru de deplasare realizat cu bistabile de tip D (D flip-flops)

Schema de generare de tip FOR

-- Instructiunea GENERATE cu-- schema de generare de tip FOR

ARCHITECTURE shift_gen_1 OF shift_reg IS COMPONENT dff IS GENERIC(tp:TIME:=1ns); PORT(d, clk, reset: IN BIT; q, qb: OUT BIT); END COMPONENT; SIGNAL z: BIT_VECTOR(0 TO 4);BEGIN z(0)<=a; g: FOR i IN 0 TO 3 GENERATE dffx: dff PORT MAP(z(i), clock, reset, z(i+1), OPEN); END GENERATE; b<=z(4);END shift_gen_1;

GENERATE cu schema de tip FOR si IF

Dezavantajul acestei descrieri este ca nu sunt tratate unitar, in cadrul instructiunii GENERATE, bistabilele de la capetele registrului de deplasare. Acest lucru se poate face combinind schema de generare de tip FOR cu scheme de tip IF:-- Instructiunea GENERATE cu scheme de generare de tip-- FOR si IF

ARCHITECTURE shift_gen_2 OF shift_reg IS COMPONENT dff IS GENERIC(tp:TIME:=1ns); PORT(d, clk, reset: IN BIT; q, qb: OUT BIT); END COMPONENT; SIGNAL z:BIT_VECTOR(1 TO len-1);

BEGIN g1: FOR i IN 0 TO (len-1) GENERATE g2: IF i=0 GENERATE dffx: dff PORT MAP(d=>a, clk=> clock, reset=>reset, q=>z(1), qb=>OPEN); END GENERATE g2;

g3: IF i=(len-1) GENERATE dffx: dff PORT MAP(d=>z(len-1), clk=>clock, reset=>reset, q=>b, qb=>OPEN); END GENERATE; --g3

g4: IF (i>0) AND (i<len-1) GENERATE dffx: dff PORT MAP(z(i), clock, reset, z(i+1), OPEN); END GENERATE g4; END GENERATE; -- g1END ARCHITECTURE shift_gen_2;

Configuratie pentru GENERATEConfiguratia registrului de deplasare:-- Configuratia pentru arhitectura shift_gen_2 va fi:CONFIGURATION cfg_gen OF shift_reg IS FOR shift_gen_2 FOR g1 FOR g2 FOR ALL: dff USE CONFIGURATION WORK.dff_cfg; END FOR; END FOR;--g2 FOR g3 FOR ALL: dff USE ENTITY WORK.dff_1(behave); END FOR; END FOR;--g3 FOR g4 FOR ALL: dff USE ENTITY WORK.dff_1(behave); END FOR; END FOR;--g4 END FOR; -- g1END FOR; -- shift_gen_2 END cfg_gen;

entity test_shift_reg isend;

architecture a_test of test_shift_reg is COMPONENT shift_reg IS GENERIC(len: NATURAL:=4); PORT(reset, clock, a: IN BIT; b:OUT BIT); END COMPONENT; SIGNAL insig, r, cl, outsig: BIT;BEGIN l: shift_reg PORT MAP(r, cl, insig, outsig); cl<=NOT cl AFTER 50ns; r<='1', '0' after 3ns, '1' after 40ns; insig<='1' after 145ns, '0' after 380ns, '1' after 1680ns;end;

O entitate de test a registrului de deplasare:

configuration cfg_test of test_shift_reg isfor a_test for l: shift_reg use configuration work.cfg_gen; end for;end for;end cfg_test;