Różnica między instrukcją If-else a instrukcją Case w VHDL

11

Chcę zrozumieć, w jaki sposób różne konstrukcje w kodzie VHDL są syntetyzowane w RTL.

  • Czy ktoś może mi powiedzieć różnicę między konstrukcją If-Else a konstrukcją instrukcji Case procesu w VHDL pod względem sposobu wnioskowania kodu do obwodu RTL przez narzędzie do syntezy?
  • Rozważ przypadek wielu zagnieżdżonych instrukcji if-else i mieszania instrukcji case z konstrukcją if-else wewnątrz procesu.
  • Również kiedy użyć której konstrukcji?

PS: Widziałem podobne pytanie „Wiele instrukcji w toku w vhdl”, ale to i tak nie odpowiada na moje pytanie.

nurabha
źródło
Nie mogę wypowiedzieć się na temat konfiguracji fizycznych bramek, ale w większości kompilatorów, które emitują zestaw x86, jeśli-inaczej zwykle istnieje jako pojedyncze sprawdzenie ze skokiem warunkowym (np. Jg, jl, jz, jnz itp.), podczas gdy switch porządkuje przypadki w kolejności numerycznej i wykonuje iterację dec/ jzinstrukcje, co jest znacznie wydajniejsze. Być może zastosowano tutaj podobną optymalizację.
Wielomian
@Polynomial Zachowanie If-else i wielkość liter różnią się znacznie w językach sprzętowych w porównaniu do typowego programowania liniowego. Optymalizacje kodu operacyjnego nie są zbyt istotne, ponieważ instrukcja HDL wykonuje się „natychmiast”.
W5VO,

Odpowiedzi:

10

Czy ktoś może mi powiedzieć różnicę między konstrukcją If-Else a konstrukcją instrukcji Case procesu w VHDL pod względem sposobu wnioskowania kodu do obwodu RTL przez narzędzie do syntezy?

if-elsif-elseKonstrukcja wywodzi priorytet routingu sieci:

schematyczny

symulacja tego obwodu - Schemat utworzony przy użyciu CircuitLab

To odpowiada

if bool_expr_1 then
    sig <= val_expr_1;
elsif bool_expr_2 then
    sig <= val_expr_2;
elsif bool_expr_3 then
    sig <= val_expr_3;
else
    sig <= val_expr_4;
end if;

Z casedrugiej strony konstrukt wnioskuje z dużego olxu:

wprowadź opis zdjęcia tutaj

To odpowiada

case case_expr is
  when c0 =>
    sig <= val_expr_0;
  when c1 =>
    sig <= val_expr_1;
  when c2 =>
    sig <= val_expr_2;
      ...
  when others =>
    sig <= val_expr_N;
end case;

Oczywiście są to bardzo uproszczone projekty z tylko jednym wyrażeniem wartości, co daje jeden wynik.

Rozważ przypadek wielu zagnieżdżonych instrukcji if-else i mieszania instrukcji case z konstrukcją if-else wewnątrz procesu.

Na podstawie powyższego możesz zobaczyć, jak by się zagnieżdżały / miksowały.

Również kiedy użyć której konstrukcji?

Ponieważ ma on if-elsepriorytet, należy go stosować, gdy może wystąpić więcej niż jeden warunek wejściowy. Używanie case, z drugiej strony, jest odpowiednie, gdy dane wejściowe wzajemnie się wykluczają.

Angelo Stavrow
źródło
Rozumiem, że statystyka przypadków działa tylko w przypadku warunku pojedynczego wejścia, a if-else może działać w przypadku wielu warunków wejściowych. Ale oba konstrukty zasadniczo generują multipleksy (przy braku clk). Czy nie jest możliwe, że synteza logiczna może zoptymalizować jedno-wejściowy if-else do pojedynczego dużego multipleksera zamiast łańcucha multiplekserów? Ponadto, czym jest priorytetowa sieć routingu ... czy to nie jest po prostu łańcuch multiplekserów zamiast 1 dużego multipleksera?
nurabha
Dodatkowo, gdy mamy proces wrażliwy na zegar, if-else może generować elementy sekwencyjne, takie jak rejestry, zatrzaski itp. Czy instrukcja case może również generować logikę sekwencyjną?
nurabha
Tak, priorytetem jest właśnie sieć routingu priorytetowego - łańcuch multiplekserów. Natura if-elsekonstruktu jest jednak tym, gdzie powstaje ten łańcuch. Pierwszy warunek musi zawieść, aby drugi warunek został przetestowany. Nie jest tak w przypadku, po prostu, casekonstrukcji i dlatego if-elseinstrukcja nie mogła zostać zsyntetyzowana jako pojedynczy duży multiplekser.
Angelo Stavrow,
1
I tak, caseinstrukcja może również generować logikę sekwencyjną. Znalazłem „Real World VHDL” , serię wykładów z Uniwersytetu w Glasgow, które mogą być dla ciebie pomocne.
Angelo Stavrow,
To jest dobre odniesienie.
nurabha
4

W tym starym wpisie na blogu autor napisał i zsyntetyzował dwie funkcjonalnie równoważne wersje kodu VHDL. Jeden używa if-else, drugi używa case. Wynik:

Zsyntetyzowałem ten kod i uzyskałem dokładne wyniki. Nawet schemat RTL był dokładnie taki sam dla obu programów.

I jego wniosek:

To pokazuje, że instrukcje „case” i „if ... elsif ... else” są równie wydajne, ale jeśli chcesz napisać przejrzysty kod, lepiej użyj „case”. „Case” jest bardzo przydatne, gdy wynik zależy od dużej liczby warunków, ale jeśli liczba warunków jest bardzo mała (2 lub 3), możesz użyć „if..elseif..else”.

Istnieją również dziesiątki postów na ten temat na temat przepełnienia stosu dla każdego możliwego języka. Wniosek jest ogólnie taki sam, że nie ma różnicy pod względem wydajności. Czasami, jeśli istnieje duża liczba przypadków, kompilator może być wystarczająco inteligentny, aby utworzyć tabelę przeglądową, która dałaby nieco lepszą wydajność.

Syntezator VHDL może być w stanie zrobić coś podobnego. Ale nadal potrzebujesz dużej liczby przypadków, w którym to przypadku (gra słów zamierzona) prawdopodobnie i tak chciałbyś użyć instrukcji case, ponieważ zapewnia ona lepszą czytelność tam, gdzie jest wiele opcji.

embedded.kyle
źródło