Spisu treści:

Gra Mastermind w VHDL: 3 kroki
Gra Mastermind w VHDL: 3 kroki

Wideo: Gra Mastermind w VHDL: 3 kroki

Wideo: Gra Mastermind w VHDL: 3 kroki
Wideo: Programming Language Tier List 2024, Lipiec
Anonim
Gra Mastermind w VHDL
Gra Mastermind w VHDL
Gra Mastermind w VHDL
Gra Mastermind w VHDL

Na potrzeby naszego projektu stworzyliśmy grę „Mastermind” w języku VHDL do gry na płycie Basys3. Mastermind to gra polegająca na łamaniu kodów, tradycyjnie rozgrywana za pomocą kołków i planszy. Gracz pierwszy umieszcza kołki w różnych kolorach w rzędzie po 4, ukryte przed graczem drugim. Gracz drugi ma wtedy „x” odgadnięć, umieszczając kołki na planszy w rzędzie widocznym dla gracza pierwszego. Po każdym odgadnięciu drugi gracz otrzymuje 2 liczby: ile kołków ma właściwy kolor i ile kołków jest we właściwej pozycji w rzędzie. Korzystając z tych wskazówek, gracz drugi musi odgadnąć prawidłową sekwencję szpilek, które gracz pierwszy umieścił w przydzielonej liczbie.

W naszej realizacji gra jest jednoosobowa. Program generuje losową kombinację kołków, a gracz musi użyć planszy Basys3, aby odgadnąć poprawną sekwencję. Istnieją cztery „kolory” reprezentowane przez wartości binarne. Wyświetlacz 7-segmentowy pokazuje trzy wartości: pozostałe obroty, liczbę kołków w prawidłowej pozycji oraz liczbę kołków, które mają prawidłowy kolor w niewłaściwym położeniu (te wartości zaczynają się od 9, 0 i 0). Gracz używa przełączników na tablicy, aby wybrać wartości binarne do swojego przypuszczenia, i przestawia inny przełącznik, aby przesłać przypuszczenie. Jeśli są poprawne, gra się kończy, a wyświetlacz 7-segmentowy pokazuje „GG”. Jeśli nie, licznik tur zmniejsza się o 1, a gracz otrzymuje informację zwrotną w oparciu o to, ile szpilek w ich zgadywaniu pasuje do koloru lub pozycji szpilek w kombinacji. Jeśli graczowi skończą się tury bez poprawnego odgadnięcia, na wyświetlaczu pojawi się napis „GO” (oznaczający koniec gry). Gracz może również w dowolnym momencie przestawić przełącznik resetowania, aby zacząć od nowa.

Krok 1: Materiały

Materiały
Materiały
Materiały
Materiały
Materiały
Materiały

Ponieważ cała gra może być rozgrywana na samej planszy, jedyne potrzebne materiały to tablica Basys3, kabel micro USB do podłączenia do planszy oraz komputer/laptop, którego można użyć do kodowania!

Krok 2: Kodeks

Kod
Kod
Kod
Kod

Aby ta gra działała na FPGA, najprostszym sposobem na napisanie jej byłoby stworzenie maszyny stanów. Posiadanie maszyny stanowej umożliwia sekwencyjne i interaktywne doświadczenie niezbędne do rzeczywistej pracy gry. Aby wszystko działało płynnie, maszyna stanu będzie bazować na wewnętrznym sygnale zegara FPGA, zapewniając, że wszystko jest zsynchronizowane. Główny moduł to maszyna stanów z czterema stanami; Stan początkowy (początkowy), stan SubmitAnswer (SubAns), stan wyświetlania (Dis) i stan CheckEndGame (CheckEnd). Wraz z maszyną stanu, moduł główny posiada dwa podmoduły, 4-cyfrowy wyświetlacz siedmiosegmentowy (który posiada własny podmoduł ClkDivider) oraz generator liczb losowych (właściwie generator liczb pseudolosowych). Istnieje również podstawowy blok procesowy, w którym diody LED nad każdym przełącznikiem włączają się po włączeniu, aby ludzie mogli łatwiej zobaczyć, co wprowadzają. Podstawowy przegląd kodu można zobaczyć na przedstawionej mapie myśli.

