Diferență între revizuiri ale paginii „SystemVerilog”

De la WikiLabs
Jump to navigationJump to search
(Ștergerea conținutului paginii)
Linia 1: Linia 1:
== Module ==
 
  
Limabjul Verilog este structurat pe module. Fiecare modul reprezintă un circuit care implementează o anume funcție. Spre exemplu un modul poate reprezenta un sumator, adică un circuit care are două intrări ce specifică cei doi operanzi și o ieșire ce reprezintă rezultatul adunării. Conținutul modulului reprezintă descrierea (structurală sau comportamentală) a porților care calculeaza suma celor două intrări. Prin urmare, definiția unui modul Verilog are două părți:
 
* interfață - lista tuturor porturilor de intrare și ieșire ale circuitului, specificate prin nume și dimensiune;
 
* implementare - descrierea efectivă a circuitului care se folosește de valorile de intrare pentru a calcula valorile de ieșire;
 
 
=== Interfața modulelor Verilog ===
 
Interfața modulului '''Adder''' este prezentată mai jos. '''''Observație:''''' Ca și în sistemul numeral zecimal, unde suma a două numere de '''n''' cifre are nevoie de '''n + 1''' cifre (9 + 9 = 18), și în sistemul binar, suma a două numere de '''n''' biți va fi pe '''n + 1''' biți.
 
[[Fișier:Adder_interface.svg|thumb|Reprezentarea interfetei modulului "Adder" (black box)]]
 
<syntaxhighlight lang="verilog">
 
module Adder(
 
    output [4:0] out,
 
    input  [3:0] in0,
 
    input  [3:0] in1
 
);
 
 
//implementare
 
 
endmodule
 
</syntaxhighlight>
 
Cuvintele cheie '''''module''''' și '''''endmodule''''' sunt folosite pentru a începe și a încheia definirea unui modul. Imediat după cuvântul cheie '''''module''''' urmează numele modulului.
 
 
<div class="conventie">
 
<font color="#0000AA">'''''Convenție:'''''</font> Numele unui modul va începe cu literă mare.
 
</div>
 
 
După definirea numelui modulului, urmează lista de porturi, plasată între '''paranteze rotunde''' și separate prin '''virgulă'''. Cuvintele cheie acceptate sunt '''''output''''' (reprezentând un port de ieșire), '''''input''''' (reprezentând un port de intrare) și '''''inout''''' (reprezentând un port bidirecțional).
 
 
<div class="sfat">
 
<font color="#00AA00">'''''Sfat:'''''</font> Când aveți de ales în privința interfeței unui modul, se evită utilizarea semnalelor de tip '''''inout'''''. Acestea introduc elemente de tip [http://en.wikipedia.org/wiki/Tri-state_buffer#Tri-state_Buffer Tri-state Buffer] care sunt ineficiente. O alternativă mai eficientă este definirea a două porturi, unul de intrare și unul de ieșire, cu nume similare (ex: ''data_in'' și ''data_out'').
 
</div>
 
 
<div class="conventie">
 
<font color="#0000AA">'''''Convenție:'''''</font> Întâi se definesc ieșirile, apoi intrările unui modul.
 
</div>
 
 
<div class="conventie">
 
<font color="#0000AA">'''''Convenție:'''''</font> Porturile unui modul se scriu unul sub altul, pe câte o linie, aliniate cu un tab la dreapta față de cuvântul cheie '''''module'''''.
 
</div>
 
 
După tipul portului, urmează dimensiunea acestuia, specificată în indecșii biților, unde cel mai puțin semnificativ bit are indexul 0. Spre exemplu, un semnal de 4 biți va avea următoarea specificație '''[3:0]''' (bitul cel mai semnificativ are indexul 3, cel mai puțin semnificativ 0, în total 4 biți). '''''Observație:''''' Semnalelor de un bit le lipsește specificația de dimensiune:
 
 
<syntaxhighlight lang="verilog">
 
input oneBitSignal,
 
</syntaxhighlight>
 
 
După lista de porturi aflată între paranteze, definirea interfeței se termină cu caracterul ''';'''.
 
 
<!--
 
#'''''Observație:''''' Există module nesintetizabile (care nu au corespondent in porți logice), care sunt folosite ca "programe" de test în medii de simulare și se numesc module de test. Aceste module nu au porturi de intrare și ieșire și sunt utilizate doar pentru a da valori porturilor de intrare ale modulului care se testează, și de a verifica valorile de pe porturile de ieșire ale acestuia. În cazul acestor module, lista de porturi și parantezele rotunde aferente lipsesc:
 
<syntaxhighlight lang="verilog">
 
module TestModule;
 
 
//implementare
 
 
endmodule
 
</syntaxhighlight>
 
-->
 
=== Implementarea modulelor Verilog ===
 
 
Implementarea modulelor Verilog se face prin blocuri. Aceste blocuri pot avea sau nu corespondent într-un ciruit fizic. Dacă toate blocurile unui modul au corespondent într-un circuit fizic, atunci modulul este sintetizabil și poate fi transformat într-un circuit fizic. Blocurile care pot genera construcții sintetizabile sunt de patru tipuri:
 
* blocuri '''assign'''
 
* blocuri '''always'''
 
* blocuri '''generate'''
 
* blocuri de instanțiere
 
 
În plus, în Verilog se pot defini fire ('''wire''') și registre ('''reg''').
 
 
Blocurile care sunt întotdeauna nesintetizabile și sunt folosite exclusiv pentru simulare:
 
* blocuri '''initial'''
 
* blocuri '''forever'''
 
 
'''''Observație:''''' Nu orice bloc '''assign''' sau '''always''' este sintetizabil. Există construcții valide sintactic dar care nu au corespondent în circuit. Aceste blocuri pot fi simulate dar nu pot fi utilizate pentru programarea unei plăci [[FPGA]].
 
 
'''''Observație:''''' Ordinea blocurilor într-un modul nu contează.
 
 
==== Fire (wire) și registre (reg) ====
 
 
Firele sunt utilizate pentru legături între module și pentru asignarea de rezultate parțiale în circuite combinaționale, prin urmare:
 
 
<div class="regula">
 
<font color="red">Regulă:</font> Un element de tip '''wire''' își schimbă valoarea doar în blocuri de tip '''assign''' ''sau'' ca ieșire a unui modul (niciodată ambele simultan).
 
</div>
 
 
Firele într-un modul Verilog se definesc în felul următor:
 
<syntaxhighlight lang="Verilog">
 
 
wire [3:0] fir;
 
 
</syntaxhighlight>
 
 
Registrele sunt utilizate uzual pentru implementarea ciruitelor secvențiale, și atunci ele definesc registre fizice, dar:
 
 
Observație: Un element de tip '''reg''' nu se translatează neapărat într-un registru fizic. Translatarea lui depinde de modul în care se utilizează.
 
 
Un registru se definește în felul următor:
 
<syntaxhighlight lang="Verilog">
 
 
reg [3:0] registru;
 
 
</syntaxhighlight>
 
 
<div class="regula">
 
<font color="red">Regulă:</font> Un element de tip '''reg''' își schimbă valoarea doar în blocuri de tip '''always''' sau '''initial'''.
 
</div>
 
 
<div class="regula">
 
<font color="red">Regulă:</font> Niciun element nu își poate schimba valoarea în mai mult de un bloc. Adică pentru un fir ('''wire'''), nu pot exista două blocuri '''assign''' în care acesta ia valori, iar pentru elemente '''reg''', nu există decât un bloc '''always''' sau '''initial''' în care acesta își schimbă valoarea.
 
</div>
 
 
'''''Observație:''''' O ieșire a unui modul poate fi de tip '''wire''' sau '''reg'''. Dacă nu se specifică, ea este implict de tip '''wire'''.
 
 
==== Blocuri '''assign''' ====
 
 
'''Assign''' este un cuvănt cheie care generează [[circuite combinaționale]]. Cum sumatorul este un [[circuite combinaționale|circuit combinațional]], și ieșirea acestuia este implicit de tip wire, îl putem implementa cu un bloc '''assign''':
 
<syntaxhighlight lang="Verilog">
 
module Adder(
 
    output [4:0] out,
 
    input [3:0] in0,
 
    input [3:0] in1
 
);
 
 
assign out = in0 + in1;
 
 
endmodule
 
</syntaxhighlight>
 
 
'''''Observație:''''' În general, un bloc '''assign''' va genera un circuit sintetizabil. Există și excepții, atunci când operația dorită este prea complexă pentru a fi implementată printr-un circuit combinațional, în mod eficient. Spre exemplu:
 
 
<syntaxhighlight lang="Verilog">
 
assign out = in0 / in1;
 
</syntaxhighlight>
 
 
nu este un cod sintetizabil pentru majoritatea tool-urilor de sinteză, dar funcționează perfect într-o simulare.
 
 
==== Blocuri '''always''' ====
 

Versiunea de la data 30 ianuarie 2012 10:49