VLSI Design - Verilog Wprowadzenie

Verilog to JĘZYK OPISU SPRZĘTU (HDL). Jest to język używany do opisu systemu cyfrowego, takiego jak przełącznik sieciowy, mikroprocesor, pamięć lub przerzutnik. Oznacza to, że używając HDL możemy opisać dowolny sprzęt cyfrowy na dowolnym poziomie. Projekty, które są opisane w HDL są niezależne od technologii, bardzo łatwe do projektowania i debugowania i są zwykle bardziej przydatne niż schematy, szczególnie w przypadku dużych obwodów.

Verilog obsługuje projekty na wielu poziomach abstrakcji. Trzy główne to -

  • Poziom behawioralny
  • Poziom przeniesienia rejestru
  • Poziom bramy

Poziom behawioralny

Ten poziom opisuje system za pomocą współbieżnych algorytmów (behawioralnych). Każdy algorytm jest sekwencyjny, co oznacza, że ​​składa się z zestawu instrukcji, które są wykonywane jedna po drugiej. Funkcje, zadania i bloki to główne elementy. Nie ma znaczenia konstrukcyjna realizacja projektu.

Rejestracja - poziom transferu

Projekty wykorzystujące Register-Transfer Level określają charakterystykę obwodu wykorzystując operacje i przesyłanie danych pomiędzy rejestrami. Współczesna definicja kodu RTL brzmi: „Każdy kod, który można syntetyzować, nazywa się kodem RTL”.

Poziom bramy

Na poziomie logicznym cechy systemu są opisywane przez łącza logiczne i ich właściwości czasowe. Wszystkie sygnały są sygnałami dyskretnymi. Mogą mieć tylko określone wartości logiczne („0”, „1”, „X”, „Z”). Użyteczne operacje to predefiniowane prymitywy logiczne (podstawowe bramki). Modelowanie na poziomie bramki może nie być dobrym pomysłem do projektowania logiki. Kod poziomu bramy jest generowany przy użyciu narzędzi takich jak narzędzia do syntezy, a jego lista sieci jest używana do symulacji poziomu bramy i do zaplecza.

Tokeny leksykalne

Źródłowe pliki tekstowe języka Verilog to strumień tokenów leksykalnych. Żeton składa się z jednego lub więcej znaków, a każdy pojedynczy znak znajduje się dokładnie w jednym żetonie.

Podstawowe tokeny leksykalne używane przez Verilog HDL są podobne do tych w języku programowania C. Verilog rozróżnia wielkość liter. Wszystkie słowa kluczowe są zapisane małymi literami.

Biała przestrzeń

Spacje mogą zawierać znaki spacji, tabulatorów, nowych wierszy i kanałów informacyjnych. Te postacie są ignorowane, z wyjątkiem sytuacji, gdy służą do oddzielnych żetonów.

Białe znaki to spacja, tabulatory, powrót karetki, nowy wiersz i wysuwy stron.

Komentarze

Istnieją dwa formularze do przedstawiania komentarzy

  • 1) Komentarze jednowierszowe zaczynają się od tokena // i kończą znakiem powrotu karetki.

Np .: // to jest składnia jednowierszowa

  • 2) Komentarze wielowierszowe zaczynają się od tokena / * i kończą tokenem * /

Np .: / * to jest składnia wielowierszowa * /

Liczby

Możesz podać liczbę w formacie binarnym, ósemkowym, dziesiętnym lub szesnastkowym. Liczby ujemne są reprezentowane przez liczby komplementów 2. Verilog dopuszcza liczby całkowite, liczby rzeczywiste oraz liczby ze znakiem i bez znaku.

Składnia jest określona przez - <rozmiar> <radix> <wartość>

Rozmiar lub liczbę bez rozmiaru można zdefiniować w <Rozmiar>, a <radix> określa, czy jest to liczba dwójkowa, ósemkowa, szesnastkowa czy dziesiętna.

Identyfikatory

Identyfikator to nazwa używana do zdefiniowania obiektu, takiego jak funkcja, moduł lub rejestr. Identyfikatory powinny zaczynać się od znaków alfabetu lub znaków podkreślenia. Dawny. A_Z, a_z, _

Identyfikatory to kombinacja znaków alfabetycznych, numerycznych, podkreślenia i $. Mogą mieć do 1024 znaków.

Operatorzy

Operatory są znakami specjalnymi używanymi do stawiania warunków lub do obsługi zmiennych. Jest jeden, dwa, a czasem trzy znaki używane do wykonywania operacji na zmiennych.

Dawny. >, +, ~, &! =.

