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

Czytałem tę stronę http://www.asic-world.com/verilog/verilog_one_day3.html , gdy natknąłem się na:

Zwykle musimy resetować przerzutniki, więc za każdym razem, gdy zegar przejście z 0 na 1 (posedge), sprawdzamy czy jest załączony reset (reset synchroniczny), następnie przechodzimy do normalnej logiki. Jeśli przyjrzymy się uważnie, zobaczymy, że w przypadku logiki kombinacyjnej mieliśmy przypisanie „=”, a dla bloku sekwencyjnego mieliśmy operator „< =”. Cóż, „=” blokuje przypisanie, a „< =” to nieblokujące przypisanie. „=” wykonuje kod sekwencyjnie wewnątrz początku / końca, podczas gdy nieblokujący „< =” jest wykonywany równolegle.

Byłem dość pewien, że nieblokujące przypisania są sekwencyjne, podczas gdy blokujące są równoległe. W końcu możesz tworzyć przypisania blokujące za pomocą instrukcji assign poza blokami always, a wszystkie one działają równolegle. Czy to pomyłka, czy też zachowanie wewnątrz bloku zawsze jest inne? A jeśli zachowanie JEST inne wewnątrz bloku always, czy nieblokujące przypisania mogą być wykonywane poza blokiem always?

Odpowiedź

był dość pewien, że nieblokujące przypisania są sekwencyjne, podczas gdy blokujące są równoległe.

Przypisanie blokujące jest wykonywane „w serii”, ponieważ przypisanie blokujące blokuje wykonanie następnej instrukcji aż do zakończenia. Dlatego wynik następnej instrukcji może zależeć od ukończenia pierwszej.

Nieblokujące przypisanie jest wykonywane równolegle, ponieważ opisuje przypisania, które występują w tym samym czasie. Wynik instrukcji w drugiej linii nie będzie zależał od wyników instrukcji w pierwszej linii. Zamiast tego druga linia zostanie wykonana tak, jakby pierwsza linia jeszcze się nie wydarzyła.

Komentarze

  • A co z instrukcjami assign? Czy są one tylko całą własną klasą?
  • Tak, assign instrukcje występują poza blokami zawsze i są zwykle używane do opisywania jako kombinatoryczne (niezatwierdzone ) logika (chociaż zawsze bloki, z pewnymi wyjątkami, opisują logikę sekwencyjną). AFAIK, assign instrukcje zawsze wykonują ” równolegle ” za każdym razem, gdy ich LHS ma zmianę wartości .
  • OK … Zaczynam od ' odnieść wrażenie, że Verilog nie jest ' najbardziej elegancko zaprojektowany język. Będzie to wyglądało tak, jak nauka C.
  • Verilog został zaprojektowany, aby ” opisywać ” sprzęt, który już istnieje. Używanie go jako języka do projektowania (syntetyzowania) sprzętu to hack.
  • if Verilog ” jak nauka C ” jest problem, spójrz na VHDL. Niektórzy ludzie mają dość silne preferencje co do jednego lub drugiego. Dla niektórych VHDL jest po prostu zbyt rozwlekły. Dla mnie to ' jest znacznie lepiej przemyślane. (semantyka przypisania sygnału / zmiennej jest znacznie jaśniejsza niż na przykład blokowanie / brak). stackoverflow.com/questions/13954193/… i sigasi .com / content / vhdls-crown-jewel Możesz go preferować lub nienawidzić. Jednak ' warto się przyjrzeć.

Odpowiedź

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

Przypisanie blokujące ma wpływ natychmiast po przetworzeniu. Nieblokujące przypisanie ma miejsce na końcu przetwarzania bieżącej „delty czasu”.

zawsze bloki mogą być używane do modelowania logiki kombinatorycznej lub sekwencyjnej (systemverilog ma always_comb i always_ff, aby uczynić to jawnym). 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 przypisań nieblokujących. Pozwala to na określają „stan za zboczem zegara” w kategoriach „stan przed zboczem zegara”.

Czasami przydatne jest użycie blokujących przypisań w sekwencyjnych zawsze blokach jako „zmienne”. Jeśli to zrobisz, wtedy należy pamiętać o dwóch kluczowych zasadach.

  1. Nie uzyskuj dostępu do pliku reg, który jest ustawiony z blokującymi przypisaniami wewnątrz sekwencyjnego, zawsze blokuje spoza zawsze bloku, w którym jest przypisany.
  2. Nie mieszaj blokujących i nieblokujących przypisań do tego samego rejestru.

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

Komentarze

  • ” ” Nie uzyskuj dostępu do rejestru, który jest ustawiony z blokowaniem przypisań wewnątrz sekwencji sekwencyjnej, zawsze blokuj z zewnątrz, zawsze blokuj go jest przypisany w. ” ” Czy możesz to wyjaśnić?
  • Różne kolejne bloki zawsze nie mają zdefiniowanego zamówienie. Tak więc czytanie ” reg ” zestawu z blokowaniem w jednym bloku zawsze blokowym z drugiego zawsze prowadzi do nieprzewidywalnego zachowania.
  • Nawet jeśli wydaje się, że działa w symulacji, narzędzie syntezy powinno się temu przyjrzeć i powiedzieć ” nope „. Używam lokalnych rejestrów dla tych zmiennych pośrednich i upewniam się, że są one zawsze przypisane do każdego zegara przed odczytem, aby nie było ' magazynu ' jest implikowane.
  • IIRC przynajmniej w quartus jest uważane tylko za ostrzeżenie, a nie za błąd.
  • Nie powinieneś używać przypisania nieblokującego w logice kombinacyjnej, może się zablokować symulacja. Aby uzyskać więcej informacji, zapoznaj się z tą odpowiedzią: electronics.stackexchange.com/a/506047/238188

Odpowiedź

Termin blokowanie przypisania dezorientuje ludzi, ponieważ słowo blokowanie wydaje się sugerować logikę sekwencyjną. Ale w logice syntetyzowanej nie oznacza to , ponieważ wszystko działa w równoległe .

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

Z legalistycznego punktu widzenia wszystko to działa bardzo dobrze. W rzeczywistości możesz uznać operację = za operację blokującą (sekwencyjną), nawet w ramach always_comb sekwencje. Jednak rozróżnienie między sekwencją czasową a równoległą nie ma absolutnie żadnego znaczenia w tym przypadku, ponieważ always_comb blok jest zdefiniowany tak, aby powtarzał się, dopóki sekwencja instrukcji nie osiągnie stanu stabilnego – co jest dokładnie tym, co zrobi obwód sprzętowy (jeśli spełnia wymagania czasowe).

Syntezowalny podzbiór Verilog (a zwłaszcza SystemVerilog) jest niezwykle prosty i łatwy w użyciu – jeśli znasz już niezbędne idiomy. Wystarczy ominąć sprytne stosowanie terminologii związanej z tak zwanymi elementami behawioralnymi w języku.

Komentarze

  • W behawioralnych stylach kodowania ( w porównaniu z 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 komponentów behawioralnych.
  • Oczywiście proceduralny tryb SystemVerilog, stosowany zwłaszcza do instrukcji initial w blokach program, używa (sekwencyjnie w czasie) przypisania blokującego wyłącznie. Jest to przydatne przy projektowaniu testbench , ale generalnie nie w przypadku specyfikacji RTL.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *