You are on page 1of 17

Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12

1. Verifikacija
Verifikacija projektovanog digitalnog sistema je sloeni proces koji ima sledee ciljeve:
Demonstracija funkcionalne ispravnosti
Pronalaenja greaka u implementaciji
Dokazati da je implementacija u skladu sa projektnom specifikacijom

Krajnji domet verifikacije projektovanog digitalnog sistema je da je on implementiran prema ranije definisanoj
specifikaciji. Detekcijom samo jedne greke u implementaciji pokazuje se da ona nije funkcionalno korektna. Meutim,
pomou verifikacije se ne moe pokazati da u implementaciji nema greaka, ve samo da je ona u skladu sa specifikacijom.
Osnovna ideja verifikacije je da se implementacija poredi sa specifikacijom digitalnog sistema, Slika 1.1.

Pisanje RTL koda

Pisana
RTL kod
specifikacija

Verifikacija

Slika 1.1 Osnovni princip verifikacije RTL koda naspram specifikacije

Meutim, tokom stvarnog procesa projektovanja digitalnog sistema inenjer se prvo upozna sa specifikacijom i praktino
napravi interpretaciju specifikacije u skladu sa njegovim znanjima. Na osnovu interpretacije se u sledeem koraku formira
odgovarajui RTL opis. Ukoliko isti inenjer uestvuje u verifikaciji ovako formiranog RTL koda, on zapravo ne verifikuje
naspram specifikacije ve naspram njegove interpretacije tog dokumenta, Slika 1.2.

Pisanje RTL koda

Pisana Interpretacija
RTL kod
specifikacija

Verifikacija
Slika 1.2 Stvaran process verifikacije RTL koda naspram specifikacije

Da bi se izbegle mogue greke prilikom interpretacije specifikacije digitalnog sistema koji se projektuje najbolji pristup
je da formiranje RTL koda i njegovu verifikaciju rade dva razliita inenjera, Slika 1.3. Ovakvim pristupom se formiraju dve
razliite interpretacije specifikacije i konaan oblik RTL koda se verifikuje nezavisno od interpretacije inenjera koji je
napisao RTL kod.

Interpretacija
Pisanje RTL koda
dizajnera

Pisana RTL kod


specifikacija

Verifik.
interpretacija
Verifikacija

Slika 1.3 Redundantnost u verifikaciji RTL koda naspram specifikacije

U skladu sa prethodnim opisom, pod verifikacijom se podrazumeva proces untvrivanja funkcionalne ispravnosti RTL
koda naspram specifikacije. Ovaj proces se realizuje pomou alata za simulaciju sistema.
Kada se utvrdi funkcionalna ispravnost isprojektovanog digitalnog sistema, sledei korak je njegovo testiranje u realnom
vremenu uz pomo odgovarajueg fizikog sistema, npr. na demostracionoj ploici LL5000. Pri tome je potrebno na osnovu
verifikovanog RTL koda napraviti binarnu datoteku koja e se iskoristiti za programiranje fizike arhitekture. U sluaju da je
krajnji cilj programabilna sekvencijlana mrea potrebno je uraditi sintezu RTL koda. U terminologiji proizvoaa
programabilnih sekvencijalnih mrea Xilinx, proces sinteze se naziva FPGA place & route.

1
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
Meusobni odnos izmeu verifikacije i testiranja prikazuje Slika 1.4.

Implementacija FPGA place & route

Specifikacija RTL kod FPGA

Verifikacija Testiranje

Slika 1.4 Odnos verifikacije i testiranja

Praktino pomou verifikacije se proverava da li je implementacija u skladu sa verifikacijom i realizuje se pre pokretanja
u realnom vremenu (pre sinteze). Testiranje proverava da li su nastupile neke greke rokom sinteze implementacije za rad u
realnom vremenu i realizuje se nakon procesa verifikacije (posle sinteze).
Tokom funkcionalne verifikacije postoje tri razliita pristupa:
1. Metod crne kutije (engl. Black Box)
koriste se samo ulazno/izlazni portovi i pristup unutranjim informacijama nije mogu
kod ovog pristupa informacije o implementaciji nisu relevantne i ne utiu na proces verifikacije
2. Metod bele kutije (engl. White Box)
koriste se ulazno/izlazni portovi i unitranji signali ime informacije o nainu implementacije utiu na tok
verifikacije zahvaljujui potpunom pristupu unutranjim informacija tokom procesa verifikacije
3. Metod sive kutije (engl. Grey Box)
koriste se samo ulazno/izlazni portovi za verifikaciju i pristup unutranjim informacijama nije mogu
kod ovog pristupa informacije o implementaciji utiu na tok verifikacije

Sve tri metode verifikacije prikazuje Slika 1.5.

Slika 1.5Metode verifikacije


a) metod crne kutije, b) metod bele kutije, c) metod sive kutije

2. Testbench
Pod testbench-om se podrazumeva HDL izvorni kod koje se koristi za verifikaciju isprojektovanog modula. Testbench
sadri sledee tri osnovne funkcije:
1. Formiranje pobude
2. Provera izlaza
3. Izvetavanje o grekama i toku simulacije

Praktino, testbench je model na najviem hijerarhijskom nivou koji instancira modul koje se verifikuje, pobuuje ga
definisnaim skupom test vektora i poredi generisane rezultate sa oekivanim.
Modul koji se verifikuje se oznaava sa UUT (engl. Unit Under Test). Takoe, este oznake su i DUV (engl. Device
Under Verification) i DUT (engl. Device Under Test).
Testbench se gotovo u svim situacijma oznaava skraenicom TB.
Kada se testbench uporedi sa grafikim alatima za formiranje pobude modula koji se verifikuje (npr. Xilinx TestBench
Waveform) istiu se tri osnovne prednosti:
TB je nezavistan od simulatora
Mogunost automatske verifikacije, bez vizuelne interpretacije vremenskih dijagrama
Kompleksni ulazi i izlazi se mogu modelovati uz pomo punog skupa HDL komandi jezika koji se koristi za
verifikaciju, ukljuujui i kontrolu toka simulacije.
Svaki HDL jezik prua podrku i za pristup dodatnim datotekama koje se mogu iskoristiti za generisanje pobude
ili za upisivanje toka i rezultata simulacije

Tipino se prilikom verifikacije formira poseban testbench za svaki modul pojedinano. Tako na primer za sistem koji
prikazuje Slika 2.1 se tipino formiraju 4 razliita testbench-a: po jedan za podmodule M1, M2 i M3 i jedan za najvii
hijerarhijski nivo prestavljen modulom M4.
2
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12

Definicija modula M4

Instanca
modula
M1

Instanc Instanca
a modula
modula M3
M2

Slika 2.1Primer tipinog sistema za verifikaciju

Sa ovakvim pristupom se proverava funkcionalnost svakog modula pojedinano tokom implementacije sistema. Poto se
u procesu implementacije i verifikacije deavaju promene u RTL kodu, testbench se koristi za proveru funkcionalne ispravnosti
nakon odreene izmene u tom modulu kao i za proveru rezultata nakon sinteze. Sa skupom testbench-eva za sve module
pojedinano se moe uraditi poluautomatska verifikacija nakon modifikacije odreene grupe modula.
Izgled tipinog testbench-a prikazuje Slika 2.2.

Testbench

Device
Under
Verification
(DUV)

Slika 2.2 Tipian testbench

U zavisnosti od vrste sistema koji se verifikuje moe se iskoristi jedan od sledeih pristupa verifikaciji pomou testbench-
eva.

Vizuelna provera izlaza:


Veoma rairena metoda verifikacije je pomou vizuelne provere rezultata simulacije. Ovakav pristup se najee koristi u
ranim fazama verifikacije sistema kada je testbench i sam digitalni sistem jo uvek u fazi razvoja.
Praktino, u testbenchu se na odreeni nain formira pobuda (engl. stimulus) za modul koji se verifikuje i rezultat
simulacije se snimi u odgovarajuu datoteku. Izlazni vektor moe biti snimljenu formi vremenskog dijagrama ili u obliku
tekstualne datoteke odgovarajueg formata. Nakon zavretka simulacije sadraj snimljenog izlaznog vektora se vizuelno
interpretira i proveravaju se da li su uslovi iz specifikacije zadovoljeni ili ne. Ovaj koncept prikazuje Slika 2.3.

3
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
Simulator

Stimulus DUV Vector Viewer


file

Slika 2.3 Vizuelna provera rezultata simulacije

Pored iroke rairenosti, ova metoda obuhvati niz potekoa. Zbog vizuelne provere, interpretacija rezultata moe biti
pogrena. Takoe, u dugakim simulacijama sa dugakim izlaznim vektorima mogu je previd odreenih kritinih momenata.
U praksi, veliki broj promena u simulaciji nije mogue u potpunosti ispratiti do kraja. Veliki nedostatak ove metode je da se ne
moe reprodukovati isti rezultat verifikacije iz razloga vizuelne provere rezultata.
Na osnovu ove kratke analize zakljuuje se da je ovaj pristup verifikaciji pogodan samo za verifikaciju relativno malih i
jednostavnih digitalnih sistema.

Referentni vektori:
Ovaj pristup olakava proces utvrivanja korektnosti rezultata jer su oekivani rezultati snimljeni u posebnu datoteku.
Praktino nakon zavretka simulacije potrebno je samo uporediti da li su rezultati simulacije i oekivani rezultati iz referentne
datoteke identini. Ukoliko jesu, verifikacija je zavrena dok se u suprotnom sluaju mora utvrditi mesto i razlog neslaganja.
Slika 2.4 ilustruje ovakav pristup verifikaciji.

Simulator

Stimulus DUV Vector Viewer


file

Vector Comparator
file

Slika 2.4 Provera rezultata poreenjem sa referentnim vektorom

Samoprovera rezultata tokom simulacije:


Kod ovog pristupa taan rezultat simulacije se izraunava tokom same simulacije. Potrebno je veliko ulaganje za razvoj
ovakvog simulacionog okruenja jer je potrebno obezbediti sistem za raunanje referentne vrednosti. Ukoliko se oekuju
promene u specifikaciji referentnog modela ovaj pristup nije pogodan jer je potrebno usaglasiti i testbench i implementaciju
digitalnog sistema. Slika 2.5 prikazuje blok emu testbench-a za ovakav pristup verifikaciji.

Scoreboard

Transfer Data
function Structure

Stimulus DUV Compare

Slika 2.5 Samoprovera rezultata tokom simulacije

Samo provera izlaza nakon simulacije:


Ovakav pristup je modifikacija prethodnog, sa razlikom da se rezultati porede nakon zavretka simulacije. Za pobudu
modula koji se verifikuje i referentnog modela se koristi ista datoteka sa ulaznim vektorom i dve simulacije se pokrenu u
paraleli. Rezultati se porede nakon zavretka simulacija, Slika 2.6.
U sluajevima kada postoji C ili C++ model kao deo referentne specifikacije ovaj pristup daje najbolje rezultate.

4
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
Simulator

Stimulus DUT File Comparator

Other

File REF

Slika 2.6 Samo provera rezultata nakon simulacije

U sluaju verifikacije kompleksnih sistema bilo koji oblik samoprovere rezultata je neophodan radi lakeg utvrivanja
rezultata simulacije.

3. Testbench-evi u VHDL-u
Prva osnovna karakteristika testbenech-a napisanog u VHDL-u je da njegov entitet nema ni ulaznih ni izlaznih signala.
Tipian primer entiteta testbench-a je sledei:

ENTITY brojac_tb IS
END brojac_tb;

Arhitektura testbech-a po definiciji sadri instancu modula koji se verifikuje, kao to prikazuje Slika 2.2. Pored instance,
treba obezbediti generisanje pobude i kontrolu vrednosti izlaza prema jednoj od prethodno navedenih metoda. Tipian poetak
formiranja arhitekture testbench-a prikazuje sledei fragment izvornog koda:

ARCHITECTURE behavior OF brojac_tbIS

-- Deklaracija modula koji se verifikuje


COMPONENT BROJAC
PORT(
iCLK : IN std_logic;
inRESET : IN std_logic;
iDIRECTION : IN std_logic;
oCNT : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;

-- Ulazni signali modula koji se verifikuje


SIGNAL iCLK : std_logic := '0';
SIGNAL inRESET : std_logic := '0';
SIGNAL iDIRECTION : std_logic := '0';

-- Izlazni signali modula koji se verifikuje


SIGNAL oCNT : std_logic_vector(3 downto 0);

BEGIN

-- Instanca modula koji se verifikuje


uut: BROJAC PORT MAP(
iCLK => iCLK,
inRESET => inRESET,
iDIRECTION => iDIRECTION,
oCNT => oCNT
);

-- proces za generisanje pobude


tb : PROCESSBEGIN
END PROCESS tb;

END;

Od signala koji se generiu za pobudu modula koji se verifikuje, prvo se definiu takt i reset. U VHD testbench-u to se
moe uraditi na sledei nain:
5
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12

iCLK<= NOT iCLK AFTER ( CLK_PERIOD / 2 );


inRESET<= '1', '0' AFTER 20 ns, '1' AFTER 400 ns;

Deklaraciju periode takt signala koji pobuuje modul koji se verifikuje treba uraditi u zaglavlju arhitekture na primer
definicijom konstante:

-- definicija periode takt signala od 24MHz


CONSTANT CLK_PERIOD : time := 41 ns;

Reset signal definisan u gornjem primeru na poetku simulacije ima vrednost logike jedinice u trajanju od 20 ns, nakon
ega se on aktivira postavljanjem na vrednost nula. Logika nula traje narednih 400 ns nakon ega, 420 ns nakon poetka
simulacije, ponovo dobija vrednost logike jedinice koja traje do kraja simulacije.
Tip signala time je definisan u VHDLpakovanju standard na sledei nain:

type TIME is range -2147483647 to 2147483647


-- this declaration is for the convenience of the parser. Internally
-- the parser treats it as if the range were:
-- range -9223372036854775807 to 9223372036854775807
units
fs;-- femtosecond
ps= 1000 fs; -- picosecond
ns= 1000 ps; -- nanosecond
us= 1000 ns; -- microsecond
ms= 1000 us;-- millisecond
sec= 1000 ms;-- second
min= 60 sec;-- minute
hr= 60 min;-- hour
end units;

U sluaju potrebe da se vrednost vremenskog trenutka treba konvertovati u celobrojni tip to se moe uraditi iskazom
integer_variable := time_variable / 1 ns;. U suprotnom sluaju, konverzija celobrojnog tipa u vremensku
vrednost, iskaz je sledei: time_variable := integer_variable * 1 ns;.
U sluaju da se eli generisati takt signal iji je faktor ispune razliit od 50% to se moe uraditi na sledei nain:

ARCHITECTURE TB_ARCH of ...


...
constant PERIOD : time := 42 ns; -- perioda takt signala
constant DUTY_CYCLE : real := 0.33; -- faktor ispune
constant OFFSET : time := 100 ns; -- pomeraj na poetku simulacije
...
BEGIN

PROCESS BEGIN
WAIT for OFFSET;
CLOCK_LOOP : LOOP
iCLK <= '0';
WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
iCLK <= '1';
WAIT FOR (PERIOD * DUTY_CYCLE);
END LOOP CLOCK_LOOP;
END PROCESS;

...

END TB_ARCH;

Vrednost vremenskog trenutka do kojeg je stigao tok simulacije se uvek moe odrediti uz pomo VHDL kljune rei
NOW. Na primer VHDL iskaz time_variable := now; smeta trenutno vreme simulacije u promenljivu
time_variable.
Generisanje preciznih vremenskih dijagrama pobude modula koji se verifikuje se moe uraditi na primer na sledei nain:

PROCESSBEGIN
-- ------------- Vremenski trenutak: 195ns
WAIT FOR 195 ns;
inRESET <= '1';
6
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
-- -------------------------------------
-- ------------- Vremenski trenutak: 1161ns
WAIT FOR 966 ns;
iDIRECTION <= '1';
-- -------------------------------------
-- ------------- Vremenski trenutak: 1287ns
WAIT FOR 126 ns;
inRESET <= '0';
-- -------------------------------------
-- ------------- Vremenski trenutak: 1455ns
WAIT FOR 168 ns;
inRESET <= '1';
-- -------------------------------------
-- ------------- Vremenski trenutak: 2421ns
WAIT FOR 966 ns;
iDIRECTION <= '0';
-- -------------------------------------
WAIT FOR 2621 ns;

END PROCESS;

Pored ovakvog eksplicitnog naina generisanja vremenskih dijagrama pomou WAIT ON iskaza mogue je i generisanje
vremenskih dijagrama koji su zavisni od promene vrednosti nekog od signala u testbench-u. Na primer, esto interesantan
trenutak je da generisanje pobude krene nakon deaktiviranja reset signala na poetku simulacije. Ovaj vremenski trenutak se
moe detektovati iskazom WAIT UNTIL inRESET = '1'. Na isti nain se moe saekati promena bilo kojeg drugog
signala ili magistrale u testbench-u. Pomou ove tehnike se jednostavno moe formirati odgovarajui protokol u komunikaciji
izmeu dva modula.
Pored ova dva naina korienja WAIT iskaza postoji mogunost i korienja WAIT ON ime_signala komande. U ovom
sluaju izvrenje se zaustavlja do trenutka kada se desi neka promena na navedenom signalu. Dozvoljeno je navesti vie
signala, razdvojenih zarezom, gde e se izvrenje procesa nastaviti nakon promene bilo kog signala u listi.
Rezime mogunosti korienja WAIT komande u VHDL procesima je sledei:
WAIT ON signal1 [, signal2, signal3]
WAIT UNTIL bulov_iskaz
WAIT FOR vremensko_kanjenje

Mogue je i kombinovanje WAIT iskaza u jednom. Na prime:

WAIT ON nmi,interrupt
UNTIL ((nmi = TRUE) or (interrupt = TRUE))
FOR 5 usec

Ovakvim sloenim iskazom proces eka na promenu signala nmi ili interrupt. Nastavak je uslovljen da na logikoj
jedinici bude jedan od ova dva signala ili da je prolo 5 mikrosekundi nakon detektovane promene vrednosti signala.

U VHDL-u postoji mogunost korienja iskaza ASSERT radi ispisivanja tekstualnih poruka (REPORT) tokom izvrenja
simulacije. Ovaj iskaz proverava da li je odgovarajui logiki uslov zadovoljen ili ne. Ukoliko je logiki uslov zadovoljen,
ASSERT iskaz ne radi nita. U suprotnom sluaju, logiki uslov nije zadovoljen, ispisae se poruka definisana u VHDL kodu.
Poruka koja se ispisuje mora biti u formi stringa. Da bi se ispisala vrednost nekog signala ona se mora konvertovati u tip string.
Mogue je spajanje stringova pomou VHDL iskaza za konkatenaciju (&) kod formiranja poruka koje e se ispisati pomou
REPORT iskaza.
Klasifikacija poruka koje se ispisuju se moe uraditi na osnovu definisanog nivoa uticaja greke koja se prouzrokuje
neispunjenim logikim uslovom. Ovaj uticaj se definie iskazom SEVERITY i moe imati sledee nivoe: NOTE, WARNING,
ERROR i FAILURE. U sluaju de se definie nivo FAILURE simulacija se automatski prekida u sluaju aktiviranja ASSERT
iskaza. U simulatoru se mogu definisati odgovarajue akcije na nivo greke. Takoe, veina simulatora omoguuju maskiranje
ASSERT iskaza odreenog nivoa tokom simulacije, ukoliko za time postoji potreba.

ASSERT vERR_CNT = 0
REPORT "N@TB: Izlaz modula nije u skladu sa definisanim test vektorom."
SEVERITY NOTE;
ASSERT vERR_CNT /= 0
REPORT "N@TB: Izlaz modula je u skladu sa definisanim test vektorom."
SEVERITY NOTE;

7
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
ASSERT iskazi slue da informiu projektanta digitalnog sistema da se tokom situacije desio odreeni dogaaj koji moe
da ugrozi dalji rad celokupnog sistema. Stepen uticaja ove greke na nastavak rada isprojektovanog sistema se definie
SEVERITY nivoom.
REPORT i SEVERITY iskazi su opcioni prilikom definisanja ASSERT iskaza.
ASSERT iskazi se mogu definisati u telu procesa (sekvencijalni iskazi) ili izvan njega (konkurentni iskazi).

Ispisivanje poruka tokom izvrenja simulacije mogue je i uz pomo komandi raspoloivih u VHDL pakovanju textio. U
nekim situacijama ovaj nain prua veu fleksibilnost od ASSERT iskaza, zbog mogunosti formiranja kompleksnijih poruka
kombinacijom stringova i vrednosti signala u datom trenutku. Pakovanje textio i odgovarajue komande su opisane u sledeem
poglavlju.

Standardizovanje formata poruka moe olakati njihov pregled. Preporuuje se stavljanje prefiksa ispred poruke u
formatu gde se poetna velika slova iskaza Note, Warning, Error, Failure, Info stave ispred znaka @i imena modula gde se
formiraju. Na primer, poruka moe izgledati na sledei nain: E@TB: Adresni brojac izasao iz dozvoljenog
opsega.

U svim porukama koje se ispisuje javlja se informacija u formi nekog stringa. String je u VHDL/u definisan na sledei
nain:

type STRING is array (POSITIVE range <>) of CHARACTER;

Karakteristino za VHDL je da se za definiciju niza karaktera (tj. stringa) koristi tip POSITIVE, ime prvi element niza
nije 0 ve 1. Iz tog razloga sledei VHDL iskaz e prouzrokovati sintaksnu greku: variable msg : string(0 to 4)
:= Hello!.

4. VHDL pakovanje: textio


Pakovanje textio prua na raspolaganje funkcije i procedure za itanje VHDL tipova iz ulazne datoteke ili sa standardnog
ulaza (tastatura). Takoe, funkcije upisa u izlazne datoteke ili na standardni izlaz (ekran) su omoguene ukljuivanjem ovog
pakovanja.Naalost, mogunosti koje prua textio pakovanje nisu na nivou slinih funkcija drugih jezika.
Da bi se ovo pakovanje koristilo potrebno je u VHDL datoteci ukljuiti sledee dve linije koda:

LIBRARY std;
USE std.textio.all;

Sledei tipovi podataka su definisani u ovom pakovanju:

type LINE is access STRING; -- A LINE is a pointer to a STRING value


type TEXT is file of STRING; -- A file of variable-length ASCII records.
type SIDE is (RIGHT, LEFT); -- For justifying output data within fields.

subtype WIDTH is NATURAL; -- For specifying widths of output fields.

-- Standard text files:


file INPUT: TEXT open READ_MODE is "STD_INPUT";
file OUTPUT: TEXT open WRITE_MODE is "STD_OUTPUT";

VHDL datoteke posmatra kao niz redova (linija). Procedure READ() i WRITE() slue za operacije nad podacima koji
su sadrani u jednoj liniji. Za manipulaciju sa linijama koriste se procedure READLINE() i WRITELINE().
VHDL pakovanje textio omoguuje samo tekstualni ulaz/izlaz pomou tipa TEXT. Ukoliko se eli komunikacija sa
datotekama u binarnom obliku, tada treba deklarisati novi tip podataka. Na primer, tip podataka za pristup binarnim
datotekama moe biti deklarisan na sledei nain:

type INTEGER_FILE_TYPE is file of INTEGER;

Deklaracija datoteka se razlikuje od VHDL standarda koji se koristi. U sluaju da se koristi VHDL 1987 datoteke se
deklariu na sledei nain:

FILE ulazna_datoteka : TEXT IS IN ime_ulazne_datoteke.txt;


FILE izlazna_datoteka : TEXT IS OUT ime_izlazne_datoteke.txt;

VHDL standard iz 1993 godine je promenio nain deklaracije datoteka. Kada se koristi ovaj VHDL standard datoteke se
deklariu na sledei nain:

8
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
FILE ulazna_datoteka : TEXT open READ_MODE IS ime_ulazne_datoteke.txt;
FILE izlazna_datoteka : TEXT open WRITE_MODE IS ime_izlazne_datoteke.txt;

VHDL 1993 prua i jednostavniji nain deklarisanja datoteka, potpuno ekvivalentan deklarisanju bilo kojeg drugog
signala:

FILE ulazna_datoteka : TEXT;


FILE izlazna_datoteka : TEXT;

U ovom sluaju datoteku je potrebno otvoriti i zatvoriti pomou procedure FILE_OPEN() i FILE_CLOSE():

FILE_OPEN(ulazna_datoteka, string(ime_ulazne_datoteke.txt), READ_MODE);


FILE_OPEN(izlazna_datoteka, string(ime_izlazne_datoteke.txt), WRITE_MODE);
... -- operacije sa datotekama
FILE_CLOSE(ulazna_datoteka);
FILE_CLOSE(izlazna_datoteka);

Kod otvaranja datoteka treba obezbediti da se one otvaraju samo jedanput. U sluaju da proces nema listu osetljivosti to
se reava jednostavno dodavanjem iskaza WAIT na kraj procesa. Ovakav proces e se aktivirati samo jedanput.

PROCESS
FILE ulazna_datoteka : TEXT;
BEGIN
FILE_OPEN(ulazna_datoteka, string(ime_ulazne_datoteke.txt), READ_MODE);
...
WAIT;
END PROCESS;

Ako proces poseduje listu osetljivosti, tada e se on aktivirati svaki put kad se promeni vrednost nekog signala u listi. U
tom sluaju treba obezbediti uslovni iskaz provere da li je datoteka otvorena ili ne:

PROCESS (signal1, signal2)


FILE ulazna_datoteka : TEXT;
VARIABLE init : BOOLEAN;
BEGIN
IF (NOT init) THEN
FILE_OPEN(ulazna_datoteka, string(ime_ulazne_datoteke.txt), READ_MODE);
init := TRUE;
END IF;
...
WAIT;
END PROCESS;

Procedura FILE_OPEN() pored otvaranja datoteke u reimu READ_MODE i WRITE_MODE, podrava i reim
APPEND_MODE gde se podaci dodaju na kraj otvorene datoteke.
Pored navedenog naina korienja, mogua je i provera da li je dolo do neke greke prilikom otvaranja datoteke. Status
nakon otvaranja datoteke moe se proitati kao dodatni parametera procedure koji se stavlja na prvu poziciju prilikom poziva:

procedure FILE_OPEN(status : out FILE_OPEN_STATUS,


file F : FT;
fname : in STRING;
open_type : in FILE_OPEN_KIND := READ_MODE);

Status nakon otvaranja moe biti jedan od sledeih: OPEN_OK, STATUS_ERROR, NAME_ERROR ili MODE_ERROR.
Standardni ulaz i standardni izlaz ne moraju da se deklariu jer su oni ve definisani u pakovanju textio.

Na primer, sledei VHDL proces ita karaktere sa standardnog ulaza i smeta ih u promenljivu ll.

PROCESS
VARIABLE ll : LINE;
BEGIN
READLINE(INPUT, ll);
...
END PROCESS;

9
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
Za itanje karaktera iz ulazne datoteke prethodni VHDL process je potrebno modifikovati na sledei nain:

PROCESS
FILE ulazna_datoteka : TEXT;
VARIABLE ll : LINE;
BEGIN
FILE_OPEN(ulazna_datoteka, string(ime_ulazne_datoteke.txt), READ_MODE);
READLINE(ulazna_datoteka, ll);
...
FILE_CLOSE(ulazna_datoteka);
END PROCESS;

Za preuzimanje podataka iz proitane linije koristi se procedura READ(). Podaci u liniji treba da su razdvojeni praznim
mestima (space ili tab). Nakon uspenog itanja podatka sa poetka linije READ()procedura modifikuje liniju tako to obrie
karaktere koje je preuzela. Ovime se omoguuje uzastopno itanje svi podataka u jednoj liniji.
Na primer, ako prva linija datoteke file.txt sadri sledee podatke 56 4.7 20ns, njihovo itanje se moe
realizovati na sledei nain:

PROCESS
FILE vINFILE : TEXT open READ_MODE IS file.txt;
VARIABLE vLL : LINE;
VARIABLE vINT : INTEGER;
VARIABLE vREAL : REAL;
VARIABLE vTIME : TIME;
BEGIN
READLINE(vINFILE, vLL);
READ(vLL, vINT);
READ(vLL, vREAL);
READ(vLL, vTIME);
...
END PROCESS;

Redosled poziva READ() procedure mora biti usklaen sa preuzimanjem podataka iji se tip poklapa sa tipom varijable
u koju se smetaju. Ukoliko se to ne obezbedi, VHDL e generisati signal greke i prekinuti tok simulacije. Provera ispravnosti
tipova podataka koji se itaju iz datoteke u odreene promenljive se moe uraditi na sledei nain:

PROCESS
FILE vINFILE : TEXT open READ_MODE IS file.txt;
VARIABLE vLL : LINE;
VARIABLE vINT : INTEGER;
VARIABLE vREAL : REAL;
VARIABLE vTIME : TIME;
VARIABLE vOK : BOOLEAN;
BEGIN
READLINE(vINFILE, vLL);
READ(vLL, vTIME, vOK);
ASSERT vOK
REPORT Procitana vrednost nije tipa TIME !!!
SEVERITY ERROR;
...
END PROCESS;

Poto prvi podatak u liniji nije tip time ve je tipa integer, generisae se greka koja e aktvirati assertion iskaz i prikazati
odgovarajuu poruku u simulaciji.

Za itanje kompletne datoteke od prve do poslednje linije se moe iskoristiti funkcija ENDFILE(). Funkcija
ENDFILE() vraa vrednost tipa BOOLEAN. Kada se dostigne kraj datoteke, proitana je poslednja linija, vratie vrednost
TRUE. U suprotnom vraa vrednost FALSE.
Prazne linije se mogu preskoiti u sluaju da atribut LENGTH ima vrednost nula za proitanu liniju. Na primer petlja za
itanje datoteke moe imati sledei oblik:

WHILE (NOT ENDFILE(vINFILE)) LOOP


deallocate(vLL); -- oslobodi prostor za novu liniju
readline(vINFILE, vLL); -- proitaj liniju iz datoteke
IF (vLLLENGTH = 0) THEN -- preskoi prazne linije

10
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
NEXT;
END IF;
-- preuzmi podatke iz linije
...
END LOOP;

Slino kao kod itanja iz datoteke par procedure WRITE() i WRITELINE() slui za upis u datoteke ili na standardni
izlaz OUTPUT.

PROCESS
FILE vOUTFILE : TEXT;
VARIABLE vLL : LINE;
VARIABLE vINT : INTEGER := 82;
VARIABLE vREAL : REAL := 37.2;
VARIABLE vTIME : TIME := 10 ns;
BEGIN
-- otvori datoteku
FILE_OPEN(vOUTFILE, string(file.txt), WRITE_MODE);
-- upisi podatke u liniju
WRITE(vOUTFILE, vINT); WRITE(vOUTFILE, STRING());
WRITE(vOUTFILE, vREAL); WRITE(vOUTFILE, STRING());
WRITE(vOUTFILE, vTIME, RIGHT, 19, NS); WRITE(vOUTFILE, STRING());
WRITE(vOUTFILE, string(LF)); -- nova linija
-- upis u datoteku
WRITELINE(vOUTFILE, vLL);
END PROCESS;

U sluaju potrebe za ispis na ekran, tj. standardni izlaz, upis se realizuje pozivom WRITELINE() procedure na sledei
nain: WRITELINE(OUTPUT, vLL).
WRITE() procedura je je definisana na isti nain za sve tipove podataka na sledei nain (izuzev za tip TIME):

WRITE(L : INOUT LINE;


VALUE : IN sometype;
JUSTIFIED : IN SIDE := RIGHT;
FIELD : IN WIDTH := 0);

Za tip TIME, ona je definisana na sledei nain:

WRITE(L : INOUT LINE;


VALUE : IN sometype;
JUSTIFIED : IN SIDE := RIGHT;
FIELD : IN WIDTH := 0;
UNIT : IN TIME := ns);

U sluaju pristupa binarnim datotekama, definisane tipom type INTEGER_FILE_TYPE is file of INTEGER,
koriste se samo WRITE() i READ() procedure jer se datoteci pristupa na nivou bajta a ne na nivou cele linije kao to je to
sluaj za tekstualne datoteteke. Iz tog razloga se ne koriste WRITELINE() i READLINE() procedure za pisanje i itanje
binarnih datoteka.
Sledei primer ilustruje proces za upis u binarnu datoteku. Slian princip se koristi i kod itanja banarne datoteke.

PROCESS
type INTEGER_FILE_TYPE is file of INTEGER;
FILE vDATA_OUT : INTEGER_FILE_TYPE;
VARIABLE vCNT : integer := 0;
VARIABLE vSTATUS : FILE_OPEN_STATUS;
BEGIN
FILE_OPEN(vSTATUS, vDATA_OUT, string(binary_file.txt), WRITE_MODE);
FOR j IN 1 TO 8 LOOP
WRITE(vDATA_OUT, vCNT);
vCNT := vCNT + 2;
END LOOP;
FILE_CLOSE(vDATA_OUT);
WAIT;
END PROCESS;

11
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
5. Procedure i funkcije u VHDL-u
VHDL dozvoljava formiranje korisniki definisanih funkcija i procedura. One mogu biti definisane u zaglavlju
arhitekture ili u zaglavlju procesa. Ukoliko su funkcije i/ili procedure definisane u zaglavlju arhitekture, tada su one vidljive u
celoj arhitekturi, odnosno svaki konkurentni iskaz moze da koristi proceduru ili funkciju definisanu u deklarativnom prostoru
arhitekture. Ako je procedura i/ili funkcija definisana u zaglavlju procesa, tada je ona vidljiva smo u tom procesu i nigde vie.
Funkcije u VHDL-u imaju sledei format:

FUNCTION ime_funkcije(SIGNAL signal1: tip1 <, SIGNAL signal2: tip2, ...>)


RETURN BOOLEAN IS
-- deklarativni region
-- lokalne promenljive se definiu u ovom prostoru
BEGIN
-- telo funkcije

RETURN (povratna_vrednost_funkcije)
END ime_funkcije;

Svaka funkcija u VHDL-u mora da vrati neku vrednost, odnosno svaki poziv funkcije treba da izvri RETURN iskaz u telu
funkcije.
Iskaz WAIT nije dozvoljen u VHDL funkcijama.
Funkcije se u VHDL-u tipino koriste za konverziju tipova signala i za realizaciju esto korienih kombinacionih mrea
koje imaju samo jedan izlaz.
Na primer, primer realizacije VHD funkcije se moe ilustrovati sa detektovanjem rastue ivice takt signala:

FUNCTION rising_edge (SIGNAL iCLOCK : STD_LOGIC)


RETURN BOOLEAN IS
VARIABLE vEDGE : BOOLEAN := FALSE;
BEGIN
vEDGE := (iCLOCK=1 AND iCLOCKevent);
RETURN vEDGE;
END rising_edge;

Sledei ilustrativan primer je konverzija tipa signala:

-- funkcija za konverziju vektora tipa STD_LOGIC_VECTOR u vektor tipa INTEGER


-- ulazni parametar je oznacen sa ARG
FUNCTION CONV_TO_INTEGER (ARG: STD_LOGIC_VECTOR) RETURN INTEGER IS
-- potrebno je odredsiti broj bita ulaznog vektora
-- indeks krajnjeg levog bita ulaznog parametra
CONSTANT cARG_LEFT: INTEGER := ARG'LENGTH-1;
-- alias na ulazni vektor sa tipom koji ima ograniceni broj bita
ALIAS XXARG: STD_LOGIC_VECTOR(cARG_LEFT DOWNTO 0) is ARG;
-- promenljiva koja ce primiti vrednost ulaznog vektora
-- na osnovu koje ce se vrsiti konverzija u tip INTEGER
VARIABLE vXARG: STD_LOGIC_VECTOR(cARG_LEFT DOWNTO 0);
-- rezulta konverzije
VARIABLE vRESULT: INTEGER := 0;
BEGIN
-- telo funkcije za konverziju
vXARG := XXARG;
FOR I IN vXARG'RANGE LOOP
vRESULT := vRESULT + vRESULT;
IF vXARG(I) = '1' THEN
vRESULT := vRESULT + 1;
END IF;
END LOOP;
RETURN vRESULT;
END CONV_TO_INTEGER;

Procedure u VHDL-u imaju sledei format:

PROCEDURE ime_procedure(klasa1 promenljiva1: reim1 tip1


<, klasa2 promenljiva2: reim2 tip2, ...>
)

12
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
-- deklarativni region
-- lokalne promenljive se definiu u ovom prostoru
BEGIN
-- telo procedure

RETURN (povratna_vrednost_funkcije)
END ime_procedure;

Parametri procedure mogu da budu iz klase SIGNAL, VARIABLE ili CONSTANT.


Parametri procedure mogu biti u ulaznom (IN) reimu ili u izlaznom (OUT) reimu. Ako je parametar u ulaznom reimu
u telu procedure je mogue samo proitati njegovu vrednost. Parametre u izlaznom reimu se ne moe proitati u telu
procedure ve samo upisati nova vrednost. Nova vrednost e se preneti na signal (ili promenljivu) koji je povezan na
odgovarajui parametar.
Predefinisana klasa ulaznih parametara procedure je CONSTNAT, dok za izlatne parametre to je VARIABLE, i parametri
deklarisani bez oznake klase e biti inicijalizovani sa ovim predefinisanim klasama.
Promenljive koje su deklarisane u telu procedure se inicijalizuju sa svakim pozivom procedure, odnosno po zavretku
procedure vrednost lokalne promenljive nije vie na raspolaganju.
U deklarativnom regionu procedure nije mogue deklarisati signale. Dozvoljene su samo lokalne promenljive.
Procedure mogu imati WAIT iskaz pod uslovom da se pozivaju iz procesa koji nema listu osetljivosti.
Tipina primena procedura u VHDL-u je da se pomou njih realizuju odreeni taskovi koji se esto koriste. Iz razloga to
omoguuju vie razliitih parametara pomou njih jemogue realizovati i odreene sekvencijalne mree i koristiti ih kao
konkurentne iskaze u arhitekturu, potpuno ravnopravne sa ostalim procesima. U tom sluaju svi parametri procedura moraju
biti signali. Ilustrativan primer ovakve procedure je implementacija D flip-flopa:

PROCEDURE dff (SIGNAL d, clk, reset : IN std_logic;


SIGNAL q, q_n : OUT std_logic);
BEGIN
IF (reset = 1) THEN
q <= 0 AFTER 5 ns;
q_n <= 1 AFTER 5 ns;
ELSIF (rising_edge(clk)) THEN
q <= d AFTER 5 ns;
q_n <= (NOT d) AFTER 5 ns;
END IF;
END dff;

Pomou procedura se mogu implementirati mnogi taskovi koji se ponavljaju u VHDL kodu. Tako na primer za ispis
poruke na ekran je u VHDL-u potrebno najmanje dva iskaza. Oni se mogu objediniti u jednoj proceduri na sledei nain:

PROCEDURE print(text: STRING) IS


VARIABLE msg_line: LINE;
BEGIN
WRITE(msg_line, text);
WRITELINE(OUTPUT, msg_line);
END print;

Nakon toga se za ispis stringa na ekran moe iskoristiti procedura print.

6. Primer kompletnog testbench-a


U nastavku se prikazuje kompletan VHDL kod testbencha za verifikaciju rada evorobitnog dvosmernog brojaa pomou
test vektora definisanog u samom testbench-u.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
LIBRARY std;
USE std.textio.all;

ENTITY brojac_tb_vhd IS
END brojac_tb_vhd;

13
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
ARCHITECTURE behavior OF brojac_tb_vhd IS
-- deklaracija modula koji se verifikuje (UUT)
COMPONENT BROJAC
PORT(
iCLK : IN std_logic;
inRESET : IN std_logic;
iDIRECTION : IN std_logic;
oCNT : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;

-- ulazni signali modula koji se verifikuje


SIGNAL iCLK : std_logic := '0';
SIGNAL inRESET : std_logic := '0';
SIGNAL iDIRECTION : std_logic := '0';
-- izlazni signali modula koji se verifikuje
SIGNAL oCNT : std_logic_vector(3 downto 0) := "0000";
-- interni takt i reset signali
SIGNAL sCLK : std_logic := '0';
SIGNAL snRST : std_logic := '0';
-- perioda takt signala od 24 MHz
CONSTANT CLK_PERIOD : time := 41.67 ns;
-- signal za ukazivanje na kraj generisanja pobude
SIGNAL sTEST_END : BOOLEAN := FALSE;

-- test vektor za pobudjivanje modula koji se verifikuje


TYPE tTEST_VECTOR IS RECORD
CLK : std_logic;
RST : std_logic;
DIR : std_logic;
CNT : std_logic_vector(3 downto 0);
END RECORD;
TYPE tTEST_VECTOR_ARRAY IS ARRAY (NATURAL RANGE<>) OF tTEST_VECTOR;
CONSTANT cTEST_VECTORS : tTEST_VECTOR_ARRAY := (
-- resetovanje brojaca
(CLK=>'0', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'1', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'0', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'1', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'0', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'1', RST=>'0', DIR=>'0', CNT=>"0000"),
-- brojac broji na gore
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0000"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0001"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0001"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0010"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0010"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0011"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0011"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0100"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0100"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0101"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0101"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0110"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0110"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0111"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0111"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1000"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1000"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1001"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1001"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1010"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1010"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1011"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1011"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1100"),

14
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1100"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1101"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1101"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1110"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1110"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1111"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1111"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0000"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0000"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0001"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0001"),
-- brojac broji na dole
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0000"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0000"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1111"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1111"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1110"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1110"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1101"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1101"),
-- resetovanje brojaca
(CLK=>'1', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'0', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'1', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'0', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'1', RST=>'0', DIR=>'0', CNT=>"0000"),
(CLK=>'0', RST=>'0', DIR=>'0', CNT=>"0000"),
-- brojac ponovo broji na dole
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1111"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1111"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1110"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1110"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1101"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1101"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1100"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1100"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1011"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1011"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1010"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1010"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1001"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1001"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1000"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1000"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0111"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0111"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0110"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0110"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0101"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0101"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0100"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0100"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0011"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0011"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0010"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0010"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0001"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0001"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"0000"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"0000"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1111"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1111"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1110"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1110"),
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1101"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1101"),

