2 Limbajul Verilog



Yüklə 59,68 Kb.
tarix31.10.2017
ölçüsü59,68 Kb.

2 Limbajul Verilog



2.1 Scurt istoric
Limbajele de descriere hardware (HDL’s) sunt limbaje de programare utilizate pentru descrierea diferitelor circuite electrice, în special a celor digitale. Aceste limbaje pot fi folosite pentru a descrie un circuit din punctul de vedere al alcătuirii fizice a acestuia cât şi pentru descrierea unor circuite din punctul de vedere al funcţionalităţii lor, fără a interesa structura lor fizică. Primul limbaj de descriere hardware a fost inventat de C. Gordon Bell şi Alan Newell la Carnegie Mellon University şi descris în cartea lor „Computer Structures” în 1972.

Limbajul Verilog a fost brevetat pentru prima dată de compania Gateway Design Automation Inc în 1984 şi are drept precursori limbajele HiLo (limbaj de descriere hardware) şi C. În momentul creării limbajului acesta nu era standardizat şi a suferit foarte multe modificări de la lansarea sa iniţială.

În perioada 1985 - 1987 a fost creat şi primul simulator de Verilog ce a fost îmbunătăţit odată cu fiecare nouă lansare pe piaţă. Prima extensie importantă a limbajului a fost Verilog-XL ce a adus printre altele o nouă şi eficientă metodă pentru simulare la nivelul de poartă logică.

În 1990 compania Cadence Design System a luat decizia de a cumpăra Gateway Design Automation, preluând în acelaşi timp şi destinele limbajului Verilog. În acelaşi an, Cadence a luat hotărârea de a face din Verilog un limbaj de programare ce aparţine domeniului public. Aceasta hotărâre a dat şansa oricărei companii rivale de a dezvolta simulatoare de Verilog.

După puţin timp Cadence a realizat că oricare dintre aceste companii producătoare de simulatoare Verilog pot modifica limbajul Verilog la fel cum au făcut la timpul lor Gateway Design sau Cadence. Acest lucru putea duce la îndepărtarea de scopul iniţial al lansării Verilog-ului în proprietatea domeniului public. Drept urmare, a fost creată organizaţia Open Verilog International (OVI) în care erau reprezentate toate companiile mari care se ocupau cu oferirea de unelte pentru dezvoltare hardware.

Sarcina principală primită de OVI a fost standardizarea limbajului. Primele schiţe ale staandardului propus au fost copii aproape identice ale manualului Verilog lansat de Cadence. Între timp, popularitatea limbajului Verilog creştea aproape exponenţial. Verilog ca şi limbaj de descriere hardware a atras mai mulţi utilizatori decât VHDL ce era deja bine definit şi sprijinit cu fonduri federale. Prin urmare, la mijlocul anului 1993 a fost format comitetul IEEE cu numărul 1364 ce a lansat standardul Verilog în mai 1995, cunoscut mai ales sub denumirea de IEEE Std. 1364-1995.

După aproape patru ani, în 1999, standardul a fost pentru prima data îmbunătăţit iar ultima redefinire a acestuia a avut loc în 2001 sub denumirea de Verilog-2001. Acest ultim standard (cunoscut şi ca IEEE 1364-2001) a fixat majoritatea problemelor pe care standardul din 1995 le-a avut.
Principalele modificări aduse de Verilog-2001 sunt:


  • aducerea la zi a limbajului în aşa fel încât să ţină pas cu cerinţele tehnicii moderne;

  • corectarea oricăror erori sau ambiguităţi ale standardului anterior;

  • implementarea unui model scalabil care să permită instanţierea diferitelor module, registre sau variabile într-un mod iterativ;

  • funcţii constante (se vor utiliza construcţii ale căror valori pot fi determinate în momentul compilării);

  • selectarea unui element al unui vector cu ajutorul operatorilor + sau - ;

  • matrici multidimensionale;

  • operatorul putere;

  • task-uri reentrante şi funcţii recursive;

  • înbunătăţirea lucrului cu fişiere;

  • detectarea pulsurilor negative;



2.2 Sintaxa limbajului Verilog
2.2.1 Sintaxa formală
2.2.1.A Definiţii şi convenţii


White space

Se poate folosi pentru separarea lexicală

<>

Se vor folosi doar în descrierea sintaxei şi nu apar în sursa Verilog.

cu litere mici

Construcţie sintactică.

cu litere mari

Construcţie lexicală.

?

Element opţional.

*

Nici unul, unul sau mai multe elemente.

+

Unul sau mai multe elemente.

<,>*

O lista de elemente separată prin virgulă.

::=

Definiţie sintactică a unui element.

||=

Introduce o definiţie de sintaxă alternativă.



2.3 Introducere în Verilog
Limbajul Verilog, ca de altfel orice limbaj de descriere hardware permite descrierea circuitelor atât folosind metodologia Bottom-Up cât şi metodologia Top-Down.

Metoda tradiţională de proiectare a circuitelor electrice este Bottom-Up. Fiecare circuit este descris la nivelul de porţi logice utilizând celulele standard. Ţinând cont de complexitatea circuitelor moderne, această apropiere este din ce în ce mai puţin folosită şi aproape imposibil de întreţinut. Sistemele noi constau din ASIC-uri sau FPGA-uri cu o complexitate de milioane de tranzistori. Acest tip de proiectare trebuie să dispară în favoarea noilor metodologii structurale şi ierarhice.

Tipul de proiectare dorit de toţi proiectanţii moderni este cel Top-Down. Un design Top-Down real permite testarea circuitelor încă din faza de proiectare permiţând schimbarea tehnologiilor atunci când acestea nu mai corespund. De asemeni această abordare oferă un alt număr de avantaje majore şi este în general preferată în ultimii ani (Figura 2.1).

O strategie pur Top-Down este de obicei foarte greu de urmat şi de aceea este de preferat o structurare a proiectului folosind această metodă dar o dezvoltare a diferitelor module aflate la nivelul cel mai de jos folosind strategia Bottom-Up. În concluzie, în general noile circuite sunt gândite global Top-Down şi implementate în mare parte Bottom-Up.




Fig. 2.1 - Proiectare Top-Down [2.2]


Orice limbaj de descriere hardware modern poate fi folosit pentru proiectarea la orice nivel de abstractizare începând de la modelele arhitecturale de nivel înalt şi până la modelele de nivel cel mai scăzut (switch, poartă logică, tranzistor). Din punctul de vedere al nivelelor de abstractizare, descrierea cu ajutorul limbajului Verilog poate fi împărţită în: funcţională (behavioural models) şi structurală (structural models)[2.3]. Aceste nivele prezentate anterior sunt descrise şi în figura 2.2.


Fig. 2.2 Nivele de abstractizare [2.3]
Modelele comportamentale reprezintă de fapt cod sursă Verilog ce descrie un circuit electric din punctul de vedere al funcţionării acestuia, fără a ţine cont în vreun fel de implementarea sa în hardware. De obicei acest tip de modele nu includ foarte multă informaţie despre constrângerile de timp. De asemeni modelele comportamentale depind în foarte mare măsură de uneltele de sinteză folosite şi de performanţele acestora în ceea ce priveşte constrângerile de arie sau număr de porţi logice folosite. De exemplu, sumatoarele pot aduna două sau mai multe numere fără să fie specificate registre, porţi logice sau tranzistori. Modelele comportamentale pot fi împărţite în algoritmice şi arhitecturale.

Algoritmii sunt metode de tipul pas cu pas pentru rezolvarea problemelor şi producerea rezultatelor. Nici un fel de implementare hardware nu este subînţeleasă dintr-un model algoritmic. Acest tip de model nu conţine nici un fel de descriere a semnalelor de ceas, de reset sau a altor tipuri de semnale. De asemeni nu conţine nici descrieri de porţi logice sau tranzistori şi nu este nevoie de descrierea în hardware a niciunei entităţi numerice sau a tipului de memorie folosită pentru a o păstra.

De exemplu, să presupunem ca dorim să descriem o ALU (Arithmetic Logic Unit). Această ALU va avea drept intrări două valori numerice (operand_a, operand_b) şi o intrare de control (operatie). Intrarea de control va putea comanda una din urmatoarele patru operaţii între cei doi operanzi: adunare, scădere, înmulţire sau împărţire. Rezultatul va fi rezultat_c. Un posibil model algoritmic ar putea fi următorul:
if operatie = 0 , then result_c = operand_a + operand_b

if operatie = 1 , then result_c = operand_a - operand_b

if operatie = 2 , then result_c = operand_a * operand_b

if operatie = 3 , then result_c = operand_a / operand_b
În descrierea de mai sus nu am ţinut în nici un fel cont de reprezentarea numerelor. Nu se ştie dacă acestea vor fi reprezentate pe 4, 8 sau 16 biţi. Nu se ştie de asemeni dacă vor fi numere cu semn sau fără. Nu se va şti nici câte cicluri de ceas vor trebui pentru a termina o operaţie de adunare sau una de înmulţire. Acest gen de întrebări trebuie să aibă un răspuns atunci când se doreşte implementarea în hardware a unui anumit algoritm.

Modelele arhitecturale descriu hardware-ul la un nivel foarte înalt folosind blocuri funcţionale cum ar fi memorii, logică de control CPU, FIFO ş.a.m.d. Aceste blocuri pot reprezenta descrieri ale unor placi PC, ASCI sau FPGA sau a altor componente majore ale unui sistem. Un model arhitectural trebuie să conţină descrieri hardware pentru modul de reprezentare a întregilor cu semn sau fără, a nivelului de memorie ce trebuie utilizată pentru valorile intermediare. De asemeni modelele arhitecturale trebuie să ţină cont de semnalul de ceas sistem dar nu până acolo încât să fie descris orice se întâmplă în fiecare ciclu de ceas. De acest lucru se ocupă nivelul RTL. Folosind modelul arhitectural ALU prezentată anterior poate fi descrisă după cum urmează:


main_block:

declare operand_a as a 16-bit bus

declare operand_b as a 16-bit bus

declare result_c as a 16-bit bus

declare mem as a 3 by 16 memory

wait for the rising edge of the clock signal

store operand_a in mem[0]

store operand_b in mem[1]

if operation = 0, then use adder_block

if operation = 1, then use subtractor_block

if operation = 2, then use multiplier_block

if operation = 3, then use divider_block

wait for five more rising edges of the clock signal

read result_c from mem[2]


În descrierea de mai sus, modelul hardware va fi de fapt împărţit în şase module: main_block, addler_block, substractor_block, divider_block şi memoria. Dintre cele şase, doar blocul principal este descris. O diagramă a structurii prezentate poate fi urmărită în figura 2.3.'


Fig. 2.3 Modelul arhitectural [2.3]

În descrierea de mai sus am împărţit descrierea hardware a sistemului în blocuri mai mici constituente dar fiecare bloc are în continuare o mare funcţionalitate. Se pune problema cum vom reprezenta numerele intern. Trebuie de asemeni să ţinem cont de semnalele de ceas, dar nu vom ţine cont de ce anume este executat în hardware în fiecare ciclu de ceas.


Modelele structurale descriu circuitul prin prezentarea exactă a fiecărei părţi hardware implicată în proiectul curent. Acest tip de model poate fi împărţit mai departe în: nivel RTL, nivel porţi logice şi nivel switch.

Modelele RTL descriu hardware-ul la nivel de registre. Cu alte cuvinte la nivelul RTL se va specifica ce anume se va întâmpla la fiecare nivel crescător al semnalului de ceas. Reprezentarea porţilor logice implicate este evitată iar funcţiile booleene vor fi implementate folosind descrierea RTL şi vor fi sintetizate în porţi logice. Descrierile de nivel înalt al funcţiilor hardware pot fi folosite atâta timp cât comportarea lor ţine cont de semnalul de ceas sistem. Automatele cu stări finite sunt exemple bune de sisteme hardware uşor de implementat folosind descrierea RTL. Funcţionarea unui automat poate fi complexă dar descrierea ţinând cont de comportarea sa la fiecare ciclu de ceas folosind RTL poate fi relativ simplă.

Un exemplu de logică secvenţială şi descrierea sa RTL este prezentat în figura 2.4:

Fig. 2.4 Descrierea RTL a unui circuit secvenţial [2.3]
Modelarea la nivel de poartă logică permite descrierea unui circuit folosind doar porţi logice cum ar fi: AND, OR, XOR, NAND, NOR, etc. Circuitul descris anterior cu ajutorul RTL poate fi descris la nivel de porţi logice ca şi în figura de mai jos:


Fig. 2.5 Descrierea la nivel de porţi logice a unui circuit secvenţial [2.3]
Avantajul principal al folosirii unui limbaj de descriere hardware cum este Verilog-ul este acela că toate aceste tipuri de modele pot fi utilizate folosind acelaşi limbaj şi în cadrul aceluiaşi proiect. Nu este nevoie de învăţarea sau utilizarea de unelte diferite care să îngreuneze proiectarea unui circuit. De asemeni se poate simula circuitul înainte de implementarea sa efectivă în hardware rezultând astfel un cost final mai scăzut al circuitului.

2.4 Exemplu de program Verilog
Pentru început, vom prezenta unul din cele mai simple programe Verilog şi anume: implementarea unui numărător:



Fig. 2.6 Implementare numărător [2.2]

Descrierea Verilog a numărătorului prezentat mai sus este:



Pentru TestBenchmark, vom folosi următoare diagramă:


Fig. 2.7 TestBench [2.2]
, ce are următorul cod Verilog:

După cum se observă din programul Verilog de mai sus, vom avea nevoie de un simulator pentru a testa numărătorul implementat. În viaţa reală însă programul va trebui supus sintezei, urmată de procesul place&route şi testat cu ajutorul unui FPGA. Pentru a sintetiza un circuit descris cu ajutorul limbajului Verilog va trebui sa rescriem programul. Una din regulile de bază în acest caz este renunţarea la instrucţiuni de genul: for, while, repeat, etc.



2.5 Cod Verilog sintetizabil
După cum am văzut şi în subcapitolul precedent există câteva deosebiri fundamentale între codul Verilog behavioral şi codul Verilog ce poate fi sintetizat şi implementat în hardware. Cu toate acestea codul Verilog ce descrie funcţionarea din punct de vedere algoritmic poate fi modificat în aşa fel încât să fie sintetizabil. Vom prezenta în continuare câteva exemple descrise de David Chinnery în ”Writing synthesizable Verilog code from behavioral code” [2.4].
2.5.1 Instrucţiunea wait
Pentru a modifica o descriere comportamentală a unei instrucţiuni wait în cod Verilog sintetizabil, putem urma exemplul de mai jos:

Cod iniţial:



command1;

wait (x != 0);

command3;
Cod Verilog sintetizabil:

case (state)

0 : begin

command1;

if (x != 0) command3;

else state <= 1;

end
1 : if (x != 0) // wait until this is true

command3;

endcase
Dacă nu este importat faptul că poate apare o întârziere de un ciclu de ceas, varianta următoare este de preferat:

case (state)

0 : begin

command1;

state <= 1;

end
1 : if (x != 0) // wait until this is true

command3;

endcase
2.5.2 Instrucţiunea while
Pentru a modifica instrucţiunea while specifică Verilog-ului behavioral în Veriog sintetizabil vom urma exemplul de mai jos.

Cod iniţial:



command1;

while (x != 0)

begin

command2;

end

command3;
Cod Verilog sintetizabil:

case (state)

0 : begin

command1;

if (x != 0)

begin

command2;

state <= 1;

end

else command3;

end
1 : if (x != 0)

begin

command2;

end

else command3;

endcase
Dacă nu este importat faptul că poate apare o întârziere de un ciclu de ceas, varianta următoare este de preferat:

case (state)

0 : begin

command1;

state <= 1;

end
1 : if (x != 0)

begin

command2;

end

else command3;

endcase
2.5.3 Instrucţiunile fork şi join
Pentru a modifica instrucţiunile fork şi join specifice Verilog-ului behavioral în Veriog sintetizabil vom urma exemplul de mai jos.

Cod iniţial:



command1;

fork

// start of fork block 1

begin

wait (y != 0);

a = y;

end
// start of fork block 2

begin

wait (z != 0);

b = z;

end

join

command2;
Cod Verilog Sintetizabil:

case (state)

0 : begin

command1;

done_fork_block_1 = 0;

done_fork_block_2 = 0;
if (y != 0)

begin

a = y;

done_fork_block_1 = 1;

end
if (z != 0)

begin

b = z;

done_fork_block_2 = 1;

end
if (done_fork_block_1 & done_fork_block_2) command2;

else state <= 1;

end
1 : begin

if ((y != 0) && !done_fork_block_1)

begin

a = y;

done_fork_block_1 = 1;

end
if ((z != 0) && !done_fork_block_2)

begin

b = z;

done_fork_block_2 = 1;

end
if (done_fork_block_1 & done_fork_block_2) command2;

// else state <= 1;

end

endcase
În unele cazuri este posibil să nu avem nevoie de semnale done, dar în general, comenzile executate în paralel în cadrul unui bloc fork nu se vor termina în acelaşi timp. Din nou, dacă nu este importat faptul că poate apare o întârziere de un ciclu de ceas, varianta următoare este de preferat:

case (state)

0 : begin

command1;

done_fork_block_1 = 0;

done_fork_block_2 = 0;

state <= 1;

end
1 : begin

if ((y != 0) && !done_fork_block_1)

begin

a = y;

done_fork_block_1 = 1;

end
if ((z != 0) && !done_fork_block_2)

begin

b = z;

done_fork_block_2 = 1;

end
if (done_fork_block_1 & done_fork_block_2) command2;

// else state <= 1;

end

endcase
2.5.4 Instrucţiunea delay
Implementarea instrucţiunilor delay în cod Veriog sintetizabil va cere o atenţie mărită dacă acestea sunt mai multe unele imediat după celelalte. Dacă sunt întârzieri doar pe partea crescătoare a semnalului de ceas, codul Verilog sintetizabil se poate implementa folosind un automat.

Cod iniţial:



forever

begin

command1;

@(posedge clock);

command2;

@(posedge clock);

command3;

@(posedge clock);

end
Cod Verilog sintetizabil:

always @(posedge clock or posedge reset)

if (reset) // reset the state machine when reset is high

state <= 0;

else

begin

case (state)

0 : begin

command1;

state <= 1;

end

1 : begin

command2;

state <= 2;

end

2 : begin

command3;

state <= 0;

end

endcase

end

Dacă ambele tranziţii ale ceasului sunt folosite, codul Verilog sintetizabil se poate implementa folosind un automat finit care-şi schimbă valorile de la o tranziţie la alta.



Cod iniţial:

forever

begin

command1;

@(posedge clock);

command2;

@(negedge clock);

command3;

@(posedge clock);

@(posedge clock);

command4;

@(negedge clock);

end
Cod Verilog sintetizabil:

always @(posedge clock or negedge clock or posedge reset)

if (reset) // reset the state machine when reset is high

begin

state <= 0;

end

else

begin

case (state)

0 : begin

command1;

state <= 1;

end
1 : if (clock == 1) // wait for the positive edge

begin

command2;

state <= 2;

end
2 : begin // this will definitely begin at the negative edge as state 1 precedes it

command3;

state <= 3;

end
// we arrive at the positive edge of the clock, but need to wait a clock cycle

3 : state <= 4;
4 : if (clock == 1) // wait for the positive edge

begin

command4;

state <= 0;

end

endcase

end
Exemplele anterioare de transformare a unui cod Verilog behavioral în cod Verilog sintetizabil vor fi în continuare folosite pentru sinteza unor circuite electrice digitale precum şi pentru testarea lor cu ajutorul unor FPGA-uri XILINX.






Yüklə 59,68 Kb.

Dostları ilə paylaş:




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2020
rəhbərliyinə müraciət

    Ana səhifə