Pierwszym komponentem, któremu należy się przyjrzeć, jest generator liczb losowych (gen losowy). Ponieważ nie jest technicznie możliwe uzyskanie prawdziwych liczb losowych generowanych ze sprzętu, najprostszym rozwiązaniem było, aby generator losowy był faktycznie rejestrem przesuwnym z liniowym sprzężeniem zwrotnym (LFSR). LFSR ma wejście clk i wyjście „a” (liczba 12-bitowa). W każdym cyklu zegara generowany jest nowy 12-bitowy numer, zaczynając od „000000000001”, ostatecznie przechodząc przez wszystkie kombinacje 12-bitów jedynek i zer, zanim się powtórzy. Wyjście „a” jest podawane w każdym cyklu zegara, więc działa przez cały czas. Clk jest mapowany do Clk z modułu głównego, a „a” jest mapowany do sygnału RandNum w module głównym.

Drugi podmoduł to 4-cyfrowy wyświetlacz siedmiosegmentowy. Jest to dość prosty sposób zaprezentowania 4-cyfrowego wyświetlacza siedmiosegmentowego. Wyświetlacz jest ustawiony na Clk z modułu głównego, ale ten podmoduł ma swój własny podmoduł ClkDivider. ClkDivider (ustawiony na 1298 Hz) jest używany do przyspieszenia zegara dla siedmiu segmentów, tak aby wszystkie cyfry wydawały się być włączone w tym samym czasie (ponieważ tylko jedna cyfra może być włączona na raz). Zmienna „digit” służy do przełączania punktów na wyświetlaczu, a z każdą cyfrą pojawiają się warunki podstawowego 4-bitowego wyświetlacza wejściowego, z opcjami wyświetlania cyfr od 0 do 9, a także nic. Najdalej wysunięta lewa cyfra na wyświetlaczu jest ustawiona na zero, ponieważ nie jest używana w tej grze.

Moduł główny składa się z maszyny stanowej. Cztery stany w procesie to Initial, SubAns, Dis i CheckEnd. W stanie początkowym, jeśli SubmitBtn (przełącznik używany do przesłania odpowiedzi do sprawdzenia) jest ustawiony na „1”, to maszyna przechodzi do stanu SubAns. W dowolnym momencie Rbtn (przełącznik służący do resetowania maszyny) jest ustawiony na „1”, a następnie maszyna powraca do stanu początkowego. W stanie SubAns, gdy SubmitBtn = „0” ponownie, przechodzi do stanu Dis. W stanie Dis, jeśli odliczanie = 0 (obróty w lewo do zgadywania spadają do 0) lub jeśli RSpotCount = 4 (co oznacza, że gracz ma wszystkie prawidłowe kolory we właściwych miejscach), maszyna przechodzi do stanu CheckEnd. Jeśli żadna z tych sytuacji nie wystąpi, gdy ponownie SubmitBtn = „1”, powraca do stanu SubAns, aby umożliwić kolejne odgadnięcie. W stanie CheckEnd jest to koniec gry, a jedynym wyjściem jest zresetowanie, przywrócenie stanu początkowego. Można to łatwo zobaczyć na schemacie maszyny stanów. Behawioralnie stan początkowy inicjalizuje wszystko z powrotem do pozycji wyjściowej. Odliczanie (sygnał, który zapisuje ile tur pozostał graczowi) jest ustawione na 9, RSpotCount (sygnał, który zapisuje, ile kolorów, które odgadłeś jest we właściwym miejscu) jest ustawiony na 0, RColorCount (sygnał, który zapisuje ile kolory, które zgadłeś, są prawidłowe, ale w złym miejscu) jest ustawione na 0, a małe odliczanie (sygnał, który jest ostatecznie mapowany na Countdown, który faktycznie zmienia się co turę w późniejszych stanach) jest ustawione na 9. Również w stanie początkowym RandNum (psuedo-losowo generowana liczba) jest dzielony na cztery różne kontrole (po jednym dla każdego 3-bitowego koloru) i zapisywany w sygnałach check1, check2, check3, check4. Te kontrole są faktycznie porównywane z twoim przypuszczeniem, więc chociaż LFSR zawsze powoduje, że RandNum zmienia się w każdym cyklu, po opuszczeniu stanu początkowego kontrole pozostają takie same, umożliwiając zapisaną wartość do porównania twojej odpowiedzi. Oznacza to również, że za każdym razem, gdy maszyna jest resetowana, gracz ma nową wartość do odgadnięcia.

