6. Structura sistemelor in VHDL

6.1. Entitati

Un sistem digital este format dintr-o colectie ierarhica de module. Fiecare modul are un set deporturi care constituie interfata lui cu exteriorul. Un asemenea modul se numeste in VHDL entity.

Sintaxa pentru descrierea unei entitati este:

entitate ::= entity identificator is

antet_entitate

declaratii_entitate

[begin

instructiuni_entitate ]

end [ nume_simplu_entitate ] ;

antet entitate ::=

[ clauze_formale_generice ]

[ clauze_formale_porturi ]

clauze generice :.= generic ( lista generic ) ;

lista generic ::= lista interfata generica

clauze_porturi ::= port ( lista porturi ) ;

lista_porturi::= lista interfata porturi

declaratie_entitate ::= { elemente_declaratie_entitate}

In partea declarativa a unei entitati se declara elementele care vor fi folosite in implementarea acesteia. De obicei aceste declaratii sint incluse in partea de implementare. De obicei, declaratiile optionale din partea declarativa a unei entitati sint pentru a defini comportamente particulare ale entitatii.

Constantele generice pot fi folosite pentru a controla structura si comportamentul entitatii, iar porturile pentru a specifica canalele de intrare si iesire ale entitatii. Ele sint de tip constant. Valoarea actuala a unei constante generice este transmisa in momentul in care entitatea este folosita.

Porturile unei entitati sint de tip signal. Sintaxa este:

interfata_signal ::=

[ signal ] lista-identificatori : [ mod ] subtip [ bus]

[ := expresie statica ]

Cuvintul bus poate fi folosit daca portul poate fi conectat la mai mult de o iesire . La fel ca la constantele generice, semnalele care trebuie conectate la porturi sint specificate cind entitatea este folosita.

Exemple:

entity processor is

generic (max_clock_freq: frequency := 30 MHz);

port (clock: in bit; address: out integer; data: inout word_32; control: out proc control; ready in bit );

end processor;

In acest caz constanta generica max clock freq este folosita pentru a specifica comportamentul in timp al entitatii. In codul care descrie comportamentul entitatii, se va folosi aceasta valoare pentru a determina intirzierile in schimbarea valorilor semnalelor. In exemlul urmator se arata cum pot fi folositi parametrii generici pentru a specifica o clasa de entitati de structura variabila:

entity ROM is

generic (width , depth: positive);

port (enable : in bit; address: in bit_vector(depth - 1 downto 0; data : out bit_vector(width - 1 downto 0);

end ROM;

Aici cele doua constante generice sint folosite pentru a specifica numarul de biti de date si respectiv de adresa pentru memoria "read-only". Trebuie notat ca nu este data nici o valoare implicita pentru aceste constante. Aceasta inseamna ca atunci cind entitatea este folosita ca o componenta trebuie actualizate valorile acestora.

Exemplu de declaratie de entitate fara constante sau porturi generice:

entity test bench is

end test_bench

Cu toate ca acest exemplu pare la prima vedere sa nu aiba sens, de fapt el ilustreaza o utilizare des intilnita a entitatilor:

O entitate "top-level" pentru un design in curs de testare (design under test - DUT) este folosita ca o componenta intr-un circuit de tip "banc de lucru" impreuna cu o alta entitate generator de test (test generator - TG). Nu este nevoie de conexiuni externe, deci nu exista porturi.

 

6.2. Arhitecturi

Odata specificata interfata entitatii, una sau mai multe implementari ale acesteia pot fi descrise in sectiunea architecture, care reprezinta corpul entitatii. Pot fi date mai multe arhitecturi care descriu aceeasi entitate. De exemplu, o arhitectura poate descrie pur si simplu comportamentul entitatii, in timp ce alta poate descrie aceeasi entitate ca o colectie ierarhica de componente. In aceasta sectiune vom prezenta numai descrierile structurale.

arhitectura ::= architecture identificator of nume entitate is parte_declarativa_arhitectura

begin

instructiuni arhitectura

end [ nume arhitectura ];

parte_declarativa_arhitectura ::= { bloc declaratii }

instructiuni-arhitectura ::={ instructiune-concurenta }

bloc_declaratii ::= declaratie_subprogram

corp_subprogram

declaratie_tip

declaratie_subtip

declaratie_constanta

declaratie_alias

declaratie_signal

declaratie_componente

declaratie_configuratie

clauza_use

instructiune_concurenta ::=

instructiune_bloc

instructiune-instantiere_componenta

Declaratiile dintr-o arhitectura definesc elemente care vor fi folosite pentru a construi descrierea designului. In particular, semnalele si componentele pot fi declarate aici si folosite pentru a construi o descriere structurala, dupa cum a fost exemplificat.

a)Declaratiile de semnal

Semnalele sint folosite pentru a conecta submodule. Ele sint declarate cu sintaxa urmatoare:

declaratie_signal ::=

signal lista-identificatori : subtip [ tip-signal ][ :=expresie ] ;

tip-signal ::= register | bus

Expresia din declaratie este folosita pentru a initializa semnalul in timpul fazei de initializare a simulari. Daca expresia este omisa, atunci va fi asignata o valoare implicita.

b)Blocuri

Submodulele dintr-o arhitectura pot fi descrise ca blocuri. Un bloc este o unitate ce contine propria interfata, conectat cu alte blocuri sau porturi prin semnale. Sintaxa este:

bloc ::= eticheta_bloc

block [ (expresie_garda) ]

antet_bloc

parte_declarativa_bloc

begin

instructiuni bloc

end block [ eticheta bloc ] ;

antet_bloc ::=

[ clauza generica [ map_generic ;] ]

[ clauza port ]

[ map port ; ] ]

map-generic ::=

generic map ( lista asociatie generic )

map_port ::=

port map ( lista asociatie port )

parte_declarativa_bloc ::= declaratie bloc }

instructiuni_bloc ::=

{ instructiune concurenta }

Antetul blocului defineste interfata cu blocul respectiv in mod similar cu modul in care antetul entitatii defineste interfata unei entitati. Lista de asociatie generica specifica valorile pentru constantele generic evaluate in blocul inconjurator sau in arhitectura. Lista de asociatie a porturilor specifica care dintre semnalele sau porturile blocului inconjurator sau arhitecturii sint conectate la porturile blocului. Trebuie notat ca instructiunile dintr-un bloc pot de asemenea contine instructiuni bloc, astfel ca un proiect (design) poate fi privit ca o ierarhie de blocuri ce contine descrierea comportamentului la baza ierarhiei.

Ca si exemplu, sa presupunem ca se doreste descrierea structurii unei arhitecturi a entitatii procesor descrise intr-o sectiune anterioara. Daca separam procesorul intr-o structura de control si o sectiune ce se ocupa cu calea datelor, putem scrie o descriere ca o pereche de blocuri inlantuite.

Unitatea de control are porturile clk, bus control si bus ready, care sint conectate la porturile entitatii procesor. Exista de asemenea un port de iesire pentru controlul caii de date, acesta fiind conectat la un semnal declarat in sectiunea de arhitectura. Acest semnal este conectat de asemenea la un port de control din blocul caii de date. Porturile de date si de adrese ale blocului caii de date sint conectate la porturile corespunzatoare ale entitath respective. Avantajele acestei abordari modulare se refera la faptul ca odata precizate blocurile, fiecare dintre acestea poate fi dezvoltat separat. Aici putem observa aplicarea cu succes a separarii partii de interfata in mod clar, lucru ce permite astfel dezvoltarea in paralel.

architecture block structure of processor is

type data-path-control is .... ;

signal internal control : data-path-control;

begin

control unit: block

port (clk: in bit; bus _control : out proc_control;bus _ready : out data-path-control);

port map (clk => clock, bus_control => control, bus_ready => ready,

control => internal control);

declaratii pentru control_unit

begin

instructiuni pentru control-unit

end block control unit;

data_path: block

port (address: out integer;data : inout word 32; control : in data_path_control);

port map (address => address, data=> data, control => internal-control);

declaratii pentru data_path

begin

instructiuni pentru data_path;

end block_data_path;

end block_structure;

c)Declaratii de componente

O arhitectura poate folosi de asemenea si alte entitati descrise separat si plasate in biblioteci de proiectare. Pentru aceasta, intr-o arhitectura trebuie sa se declare o componenta la care ne putem gindi ca la un model ce defineste o entitate de proiectare virtuala. Aceasta componenta virtuala va fi instantiata mai tirziu in cadrul arhitecturii.

Sintaxa este:

componenta ::=

component identificator

[ clauza generic-locala ]

[ clauza port locala ]

end component;

Exemple:

component nand3

generic (Tpd : Time := 1 ns );

port (a,b,c :in logic level; y :out logic-level);

end component;

component read_only_memory

generic(data bits, addr_bits : positive);

port( en : in bit;

addr : in bit _vector(depth-1 downto 0);

data : out bit_vector(width-1 downto 0);

end component;

Acest exemplu declara o poarta cu 3 porturi si un parametru generic care specifica intrizierea de propagare. Instante diferite pot fi folosite apoi cu intirzieri de propagare diferite. Al doilea exemplu declara o componenta de memorie "read-only" ale carei dimensiuni sint dependente de constante generice.

b)Instantierea componentelor

O componenta definita intr-o arhitectura poate fi definita astfel:

instructiune instantiere_componenta::=

eticheta_instantiere: nume_componenta

[ map generic ]

[ map port ] ;

Aceasta inseamna ca arhitectura contine o instanta a unei componente pentru care sint specificate valorile actuale ale constantelor generice. De asemenea, porturile componentei respective sint conectate la semnalele corespunzatoare sau la porturile entitatii.

enable gate: nand3 port map (a => enl, b => en2, c => int_req, y => interrupt);

parameter rom: read_only_memory

*generic ma* (data bits => 16, addr_bits => 8);

port map (en => rom_sel, data => param, addr => a(7 downto 0) );

In primul exempla nu este specificat map-generic, asa ca constanta generica Tpd timpul de propagare) este folosita. In al doilea exemplu sint specificate valorile pentru porturile de adrese si date.