Diferență între revizuiri ale paginii „CID Seminar 1”

De la WikiLabs
Jump to navigationJump to search
 
(Nu s-au afișat 38 de versiuni intermediare efectuate de alți 4 utilizatori)
Linia 1: Linia 1:
În acest seminar veţi învăţa să descrieţi unele circuite digitale simple în limbajul Verilog şi să folosiţi programul Xilinx ISim pentru a simula funcţionarea acestora.
+
În acest seminar veţi învăţa să descrieţi unele circuite digitale simple în limbajul Verilog şi să folosiţi programele Quartus II și ModelSim.
  
  
'''Cuvinte cheie:''' formă de undă, proiect, modul, instanţiere, testbench
 
  
'''Sintaxa Verilog:''' ''module'', ''assign'', ''initial'', ''$stop''
+
'''Cuvinte cheie:''' porți logice, porturi, formă de undă, proiect, modul, instanţiere, testbench
  
 +
'''Sintaxa Verilog:''' ''module'', ''wire'', ''reg'', ''initial'', ''$stop''
  
În domeniul digital, toate sistemele, circuitele şi blocurile funcţionale sunt conectate între ele numai prin semnale digitale, adică dreptunghiulare (care pot lua doar două valori, 0 si 1).
+
Verilog este un limbaj de descriere hardware (hardware description language). În acest limbaj putem descrie circuite digitale precum cel din figura 1.  
Cum obţinem formele de undă de la ieşirea unui circuit?
 
Descriem circuitul într-o manieră inteligibilă (folosind un HDL – în cazul nostru, Verilog). Aplicăm semnale pe intrare şi apoi simulăm funcţionarea, folosind un simulator (aici, Xilinx ISim).
 
  
 +
== Noțiuni și cunoștințe necesare ==
  
=== Exemplul 1===
+
* [[Introducere. Verilog HDL și ModelSim#Introducere în Circuite Digitale|Logică booleană și sisteme de numerație]]
 +
* Noțiuni de sintaxă [[Verilog]]
  
Descrieţi în Verilog un circuit de incrementare pentru numere binare pe 4 biţi şi testaţi funcţionarea acestui circuit, folosind modulul test_inc, cu ajutorul programului Model Sim.
+
== Exercițiul 1==
 +
 
 +
În figura 1 este reprezentată schema unui circuit digital care conține porți logice. Descrieți această schemă în limbajul Verilog.
  
 
[[Fișier:sem1ex1.png|Schema bloc pentru exemplul 1]]
 
[[Fișier:sem1ex1.png|Schema bloc pentru exemplul 1]]
  
<u>Explicaţii suplimentare</u>
+
'''Explicații''': Porțile logice elementare sunt predefinite în Verilog: '''not''', '''and''', '''nand''', '''or''', '''nor''', '''xor''', '''nxor'''. Sintaxa corectă este, pentru instanțierea unei porți '''and''':
 +
 
 +
<syntaxhighlight lang="verilog">
 +
and nume_poarta (iesire, intrare_1, intrare_2, …. intrare_n);
 +
</syntaxhighlight>
 +
 
  
Descrierea unui circuit include:
+
==Exercițiul 2==
* descrierea interfetei (declararea porturilor)
 
* descrierea funcţiei (ce face circuitul? în esenţă, cum depind ieşirile de intrări)
 
  
Circuitul din acest exemplu are o intrare (in), pe 4 biţi şi o ieşire (out), pe 5 biţi.
+
Creați un fișier Verilog care descrie circuitul de la exercițiul 1.
Bus-urile sunt semnale pe mai mulţi biţi care au o semnificaţie comună, este mai avantajos să îi definim împreună.
 
Funcţia realizată de circuit este out = in + 1.
 
  
<div class="regula">
+
'''Explicații:'''  
<font color="red">Regulă:</font> Descrierile circuitelor în Verilog sunt alcătuite din ''module''.
+
Descrierea unui circuit include:
</div>
+
*interfața (declararea porturilor de intrare și ieșire)
 +
*descrierea funcției sau a schemei circuitului
  
Intrările în Verilog se definesc cu cuvântul ''input'', ieşirile sunt ''output''.
+
În Verilog, descrierile circuitelor sunt alcătuite din module. Sintaxa este următoarea:
Orice modul începe cu cuvântul ''module'' şi se termină cu ''endmodule''. Modulele nu se pot suprapune şi nu pot fi incluse unele în altele.
 
  
 
<syntaxhighlight lang="verilog">
 
<syntaxhighlight lang="verilog">
 
module circuitul_meu(lista_porturi); /* porturile sunt conexiunile externe ale circuitului*/
 
module circuitul_meu(lista_porturi); /* porturile sunt conexiunile externe ale circuitului*/
  
……//declaraţi mai întâi porturile
+
//declaraţi mai întâi porturile
……//apoi daţi detaliile funcţionale
+
//apoi daţi detaliile funcţionale sau structurale
 
endmodule
 
endmodule
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Liniile de cod în Verilog se încheie cu ";" (există şi excepţii pe care le vom menţiona explicit, de exemplu după ultima linie – ''endmodule'' – de mai sus. În principiu, ";" determină o acţiune).
+
==Exercițiul 3==
Comentariile se introduc cu // sau cu /*....*/, vor apărea scrise în editorul programului cu verde şi sunt ignorate la compilare.
 
  
Un scurt tutorial pentru folosirea programului Xilinx ISim găsiţi [[Tutorial Xilinx ISim|aici]].
+
Generați formele de undă din figurile următoare în simulator.  
  
====Simularea funcţionării circuitelor====
+
1. Semnalul i0:
  
Pentru a verifica funcţionarea corectă a unui circuitul trebuie să îi aplicăm semnale pe intrare şi să verificăm dacă ieşirea este aşa cum ne-am aşteptat, altfel spus simulăm fucţionarea acestuia.
+
[[Fișier:cid_sem1_img2.png|Semnal i0]]
Definim un circuit care este de fapt o platformă de testare (testbench).
+
 
 +
2. Două semnale, i0 și i1:
 +
 
 +
[[Fișier:cid_sem1_img3.png|Semnale i0 și i1]]
 +
 
 +
3. Trei semnale:
 +
 
 +
[[Fișier:cid_sem1_img4.png|Trei semnale]]
 +
 
 +
<u>Rezolvare punctul 1:</u>
 +
 
 +
Se va scrie un fișier sursă nou, care nu are porturi exterioare (deoarece nu descrie un circuit).
 +
 
 +
[[Fișier:cid_sem1_img5.png|Cod sursă exercițiul 3]]
 +
 
 +
==Exemplul 4==
 +
Simulați funcționarea modulului de la exercițiul 2, aplicând pe intrare semnalele de la exercițiul 3 – punctul 3.
 +
Știind că acest circuit este un multiplexor (circuit de selecție), analizați formele de undă pentru a vedea dacă sunt corecte. Modificați eventual forma de undă pe intrarea s și verificați funcționarea corectă.
 +
 
 +
'''Explicații:''' Pentru a simula funcționarea unui circuit, trebuie să realizăm o platformă de test (Testbench) descrisă într-un nou modul. Aplicăm semnalele respective pe intrarea circuitului testat – instanțiem circuitul respectiv.  Simulăm modulul de test și apoi analizăm formele de undă pentru a vedea dacă acestea corespund funcției implementate.
  
[[Fișier:sem1tb.png|Conceptul de testbench]]
+
==Exercițiul 5==
  
Acesta circuit este un modul distinct, special pentru testare, numit de obicei modul de test. Modulul de test nu are conexiuni externe, dar face referinţă la modulul pe care l-am descris anterior.
+
Desenaţi schema descrisă de următorul cod Verilog:
  
 
<syntaxhighlight lang="verilog">
 
<syntaxhighlight lang="verilog">
module test_inc ();  //nu are porturi externe, ()” poate lipsi
+
circuit1 ana (.in1(a), .in2 (b), .out1(w), .out2(en));
  reg [3:0] a; // aici am definit o variabila pe 4 biti
+
circuit2 doru(.in3(w), .in4 (b), .out(c));
  wire [4:0] b; // aici am definit o conexiune, un “fir” pe 5 biti
+
circuit3 zuzu(.in0(en), .in1(c), .out(out));
//urmeaza generarea semnalelor care vor fi aplicate pe INTRARI
+
</syntaxhighlight>
  initial begin // intructiunile initial se executa la t = 0
 
a=0;
 
#10 a=5; /* #10 reprezinta o intarziere de 10 unitati timp, care se
 
            aduna la intarzierea anterioara, in acest caz la t=0. Deci t
 
    devine t = 10  */
 
#10 a=8; // aici suntem la t = 20
 
#15 a=15;
 
#5 a=4’b0001; // a este de fapt un semnal pe patru biti
 
#5 a=4’b0100;
 
#30 $stop; // va opri simularea, este bine sa nu lipseasca
 
  end // dupa begin si end nu se pune “;”
 
  
  inc dut(a, b); // atentie! modulul de incrementare trebuie denumit inc
+
... unde modulele au porturile declarate astfel:
  
 +
<syntaxhighlight lang="verilog">
 +
module circuit1 (
 +
            input in1, in2,
 +
            output out1,
 +
            output out2);
 +
...
 +
endmodule
 +
 +
 +
 +
module circuit2 (
 +
            input in3, in4,
 +
            output out);
 +
...
 +
endmodule
 +
 +
 +
 +
module circuit3 (
 +
            input in1,
 +
            input in0,
 +
            output out);
 +
...
 
endmodule
 
endmodule
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Exemplul 2===
+
== Principalele noțiuni de Verilog introduse în acest seminar ==
  
# Descrieţi în Verilog o poartă ŞI cu trei intrări.  
+
1. '''Descrierile circuitelor în Verilog sunt alcătuite din ''module''.'''
# Testaţi funcţionarea acestei porţi.
+
Orice modul începe cu cuvântul module şi se termină cu endmodule. Modulele nu se pot suprapune şi nu pot fi incluse unele în altele.
  
 +
<syntaxhighlight lang="verilog">
 +
module circuitul_meu(lista_porturi); /* porturile sunt conexiunile externe ale circuitului*/
  
<u>Explicaţii suplimentare</u>
+
……//declaraţi mai întâi porturile
 
+
……//apoi daţi detaliile funcţionale sau structurale
Principalele funcţii logice (şi porţile logice corespunzătoare) sunt prezentate [[Introducere. Verilog HDL și ModelSim#Circuite|aici]]. Funcţia ŞI (AND) cu trei intrări ia valoarea 1 numai dacă toate intrările sunt 1, în rest ia valoarea 0.
+
endmodule
 +
</syntaxhighlight>
  
'''Definirea porturilor unui circuit''' se poate face:
+
2. '''Porturile''' unui circuit se pot declara
 
* în corpul modulului
 
* în corpul modulului
* compactat, în lista porturilor
+
* compactat, în lista porturilor.
 +
Intrările în Verilog se declară cu cuvântul ''input'', ieşirile sunt ''output''.
  
Varianta1 (Verilog '95)
+
<u>Varianta 1 (Verilog '95)</u>
 
<syntaxhighlight lang="verilog">
 
<syntaxhighlight lang="verilog">
module poarta_AND_3 (a, b, c, out);
+
module circuit (a, b, c, out);
 
   input a, b, c; // putem pune mai multe pe aceeasi linie, separate cu ,
 
   input a, b, c; // putem pune mai multe pe aceeasi linie, separate cu ,
 
   output out;
 
   output out;
Linia 102: Linia 139:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Varianta 2. (Verilog 2001)
+
<u>Varianta 2. (Verilog 2001)</u>
 
<syntaxhighlight lang="verilog">
 
<syntaxhighlight lang="verilog">
module poarta_AND_3 (
+
module circuit (
 
input a,          // scriem cu tab-uri ca sa fie vizibile
 
input a,          // scriem cu tab-uri ca sa fie vizibile
 
input b,  
 
input b,  
Linia 113: Linia 150:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Aici avem mai multe intrări pe 1 bit deci putem scrie şi
+
Dacă avem mai multe intrări similare putem scrie şi:
 
<syntaxhighlight lang="verilog">
 
<syntaxhighlight lang="verilog">
module poarta_AND_3 (
+
module circuit (
input a, b, c,        // scriem cu tab-uri ca sa fie vizibile
+
input a, b, c,         
 
output out);
 
output out);
 
...
 
...
Linia 122: Linia 159:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Vom verifica funcţionarea corectă cu modulul de test.
 
  
[[Fișier:sem1ex2codeprint.png|Codul modulului de test]]
+
3. '''Liniile de cod în Verilog se încheie cu “;”''' (există şi excepţii pe care le vom menţiona explicit, de exemplu după ultima linie – ''endmodule'' – de mai sus. În principiu, “;” determină o acţiune).
 +
 
 +
4. '''Comentariile''' se introduc cu // sau cu /*....*/, vor apărea scrise în editorul programului cu altă culoare şi sunt ignorate la simulare și sinteză.
 +
 
 +
5. '''Simularea funcţionării circuitelor'''
 +
 
 +
Pentru a verifica funcţionarea corectă a unui circuitul trebuie să îi aplicăm semnale pe intrare şi să verificăm dacă ieşirea este aşa cum ne-am aşteptat, altfel spus simulăm fucţionarea acestuia.
 +
 
 +
Definim un circuit care este de fapt o platformă de testare (testbench)
 +
 
 +
[[Fișier:Sem1tb.png]]
 +
 
 +
Acesta circuit este un modul distinct, special pentru testare, numit de obicei modul de test. Modulul de test nu are conexiuni externe, dar instanțiază modulul pe care îl testăm (UUT) și pe care l-am descris în prealabil în alt fișier.
 +
 
 +
6. '''Instanţierea''' permite folosirea unui modul, după ce el a fost definit. Odată ce am definit un modul, numele lui este similar unei instrucţiuni a limbajului Verilog.
 +
De exemplu, după ce am definit circuitul de la exercițiul 1 și 2, putem să îl folosim în alte scheme, în modul următor:
 +
 
 +
<syntaxhighlight lang="verilog">
 +
ex1 UUT (lista porturi);
 +
</syntaxhighlight>
 +
 
 +
Porturile se pot conecta ţinând cont de ordinea lor sau definind explicit semnalele conectate pe fiecare port:
 +
 
 +
<syntaxhighlight lang="verilog">
 +
ex1 dut1 (i0, i1, i2, out);
 +
ex1 dut1(.a(i0), .b (i1), .s(i2),. y (out));
 +
</syntaxhighlight>
 +
 
 +
Deşi în varianta 2 putem scrie porturile în orice ordine, preferăm să le scriem în aceeaşi ordine!
 +
Este posibil să nu conectăm semnale pe toate intrările, dacă într-un context particular nu sunt necesare.
 +
Modulul instanțiat trebuie să fie definit în acelaşi proiect (nu neapărat în acelaşi fişier).
 +
 
 +
 
 +
'''7. Porţi logice în Verilog'''
 +
În Verilog, porțile logice elementare sunt predefinite ca primitive, există deci cuvinte speciale de limbaj.
 +
 
 +
Pentru funcția ŞI:
 +
<syntaxhighlight lang="verilog">
 +
and P1(out1, in1, in2,..., ink); // pentru toate portile logice predefinite in verilog primul port este iesirea
 +
and P2(out2, in1, in2); // fiecare instanta trebuie sa aiba un nume unic
 +
</syntaxhighlight>
 +
 +
Celelalte porţi logice sunt: ''nand'', ''or'', ''nor'', ''xor'', ''xnor''.
 +
La toate aceste porţi, implicit prima este ieşirea şi se pot pune oricâte intrări.
 +
 
 +
'''Observaţie''': Notaţiile simple folosite pentru funcţii logice în scrierea curentă nu sunt identice cu simbolurile operatorilor din Verilog.
 +
 
 +
{| class="wikitable"
 +
! Funcţie logică!! Simbol !! operator Verilog
 +
|-
 +
| ȘI ||•  (se poate omite) ||&
 +
|-
 +
| SAU ||+ || <nowiki>|</nowiki>
 +
|-
 +
| XOR || &oplus; || ^
 +
|-
 +
| NOT || ' || ~
 +
|}
 +
 
 +
== Reguli de bună practică ==
 +
 
 +
=== Organizarea fişierelor ===
 +
* Salvaţi modulele pe care le scrieţi în fişiere distincte.
 +
* Numele fişierului să fie identic cu numele modulului.
 +
* Pentru simulare, folosiţi un folder distinct.
 +
 
 +
=== Scrierea codului ===
 +
* Daţi nume sugestive modulelor, porturilor şi semnalelor.
 +
* Introduceţi comentarii pentru documentarea codului.
 +
* Folosiţi tab-uri şi linii goale pentru alinierea şi gruparea blocurilor de instrucţiuni.

Versiunea curentă din 28 martie 2017 09:20

În acest seminar veţi învăţa să descrieţi unele circuite digitale simple în limbajul Verilog şi să folosiţi programele Quartus II și ModelSim.


Cuvinte cheie: porți logice, porturi, formă de undă, proiect, modul, instanţiere, testbench

Sintaxa Verilog: module, wire, reg, initial, $stop

Verilog este un limbaj de descriere hardware (hardware description language). În acest limbaj putem descrie circuite digitale precum cel din figura 1.

Noțiuni și cunoștințe necesare

Exercițiul 1

În figura 1 este reprezentată schema unui circuit digital care conține porți logice. Descrieți această schemă în limbajul Verilog.

Schema bloc pentru exemplul 1

Explicații: Porțile logice elementare sunt predefinite în Verilog: not, and, nand, or, nor, xor, nxor. Sintaxa corectă este, pentru instanțierea unei porți and:

and nume_poarta (iesire, intrare_1, intrare_2, . intrare_n);


Exercițiul 2

Creați un fișier Verilog care descrie circuitul de la exercițiul 1.

Explicații: Descrierea unui circuit include:

  • interfața (declararea porturilor de intrare și ieșire)
  • descrierea funcției sau a schemei circuitului

În Verilog, descrierile circuitelor sunt alcătuite din module. Sintaxa este următoarea:

module circuitul_meu(lista_porturi); /* porturile sunt conexiunile externe ale circuitului*/

	//declaraţi mai întâi porturile
	//apoi daţi detaliile funcţionale sau structurale
endmodule

Exercițiul 3

Generați formele de undă din figurile următoare în simulator.

1. Semnalul i0:

Semnal i0

2. Două semnale, i0 și i1:

Semnale i0 și i1

3. Trei semnale:

Trei semnale

Rezolvare punctul 1:

Se va scrie un fișier sursă nou, care nu are porturi exterioare (deoarece nu descrie un circuit).

Cod sursă exercițiul 3

Exemplul 4

Simulați funcționarea modulului de la exercițiul 2, aplicând pe intrare semnalele de la exercițiul 3 – punctul 3. Știind că acest circuit este un multiplexor (circuit de selecție), analizați formele de undă pentru a vedea dacă sunt corecte. Modificați eventual forma de undă pe intrarea s și verificați funcționarea corectă.

Explicații: Pentru a simula funcționarea unui circuit, trebuie să realizăm o platformă de test (Testbench) descrisă într-un nou modul. Aplicăm semnalele respective pe intrarea circuitului testat – instanțiem circuitul respectiv. Simulăm modulul de test și apoi analizăm formele de undă pentru a vedea dacă acestea corespund funcției implementate.

Exercițiul 5

Desenaţi schema descrisă de următorul cod Verilog:

circuit1 ana (.in1(a), .in2 (b), .out1(w), .out2(en));
circuit2 doru(.in3(w), .in4 (b), .out(c));
circuit3 zuzu(.in0(en), .in1(c), .out(out));

... unde modulele au porturile declarate astfel:

module circuit1 (
            input in1, in2,
            output out1,
            output out2);
...
endmodule
 
 
 
module circuit2 (
            input in3, in4,
            output out);
...
endmodule
 
 
 
module circuit3 (
            input in1,
            input in0,
            output out);
...
endmodule

Principalele noțiuni de Verilog introduse în acest seminar

1. Descrierile circuitelor în Verilog sunt alcătuite din module. Orice modul începe cu cuvântul module şi se termină cu endmodule. Modulele nu se pot suprapune şi nu pot fi incluse unele în altele.

module circuitul_meu(lista_porturi); /* porturile sunt conexiunile externe ale circuitului*/

	……//declaraţi mai întâi porturile
	……//apoi daţi detaliile funcţionale sau structurale
endmodule

2. Porturile unui circuit se pot declara

  • în corpul modulului
  • compactat, în lista porturilor.

Intrările în Verilog se declară cu cuvântul input, ieşirile sunt output.

Varianta 1 (Verilog '95)

module circuit (a, b, c, out);
   input a, b, c; // putem pune mai multe pe aceeasi linie, separate cu ,
   output out;
.....
endmodule

Varianta 2. (Verilog 2001)

module circuit (
		input a,          // scriem cu tab-uri ca sa fie vizibile
		input b, 
		input c, 
		output out);
...
endmodule

Dacă avem mai multe intrări similare putem scrie şi:

module circuit (
		input a, b, c,         
		output out);
...
endmodule


3. Liniile de cod în Verilog se încheie cu “;” (există şi excepţii pe care le vom menţiona explicit, de exemplu după ultima linie – endmodule – de mai sus. În principiu, “;” determină o acţiune).

4. Comentariile se introduc cu // sau cu /*....*/, vor apărea scrise în editorul programului cu altă culoare şi sunt ignorate la simulare și sinteză.

5. Simularea funcţionării circuitelor

Pentru a verifica funcţionarea corectă a unui circuitul trebuie să îi aplicăm semnale pe intrare şi să verificăm dacă ieşirea este aşa cum ne-am aşteptat, altfel spus simulăm fucţionarea acestuia.

Definim un circuit care este de fapt o platformă de testare (testbench)

Sem1tb.png

Acesta circuit este un modul distinct, special pentru testare, numit de obicei modul de test. Modulul de test nu are conexiuni externe, dar instanțiază modulul pe care îl testăm (UUT) și pe care l-am descris în prealabil în alt fișier.

6. Instanţierea permite folosirea unui modul, după ce el a fost definit. Odată ce am definit un modul, numele lui este similar unei instrucţiuni a limbajului Verilog. De exemplu, după ce am definit circuitul de la exercițiul 1 și 2, putem să îl folosim în alte scheme, în modul următor:

ex1 UUT (lista porturi);

Porturile se pot conecta ţinând cont de ordinea lor sau definind explicit semnalele conectate pe fiecare port:

ex1 dut1 (i0, i1, i2, out);
ex1 dut1(.a(i0), .b (i1), .s(i2),. y (out));

Deşi în varianta 2 putem scrie porturile în orice ordine, preferăm să le scriem în aceeaşi ordine! Este posibil să nu conectăm semnale pe toate intrările, dacă într-un context particular nu sunt necesare. Modulul instanțiat trebuie să fie definit în acelaşi proiect (nu neapărat în acelaşi fişier).


7. Porţi logice în Verilog În Verilog, porțile logice elementare sunt predefinite ca primitive, există deci cuvinte speciale de limbaj.

Pentru funcția ŞI:

and P1(out1, in1, in2,..., ink); // pentru toate portile logice predefinite in verilog primul port este iesirea
and P2(out2, in1, in2); // fiecare instanta trebuie sa aiba un nume unic

Celelalte porţi logice sunt: nand, or, nor, xor, xnor. La toate aceste porţi, implicit prima este ieşirea şi se pot pune oricâte intrări.

Observaţie: Notaţiile simple folosite pentru funcţii logice în scrierea curentă nu sunt identice cu simbolurile operatorilor din Verilog.

Funcţie logică Simbol operator Verilog
ȘI • (se poate omite) &
SAU + |
XOR ^
NOT ' ~

Reguli de bună practică

Organizarea fişierelor

  • Salvaţi modulele pe care le scrieţi în fişiere distincte.
  • Numele fişierului să fie identic cu numele modulului.
  • Pentru simulare, folosiţi un folder distinct.

Scrierea codului

  • Daţi nume sugestive modulelor, porturilor şi semnalelor.
  • Introduceţi comentarii pentru documentarea codului.
  • Folosiţi tab-uri şi linii goale pentru alinierea şi gruparea blocurilor de instrucţiuni.