Dwie nazwy, jedno zadanie
Każdy sygnał w Verilogu ma typ. Pierwsze dwa typy, które poznasz, to wire i reg. Oba mogą przechowywać wartość. Oba mogą być jednobitowe albo wielobitowe. Różnica nie dotyczy tego, czym sygnał jest, tylko tego, co nim steruje.
- Sygnały
wiresą sterowane poza blokami proceduralnymi: przez instrukcjeassign, przez wyjścia podmodułów albo przez porty wejściowe modułu. - Sygnały
regsą sterowane wewnątrz bloków proceduralnych:initiallubalways.
To cała reguła. Nazwy słów kluczowych są niezręczne, bo powstały, zanim wykształcił się nowoczesny sposób pisania w Verilogu. reg nie zawsze staje się rejestrem w sprzęcie. Czytaj dalej, żeby dowiedzieć się dlaczego.
Wire: połączenie ciągłe
wire to przewód elektryczny. Nieprzerwanie przenosi to, co wytwarza jego źródło (driver). Przewód może być sterowany na dwa sposoby:
Warto zauważyć trzy rzeczy:
yizsą zadeklarowane jakowirew module i ponownie jakowirew testbenchu.- Steruje nimi
assign, czyli forma przypisania ciągłego. Prawa strona=jest obliczana na nowo, gdy zmieni się którykolwiek sygnał, który się w niej pojawia. - Nie możemy napisać
y = a & bw blokualways, zostawiającyjakowire. Kompilator by to odrzucił.
Jeśli zapomnisz słowa kluczowego wire, Verilog niejawnie zadeklaruje sygnał jako jednobitowy wire. Czasem jest to wygodne, a czasem to cichy błąd. Większość zespołów włącza w narzędziu opcję, która zgłasza błąd przy niejawnych przewodach. Pisz jawnie i omiń tę pułapkę.
Reg: przechowywanie wartości w bloku proceduralnym
reg to sygnał, do którego przypisujesz wartość w initial lub always. Nazwa to relikt wczesnych lat języka, gdy "reg" kojarzyło się z "register". We współczesnym użyciu reg to po prostu typ każdego sygnału, do którego zapisuje kod proceduralny.
count jest typu reg w module (bo zapisuje do niego blok always) i typu wire w testbenchu (bo steruje nim port wyjściowy DUT). Ten sam sygnał, różne role, różne typy w każdym zasięgu.
Dlaczego "reg" nie zawsze oznacza "rejestr"
Oto najczęstsza pułapka początkujących. Ten moduł deklaruje y jako reg, ale zsyntezowany sprzęt nie zawiera przerzutnika:
Blok always @(*) reaguje na każdą zmianę wejścia. Jest kombinacyjny. Narzędzie do syntezy rozpoznaje ten wzorzec i tworzy bramkę AND: bez przerzutnika, bez zegara, sama logika. Słowo kluczowe reg jest tu wyłącznie wymogiem składni, bo y jest przypisywane w bloku always.
Żeby dostać prawdziwy przerzutnik, blok always musi reagować na zbocze zegara:
always @(posedge clk) begin
q <= d;
end
To wzorzec "narzędzie do syntezy, zrób mi przerzutnik": lista czułości z zegarem i przypisanie nieblokujące. To samo słowo kluczowe reg, zupełnie inny sprzęt. To rozróżnienie omawiamy w częściach Blok always oraz Przypisania blokujące i nieblokujące.
Decyzja w praktyce
Za każdym razem, gdy deklarujesz sygnał, zapytaj: jak będę nim sterować?
- Sterowanie przez
assign? →wire. - Podłączenie do portu wyjściowego podmodułu? →
wire. - Port wejściowy modułu? →
wire. (Wejścia są zawsze typu wire.) - Sterowanie z
initiallubalways? →reg. - Port wyjściowy modułu sterowany kodem proceduralnym? →
output reg. - Port wyjściowy modułu sterowany przez
assign? →output wire. (Albo po prostuoutput, bo sam kierunek domyślnie oznacza wire.)
To drzewo decyzyjne obejmuje każdą sytuację, jaką napotkasz w zwykłym Verilogu.
Konflikty sterowania
Sygnały wire mogą teoretycznie mieć wiele źródeł. Tak działają magistrale trójstanowe, w których kilka modułów może sterować tym samym przewodem, a nieaktywne przechodzą w stan wysokiej impedancji (z). W zwykłej logice dwie instrukcje assign zapisujące ten sam przewód dają niezdefiniowane zachowanie:
assign y = a;
assign y = b; // BAD - y has two drivers
Symulator może wybrać jedno z nich albo ustawić sygnał na X, zależnie od narzędzia. Tak czy inaczej to błąd. Jedno źródło na przewód, chyba że świadomie budujesz magistralę.
Sygnały reg mogą być sterowane tylko z jednego bloku proceduralnego. Dwa bloki always przypisujące ten sam reg to błąd syntezy i dziwne zachowanie w symulacji. Ta sama zasada: jedno źródło.
Nowość z SystemVeriloga: logic
SystemVerilog (nadzbiór, w który rozwinął się Verilog) dodaje jedno słowo kluczowe, które zastępuje oba: logic. Sygnałem logic może sterować assign albo blok proceduralny, ale nie oba naraz, a kompilator nie pozwoli ci przypadkiem stworzyć błędu z wieloma źródłami.
module modern(input logic a, input logic b, output logic y);
assign y = a ^ b;
endmodule
Jeśli zaczynasz projekt od zera, a twoje narzędzie obsługuje SystemVerilog (edytor na tej stronie obsługuje, z -g2012), używanie wszędzie logic upraszcza reguły. Zwykłe pliki .v wciąż wymagają podziału na wire/reg, a w prawdziwym kodzie zawsze będziesz spotykać oba style.
Co dalej
Następna strona, Wektory i tablice, bierze te same dwa typy i pokazuje, jak zrobić z nich sygnały wielobitowe. Szerokości magistral, zakresy, wymiary packed, różnica między wektorem bitów a tablicą wektorów. Wszystko, czego potrzebujesz, zanim zbudujesz coś większego niż jednobitowy sumator.
Najczęściej zadawane pytania
Jaka jest różnica między wire a reg w Verilogu?
Zarówno wire, jak i reg przechowują wartość sygnału w każdej chwili symulacji, ale wybierasz między nimi na podstawie tego, co steruje sygnałem. wire jest sterowany spoza bloku proceduralnego: przez assign albo wyjście podmodułu. reg jest sterowany z wnętrza bloku initial lub always. Nazwy są historyczne i mylące: reg nie zawsze oznacza 'rejestr'.
Czy reg w Verilogu oznacza przerzutnik?
Niekoniecznie. reg syntezuje się do przerzutnika tylko wtedy, gdy jego blok always reaguje na zbocze zegara i używa przypisania nieblokującego. reg przypisywany w kombinacyjnym bloku always @(*) syntezuje się do zwykłej logiki kombinacyjnej. Słowo kluczowe wybiera typ danych Veriloga, a nie sprzęt.
Kiedy używać wire, a kiedy reg?
Prosta reguła: jeśli sygnałem będzie sterować assign albo podłączysz go do portu wyjściowego podmodułu, użyj wire. Jeśli będziesz go przypisywać w bloku always lub initial, użyj reg. Wejścia modułu są zawsze typu wire. Wyjścia są wire, gdy steruje nimi assign, i reg, gdy steruje nimi blok proceduralny.
Czy można przypisać wartość do wire w bloku always?
Nie, to błąd składni. Sygnałami wire mogą sterować tylko przypisania ciągłe (assign) albo podłączenie jako wyjście instancji podmodułu. Wszystko w initial lub always musi mieć za cel reg (albo w SystemVerilogu logic). Kompilator to wychwyci i zgłosi 'left-hand side type mismatch'.
Czym jest logic w SystemVerilogu?
logic to połączenie wire i reg w SystemVerilogu. Może nim sterować przypisanie ciągłe albo blok proceduralny (ale nie oba jednocześnie). Nowoczesny kod coraz częściej używa logic wszędzie i zapomina o rozróżnieniu wire/reg. W zwykłych plikach Verilog wciąż trzeba wybierać.