Słowa kluczowe Verilog

Słowa, które mają specjalne znaczenie w Verilog, nazywane są słowami kluczowymi Verilog. Na przykład: assign, case, while, wire, reg, and, or, nand i module. Nie powinny być używane jako identyfikatory. Słowa kluczowe Verilog obejmują również dyrektywy kompilatora oraz zadania i funkcje systemowe.

Modelowanie poziomu bramy

Verilog ma wbudowane prymitywy, takie jak bramki logiczne, bramki transmisyjne i przełączniki. Są one rzadko używane w pracach projektowych, ale są używane w świecie postsyntezy do modelowania komórek ASIC / FPGA.

Modelowanie na poziomie bramy wykazuje dwie właściwości -

Drive strength- Siła bramek wyjściowych jest określana przez siłę napędu. Wyjście jest najsilniejsze, jeśli istnieje bezpośrednie połączenie ze źródłem. Siła maleje, jeśli połączenie jest realizowane przez tranzystor przewodzący, a przynajmniej w przypadku połączenia przez rezystor podwyższający / obniżający. Siła napędu zwykle nie jest określana, w takim przypadku wartości domyślne to strong1 i strong0.

Delays- Jeśli opóźnienia nie są określone, bramki nie mają opóźnień propagacji; jeśli określono dwa opóźnienia, to pierwsza reprezentuje opóźnienie narastania, a druga - opadania; jeśli określono tylko jedno opóźnienie, to zarówno wzrost, jak i spadek są równe. Opóźnienia można zignorować w syntezie.

Brama prymitywów

Podstawowe bramki logiczne wykorzystujące jedno wyjście i wiele wejść są używane w Verilog. GATE używa jednego ze słów kluczowych - and, nand, or, nor, xor, xnor do użycia w Verilog dla N liczby wejść i 1 wyjścia.

Example:  
   Module gate() 
   Wire ot0; 
   Wire ot1; 
   Wire ot2; 
   
   Reg in0,in1,in2,in3; 
   Not U1(ot0,in0); 
   Xor U2(ot1,in1,in2,in3); 
   And U3(ot2, in2,in3,in0)

Prymitywy bramy transmisyjnej

Prymitywy bramek transmisji obejmują zarówno bufory, jak i inwertery. Mają jedno wejście i jedno lub więcej wyjść. W przedstawionej poniżej składni tworzenia instancji bramki GATE oznacza słowo kluczowe buf lub NOT bramka.

Przykład: Not, buf, bufif0, bufif1, notif0, notif1

Nie - nie ma falownika

Buf - n bufor wyjściowy

Bufifo - bufor trójstanowy, aktywny stan niski

Bufif1 - bufor trójstanowy, aktywny stan wysoki

Notifo - falownik trójstanowy, aktywne niskie zezwolenie

Notif1 - falownik trójstanowy, aktywny stan wysoki

Example:  
   Module gate() 
   Wire out0; 
   Wire out1; 
   
   Reg in0,in1;
   Not U1(out0,in0); 
   Buf U2(out0,in0);

Typy danych

Zestaw wartości

Verilog składa się głównie z czterech podstawowych wartości. Wszystkie typy danych Verilog, które są używane w Verilog, przechowują te wartości -

0 (logiczne zero lub warunek fałszywy)

1 (logiczny jeden lub prawdziwy warunek)

x (nieznana wartość logiczna)

z (stan wysokiej impedancji)

użycie x i z jest bardzo ograniczone do syntezy.

Drut

Przewód jest używany do reprezentowania fizycznego przewodu w obwodzie i służy do łączenia bramek lub modułów. Wartość przewodu można tylko odczytać i nie można jej przypisać w funkcji lub bloku. Przewód nie może przechowywać wartości, ale zawsze jest sterowany przez ciągłą instrukcję przypisania lub przez podłączenie przewodu do wyjścia bramki / modułu. Inne określone typy przewodów to -

Wand (wired-AND) - tutaj wartość Wand jest zależna od logicznego AND wszystkich sterowników urządzeń do niego podłączonych.

Wor (wired-OR) - tutaj wartość Wor zależy od logicznego LUB wszystkich sterowników urządzeń do niego podłączonych.

Tri (three-state) - tutaj wszystkie sterowniki podłączone do tri muszą być z, z wyjątkiem tylko jednego (który określa wartość tri).

Example: 
   Wire [msb:lsb] wire_variable_list; 
   Wirec // simple wire 
   Wand d; 
   
   Assign d = a; // value of d is the logical AND of 
   Assign d = b; // a and b 
   Wire [9:0] A; // a cable (vector) of 10 wires. 
   
   Wand [msb:lsb] wand_variable_list; 
   Wor [msb:lsb] wor_variable_list; 
   Tri [msb:lsb] tri_variable_list;

