Widziałem ładne pytanie do wywiadu dla VHDL - zbuduj system, który odbiera liczbę i wykrywa, czy można ją podzielić przez 5 bez reszty. Próbowałem rozwiązać to za pomocą automatu stanów (przypuszczam, że nie chcą, abyś używał modów lub remów ) i chociaż odniosłem początkowy sukces (liczby takie jak 5, 10, 15 i liczby takie jak 20, 40, 80 działały ), inne liczby, takie jak 130, 75 itd., zawiodły dla mnie.
Chciałbym pokazać moją maszynę stanów, ale to kompletny bałagan (to nie kod, to rysunek) i, jak powiedziałem, nawet nie działa.
Zasadniczo starałem się zapisać liczby binarne, które można podzielić przez 5, i zbudować maszynę stanu, która będzie dla nich działać.
Byłbym szczęśliwy, gdybyś mógł pokazać mi, jak rozwiązać ten problem i jak myśleć, gdy staje się coś takiego.
Dziękuję Ci!
źródło
Odpowiedzi:
Wykonanie pozostałej operacji seryjnie jest w rzeczywistości dość łatwe. Kluczowym założeniem jest to, że dane przychodzą najpierw do MSB, jeśli są szeregowe. Potrzebujesz tylko stanów N, aby obliczyć resztę modulo N. Zacznij od stanu „0”, a jeśli skończysz w stanie „0” po ostatnim bicie (nie ma znaczenia, ile jest bitów), reszta to zero.
symulacja tego obwodu - Schemat utworzony za pomocą CircuitLab
Pomyśl o tym, jak zrobiłbyś długi podział, gdyby jedyną rzeczą, którą musisz śledzić, była reszta:
źródło
2n mod 5
, a strzałka 1 wskazuje na(2n + 1) mod 5
.state
,din
iN
do kodu?Możesz także zaprojektować maszynę stanową, jeśli dane pochodzą najpierw od LSB:
Istnienie takiego deterministycznego automatu skończonego (DFA) wynika bezpośrednio z innej odpowiedzi , która opisuje DFA dla MSB-first. Ponieważ języki akceptowane przez DFA są zwykłe, a znane języki są zamknięte w trakcie cofania (np. Patrz tutaj ), musi istnieć DFA, który akceptuje następujący język:
.L = { w ∈ { 0 , 1 }∗| rewers ( w )10 jest podzielny przez 5 }
Budowa
Skopiuj pierwszy MSB DFA z odpowiedzi Dave'a Tweeda . Użyłem narzędzia automatycznego JFLAP .
Zastosuj jawny algorytm transformacji dla zamian DFA, np. Jak opisano w CS.SE: Projektowanie DFA i jego odwrotność .
Możesz zobaczyć (niezminimalizowany) wynik tego kroku w starej wersji tej odpowiedzi.
Zminimalizuj wynikowy DFA. Niestety, ta funkcja jest trochę wadliwa w najnowszej wersji JFLAP, więc zrezygnowałem z jej ręcznego minimalizowania.
q0 q1 są równoważnymi stanami w DFA, jak uzyskano w punkcie 2. Moje nie są, dziękuję, że zauważyłeś, że to idzie do komentarza superkata !)
Znów istnieje wiele algorytmów i źródeł dla nich. Użyłem tego opisanego w „Minimalizacji DFA” na tutorialspoint.com .
(W rzeczywistości, jeśli twoje oczy są wystarczająco dobrze wyszkolone w patrzeniu na DFA, możesz bezpośrednio zobaczyć, że i q 1
Rzeczywiście, wynikowy automat daje prawidłowe odpowiedzi:
źródło
Jednym ze sposobów wymyślenia automatu stanowego (MSB first) jest:
Dotychczas otrzymano numer
N
. Załóż, że znasz resztęM = N mod 5
.Nadchodzi nowy bit i nowa wartość jest teraz
N' = N*2 + b
.Nowa reszta jest wtedy
M' = (N*2 + b) mod 5 = (M*2 + b) mod 5
.Łatwo jest to zestawić ręcznie:
Który pasuje do automatu stanowego w odpowiedzi Dave'a Tweeda.
źródło
Mam nadzieję, że pytanie w wywiadzie dotyczyło sposobu rozwiązania problemu, a nie tajników VHDL lub Verilog. Szczegóły języka są proste, gdy masz już algorytm.
źródło
W zależności od tego, dla czego jest napisany VHDL, możesz zastosować podejście, które opisuje go jako bezpośrednie obliczenie kombinacyjne. Otrzymanie numeru może oznaczać, że cały numer będzie w rejestrze dla jednego cyklu zegara.
Możesz na przykład zanotować mod 5 wartości, którą reprezentują każdy z bitów, dodać je razem, a następnie powtarzać proces, aż pozostanie coś mniejszego niż 5. Albo zaimplementuj to łącznie dla wszystkich etapów redukcji, lub ponownie użyć logiki dla niewielkiej liczby cykli.
Ale jeśli używasz operatora rem VHDL, może to być właściwa odpowiedź. Zakładając, że firma ma przyzwoite narzędzia do syntezy, dałoby to dość wydajną implementację - być może nieco większy obszar niż rozwiązania typu maszyna-maszyna, ale pełna przepustowość, a zatem prawdopodobnie dobra energia na obliczenia. Jest to opcja, która wdrożyłaby najmniej czasu, a zatem prawdopodobnie najmniej pieniędzy dla pracodawcy!
Szczerze mówiąc, prawdopodobnie nie jest to odpowiedź, której szukają z takim pytaniem - ale jest to również okazja, aby pochwalić się prawdziwym doświadczeniem projektowym.
źródło
Jeśli liczba jest prezentowana w kawałkach większych niż jeden bit, pomocne może być zastosowanie równoległych obliczeń do obliczenia reszty mod 15, z zastrzeżeniem, że obliczenia mogą dać 15 dokładnie wtedy, gdy reszta jest równa zero. Prostym sposobem obliczenia reszty mod-15 jest zaobserwowanie, że dla dowolnej wartości N> = 1, dodanie skrajnie lewych 4N bitów do części liczby poza nią da wartość zgodną z oryginalnym modem 15. To pozwala podzielić problem na wiele różnych sposobów, w zależności od dostępnych zasobów.
Na przykład, jeśli zaczyna się od wartości 32-bitowej, można to traktować jako osiem wartości 4-bitowych. Można je sumować parami, aby uzyskać cztery wartości 5-bitowe, które z kolei można połączyć w dwie wartości 6-bitowe lub jedną wartość 7-bitową. Dodanie trzech górnych bitów tej 7-bitowej wartości do dolnych 4-bitowych da 5-bitową wartość, która wynosi najwyżej 21. Można w ten sposób ustalić, czy oryginalna wartość jest wielokrotnością 5, obserwując, czy ostateczna wartość jest jeden z 0, 5, 10, 15 lub 20.
źródło
Nie pamiętam mojego VHDL, ale oto szkic idei, która pojawiła się po raz pierwszy:
Ostatnie cyfry (w podstawie 10) pierwszych potęg dwóch to 1, 2, 4, 8, 6, 2, ... i cykl się powtarza. Stąd reszta mod 5 potęg dwóch to 1, 2, 4, 3, ....
Korzystając z tego, moglibyśmy przesunąć bity z LSB i gromadzić resztki mod 5 odpowiadające pozycji, ilekroć
1
bit jest widoczny. Wykonaj także mod akumulacji 5 i wystarczy sprawdzić, czy suma na końcu wynosi zero.źródło
Możemy skorzystać z pomysłu z odpowiedzi tutaj , że w podstawie 4 możemy wywnioskować, że liczba jest podzielna przez 5 tylko wtedy, gdy suma cyfr naprzemiennych jest. My zatem
Spróbujmy na liczbie 166 = (10) (10) (01) (10): 2,2,1,2
2-2 + 1-2 = -1
która wynosi <= 3 w wartości bezwzględnej, a nie 0, dlaczego możemy stwierdzić w jednej iteracji, że 166 nie jest podzielone równomiernie przez 5.
Może być tak, że mała pamięć może być tańsza / lepsza pod względem prędkości / liczby bramek niż iteracja. Można oczywiście wstępnie obliczyć najgorszy (największy możliwy wynik przy dozwolonych danych wejściowych) i odpowiednio zaplanować projekt.
źródło
Podejście MSB jest zdecydowanie łatwiejsze, ale udało mi się wykonać diagram stanu LSB bez potrzeby generowania rozwiązania MSB ... zajęło mi to tylko kilka godzin. Okazuje się, że jest to odpowiednik tego pokazanego przez @ComFreek, po prostu inaczej opisany.
Będziemy śledzić dwie liczby. Najpierw będziemy śledzić bieżącą sumę, modulo 5 („SUM”). Po drugie, będziemy śledzić wartość następnej mocy 2, która ma zostać przesunięta, modulo 5 („NASTĘPNY”). Przedstawię każdy stan możliwymi wartościami „SUM” u góry i odpowiadającymi im wartościami „NASTĘPNY” poniżej.
Zaczniemy od przypadku, w którym „SUM” modulo 5 wynosi 0:
Zauważ, że stan wygląda następująco:
3,2,4,1
1,4,3,2
odpowiada:
1,3,4,2
2,1,3,4
Ponieważ oba stany reprezentują, że:
SUMA = 1 i NASTĘPNA = 4 LUB
SUMA = 2 i NASTĘPNA = 3 LUB
SUMA = 3 i NASTĘPNA = 2 LUB
SUMA = 4 i NASTĘPNA = 1.
Ok, więc teraz musimy opracować dodatkowe stany, ponieważ większość ankieterów nie będzie pod wrażeniem diagramu stanu z tylko jednym stanem. Skończymy, gdy każdy stan ma dwa przejścia.
Ilekroć przejdziesz do nowego stanu, każda liczba w „NASTĘPNYM” jest podwojona, a następnie modulo'd 5. W przypadku „SUMY” przestrzegaj następujących zasad:
Zacznijmy więc od wypełnienia przejść, gdy bit przychodzący ma wartość 1.
W porządku, teraz wypełniamy zera. Dodano tylko jeden stan, więc przejdziemy dalej i uzupełnimy jego przejścia.
I voila! Mamy maszynę stanów, która najpierw akceptuje LSB, bez konieczności generowania rozwiązania MSB.
źródło
Wszystko to wydaje się takie skomplikowane! Istnieje prosty matematyczny sposób na wykrycie, czy binarna liczba całkowita jest podzielna przez pięć. Na początek, czy pamiętasz, jak „wyrzucić dziewiątki” w zwykłej arytmetyki dziesiętnej? Moduł resztowy 9 liczby dziesiętnej jest taki sam, jak moduł resztowy 9 sumy jego cyfr. Działa to, ponieważ 9 jest o jeden mniej niż podstawa liczbowa.
Istnieje podobny proces, „wyrzucanie jedenastu”, w którym znaki alternatywnych cyfr są ustawione na ujemne. Działa to, ponieważ jedenastka jest o jeden większa od podstawy liczbowej.
Więc jeśli chcemy „wyrzucić piątki”, możemy reprezentować naszą liczbę całkowitą w bazie czwartej. Następnie zaczynamy od najniższej pary cyfr jako sumy początkowej i odejmujemy ją od następnej pary cyfr, aby otrzymać następną sumę. Po przejściu przez naszą liczbę całkowitą kandydata w ten sposób końcowa suma będzie równa zero lub podzielna przez 5, jeśli nasza pierwotna liczba całkowita będzie podzielna przez 5.
Przykład 70: 01 00 01 10 -> 01 00 -1 -> 01 01 -> 00, podzielny przez 5 Przykład 49: 11 00 01 -> 11 -1 -> 1 00 -> 1, NIE podzielny przez 5
Pamiętaj, że musisz nosić dodatkowe bity dla znaku skumulowanej różnicy i dla przypadków, gdy występuje.
Innym sposobem jest dodanie cyfr szesnastkowych, aby uzyskać resztkowy modulo 15. Oczywiście potrzebujesz ostatniego kroku logicznego, aby zidentyfikować trzy akceptowalne wyniki zero, pięć i dziesięć.
Przykład 70: 4 6 -> A, więc 70 można podzielić przez 5 (ale nie przez 15) Przykład 49: 3 1 -> 4, więc 70 NIE można podzielić przez 5.
Zauważ, że możesz użyć różnych baz liczbowych do zbudowania wielu testów podzielności, chociaż w logice komputerowej te dla potęg 2 +/- 1 są najłatwiejsze do wdrożenia.
W przypadku arytmetyki dziesiętnej jednym z moich ulubionych jest mój test na pozostałość mod 7. Zauważ, że 100 jest dwa większe od wielokrotności 7, więc zgrupuj cyfry w pary (pracuj w bazie liczb 100) i dodaj setki DWUKROTNIE z jednostek. Tutaj pracujemy od lewej do prawej ...
Przykład: 98 76 -> 2 72 -> 76, więc 9876 nie można podzielić przez 7. Jest to 6 mod 7. Przykład: 03 45 67 -> 51 67 -> 1 69 -> 71 więc jest 1 mod 7.
Oczywiście w systemie binarnym wystarczy wziąć sumę cyfr ósemkowych (grupy 3 bitów).
Przepraszam, chciałbym być guru Verilog, ale arytmetyka jest wszystkim, co mogę zaoferować na tym etapie życia. Zobacz „Dead Reckoning” Rona Doerflera, aby uzyskać wiele takich sztuczek.
źródło
Pytanie do wywiadu VHDL powinno spowodować powstanie kodu VHDL.
Miałem okazję znaleźć błąd zaplecza ghdl llvm z implementacją tabeli przejścia stanu Dave'a Tweeda, w której autor ghdl destylował implementację w funkcji do 17 wierszy:
Powiązany przypadek testowy jest dość mały, co pozwala na łatwiejsze debugowanie i używa nazw stanów zgodnych z VHDL w wyliczonym typie pozostaje:
(stworzony przy pomocy Dia)
Chodzi o to, że funkcja (lub nawet przykładowy program 27 linii VHDL) jest wystarczająco krótki, aby napisać odpowiedź VHDL podczas wywiadu. Nie musisz się martwić, że zepsujesz pytanie podczas rozmowy kwalifikacyjnej wymagające wykazania się zarówno wiedzą, jak i umiejętnościami, od osoby, z którą rozmawiamy, będzie się bronić implementacji, gdy zostanie zapytany.
(Błąd llvm został naprawiony dzisiaj w commit 1f5df6e ).
Jedną z ważniejszych rzeczy jest to, że tabela przejścia stanu mówi nam również, gdzie bit ilorazu byłby „1” pokazany przez przejście do stanu o niższej wartości resztkowej (lub obu przejść dla r4) przy odejmowaniu 5 od dywidendy. Można to zakodować w osobnej tabeli (lub tabeli typu rekordu, która wydaje się niewygodna). Robimy to historycznie w sprzęcie graficznym obsługującym poziome rozdzielczości ekranu wielokrotności 5 pikseli.
W ten sposób otrzymujemy div / mod5, który tworzy iloraz, a resztę:
Zaimplementowane tutaj z instrukcją generowania, wewnętrzną instrukcją generowania produkującą bity ilorazowe. Pozostała tablica zapewnia śledzenie przejścia stanu:
Wszystko bez operacji arytmetycznej.
Możliwe jest również wdrożenie w procedurze bez wykorzystywania przez wszystkie rejestry parametrów bez trybu. To zbliży się do minimalnej liczby linii na rozmowę kwalifikacyjną.
Taktowana sekwencyjna implementacja wymagałaby nieco licznika i kontroli przepływu (przerzutnik JK i kilka bramek).
Kompromis czas / złożoność zależy od wielkości dywidendy, której prawdopodobnie będziesz musiał bronić podczas wywiadu.
źródło