CID Seminar 1: Diferență între versiuni

De la WikiLabs
(Exemplul 3)
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 programul Xilinx ISim pentru a simula funcţionarea acestora.
  
 +
Un scurt tutorial pentru folosirea programului Xilinx ISim găsiţi [[Tutorial Xilinx ISim|aici]].
  
'''Cuvinte cheie:''' formă de undă, proiect, modul, instanţiere, testbench
+
'''Cuvinte cheie:''' porți logice, porturi, formă de undă, proiect, modul, instanţiere, testbench
  
'''Sintaxa Verilog:''' ''module'', ''assign'', ''initial'', ''$stop''
+
'''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).
 
  
  
== Exemplul 1==
+
== Exercițiul 1==
  
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.
+
Î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 sunt predefinite în Verilog: '''not''', '''and''', '''nand''', '''or''', '''nor''', '''xor''', '''nxor'''. Sintaxa corectă este, pentru poarta '''and''':
 +
 
 +
<syntaxhighlight lang="verilog">
 +
and nume_poarta (iesire, intrare_1, intrare_2, …. intrare_n);
 +
</syntaxhighlight>
  
Descrierea unui circuit include:
 
* 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.
+
==Exercițiul 2==
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">
+
Creați un fișier Verilog care descrie circuitul de la exercițiul 1.
<font color="red">Regulă:</font> Descrierile circuitelor în Verilog sunt alcătuite din ''module''.  
 
</div>
 
  
Intrările în Verilog se definesc cu cuvântul ''input'', ieşirile sunt ''output''.
+
'''Explicații:'''  
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.
+
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:
  
 
<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 simulatorul ISim.
 +
# Semnalul i0:
 +
[[Fișier:cid_sem1_img2.png|Semnal i0]]
 +
# Două semnale, i0 și i1:
 +
[[Fișier:cid_sem1_img3.png|Semnale i0 și i1]]
 +
# Trei semnale:
 +
[[Fișier:cid_sem1_img4.png|Trei semnale]]
  
Puteți descărca Xilinx ISE 14.7 de pe site-ul departamentului: ftp://zeus.arh.pub.ro/pub/kits/
+
<u>Rezolvare punctul 1:</u>
  
===Simularea funcţionării circuitelor===
+
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]]
  
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|Conceptul de testbench]]
+
==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ă.
  
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.
+
'''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.
  
<syntaxhighlight lang="verilog">
+
==Exercițiul 5==
module test_inc ();  //nu are porturi externe, “()” poate lipsi
 
  reg [3:0] a;  // aici am definit o variabila pe 4 biti
 
  wire [4:0] b; // aici am definit o conexiune, un “fir” pe 5 biti
 
//urmeaza generarea semnalelor care vor fi aplicate pe INTRARI
 
  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
+
Desenaţi schema descrisă de următorul cod Verilog:
  
endmodule
+
<syntaxhighlight lang="verilog">
 +
circuit1 ana (.in1(a), .in2 (b), .out1(int), .out2(en));
 +
circuit2 doru(.in3(int), .in4 (b), .out(c));
 +
circuit3 zuzu(.in0(en), .in1(c), .out(out));
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Exemplul 2==
+
... unde modulele au porturile declarate astfel:
 
 
# Descrieţi în Verilog o poartă ŞI cu trei intrări.  
 
# Testaţi funcţionarea acestei porţi.
 
 
 
[[Fișier:sem1ex2gate.png|Poartă ȘI cu 3 intrări]]
 
  
<u>Explicaţii suplimentare</u>
 
 
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.
 
 
'''Definirea porturilor unui circuit''' se poate face:
 
* în corpul modulului
 
* compactat, în lista porturilor
 
 
Varianta1 (Verilog '95)
 
 
<syntaxhighlight lang="verilog">
 
<syntaxhighlight lang="verilog">
module poarta_AND_3 (a, b, c, out);
+
module circuit1 (
  input a, b, c; // putem pune mai multe pe aceeasi linie, separate cu ,
+
            input [3:0] in1, in2,
  output out;
+
            output [3:0] out1,
.....
+
            output out2);
 +
...
 
endmodule
 
endmodule
</syntaxhighlight>
+
 
+
Varianta 2. (Verilog 2001)
+
<syntaxhighlight lang="verilog">
+
module circuit2 (
module poarta_AND_3 (
+
            input [3:0] in3, in4,
input a,         // scriem cu tab-uri ca sa fie vizibile
+
            output [3:0] out);
input b,
 
input c,  
 
output out);
 
 
...
 
...
 
endmodule
 
endmodule
</syntaxhighlight>
+
 
+
Aici avem mai multe intrări pe 1 bit deci putem scrie şi
+
<syntaxhighlight lang="verilog">
+
module circuit3 (
module poarta_AND_3 (
+
            input [3:0] in1,
input a, b, c,         // scriem cu tab-uri ca sa fie vizibile
+
            input in0,
output out);
+
            output [3:0] out);
 
...
 
...
 
endmodule
 
endmodule
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Vom verifica funcţionarea corectă cu modulul de test.
+
===Porţi logice în Verilog===
 +
În Verilog, porțile logice elementare sunt predefinite ca primitive, există deci cuvinte speciale de limbaj.
  
[[Fișier:sem1ex2codeprint.png|Codul modulului de test|link=]]
+
Pentru funcția ŞI:
 
+
<syntaxhighlight lang="verilog">
Completaţi formele de undă la intrare cu mai multe combinaţii logice. Simulaţi funcţionarea circuitului.
+
and (out, in1, in2,..., ink); // intotdeauna prima e iesirea
 
+
and P1(out, in1, in2); // este bine sa dam si un nume fiecarei porti
==Exemplul 3==
+
</syntaxhighlight>
Folosiţi modulul anterior de test pentru a testa funcţionarea unui circuit care calculează funcţia logică '''out=ac+b'''.
+
 
+
Celelalte porţi logice sunt: ''nand'', ''or'', ''nor'', ''xor'', ''xnor''.
[[Fișier:sem1ex3gate.png|Circuit exercițiul 3]]
+
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.
 
'''Observaţie''': Notaţiile simple folosite pentru funcţii logice în scrierea curentă nu sunt identice cu simbolurile operatorilor din Verilog.
Linia 149: Linia 128:
 
| NOT || ' || ~
 
| NOT || ' || ~
 
|}
 
|}
 
<u>Explicaţii suplimentare</u>
 
 
<div class="regula">
 
<font color="red">Atenție:</font> În explicaţia de mai jos modulul respectiv este denumit circuitlogic şi are porturile a, b, c, out ca în figură. În modulul de test veţi experimenta simultan mai multe conexiuni posibile pentru semnalele de test, instanţiind de  mai multe ori circuitul.
 
</div>
 
 
 
<syntaxhighlight lang="verilog">
 
circuitlogic dut1(i1, i2, i3, out);
 
circuitlogic dut2(i1, i3, i2, out);
 
circuitlogic dut3(.a(i1), .b (i3), .c(i2),. out (out));
 
circuitlogic dut4(.a(i1), .b(i3), .out(out)); //nu am conectat semnal pe c
 
</syntaxhighlight>
 
 
'''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 poarta ŞI cu 3 intrări putem folosi două porţi de acest tip, P1 şi P2, fiecare din ele fiind o poartă SI cu 3 intrări
 
 
<syntaxhighlight lang="verilog">
 
poarta_AND_3 P1(i1, i2, i3, w1); // trebuie neaparat sa precizam numele
 
poarta_AND_3 P2(i4, i5, i6, w2);
 
</syntaxhighlight>
 
 
Porturile se pot conecta ţinând cont de ordinea lor (ca mai sus), sau definind explicit semnalele conectate pe fiecare port:
 
 
<syntaxhighlight lang="verilog">
 
circuitlogic dut3(.a(i1), .b (i3), .c(i2),. out (out));
 
circuitlogic dut4(.a(i1), .b(i3), .out(out)); //nu am conectat semnal pe c
 
</syntaxhighlight>
 
 
Deşi le putem scrie î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 trebuie să fie definit în acelaşi proiect (nu neapărat în acelaşi fişier).
 
 
==Exemplul 4==
 
Descrieţi structural o poartă ŞI cu 3 intrări folosind 2 porţi ŞI cu 2 intrări, în următoarele variante:
 
# descrieţi poarta ŞI cu două intrări
 
# folosiţi primitiva and din Verilog
 
 
[[Fișier:sem1ex4gate.png|frame|none|Varianta 1]] [[Fișier:sem1ex2gate.png|frame|none|Varianta 2]]
 
 
 
<u>Explicaţii suplimentare </u>
 
 
Descrierea unor scheme în Verilog (adică, a structurii unui circuit) se face instanţiind diferitele componente ale schemei şi conectând corespunzător semnalele din circuit pe porturile modulelor.
 
Nu are nicio importanţă ordinea instrucţiunilor de instanţiere, deoarece ele rulează în paralel. Un modul care este apelat (prin instanţiere) trebuie să fie definit în acelaşi proiect.
 
 
===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 (out, in1, in2,..., ink); // intotdeauna prima e iesirea
 
and P1(out, in1, in2); // este bine sa dam si un nume fiecarei porti
 
</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.
 
 
Inversorul este definit cu ''not'' și poate avea mai multe ieșiri:
 
<syntaxhighlight lang="verilog">
 
not P2 (out1, out2, in);
 
</syntaxhighlight>
 
 
==Exemplul 5==
 
Desenaţi schema descrisă de următorul cod Verilog:
 
<syntaxhighlight lang="verilog">
 
diferenta D(.in1(a), .in2 (b), .br (s), .out (dif));
 
complement C(.in(dif), .out(c2dif));
 
mux M(.in0(dif), .in1(cdif), .sel(s), .out(out));
 
</syntaxhighlight>
 
 
... unde modulele au porturile declarate astfel:
 
 
<syntaxhighlight lang="verilog">
 
module diferenta (
 
input [3:0] in1, in2,
 
output [3:0] out,
 
output br);
 
/* acest circuit face diferenta a doua numere in1 si in2, rezultatul este pe 4 biti si un bit de borrow, imprumut, br */
 
...
 
endmodule
 
 
module complement (
 
input [3:0] in,
 
output [3:0] out);
 
/* acest circuit calculeaza complementul fata de 2 pe 4 biti */
 
...
 
endmodule
 
 
module mux (
 
input [3:0] in0, in1,
 
input sel,
 
output [3:0] out);
 
/* acest circuit selecteaza la iesire unul dintre cele doua semnale de pe intrare, i0 sau i1, avand fiecare 4 biti, dupa cum bitul de selectie este 0, respectiv 1
 
iesirea circuitului este deci un semnal pe 4 biti*/
 
...
 
endmodule
 
</syntaxhighlight>
 
  
 
==Temă==
 
==Temă==

Versiunea de la data 23 februarie 2015 10:42

Î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.

Un scurt tutorial pentru folosirea programului Xilinx ISim găsiţi aici.

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.


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 sunt predefinite în Verilog: not, and, nand, or, nor, xor, nxor. Sintaxa corectă este, pentru poarta 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 simulatorul ISim.

  1. Semnalul i0:

Semnal i0

  1. Două semnale, i0 și i1:

Semnale i0 și i1

  1. 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(int), .out2(en));
circuit2 doru(.in3(int), .in4 (b), .out(c));
circuit3 zuzu(.in0(en), .in1(c), .out(out));

... unde modulele au porturile declarate astfel:

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

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 (out, in1, in2,..., ink); // intotdeauna prima e iesirea
and P1(out, in1, in2); // este bine sa dam si un nume fiecarei porti

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 ' ~

Temă

  1. Tema 1
    Descrieţi structural în Verilog circuitul din figură (veţi descrie efectiv schema cu porţi logice). Atenţie! trebuie definite toate interconexiunile ca wire.
  2. Descrieţi comportamental acelaşi circuit (folosind operatori logici şi instrucţiunea assign).
  3. Descrieţi în Verilog modulele componente ale circuitului din exemplul 5 (diferența, complement, mux) astfel încât să realizeze funcţiile precizate şi testaţi distinct fiecare modul în parte. Indicaţie: Modulul pentru multiplexor poate fi descris folosind instrucţiunea de atribuire condiţionată care este explicată în seminarul 2 (dar o puteţi găsi şi aici)
  4. Simulaţi funcţionarea întregului circuit din exemplul 5. Indicaţie: Trebuie să descrieti mai întâi modulul Top, care cuprinde cele trei instanţieri.

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.