Dlaczego wywnioskowane zatrzaski są złe?

22

Mój kompilator narzeka na wywnioskowane zatrzaski w moich pętlach kombinatorycznych ( always @(*)w Verilog). Powiedziano mi również, że najlepiej unikać wywnioskowanych zatrzasków.

Co dokładnie jest nie tak z wnioskowanymi zatrzaskami? Z pewnością ułatwiają pisanie pętli kombinatorycznych.

Randomblue
źródło
Dobrze byłoby dołączyć przykład HDL tego, co robisz
shuckc
Zauważyłem, że to pytanie było ostatnio cytowane kilka razy. Dla każdego, kto nie jest ekspertem przychodzącym w ten sposób, zauważ, że wszystkie odpowiedzi oprócz Oli Glasera są kombinacją niepoprawnych i / lub nieprzydatnych.
EML
Nie mniej należy unikać wywnioskowanych zatrzasków, a bardziej unikać przezroczystych zatrzasków, chyba że dokładnie wiesz, co robisz (zwróć uwagę, że kwartus nieco wprowadza w błąd „zatrzaśnięty” w niektórych sytuacjach, które nie obejmują zatrzasków przezroczystych i są całkowicie bezpieczne).
Peter Green,

Odpowiedzi:

20

„Zatrzask” różni się od „Flip-Flop” tym, że FF zmienia swoją moc wyjściową tylko w odpowiedzi na zbocze zegara. Zatrzask może zmienić swoją moc wyjściową w reakcji na coś innego niż zegar. Na przykład SR-Latch ma zestaw i wejście resetowania, a jeśli jedno z nich jest aktywne, wyjście może się zmienić. Gdzie jako SR-FF reaguje na zestaw lub resetuje tylko wtedy, gdy występuje również zbocze zegara.

W FPGA chcesz, aby logika była w pełni synchroniczna. Oznacza to, że wszystkie elementy pamięci (takie jak FF) są taktowane z jednego źródła zegara. Wszystko, co jest asynchroniczne z tym zegarem, musi być traktowane bardzo ostrożnie, w przeciwnym razie wystąpią błędy synchronizacji.

Zatrzask jest w zasadzie asynchronicznym elementem pamięci. Nie ma wejścia zegara, dlatego nie można go zsynchronizować z żadnym zegarem. Powinienem zauważyć, że istnieją FF z asynchronicznym resetowaniem i resetowaniem danych wejściowych, które należy traktować z taką samą ostrożnością jak normalne zatrzaski.

Omówienie wszystkich problemów z synchronizacją, które mogą powodować zatrzaski, wykracza daleko poza to, co można tutaj omówić, ale dam wam jeden przykład:

Powiedzmy, że masz zatrzask SR i chcesz, aby był ustawiany za każdym razem, gdy 8-bitowy licznik osiągnie określoną wartość. Nie jestem pewien, jaki byłby kod Verilog, ale w VHDL kod to: ustaw <= '1', gdy count = "11010010" else '0'; Ten ustawiony sygnał trafia do ustawionego wejścia w naszej zatrzasku SR.

Generowana logika jest czysto kombinatoryczna; mieszanka bramek, bramek i falowników (lub LUT). Ale ścieżki sygnału przez tę kombinatoryczną logikę nie zawsze są idealne i „ustalony” sygnał może mieć na nim usterki. Ścieżka sygnału przez określoną grupę bramek może potrwać dłużej niż inna grupa, powodując, że ustawione wyjście uaktywni się na chwilę, zanim wyjście ustabilizuje się do stanu końcowego.

Ta usterka wyjściowa może spowodować ustawienie naszego SR-Latch, nawet jeśli nie było to konieczne. Jeśli przełączymy się z SR-Latch na SR-FF, wyzerujemy ten sam zegar, co licznik, wtedy SR-FF będzie czekał na jeden cały cykl zegara przed zmianą stanu. Zasadniczo poczeka, aż ustawiony sygnał ustabilizuje się, zanim na niego spojrzy.

Jeśli ścieżki przez kombinatoryczną logikę dla ustawionego sygnału są po prostu inaczej prowadzone (powodując różne opóźnienia), wówczas zachowanie usterki również się zmieni. Logika może działać dobrze, ale ponieważ zmieniłeś coś całkowicie niezwiązanego, logika jest kierowana inaczej, więc pojawia się błąd. Temperatura i napięcie również zmienią przebieg sygnału, a tym samym mogą zmienić zachowanie usterki.

To niepewne w czasie, dlatego powinieneś unikać zatrzasków w logice. FF są znacznie bezpieczniejsze w użyciu. Właśnie dlatego twój kompilator ostrzega cię o zatrzaskach, ponieważ łatwo jest przez pomyłkę zrobić zatrzask i prawdopodobnie i tak go nie chcesz.

