Różnica między przypisaniem blokującym a nieblokującym Verilog

15

Czytałem tę stronę http://www.asic-world.com/verilog/verilog_one_day3.html, kiedy natrafiłem na następujące:

Zwykle musimy resetować przerzutniki, więc za każdym razem, gdy zegar dokonuje przejścia z 0 do 1 (pozowanie), sprawdzamy, czy reset jest potwierdzony (reset synchroniczny), a następnie kontynuujemy normalną logikę. Jeśli przyjrzymy się bliżej, zobaczymy, że w przypadku logiki kombinacyjnej mieliśmy „=” do przypisania, a dla bloku sekwencyjnego mieliśmy operatora „<=”. Cóż, „=” blokuje przypisanie, a „<=” to przypisanie nieblokujące. „=” wykonuje kod sekwencyjnie wewnątrz początku / końca, podczas gdy nieblokujące „<=” wykonuje się równolegle.

Byłem całkiem pewien, że nieblokujące przypisania były sekwencyjne, podczas gdy blokujące przypisania były równoległe. W końcu możesz wykonywać przypisania blokujące za pomocą instrukcji przypisania poza zawsze blokami, a wszystkie działają równolegle. Czy to pomyłka, czy może zachowanie jest inne w bloku zawsze? A jeśli zachowanie JEST inne w obrębie zawsze bloku, czy można przypisać funkcje nieblokujące poza blokiem zawsze?

Gwiazda Pustki
źródło

Odpowiedzi:

21

był całkiem pewien, że nieblokujące przypisania były sekwencyjne, podczas gdy przypisania blokujące były równoległe.

Blokowanie przypisania jest wykonywane „szeregowo”, ponieważ przypisanie blokujące blokuje wykonanie następnej instrukcji, dopóki się nie zakończy. Dlatego wyniki następnego polecenia mogą zależeć od ukończenia pierwszego.

Przydział nieblokujący jest wykonywany równolegle, ponieważ opisuje przypisania, które wszystkie występują jednocześnie. Wynik instrukcji w 2. linii nie będzie zależeć od wyników instrukcji w 1. linii. Zamiast tego druga linia zostanie wykonana tak, jakby pierwsza linia jeszcze się nie wydarzyła.

The Photon
źródło
A co z przypisaniami? Czy są po prostu własną klasą?
Void Star
4
Tak, assigninstrukcje występują poza blokami zawsze i są zwykle używane do opisania logiki kombinatorycznej (bez zatrzaśnięcia) (podczas gdy zawsze bloki, z pewnymi wyjątkami, opisują logikę sekwencyjną). AFAIK, assigninstrukcje zawsze wykonują się „równolegle”, ilekroć ich LHS zmienia wartość.
Photon
Okej ... Zaczynam mieć wrażenie, że Verilog po prostu nie jest najbardziej elegancko zaprojektowanym językiem. To będzie jak nauka C.
Void Star
1
Verilog został zaprojektowany do „opisywania” sprzętu, który już istnieje. Używanie go jako języka do projektowania (syntezy) sprzętu to hack.
Photon
4
jeśli Verilog „jak nauka C” stanowi problem, spójrz na VHDL. Niektóre osoby mają dość silne preferencje dla jednego lub drugiego. Dla niektórych VHDL jest po prostu zbyt gadatliwy. Dla mnie lepiej to przemyśleć. (semantyka przypisywania sygnałów / zmiennych jest znacznie wyraźniejsza niż na przykład blokowanie / brak). stackoverflow.com/questions/13954193/... i sigasi.com/content/vhdls-crown-jewel Możesz to lubić . Ale warto to zobaczyć.
Brian Drummond
6

Instrukcje przypisania nie są ani „blokujące”, ani „nieblokujące”, są „ciągłe”. Wyjście instrukcji przypisania jest zawsze równe określonej funkcji jej danych wejściowych. Przypisania „blokujące” i „nieblokujące” istnieją tylko w obrębie zawsze bloków.

Przypisanie blokujące ma wpływ natychmiast po przetworzeniu. Przydział nieblokujący ma miejsce pod koniec przetwarzania bieżącej „delty czasowej”.

zawsze bloki mogą być użyte do modelowania logiki kombinatorycznej lub sekwencyjnej (systemverilog ma always_comb i always_ff, aby to wyjaśnić). Podczas modelowania logiki kombinatorycznej zwykle bardziej efektywne jest użycie =, ale zazwyczaj nie ma to większego znaczenia.

Podczas modelowania logiki sekwencyjnej (np. Zawsze @ (posedge clk)) zwykle używasz zadań nieblokujących. Pozwala to zniechęcić „stan po zboczu zegara” pod względem „stanu przed zboczem zegara”.

Czasami przydaje się stosowanie przypisań blokujących w sekwencyjnych blokach zawsze jako „zmiennych”. Jeśli to zrobisz, musisz pamiętać o dwóch kluczowych zasadach.

  1. Nie uzyskuj dostępu do regu, który jest ustawiony z blokowaniem przypisań wewnątrz sekwencyjnego bloku zawsze z zewnątrz bloku zawsze, w którym jest przypisany.
  2. Nie mieszaj zadań blokujących i nieblokujących z tym samym reg.

Złamanie tych reguł może spowodować błędy syntezy i / lub różnice w zachowaniu między symulacją a syntezą.

Peter Green
źródło
„” Nie uzyskuj dostępu do regu, który jest ustawiony z blokowaniem przypisań wewnątrz sekwencyjnego bloku zawsze z zewnątrz bloku zawsze, w którym jest przypisany. ”„ Czy możesz to wyjaśnić?
user125575,
Różne sekwencyjne bloki zawsze nie mają określonej kolejności. Tak więc czytanie zestawu „reg” z przypisaniem blokującym w jednym bloku zawsze w drugim bloku zawsze prowadzi do nieprzewidzianego zachowania.
Peter Green,
I nawet jeśli wydaje się, że działa w symulacji, narzędzie do syntezy powinno na to spojrzeć i powiedzieć „nie”. Używam lokalnych rejestrów dla tych pośrednich zmiennych i upewniam się, że są one zawsze przypisywane na każdym zegarze przed odczytaniem, aby nie sugerować „przechowywania”.
greggo
IIRC przynajmniej w kwartarze jest uważane tylko za ostrzeżenie, a nie za błąd.
Peter Green
5

Termin Blokowanie przypisanie dezorientuje ludzi, ponieważ słowo blokowanie wydaje się sugerować logikę czasową sekwencyjny. Ale w zsyntetyzowanej logice nie oznacza to , ponieważ wszystko działa równolegle .

Być może mniej mylącym terminem byłoby natychmiastowe przypisanie , które nadal różnicowałoby pośrednie wyniki logiki kombinacyjnej od danych wejściowych do nieprzezroczystych elementów pamięci (na przykład rejestrów taktowanych), które mogą mieć opóźnione przypisanie .

Z legalistycznego punktu widzenia wszystko działa bardzo ładnie. Można w rzeczywistości, należy rozważyć =być blokowanie (czas sekwencyjny) działanie nawet w obrębie always_combsekwencji. Jednak rozróżnienie między sekwencją czasową i równoległą nie ma w tym przypadku absolutnie żadnej różnicy, ponieważ always_combblok jest zdefiniowany tak, aby powtarzał się, dopóki sekwencja instrukcji nie zbiegnie do stanu stabilnego - dokładnie to zrobi obwód sprzętowy (jeśli spełni czas wymagania).

Syntetyczny podzbiór Verilog (a zwłaszcza SystemVerilog) jest niezwykle prosty i łatwy w użyciu - gdy poznasz niezbędne idiomy. Musisz tylko porzucić sprytne użycie terminologii związanej z tak zwanymi elementami behawioralnymi w języku.

nobar
źródło
W stylach kodowania behawioralnego ( w porównaniu do RTL ) istotne może być rozróżnienie między blokowaniem a nieblokowaniem. W niektórych przypadkach narzędzie do syntezy może być w stanie wywnioskować funkcjonalnie równoważny RTL z projektów elementów behawioralnych.
nobar
Oczywiście tryb proceduralny SystemVerilog, mający zastosowanie zwłaszcza do initialinstrukcji w programblokach, wykorzystuje wyłącznie (sekwencyjne w czasie) przypisanie blokujące . Jest to przydatne do projektowania testbench , ale ogólnie nie do specyfikacji RTL.
nobar