Zarejestrować

Reg (rejestr) to obiekt danych, który przechowuje wartość z jednego przypisania proceduralnego do następnego i jest używany tylko w różnych funkcjach i blokach proceduralnych. Reg jest prostym rejestrem Verilog typu zmiennego i nie może implikować rejestru fizycznego. W rejestrach wielobitowych dane są przechowywane w postaci liczb bez znaku i nie stosuje się rozszerzenia znaku.

Przykład -

reg c; // pojedyncza 1-bitowa zmienna rejestrowa

reg [5: 0] klejnot; // 6-bitowy wektor;

reg [6: 0] d, e; // dwie zmienne 7-bitowe

Wejście, wyjście, wejście

Te słowa kluczowe są używane do deklarowania portów wejściowych, wyjściowych i dwukierunkowych zadania lub modułu. Tutaj porty wejściowe i wejściowe, które są typu przewodowego, a port wyjściowy są skonfigurowane jako typu wire, reg, wand, wor lub tri. Zawsze domyślnie jest to typ przewodu.

Example

Module sample(a, c, b, d);  
Input c;   // An input where wire is used. 

Output a, b;  // Two outputs where wire is used. 
Output [2:0] d;  /* A three-bit output. One must declare type in a separate statement. */ 
reg [1:0] a;  // The above ‘a’ port is for declaration in reg.

Liczba całkowita

Liczby całkowite są używane w zmiennych ogólnego przeznaczenia. Są używane głównie w pętlach - wskaźnikach, stałych i parametrach. Są to dane typu „reg”. Przechowują dane jako podpisane liczby, podczas gdy jawnie zadeklarowane typy reg przechowują je jako dane bez znaku. Jeśli liczba całkowita nie jest zdefiniowana w czasie kompilacji, domyślny rozmiar będzie wynosił 32 bity.

Jeśli liczba całkowita posiada stałą, syntezator dostosowuje je do minimalnej szerokości wymaganej w momencie kompilacji.

Example

Integer c;   // single 32-bit integer 
Assign a = 63;  // 63 defaults to a 7-bit variable.

Dostawa0, Dostawa1

Zasilanie0 definiuje przewody powiązane z logiką 0 (uziemienie), a zasilanie1 określa przewody powiązane z logiką 1 (zasilanie).

Example

supply0 logic_0_wires; 
supply0 gnd1;  // equivalent to a wire assigned as 0 

supply1 logic_1_wires; 
supply1 c, s;

Czas

Czas to 64-bitowa wielkość, której można używać w połączeniu z zadaniem systemowym $ time do przechowywania czasu symulacji. Czas nie jest obsługiwany do syntezy i dlatego jest używany tylko do celów symulacji.

Example

time time_variable_list; 
time c; 
c = $time;   //c = current simulation time

Parametr

Parametr definiuje stałą, którą można ustawić podczas korzystania z modułu, co umożliwia dostosowanie modułu podczas procesu tworzenia instancji.

Example 
Parameter add = 3’b010, sub = 2’b11; 
Parameter n = 3; 
Parameter [2:0] param2 = 3’b110; 

