În acest capitol, vom examina instrumentele din VHDL pentru fișierul I / O. Fișierele servesc pentru mai multe scopuri, dintre care unul este de a asigura stocarea informațiilor pe termen lung. În acest context, "informații pe termen lung" înseamnă informații în afara duratei de viață a unei runde de simulare. Fișierele pot fi utilizate pentru a stoca date care vor fi încărcate în model la pornire sau pentru a stoca rezultatele obținute prin modelare. VHDL oferă, de asemenea, versiuni specializate ale operațiilor de fișiere pentru lucrul cu fișierele text. Afirmăm modul în care se poate utiliza modul de introducere și de ieșire a textului pentru a extinde interfața utilizator a simulatorului cu operațiunile specifice modelului.
16.1 Fișiere
Începem discuția noastră asupra fișierelor luând în considerare mecanismele cu scop general furnizate în VHDL pentru fișierele I / O. VHDL oferă acces secvențial fișierelor utilizând operațiuni precum "deschide", "închide", "citi" și "scrie", care sunt cunoscute utilizatorilor de limbi de programare tradiționale.
Fișierul VHDL este o clasă de obiecte utilizate pentru stocarea datelor. Astfel, ca și în cazul altor clase de obiecte, trebuie să adăugăm definiția fișierului la model. Sintaxa pentru specificarea tipului de fișier este:
file_type_definition. fișier de tip_mark
tip integer_file este fișierul întregului;
specifică un fișier integer care indică tipul de fișier care poate stoca numai numere întregi. Un fișier poate conține doar un singur tip de obiect, dar acest tip poate fi aproape orice tip de VHDL, inclusiv tipuri de înregistrări scalare și matrice unidimensionale. Singurele tipuri care nu pot fi salvate într-un fișier sunt matrice multidimensionale, tipuri de acces, tipuri de securitate și alte fișiere.
După ce am definit tipul de fișier, putem declara un obiect de fișier. Facem aceasta folosind o declarație de obiect, descrisă după cum urmează:
identificator de fișier. subtype_indication
[[open file_open_kind_expr] este expresia șir);
O definiție a fișierului creează unul sau mai multe obiecte din acest tip de fișier. Putem adăuga o declarație de fișier în orice parte declarativă în care putem crea obiecte, cum ar fi: descrierea arhitecturii, blocuri, procese, pachete și subrutine.
fișierul lookup_table_file. integer_file este "lookup-values";
Un simulator care rulează în sistemul de operare UNIX poate asocia un obiect de fișier cu un fișier fizic numit "lookup-values" în directorul curent de lucru. Un alt simulator care rulează sub sistemul de operare Windows poate asocia un obiect de fișier în moduri diferite, deoarece numele fișierelor includ de obicei o extensie de fișier în acest sistem de operare. Deci, puteți asocia un obiect cu un fișier fizic numit "lookup-values.dat" în directorul de lucru curent.
Expresia opțională după deschiderea cuvintelor cheie ne permite să determinăm modul în care trebuie deschis fișierul fizic asociat cu obiectul sistemului de fișiere. Această expresie trebuie să aibă o valoare a tipului predefinit file_open_kind declarat în pachetul standard. Definiția are forma:
tipul file_open_kind este (read_mode, mode_mode, append_mode);
Dacă omiteți informațiile despre declarația de fișier în definiție, dar adăugând un nume de fișier logic, fișierul fizic se va deschide în modul citire. În restul acestei secțiuni vom examina fiecare din aceste moduri și vom vedea cum se citesc și se scriu datele utilizând fișierele deschise în fiecare mod.
VHDL-87. Sintaxa definiției fișierului pentru VHDL-87 este:
file_declaration.
identificator de fișier. subtype_indication este
[in sau out] expresie string;
16.1.2 Citirea dintr-un fișier
Operațiile citite și cele finale sunt descrise după cum urmează:
citirea procedurii (fișierul f. file_type; valoarea. out element_type);
endfile de funcții (fișier f. file_type) return boolean;
Mai târziu, în acest capitol, vom examina toate opțiunile de fișier.
Exemplul 16.1 Inițializarea conținutului ROM-ului dintr-un fișier
Putem folosi operațiile de fișier pentru a inițializa conținutul ROM-ului dintr-un fișier. Următoarea este o definiție a obiectului pentru o ROM care conține o constantă comună care indică numele fișierului din care trebuie încărcat conținutul ROM-ului.
biblioteca ieee; utilizați ieee.std_logic_1164.all;
entitatea ROM este
generic (nume_carriage_firma);
port (în std_ulogic;
adresă. în std_ulogic_vector;
date. inout std_ulogic_vector);
entitate finală ROM;
citiți (load_file, storage (index));
index: = index + 1;
bucla finală;
-- răspunde la accesările ROM
buclă
.
bucla finală;
end comportamentul procesului;
end arhitectura comportamentală;
În exemplul de mai sus, fiecare element de fișier este un vector logic standard cu lungime fixă, definit de lățimea portului de date ROM. Cu toate acestea, nu suntem limitați la o serie de lungimi fixe ca elemente de fișier. Putem declara un tip de fișier, fără restricție sau parțial limitat la tipul de tip element de matrice, cu condiția ca tipul de element de matrice este un tip scalar sau subtip compozit complet restrâns, cum ar fi:
tip bit_vector_file este fișierul bit_vector;
Datele dintr-un fișier de acest tip reprezintă o secvență de vectori de biți, fiecare dintre acestea având lungimi diferite. Pentru un astfel de fișier, operația de citire are o formă ușor diferită, datorită faptului că nu știm lungimea următorului element până când nu l-am numărat. Operația este declarată implicit ca fiind
citiți procedura (fișier f. file_type;
valoare. out element_type; lungime. out naturale);
putem apela operația de citire după cum urmează:
citește (vectori, next_vector, actual_len);
Acest lucru ne permite să considerăm vectorul de biți atâta timp cât 64 de biți. Dacă următoarea valoare din fișier este mai mică sau egală cu 64 de biți, această valoare va fi plasată în partea din stânga extrema a next_vectorului, iar biții rămași vor rămâne neschimbați. Dacă valoarea din fișier este mai mare de 64 de biți, primele 64 de biți ale valorii sunt plasate în următorul_vector, iar biții rămași sunt aruncați. În ambele cazuri, actual_len este setat la lungimea reală a fișierului, indiferent dacă este mai scurtă sau mai lungă decât lungimea celui de-al doilea argument de citit. Acest lucru ne permite să verificăm dacă informațiile au fost pierdute. Dacă expresia
actual_len> next_vector'length
adevărat, vectorul nu este suficient de lung pentru a se potrivi tuturor biților.
Exemplul 16.2 Citirea valorilor dintr-un fișier
Să presupunem că am dezvoltat un model pentru un receptor de rețea și doriți să îl testați. Putem genera pachete de rețea pentru a stimula modelul prin citirea pachetelor de lungime variabilă dintr-un fișier. Fluxul de proces pentru acest lucru este după cum urmează:
stimulate_network. proces este
tip packet_file este fișierul bit_vector;
fișierul stimulus_file. packet_file
open_mode este "pachete de test";
pachet variabil. bit_vector (1 până la 2048);
lungime variabilă. naturale;
începe
în timp ce nu este bucla endfile (stimulus_file)
citiți (stimulus_file, pachet, pachet_dată);
dacă pachet_length> lungime pachet atunci
raportează "pachetul de stimulare prea lung - ignorat"
severitatea avertismentului;
altfel
pentru bit_index în buclă de la 1 la pachet
așteptați până la stimulus_clock;
rețeaua de stimuli 0);
.
începe
. -- inițializați interpretul setului de instrucțiuni
instruction_loop. buclă
. -- aduceți următoarea instrucțiune în IR
-- decoda instrucțiunea
opcode_number: = convert_to_natural (opcode);
contoarele (opcode_number): = contoare (numărul opcode) +1;
.
-- executa instructiunea decodata
caz este opcode
.
când halt_opcode => ieșire instruction_loop;
.
caz final;
end bucla instruction_loop;
pentru indicele în buclă
scrieți (instrucțiuni_conturi, contoare (index));
bucla finală;
așteptați; - programul a terminat, așteptați pentru totdeauna
end interpreter de proces;
end arhitectura instrumentat;
Dacă un fișier cu acest nume există deja în sistemul de fișiere și este deschis pentru scriere, atunci elementele de date succesive vor fi adăugate la sfârșitul fișierului utilizând operația de scriere. Dacă în sistem nu există nici un fișier cu acest nume, este creat un fișier nou cu un mod de înregistrare și elementele de date sunt scrise de la bun început. Modul de adăugare este utilizat pentru fișierele care acumulează informații sau rezultate de simulare pentru un număr de simulări. Fiecare execuție adaugă datele sale la sfârșitul datelor acumulate anterior în fișier.