15
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12
(CLK=>'1', RST=>'1', DIR=>'0', CNT=>"1100"),
(CLK=>'0', RST=>'1', DIR=>'0', CNT=>"1100"),
-- brojac ponovo broji na gore
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1101"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1101"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1110"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1110"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"1111"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"1111"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0000"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0000"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0001"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0001"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0010"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0010"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0011"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0011"),
(CLK=>'1', RST=>'1', DIR=>'1', CNT=>"0100"),
(CLK=>'0', RST=>'1', DIR=>'1', CNT=>"0100")
);
BEGIN
-- generisanje takta i reseta
-- samo ilustracija, ne koristi se u ovom primeru
-- jer se takt i reset generisu iz test vektora
sCLK <= NOT sCLK AFTER ( CLK_PERIOD / 2 );
snRST <= '1', '0' AFTER 20 ns, '1' AFTER 400 ns;

-- instanca modula koji se verifikuje


uut: BROJAC PORT MAP(
iCLK => iCLK,
inRESET => inRESET,
iDIRECTION => iDIRECTION,
oCNT => oCNT
);

-- proces za verifikaciju pomocu test vektora


verify_tv : PROCESS
VARIABLE vVECTOR : tTEST_VECTOR;
VARIABLE vERRORS : BOOLEAN := FALSE;
VARIABLE vERR_CNT : INTEGER := 0;
VARIABLE vLINE : LINE := null;
BEGIN
-- sacekaj 100 ns za zavrsetak globalnog reseta
wait for 100 ns;

-- Generisanje pobude pomocu test vektora


-- i provera ocekivanog rezultata
FOR i IN cTEST_VECTORS'RANGE LOOP
-- preuzmi vektor
vVECTOR := cTEST_VECTORS(i);
-- povezi signale na ulaz UUT
iCLK <= vVECTOR.CLK;
inRESET <= vVECTOR.RST;
iDIRECTION <= vVECTOR.DIR;

-- sacekaj stabilizaciju vremenskih signala


WAIT FOR CLK_PERIOD / 8;

-- proveri vrednost izlaza


IF oCNT /= vVECTOR.CNT THEN
ASSERT FALSE
REPORT "E@TB: Pogresna vrednost brojaca"
SEVERITY ERROR;
vERRORS := TRUE;
vERR_CNT := vERR_CNT + 1;
END IF;

16
Dodatak - Kratko uputstvo o pisanju VHDL TestBench-eva 2011/12

-- sacekaj preostalo vreme poluperiode takt signla


WAIT FOR ((CLK_PERIOD / 2) - (CLK_PERIOD / 8));
END LOOP;

-- generisanje izvestaja na kraju simulacije


WRITE( vLINE, string'( "-----------------------------------------------" ) );
WRITELINE( OUTPUT, vLINE );
ASSERT NOT vERRORS
REPORT "N@TB: ERRORS - Izlaz modula nije u skladu sa test vektorom."
SEVERITY NOTE;
ASSERT vERRORS
REPORT "N@TB: OK - Izlaz modula je u skladu sa test vektorom."
SEVERITY NOTE;

WRITE( vLINE, string'( "I@TB: END OF TEST. No of errors = " ) );


WRITE( vLINE, vERR_CNT );
WRITELINE( OUTPUT, vLINE );
WRITE( vLINE, string'( "-----------------------------------------------" ) );
WRITELINE( OUTPUT, vLINE );

-- generisi signal za kraj simulacije


sTEST_END <= TRUE;

WAIT; -- zaustavi izvrsenje procesa


END PROCESS verify_tv;

-- proces za prekidanje simulacije kada se zavrsi generisanje pobude


end_of_test : PROCESS
VARIABLE vLINE : LINE := null;
BEGIN
WAIT UNTIL sTEST_END = TRUE;
WAIT FOR (10 * CLK_PERIOD);
ASSERT FALSE
REPORT "F@TB: Kraj simulacije"
SEVERITY FAILURE;
END PROCESS end_of_test;

-- nadgledanje promene vrednosti brojaca


cnt_monitor : PROCESS ( oCNT )
VARIABLE vLINE : line := null;
BEGIN
write( vLINE, string'( "I@TB: " ) );
write( vLINE, now );
write( vLINE, string'( " oCNT = " ) );
write( vLINE, CONV_INTEGER( oCNT ) );
writeline( OUTPUT, vLINE );
END PROCESS cnt_monitor;

-- nadgledanje promene smera brojanja


dir_monitor : PROCESS ( iDIRECTION )
VARIABLE vLINE : line := null;
BEGIN
write( vLINE, string'( "I@TB: " ) );
write( vLINE, now );
IF iDIRECTION = '1' THEN
write( vLINE, string'( " Brojanje na GORE." ) );
ELSE
write( vLINE, string'( " Brojanje na DOLE." ) );
END IF;
writeline( OUTPUT, vLINE );
END PROCESS dir_monitor;

END behavior;

17

You might also like