reg [n-1:0] jam; /* A 3-bit register with length of n or above. */ 
always @(z) 
y = {{(add - sub){z}};  

if (z)
begin 
   state = param2[1];
else
   state = param2[2]; 
end

Operatorzy

Operatory arytmetyczne

Te operatory wykonują operacje arytmetyczne. + I −są używane jako operatory jednoargumentowe (x) lub binarne (z − y).

Operatory uwzględnione w operacji arytmetycznej to:

+ (dodawanie), - (odejmowanie), * (mnożenie), / (dzielenie),% (moduł)

Example -

parameter v = 5;
reg[3:0] b, d, h, i, count; 
h = b + d; 
i = d - v; 
cnt = (cnt +1)%16; //Can count 0 thru 15.

Operatorzy relacyjni

Te operatory porównują dwa operandy i zwracają wynik w postaci jednego bitu, 1 lub 0.

Zmienne wire i reg są dodatnie. Zatem (−3'd001) = = 3'd111 i (−3b001)> 3b110.

Operatory uwzględnione w operacji relacyjnej to:

  • == (równe)
  • ! = (różne od)
  • > (większe niż)
  • > = (większe lub równe)
  • <(mniej niż)
  • <= (mniejsze lub równe)

Example

if (z = = y) c = 1; 
   else c = 0; // Compare in 2’s compliment; d>b 
reg [3:0] d,b; 

if (d[3]= = b[3]) d[2:0] > b[2:0]; 
   else b[3]; 
Equivalent Statement 
e = (z == y);

Operatory bitowe

Operatory bitowe, które dokonują porównania bit po bicie między dwoma operandami.

Operatory, które są uwzględnione w operacji bitowej to:

  • & (bitowe AND)
  • | (bitowe LUB)
  • ~ (bitowe NIE)
  • ^ (bitowy XOR)
  • ~ ^ lub ^ ~ (bitowe XNOR)

Example

module and2 (d, b, c); 
input [1:0] d, b; 
output [1:0] c; 
assign c = d & b; 
end module

Operatory logiczne

Operatory logiczne są operatorami bitowymi i są używane tylko dla operandów jednobitowych. Zwracają wartość jednobitową, 0 lub 1. Mogą pracować na liczbach całkowitych lub grupach bitów, wyrażeniach i traktować wszystkie wartości niezerowe jako 1. Operatory logiczne są generalnie używane w instrukcjach warunkowych, ponieważ działają z wyrażeniami.

Operatory uwzględnione w operacji logicznej to -

  • ! (logiczne NIE)
  • && (logiczne AND)
  • || (logiczne LUB)

Example

wire[7:0] a, b, c; // a, b and c are multibit variables. 
reg x; 

if ((a == b) && (c)) x = 1; //x = 1 if a equals b, and c is nonzero. 
   else x = !a; // x =0 if a is anything but zero.

Operatory redukcji

Operatory redukcji są jednoargumentową postacią operatorów bitowych i działają na wszystkich bitach wektora operandu. Te również zwracają wartość jednobitową.

Operatory uwzględnione w operacji redukcji to:

  • & (redukcja AND)
  • | (redukcja LUB)
  • ~ & (redukcja NAND)
  • ~ | (redukcja NOR)
  • ^ (redukcja XOR)
  • ~ ^ lub ^ ~ (redukcja XNOR)

Example

Module chk_zero (x, z); 

Input [2:0] x; 
Output z; 
Assign z = & x; // Reduction AND 
End module

Operatorzy zmianowi

Operatory przesunięcia, które przesuwają pierwszy operand o liczbę bitów określoną przez drugi operand w składni. Wolne pozycje są wypełnione zerami dla obu kierunków, przesunięć w lewo iw prawo (nie ma rozszerzenia znaku użycia).

Operatory uwzględnione w operacji Shift to:

  • << (przesuń w lewo)
  • >> (przesuń w prawo)

Example

Assign z = c << 3; /* z = c shifted left 3 bits;

Wolne pozycje są wypełnione zerami * /

Operator łączenia

Operator konkatenacji łączy dwa lub więcej operandów w celu utworzenia większego wektora.

Operator zawarty w operacji konkatenacji to - {} (konkatenacja)

Example

wire [1:0] a, h; wire [2:0] x; wire [3;0] y, Z; 
assign x = {1’b0, a}; // x[2] = 0, x[1] = a[1], x[0] = a[0] 
assign b = {a, h}; /* b[3] = a[1], b[2] = a[0], b[1] = h[1], 
b[0] = h[0] */ 
assign {cout, b} = x + Z; // Concatenation of a result

Operator replikacji

Operator replikacji tworzy wiele kopii elementu.

Operator używany w operacji replikacji to - {n {element}} (n-krotna replikacja elementu)

Example

Wire [1:0] a, f; wire [4:0] x; 
Assign x = {2{1’f0}, a}; // Equivalent to x = {0,0,a } 
Assign y = {2{a}, 3{f}}; //Equivalent to y = {a,a,f,f} 
For synthesis, Synopsis did not like a zero replication.

For example:- 
Parameter l = 5, k = 5; 
Assign x = {(l-k){a}}

Operator warunkowy

Operator warunkowy syntetyzuje do multipleksera. Jest tego samego rodzaju, co jest używane w C / C ++ i oblicza jedno z dwóch wyrażeń na podstawie warunku.

Operator używany w operacji warunkowej to -

(Stan: schorzenie) ? (Wynik, jeśli warunek jest prawdziwy) -

(wynik, jeśli warunek fałszywy)

Example

Assign x = (g) ? a : b; 
Assign x = (inc = = 2) ? x+1 : x-1; 
/* if (inc), x = x+1, else x = x-1 */

Operandy

Literały

Literały to operandy o stałej wartości, które są używane w wyrażeniach Verilog. Dwa powszechnie używane literały Verilog to -

  • String - Operand literału ciągu to jednowymiarowa tablica znaków ujęta w podwójne cudzysłowy ("").

  • Numeric - Operand stałej liczby jest określony w postaci liczby binarnej, ósemkowej, dziesiętnej lub szesnastkowej.

Example

n - liczba całkowita reprezentująca liczbę bitów

F - jeden z czterech możliwych formatów podstawowych -

b - zapis binarny, o - ósemkowy, d - dziesiętny, h - szesnastkowy.

“time is”  // string literal 
267        // 32-bit decimal number 
2’b01      // 2-bit binary 
20’hB36F   // 20-bit hexadecimal number 
‘062       // 32-bit octal number

Przewody, rejestry i parametry

Przewody, rejestry i parametry to typy danych używane jako operandy w wyrażeniach Verilog.

Wybór bitu „x [2]” i wybór części „x [4: 2]”

Selekcja bitów i selekcja części służą do wybierania odpowiednio jednego bitu i wielu bitów z drutu, wektora reg lub parametru za pomocą nawiasów kwadratowych „[]”. Zaznaczenia bitowe i zaznaczenia części są również używane jako operandy w wyrażeniach w taki sam sposób, jak używane są ich główne obiekty danych.

Example

reg [7:0] x, y; 
reg [3:0] z; 
reg a; 
a = x[7] & y[7];      // bit-selects 
z = x[7:4] + y[3:0];  // part-selects

Połączenia funkcyjne

W wywołaniach funkcji zwracana wartość funkcji jest używana bezpośrednio w wyrażeniu bez konieczności przypisywania jej najpierw do rejestru lub przewodu. Po prostu umieszcza wywołanie funkcji jako jeden z typów operandów. Jest to potrzebne, aby upewnić się, że znasz szerokość bitową wartości zwracanej przez wywołanie funkcji.

Example  
Assign x = y & z & chk_yz(z, y); // chk_yz is a function 

. . ./* Definition of the function */ 
Function chk_yz; // function definition 
Input z,y; 
chk_yz = y^z; 
End function

Moduły

Deklaracja modułu

W Verilog moduł jest główną jednostką projektową. Wskazuje nazwę i listę portów (argumenty). Kolejnych kilka wierszy, które określają typ wejścia / wyjścia (wejście, wyjście lub inout) i szerokość każdego portu. Domyślna szerokość portu to tylko 1 bit. Zmienne portu muszą być zadeklarowane przez wire, wand. . ., rej. Domyślną zmienną portu jest wire. Zwykle wejścia są przewodowe, ponieważ ich dane są zablokowane poza modułem. Wyjścia są typu reg, jeśli ich sygnały są przechowywane w środku.

Example

module sub_add(add, in1, in2, out); 
input add; // defaults to wire 
input [7:0] in1, in2; wire in1, in2; 

output [7:0] out; reg out; 
... statements ... 
End module

Ciągłe przypisanie

Ciągłe przypisanie w module służy do przypisywania wartości do przewodu, co jest normalnym przypisaniem używanym na zewnątrz bloków zawsze lub początkowych. To przypisanie jest wykonywane za pomocą jawnej instrukcji przypisania lub w celu przypisania wartości do przewodu podczas jego deklaracji. Ciągłe przypisanie jest wykonywane w sposób ciągły w czasie symulacji. Kolejność instrukcji przypisania nie ma na to wpływu. Jeśli dokonasz jakiejkolwiek zmiany w dowolnym sygnale wejściowym po prawej stronie, zmieni to sygnał wyjściowy po lewej stronie.

Example

Wire [1:0] x = 2’y01;   // assigned on declaration 
Assign y = c | d;       // using assign statement 
Assign d = a & b; 
/* the order of the assign statements does not matter. */

Instancje modułów

Deklaracje modułów są szablonami do tworzenia rzeczywistych obiektów. Moduły są tworzone wewnątrz innych modułów, a każda instancja tworzy pojedynczy obiekt z tego szablonu. Wyjątkiem jest moduł najwyższego poziomu, który jest własną instancją. Porty modułu muszą być dopasowane do tych, które są zdefiniowane w szablonie. Jest określone -

  • By name, używając kropki „.template port name (nazwa przewodu podłączonego do portu)”. Lub

  • By position, umieszczając porty w tym samym miejscu na listach portów zarówno szablonu, jak i instancji.

Example

MODULE DEFINITION 
Module and4 (x, y, z); 
Input [3:0] x, y; 
Output [3:0] z; 
Assign z = x | y; 
End module