Oczywiście czasami wymagane są zatrzaski. Musisz ich używać bardzo rzadko, tylko gdy jest to absolutnie wymagane, a następnie musisz odpowiednio zaprojektować logikę, aby nie było żadnych problemów.


źródło
Spodziewałbym się, że jeśli wyraźnie określisz zatrzask w verilog lub innym języku, i jeśli zaprojektujesz obwód tak, aby działał poprawnie z dowolną kombinacją opóźnień kombinatorycznych zasilających zatrzask (co oznacza, że ​​cokolwiek generowało sygnały, które byłyby łączone dla zatrzask, zrobiłby to w taki sposób, że nawet przy najgorszych kombinacjach ścieżek logicznych o zerowym opóźnieniu i ścieżkach logicznych o maksymalnym opóźnieniu wymagania czasowe dla zatrzasków byłyby nadal spełnione), syntezator powinien wygenerować działający obwód gdzie sama zatrzask ma opóźnienie nieujemne. Jeśli jednak ...
supercat
... używa się logiki kombinatorycznej i sprzężenia zwrotnego bez określania żadnych węzłów, które muszą mieć opóźnienie nieujemne, wszystko może się zdarzyć. Rozumiem, że logika synchroniczna jest łatwiejsza do zaprojektowania niż asynchronizacja, ale wiele urządzeń musi wyłączać zegary, gdy śpią, aby oszczędzać energię, nie będąc całkowicie martwym. Interesujące może być posiadanie urządzenia, które było całkowicie synchroniczne, ale przypisało każdemu pinowi kilka wyjść logicznych dla „uruchom, jeśli pin jest wysoki” i „uruchom, jeśli pin jest niski”, a także możliwość wygenerowania zegara, jeśli jakikolwiek pin wskazał, że jeden jest potrzebny.
supercat
Taka umiejętność zmniejszyłaby w znacznym stopniu potrzebę logiki asynchronicznej, ponieważ wejście, które pojawiło się podczas uśpienia urządzenia, mogło zasilać wewnętrzny oscylator i zespół obwodów wystarczająco długo, aby wejście mogło zostać przetworzone i potwierdzone. Taka cecha byłaby o wiele bardziej wszechstronna niż posiadanie pojedynczego „budzika”, ale projekty z pojedynczym wybudzaniem wydają się normą. Czy podejście polegające na obudzeniu, takie jak opisałem, zużyłoby nadmiar krzemu? Sądzę, że zapotrzebowanie na krzem byłoby niewielkie w porównaniu ze wszystkim innym na chipie.
supercat
13

Co sprawia, że ​​wnioskujesz o zatrzasku?
W przypadku logiki kombinatorycznej wyjście obwodu jest funkcją wyłącznie wejściową i nie powinno zawierać żadnej pamięci ani stanu wewnętrznego (zatrzask).

W Verilog zmienna zachowa swoją poprzednią wartość, jeśli nie zostanie jej przypisana wartość w bloku zawsze . Aby zapisać tę wartość bieżącą, należy utworzyć zatrzask.

Niekompletna instrukcja if-else wygeneruje zatrzaski. If-else oświadczenie uważa się za „niepełne” jeśli stan wyjścia nie jest zdefiniowane dla wszystkich możliwych warunków wejściowych. To samo dotyczy niekompletnej instrukcji case lub instrukcji case , która nie ma wartości domyślnej: item.

Dlaczego wywnioskowane zatrzaski są złe?
Wnioskowane zatrzaski mogą służyć jako „znak ostrzegawczy”, że projekt logiki może nie zostać zaimplementowany zgodnie z przeznaczeniem. Wprojekcie może brakowaćkluczowejinstrukcji if-else lub case .

Zatrzaski mogą prowadzić do problemów z czasem i warunkami wyścigu. Mogą one prowadzić do kombinatorycznego sprzężenia zwrotnego - kierowania wyjścia z powrotem do wejścia - co może być nieprzewidywalne.

Aby uniknąć tworzenia wnioskowanych zatrzasków:

  • Obejmują wszystkie gałęzie na razie lub wypadku oświadczenie
  • Przypisz wartość do każdego sygnału wyjściowego w każdej gałęzi
  • Użyj domyślnych przypisań na początku procedury, aby każdy sygnał został przypisany.

Niektóre części zostały sparafrazowane z „FPGA Prototyping by Verilog Examples” P. Chu

dext0rb
źródło
2
„FPGA Prototyping by Verilog Examples” to dobra książka do nauki praktycznego Verilog for Synthesis. Ma kilka dobrych przykładowych projektów, od podstawowych elementów kombinatorycznych po podstawowe sekwencyjne, co prowadzi do użytecznych projektów, takich jak UART, VGA, procesor z miękkim rdzeniem (Picoblaze), a nawet gra w Ponga. Obejmuje także podstawowy testbench i symulację. @Randomblue, powinieneś pobrać kopię, jeśli jeszcze jej nie masz. Myślę, że on również zrobił wersję VHDL.
Oli Glaser,
8

Zatrzaski są bardzo trudne w użyciu w FPGA lub CPLD, więc wiele osób po prostu ich całkowicie unika. Jednym z powodów jest to, że wiele układów FPGA nie ma wbudowanej zatrzasku, więc są wykonane z bramek logicznych - może to powodować nieprzyjemne problemy z synchronizacją.
Ponadto nie masz żadnej kontroli nad opóźnieniami czasowymi i warunkami wyścigu podczas używania zatrzasku (chyba że istnieje element natywny)

Odradzałbym używanie zatrzasków, chyba że absolutnie nie możesz się bez nich obejść (np. Pożyczanie czasu, aby osiągnąć wymaganą maksymalną częstotliwość taktowania) i zastosować techniki kodowania, aby zmniejszyć prawdopodobieństwo przypadkowego wnioskowania zatrzasków.

Oli Glaser
źródło
6

Projekty logiki sekwencyjnej zbudowane przy użyciu logiki kombinatorycznej i sprzężenia zwrotnego generalnie przyjmują założenie, które wydawałoby się rozsądne przy zastosowaniu fizycznych bramek: że wyjście bramki nie zmieni się w odpowiedzi na zmianę danych wejściowych, aż do czasu, gdy dane wejściowe faktycznie się zmienią. W niektórych przypadkach to założenie może się nie utrzymywać, gdy używane są prawdziwe bramki (np. Jeśli zarówno szybka bramka NOR, jak i szybki falownik są napędzane sygnałem, który powoli wzrasta z VSS do VDD, i gdy falownik przełącza się na 1,2 wolta, podczas gdy NOR bramka nie przełącza się, dopóki 1,7 wolta, bramka NOR może zobaczyć niski poziom wyjściowy falownika, zanim zobaczy, że wolno rosnący sygnał osiągnął wysoki poziom), ale takie problemy można ogólnie rozwiązać, dodając bufor za każdym razem, gdy powoli się zmienia sygnał jest kierowany do więcej niż jednego miejsca docelowego. Niestety,

Problem polega na tym, że jeśli wyraźnie nie podano inaczej, kompilator FPGA może dowolnie zastąpić obwód kombinatoryczny całkowicie innym obwodem, który ma takie samo zachowanie w stanie ustalonym, ale może mieć zupełnie inne taktowanie. Załóżmy na przykład, że złożona funkcja kombinatoryczna F pobiera sześć wejść U do Z. F jest podawany bezpośrednio do obwodu P, a (F NAND Z) jest podawany do obwodu Q. Kompilator może zdawać sobie sprawę, że wartość podawana do Q będzie zależeć tylko od F, gdy Z jest wysokie, i może obliczać funkcję F ', która jest podobna do F, z tym że Z przyjmuje się jako wysoką; Q może być następnie zasilany (F 'NAND Z) zamiast (F NAND Z). Byłoby całkowicie możliwe, że najbardziej wydajna realizacja P miałaby pięć opóźnień bramki, ale najbardziej wydajna realizacja Q miałaby tylko dwa. A zatem,

Jeśli obwód ma kombinatoryczne pętle sprzężenia zwrotnego, kompilator FPGA będzie musiał dodać fizyczne węzły sygnałowe, które fizycznie będą miały opóźnienie dodatnie (pętla sprzężenia zwrotnego o zerowym opóźnieniu nie może istnieć w świecie rzeczywistym), ale nie ma gwarancji, że takie węzły zostałyby dodane w miejscach niezbędnych do tego, aby obwód zachowywał się zgodnie z potrzebami. Nie ma też żadnej gwarancji, że niewielka zmiana w projekcie nie spowoduje zmiany kompilatora z dowolnego umiejscowienia, które zdarza się działać w świecie rzeczywistym, do innego dowolnego umiejscowienia, które się nie powiedzie.

supercat
źródło
0

Szczegółowe informacje o tym, jak złapać zatrzask w projekcie, zostały krótko wyjaśnione w tym linku.

https://www.doulos.com/knowhow/fpga/latches/

użytkownik3303020
źródło
1
Witamy w EE.SE! Możesz poprawić swoją odpowiedź, dołączając kilka istotnych szczegółów z linku. To gwarantuje, że twoja odpowiedź jest wysokiej jakości, nawet jeśli oryginalna strona zniknie.
David