CID Seminar 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.
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.
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.
- Semnalul i0:
- Două semnale, i0 și i1:
- Trei semnale:
Rezolvare punctul 1:
Se va scrie un fișier sursă nou, care nu are porturi exterioare (deoarece nu descrie un circuit).
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
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 verde şi sunt ignorate la compilare.
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)
Acesta circuit este un modul distinct, special pentru testare, numit de obicei modul de test. Modulul de test nu are conexiuni externe, dar apelează la 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 (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 | ' | ~ |
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.