Stan SubmitAnswer (SubAns) zmienia aktywator odliczania (sygnał „zmiana”) na „1”. Jest to potrzebne później, aby śledzenie zakrętów działało. Następnie stan porównuje dane wejściowe odtwarzacza z przełączników z kontrolami wykonanymi w powyższym stanie. Sygnały rs1, rs2, rs3, rs4 i sygnały rc1, rc2, rc3, rc4 są typami całkowitymi, które w zależności od instrukcji If są ustawione na 1 lub 0. Sygnały rs oznaczają właściwy punkt, a rc właściwy kolor. Na przykład, jeśli zgadywanie koloru 1 jest równe check1 w RandNum, wtedy rs1 = 1, ponieważ oznacza to, że właściwy kolor jest we właściwym miejscu. Jeśli kolor 1 nie jest równy testowi1, ale jest równy jednemu z pozostałych sprawdzeń, to rc = 1. Odbywa się to dla każdego koloru i każdego sprawdzenia.

Stan wyświetlania (Dis) najpierw szuka aktywatora odliczania. Jeśli jest „1”, to małe odliczanie zmniejsza się o 1 (więc w pierwszej turze od 9 do 8 itd.). W przeciwnym razie kolej się nie zmieni. Niezależnie od tego włączone, wszystkie powyższe wartości rs są sumowane i przypisywane do sygnału RSpotCounter. Również wszystkie wartości rc są dodawane i przypisywane do RColorCounter. Na koniec Countdown przypisywana jest wartość smallcountdown. Sygnały RSpotCounter, RColorCounter i Countdown są konwertowane na 4-bitowe wektory std_logic_vectors poza procesem i przesyłane do submodułu wyświetlacza siedmiosegmentowego przez mapę portów. W ten sposób wyświetlacz pokazuje właściwe rzeczy, dopóki nie prześlesz nowej odpowiedzi.

Stan CheckEnd określa, czy wygrałeś, czy przegrałeś. Jeśli wygrałeś (wszystkie 4 kolory znajdują się we właściwym miejscu, inaczej znanym jako RSpotCounter = 4), wówczas w siedmioma segmentach wyświetlany jest symbol „GG” (technicznie pokazany jako 66), aby pokazać, że wygrałeś. Jeśli przegrałeś (Odliczanie osiągnęło 0), na wyświetlaczu pojawi się komunikat „GO” (technicznie pokazany jako 60) dla zakończenia gry. W obu przypadkach naciśnięcie przełącznika resetowania na włączone spowoduje powrót urządzenia do stanu początkowego, aby można było grać ponownie.

Kod źródłowy można znaleźć tutaj.

Krok 3: Wniosek

Ukończenie tego projektu nauczyło nas wiele o budowaniu bardziej skomplikowanych obwodów. Nasz pierwotny projekt nie był maszyną skończoną. Utrudniliśmy debugowanie i wielokrotnie przepisaliśmy kod przy użyciu różnych metod (w tym FSM). Zgodnie z sugestią instruktora trzymaliśmy się podejścia FSM i udało nam się ukończyć grę. Dowiedzieliśmy się, że projektowanie kodu w oparciu o sprzęt jest o wiele bardziej efektywne niż przy tradycyjnym podejściu programistycznym. Zmierzyliśmy się również z kilkoma wyzwaniami związanymi z wyświetlaczem siedmiosegmentowym. Sprawienie, by wyświetlał wiele liczb bez „ducha”, było trudne i musieliśmy użyć dzielnika zegara, aby to osiągnąć. Gdybyśmy mieli dalej rozwijać ten projekt, podłączylibyśmy do Basys3 kolorowe diody LED, aby użytkownik mógł widzieć kolory (jak w tradycyjnej grze), a nie numeryczną reprezentację kolorów. Ostatecznie zdobyliśmy większą wiedzę na temat złożonych projektów obwodów, rzeczywistych aplikacji i wyzwań związanych z używaniem sprzętu zamiast przeprowadzania symulacji w idealnych warunkach.

Zalecana: