İçindekiler:

VHDL'de Mastermind Oyunu: 3 Adım
VHDL'de Mastermind Oyunu: 3 Adım

Video: VHDL'de Mastermind Oyunu: 3 Adım

Video: VHDL'de Mastermind Oyunu: 3 Adım
Video: Javascript kullanarak MASTERMIND oyun yapımı 2024, Kasım
Anonim
VHDL'de Beyin Oyunu
VHDL'de Beyin Oyunu
VHDL'de Beyin Oyunu
VHDL'de Beyin Oyunu

Projemiz için Basys3 board üzerinde oynanacak VHDL formatındaki “Mastermind” oyununu oluşturduk. Mastermind, geleneksel olarak mandallar ve bir oyun tahtası ile oynanan bir kod kırma oyunudur. Birinci oyuncu, çeşitli renklerde mandalları, ikinci oyuncudan gizlenmiş olarak 4'lü sıraya yerleştirir. Daha sonra ikinci oyuncu, birinci oyuncunun görebileceği şekilde tahtaya mandalları yerleştiren 'x' sayıda tahmine sahiptir. Her tahminden sonra, ikinci oyuncuya 2 sayı bildirilir: mandallardan kaçının doğru renkte olduğu ve kaç mandalın satırda doğru konumda olduğu. Bu ipuçlarını kullanarak, ikinci oyuncu, birinci oyuncunun tahsis edilen sayıya yerleştirdiği pinlerin doğru sırasını tahmin etmelidir.

Uygulamamızda oyun tek kişiliktir. Program tarafından rastgele bir mandal kombinasyonu oluşturulur ve oyuncu doğru sırayı tahmin etmek için Basys3 kartını kullanmalıdır. İkili değerlerle temsil edilen dört “renk” vardır. 7 segmentli ekran üç değer gösterir: kalan dönüşler, doğru konumdaki pin sayısı ve yanlış pozisyonda doğru renkteki pin sayısı (bu değerler 9, 0 ve 0'dan başlar). Oyuncu, tahminine göre ikili değerleri seçmek için tahtadaki anahtarları kullanır ve tahminini göndermek için başka bir anahtarı çevirir. Doğruysa oyun biter ve 7 segmentli ekranda “GG” gösterilir. Değilse, dönüş sayacı 1 azalır ve oyuncu, kombinasyondaki pinlerin rengi veya konumuyla eşleşen pin sayısına göre geri bildirim alır. Oyuncunun sıraları doğru tahmin etmeden biterse, ekranda “GO” (oyunun bittiğini temsil eden) gösterilir. Oyuncu ayrıca istediği zaman yeniden başlamak için sıfırlama düğmesini çevirebilir.

Adım 1: Malzemeler

Malzemeler
Malzemeler
Malzemeler
Malzemeler
Malzemeler
Malzemeler

Tüm oyun tahtada oynanabildiğinden, gereken tek malzeme Basys3 Board, tahtaya bağlanmak için bir mikro USB kablosu ve kodlamak için kullanabileceğiniz bir bilgisayar/dizüstü bilgisayar!

2. Adım: Kod

kod
kod
kod
kod

Bu oyunun FPGA üzerinde çalışması için, onu yazmanın en basit yolu bir durum makinesi oluşturmaktır. Bir durum makinesine sahip olmak, oyunun gerçekten çalışması için gerekli olan sıralı ve etkileşimli deneyime izin verir. Her şeyin sorunsuz çalışması için durum makinesi, FPGA'nın dahili saat sinyalini temel alacak ve her şeyin senkronize olmasını sağlayacaktır. Ana modül, dört durumlu bir durum makinesidir; Başlangıç Durumu (Başlangıç), Gönderme Durumu (SubAns), Görüntü Durumu (Dis) ve CheckEndGame Durumu (CheckEnd). Durum makinesiyle birlikte, ana modülün iki alt modülü vardır, 4 basamaklı Yedi Segment Ekranı (kendi ClkDivider alt modülüne sahiptir) ve Rastgele Sayı Üreticisi (aslında bir psuedo-rastgele sayı üreteci). Ayrıca, insanların ne girdiklerini daha kolay görmelerinin bir yolu olarak, açıldığında her anahtarın üzerindeki LED'lerin yanmasını sağlayan temel bir işlem bloğu vardır. Resimdeki zihin haritasında kodun temel bir özeti görülebilir.

Bakılacak ilk bileşen, Rastgele Sayı Üreticisidir (rastgele). Donanımdan gerçek rastgele sayılar elde etmek teknik olarak mümkün olmadığından, en basit çözüm, rastgele genin aslında bir Lineer-feedback Shift Register (LFSR) olmasını sağlamaktı. LFSR'nin bir clk girişi ve bir "a" çıkışı (12 bitlik bir sayı) vardır. Her saat döngüsünde, "000000000001" ile başlayan yeni bir 12 bitlik sayı üretilir ve sonunda kendini tekrarlamadan önce 12 bitlik 1'ler ve 0'ların tüm kombinasyonlarından geçer. Her saat döngüsünde “a” çıkışı verilir, bu nedenle sürekli olarak çalışır. Clk, ana modülden Clk ile eşleştirilir ve "a", ana modüldeki RandNum sinyaline eşlenir.

İkinci alt modül, 4 basamaklı Yedi Segment Ekrandır. Bu, 4 basamaklı Yedi Segment Ekranı sergilemenin oldukça basit bir yoludur. Ekran, ana modülden Clk üzerinde ayarlanır, ancak bu alt modülün kendi ClkDivider alt modülü vardır. ClkDivider (1298 Hz'e ayarlı), Yedi Segment için saati hızlandırmak için kullanılır, böylece tüm basamaklar aynı anda açık görünür (çünkü aynı anda yalnızca bir basamak açık olabilir). "Dijit" değişkeni, ekrandaki noktalar arasında geçiş yapmak için kullanılır ve her bir basamakla birlikte, 0'dan 9'a kadar olan basamakları ve ayrıca hiçbir şeyi gösterme seçenekleriyle birlikte, 4 bitlik temel bir giriş ekranının koşulları gelir. Ekranda en soldaki rakam bu oyunda kullanılmadığı için sıfıra ayarlanmıştır.

Ana modül durum makinesinden oluşur. İşlemdeki dört durum Initial, SubAns, Dis ve CheckEnd'dir. İlk durumdayken, SubmitBtn (cevabınızı kontrol için göndermek için kullanılan anahtar) '1' olarak ayarlanmışsa, makine SubAns Durumuna geçer. Her zaman Rbtn (makineyi sıfırlamak için kullanılan anahtar) '1' olarak ayarlanır, ardından makine Başlangıç durumuna döner. SubAns Durumundayken, SubmitBtn = '0' tekrar olduğunda Dis Durumuna geçer. Dis Durumundayken, Geri Sayım = 0 (Tahmin etmek için sola dönüşler 0'a düşer) veya RSpotCount = 4 (oyuncu doğru noktalarda tüm doğru renkler olarak anlamına gelir) ise, makine CheckEnd Durumuna gider. Bunların hiçbiri olmazsa, SubmitBtn = '1' tekrar olduğunda, başka bir tahmine izin vermek için SubAns durumuna geri döner. CheckEnd Durumundayken, bu oyunun sonudur ve tek çıkış yolu sıfırlamaya basıp Başlangıç Durumuna geri döndürmek. Bu durum makine şemasında kolayca görülebilir. Davranışsal olarak İlk Durum, her şeyi başlangıç pozisyonuna geri başlatır. Geri Sayım (oynatıcının kaç tur kaldığını kaydeden sinyal) 9'a, RSpotCount (tahmin ettiğiniz renklerden kaçının doğru noktada olduğunu kaydeden sinyal) 0'a, RColorCount (kaç tane tur kaldığını kaydeden sinyal) tahmin ettiğiniz renkler doğru ama yanlış noktada) 0'a ve küçük geri sayım (sonunda Geri Sayım ile eşlenen ve daha sonraki durumlarda her dönüşte değişen sinyal) 9'a ayarlandı. Ayrıca, Başlangıç Durumunda RandNum (psuedo-rastgele oluşturulmuş sayı) dört farklı kontrole bölünür (her 3 bit renk için bir tane) ve kontrol1, kontrol2, kontrol3, kontrol4 sinyallerine kaydedilir. Bu kontroller, tahmininizin gerçekte karşılaştırıldığı şeydir, bu nedenle, LFSR her zaman RandNum'un her döngüde değişmesine neden olsa da, İlk durumdan çıktığınızda kontroller aynı kalır ve cevabınızı karşılaştırmak için kaydedilmiş bir değere izin verir. Bu aynı zamanda makine her sıfırlandığında oyuncunun tahmin etmesi gereken yeni bir değere sahip olduğu anlamına gelir.

Cevap Gönderme Durumu (SubAns), geri sayım etkinleştiriciyi ("değişim" sinyali) "1" olarak değiştirir. Bu, dönüş takibinin çalışması için daha sonra gereklidir. Bundan sonra durum, anahtarlardan gelen oyuncu girişlerini yukarıdaki durumda yapılan kontrollerle karşılaştırır. Sinyal rs1, rs2, rs3, rs4 ve rc1, rc2, rc3, rc4 sinyalleri, If ifadelerine bağlı olarak 1 veya 0 olarak ayarlanmış tamsayı türleridir. rs sinyali doğru nokta için ve rc doğru renk içindir. Örneğin, 1. renk oyuncunun tahmini RandNum'daki kontrol1'e eşitse, o zaman rs1 = 1 olur çünkü bu, doğru rengin doğru yerde olduğu anlamına gelir. Renk 1 kontrol1'e eşit değilse, ancak diğer kontrollerden birine eşitse, o zaman rc = 1 olur. Bu her renk ve her kontrol için yapılır.

Görüntü Durumu (Dis) önce geri sayım etkinleştiriciyi arar. Eğer '1' ise, o zaman küçük geri sayım 1'e iner (böylece ilk turda 9'dan 8'e vb. gider). Yoksa sıra değişmez. Bu etkinleştirmeden bağımsız olarak, yukarıdaki tüm rs değerleri toplanır ve RSpotCounter sinyaline atanır. Ayrıca tüm rc değerleri eklenir ve RColorCounter'a atanır. Son olarak Countdown'a küçük geri sayım değeri atanır. RSpotCounter, RColorCounter ve Countdown sinyallerinin tümü, işlemin dışında 4 bitlik std_logic_vektörlere dönüştürülür ve bir bağlantı noktası haritası aracılığıyla Yedi Segment görüntüleme alt modülüne gönderilir. Bu şekilde, siz yeni bir cevap gönderene kadar ekran doğru şeyleri gösterir.

CheckEnd Durumu, kazandığınız veya kaybettiğiniz içindir. Kazandıysanız (4 rengin tümü doğru yerdedir, aksi takdirde RSpotCounter = 4 olarak bilinir), kazandığınızı göstermek için Yedi Segmentte “GG” (teknik olarak 66 olarak gösterilir) görüntülenir. Kaybettiyseniz (Geri sayım 0'a ulaştı) Game Over için ekranda “GO” (teknik olarak 60 olarak gösterilir) görüntülenir. Her iki durumda da, sıfırlama anahtarının açık konuma getirilmesi, makineyi tekrar oynamak için Başlangıç durumuna geri getirecektir.

Kaynak Kodu burada bulunabilir.

3. Adım: Sonuç

Bu projeyi tamamlamak bize daha karmaşık devreler inşa etme konusunda çok şey öğretti. İlk tasarımımız sonlu durumlu bir makine değildi. Hata ayıklamayı zor bulduk ve farklı yöntemler (FSM dahil) kullanarak kodu birkaç kez yeniden yazdık. Eğitmenin önerisi üzerine FSM yaklaşımına bağlı kaldık ve oyunu bitirebildik. Kodu donanıma dayalı olarak tasarlamanın geleneksel programlama yaklaşımından çok daha etkili olduğunu öğrendik. Yedi segmentli ekranla ilgili çeşitli zorluklarla da karşılaştık. "Gölgelenme" olmadan birden çok sayıyı göstermesini sağlamak zordu ve bunu başarmak için bir saat bölücü kullanmamız gerekiyordu. Bu projeyi daha da geliştirecek olsaydık, kullanıcının renklerin sayısal temsilleri yerine renkleri (geleneksel oyundaki gibi) görebilmesi için renkli LED'leri Basys3'e bağlardık. Sonuç olarak, simülasyonları mükemmel koşullarda çalıştırmak yerine karmaşık devre tasarımı, gerçek yaşam uygulamaları ve donanım kullanmanın zorluklarını daha iyi anladık.

Önerilen: