Πίνακας περιεχομένων:

Mastermind Game σε VHDL: 3 βήματα
Mastermind Game σε VHDL: 3 βήματα

Βίντεο: Mastermind Game σε VHDL: 3 βήματα

Βίντεο: Mastermind Game σε VHDL: 3 βήματα
Βίντεο: 50-50 nikiforos - eisai o mastermind 2024, Ιούλιος
Anonim
Mastermind Game σε VHDL
Mastermind Game σε VHDL
Mastermind Game σε VHDL
Mastermind Game σε VHDL

Για το έργο μας, δημιουργήσαμε το παιχνίδι "Mastermind" σε VHDL που θα παιχτεί στον πίνακα Basys3. Το Mastermind είναι ένα παιχνίδι που σπάει τον κώδικα και παραδοσιακά παίζεται με μανταλάκια και έναν πίνακα παιχνιδιών. Ο παίκτης 1 τοποθετεί μανταλάκια διαφόρων χρωμάτων σε μια σειρά 4, κρυμμένα από τον παίκτη δύο. Στη συνέχεια, ο παίκτης δύο έχει «x» έναν αριθμό εικασιών που τοποθετούν μανταλάκια στον πίνακα σε μια σειρά ορατή στον παίκτη ένα. Μετά από κάθε εικασία, ο παίκτης δύο ενημερώνεται για 2 αριθμούς: πόσα από τα μανταλάκια έχουν το σωστό χρώμα και πόσα μανταλάκια βρίσκονται στη σωστή θέση στη σειρά. Χρησιμοποιώντας αυτές τις ενδείξεις, ο παίκτης δύο πρέπει να μαντέψει τη σωστή ακολουθία καρφιτσών που ο παίκτης πρώτος τοποθέτησε στην εικασία αριθμού που παραχώρησε.

Στην εφαρμογή μας, το παιχνίδι είναι single player. Ένας τυχαίος συνδυασμός καρφιών δημιουργείται από το πρόγραμμα και ο παίκτης πρέπει να χρησιμοποιήσει τον πίνακα Basys3 για να μαντέψει τη σωστή ακολουθία. Υπάρχουν τέσσερα "χρώματα", που αντιπροσωπεύονται από δυαδικές τιμές. Η οθόνη των 7 τμημάτων εμφανίζει τρεις τιμές: τις υπόλοιπες στροφές, τον αριθμό των ακίδων στη σωστή θέση και τον αριθμό των ακίδων που έχουν το σωστό χρώμα σε λάθος θέση (αυτές οι τιμές ξεκινούν από 9, 0 και 0). Ο παίκτης χρησιμοποιεί τους διακόπτες στον πίνακα για να επιλέξει τις δυαδικές τιμές για την εικασία του/της και γυρίζει έναν άλλο διακόπτη για να υποβάλει την εικασία. Εάν είναι σωστά, το παιχνίδι τελειώνει και στην οθόνη 7 τμημάτων εμφανίζεται η ένδειξη "GG". Εάν όχι, ο μετρητής στροφών μειώνεται κατά 1 και ο παίκτης λαμβάνει ανατροφοδότηση με βάση το πόσες καρφίτσες στην εικασία τους ταιριάζουν με το χρώμα ή τη θέση των ακίδων στο συνδυασμό. Εάν ο παίκτης τελειώσει με τις στροφές χωρίς να μαντέψει σωστά, στην οθόνη εμφανίζεται η ένδειξη "GO" (που αντιπροσωπεύει το παιχνίδι τελείωσε). Η συσκευή αναπαραγωγής μπορεί επίσης να αναστρέψει τον διακόπτη επαναφοράς για να ξεκινήσει από την αρχή ανά πάσα στιγμή.

Βήμα 1: Υλικά

Υλικά
Υλικά
Υλικά
Υλικά
Υλικά
Υλικά

Δεδομένου ότι ολόκληρο το παιχνίδι μπορεί να παιχτεί στον ίδιο τον πίνακα, τα μόνα υλικά που χρειάζονται είναι ο πίνακας Basys3, ένα καλώδιο micro USB για σύνδεση στον πίνακα και ένας υπολογιστής/φορητός υπολογιστής που μπορείτε να χρησιμοποιήσετε για κωδικοποίηση!

Βήμα 2: Ο κώδικας

Ο κώδικας
Ο κώδικας
Ο κώδικας
Ο κώδικας

Για να λειτουργήσει αυτό το παιχνίδι στο FPGA, ο απλούστερος τρόπος για να το γράψετε θα ήταν να δημιουργήσετε μια κρατική μηχανή. Η κατοχή μιας μηχανής κατάστασης επιτρέπει τη διαδοχική και διαδραστική εμπειρία που είναι απαραίτητη για να λειτουργήσει πραγματικά το παιχνίδι. Για να λειτουργούν όλα ομαλά, το μηχάνημα κατάστασης θα βασίζεται στο εσωτερικό σήμα ρολογιού του FPGA, διασφαλίζοντας ότι όλα είναι συγχρονισμένα. Η κύρια μονάδα είναι μια μηχανή κατάστασης με τέσσερις καταστάσεις. Αρχική κατάσταση (Αρχική), Κατάσταση υποβολής απάντησης (SubAns), Κατάσταση εμφάνισης (Dis) και κατάσταση κατάστασης CheckEndGame (CheckEnd). Μαζί με το μηχάνημα κατάστασης, η κύρια μονάδα διαθέτει δύο υπομονάδες, μια τετραψήφια οθόνη επτά τμημάτων (η οποία έχει τη δική της υπομονάδα ClkDivider) και τη γεννήτρια τυχαίων αριθμών (στην πραγματικότητα μια ψευδο-τυχαία γεννήτρια αριθμών). Υπάρχει επίσης ένα βασικό μπλοκ διαδικασίας για να ανάβουν οι λυχνίες LED πάνω από κάθε διακόπτη όταν είναι ενεργοποιημένοι, ώστε να βλέπουν οι άνθρωποι αυτό που εισάγουν ευκολότερα. Μια βασική επισκόπηση του κώδικα μπορεί να εμφανιστεί στον εικονιζόμενο χάρτη.

Το πρώτο συστατικό που πρέπει να εξετάσουμε είναι η γεννήτρια τυχαίων αριθμών (τυχαίο). Δεδομένου ότι δεν είναι τεχνικά δυνατό να ληφθούν αληθινοί τυχαίοι αριθμοί που παράγονται από υλικό, η απλούστερη λύση ήταν να υπάρξει το τυχαίο παράγοντα να είναι στην πραγματικότητα ένα Γραμμείο Μετατόπισης Γραμμικής Ανατροφοδότησης (LFSR). Το LFSR έχει είσοδο clk και έξοδο "a" (αριθμός 12-bit). Κάθε κύκλος ρολογιού, δημιουργείται ένας νέος αριθμός 12-bit ξεκινώντας από το "000000000001", περνώντας τελικά από όλους τους συνδυασμούς των 12-bit των 1 και 0 πριν επαναληφθεί. Η έξοδος "a" δίνεται σε κάθε κύκλο ρολογιού, οπότε συνεχίζει να λειτουργεί καθ 'όλη τη διάρκεια. Το clk αντιστοιχίζεται στο Clk από την κύρια μονάδα και το "a" αντιστοιχεί στο σήμα RandNum στην κύρια μονάδα.

Η δεύτερη υπομονάδα είναι η τετραψήφια οθόνη επτά τμημάτων. Αυτός είναι ένας αρκετά απλός τρόπος προβολής μιας τετραψήφιας οθόνης επτά τμημάτων. Η οθόνη είναι ρυθμισμένη στο Clk από την κύρια μονάδα, αλλά αυτό το υπομονάριο έχει τη δική του υπομονάδα ενός ClkDivider. Το ClkDivider (ρυθμισμένο σε 1298 Hz) χρησιμοποιείται για να επιταχύνει το ρολόι για το Seven Segment, έτσι ώστε όλα τα ψηφία να εμφανίζονται ταυτόχρονα (αφού μόνο ένα ψηφίο μπορεί να είναι ενεργοποιημένο ταυτόχρονα). Η μεταβλητή "ψηφίο" χρησιμοποιείται για να κυκλώσει τα σημεία της οθόνης και με κάθε ψηφίο έρχονται οι συνθήκες μιας βασικής οθόνης εισόδου 4-bit, με επιλογές για την εμφάνιση των ψηφίων 0 έως 9 και επίσης τίποτα. Το πιο απομακρυσμένο αριστερό ψηφίο στην οθόνη έχει οριστεί σε τίποτα, καθώς δεν χρησιμοποιείται σε αυτό το παιχνίδι.

Η κύρια μονάδα αποτελείται από το μηχάνημα κατάστασης. Οι τέσσερις καταστάσεις στη διαδικασία είναι η Αρχική, η SubAns, η Dis και η CheckEnd. Όταν βρίσκεται στην αρχική κατάσταση, εάν το SubmitBtn (ο διακόπτης που χρησιμοποιείται για την υποβολή της απάντησής σας για έλεγχο) έχει οριστεί σε "1", τότε το μηχάνημα μετακινείται στην κατάσταση SubAns. Το Anytime Rbtn (διακόπτης που χρησιμοποιείται για την επαναφορά του μηχανήματος) έχει οριστεί σε "1" και στη συνέχεια το μηχάνημα επιστρέφει στην αρχική κατάσταση. Όταν βρίσκεται στην κατάσταση SubAns, όταν το SubmitBtn = ‘0’ ξανά, μεταβαίνει στην κατάσταση Dis. Όταν βρίσκεστε στην κατάσταση κατάστασης, εάν η αντίστροφη μέτρηση = 0 (οι στροφές προς τα αριστερά για να μαντέψετε πέσει στο 0) ή εάν το RSpotCount = 4 (που σημαίνει ότι ο παίκτης έχει όλα τα σωστά χρώματα στα σωστά σημεία), το μηχάνημα πηγαίνει στην κατάσταση ελέγχου τερματισμού. Εάν δεν συμβεί κανένα από αυτά, τότε όταν το SubmitBtn = ‘1’ ξανά, επιστρέφει στην κατάσταση SubAns για να επιτρέψει μια άλλη εικασία. Όταν βρίσκεστε στο CheckEnd State, αυτό είναι το τέλος του παιχνιδιού και η μόνη διέξοδος είναι να κάνετε επαναφορά, επιστρέφοντάς το στην αρχική κατάσταση. Αυτό είναι εύκολο να προβληθεί στο διάγραμμα μηχανής κατάστασης. Συμπεριφορικά, η αρχική κατάσταση αρχίζει τα πάντα πίσω στην αρχική θέση. Η αντίστροφη μέτρηση (σήμα που εξοικονομεί πόσες στροφές έχει αφήσει ο παίκτης) έχει οριστεί σε 9, το RSpotCount (σήμα που αποθηκεύει πόσα από τα χρώματα που υποθέσατε ότι βρίσκονται στο σωστό σημείο) έχει οριστεί σε 0, RColorCount (σήμα που εξοικονομεί πόσες τα χρώματα που μαντέψατε είναι σωστά αλλά σε λάθος σημείο) έχει οριστεί σε 0 και το μικρό αντίστροφο χτύπημα (σήμα που τελικά αντιστοιχίζεται στην αντίστροφη μέτρηση που στην πραγματικότητα αλλάζει κάθε στροφή σε μεταγενέστερες καταστάσεις) έχει οριστεί σε 9. Επίσης, στην αρχική κατάσταση το RandNum (psuedo-random generated number) χωρίζεται σε τέσσερις διαφορετικούς ελέγχους (ένας για κάθε χρώμα 3-bit) και αποθηκεύεται στα σήματα check1, check2, check3, check4. Αυτοί οι έλεγχοι συγκρίνονται με την εικασία σας, οπότε παρόλο που το LFSR προκαλεί πάντα την αλλαγή του RandNum σε κάθε κύκλο, μόλις αφήσετε την αρχική κατάσταση, οι έλεγχοι παραμένουν οι ίδιοι, επιτρέποντας σε μια αποθηκευμένη τιμή να συγκρίνει την απάντησή σας με αυτήν. Αυτό σημαίνει επίσης ότι κάθε φορά που γίνεται επαναφορά του μηχανήματος, η συσκευή αναπαραγωγής έχει μια νέα τιμή για να μαντέψει.

Η κατάσταση SubmitAnswer (SubAns) αλλάζει τον ενεργοποιητή αντίστροφης μέτρησης (σήμα "αλλαγή") σε "1". Αυτό απαιτείται αργότερα για να λειτουργήσει η παρακολούθηση στροφών. Μετά από αυτό, η κατάσταση συγκρίνει τις εισόδους του παίκτη από τους διακόπτες με τους ελέγχους που έγιναν στην παραπάνω κατάσταση. Τα σήματα rs1, rs2, rs3, rs4 και τα σήματα rc1, rc2, rc3, rc4 είναι ακέραιοι τύποι που ανάλογα με τις προτάσεις If είναι ρυθμισμένες είτε σε 1 είτε στο 0. Το σήμα rs είναι για σωστό σημείο και rc για σωστό χρώμα. Για παράδειγμα, εάν η εικασία του παίκτη για το χρώμα 1 είναι ίση με τον έλεγχο1 του RandNum, τότε rs1 = 1 αφού αυτό σημαίνει ότι το σωστό χρώμα βρίσκεται στο σωστό σημείο. Εάν το χρώμα 1 δεν ισούται με το check1, αλλά ισούται με έναν από τους άλλους ελέγχους, τότε rc = 1. Αυτό γίνεται για κάθε χρώμα και κάθε έλεγχο.

Η κατάσταση εμφάνισης (Dis) αναζητά πρώτα τον ενεργοποιητή αντίστροφης μέτρησης. Εάν είναι "1", τότε το μικρό αντίστροφο κατέβει 1 (έτσι στην πρώτη στροφή πηγαίνει από 9 σε 8 κ.λπ.). Διαφορετικά η στροφή δεν αλλάζει. Ανεξάρτητα από αυτήν την ενεργοποίηση, όλες οι τιμές rs από τα παραπάνω προστίθενται και εκχωρούνται στο σήμα RSpotCounter. Επίσης όλες οι τιμές rc προστίθενται και εκχωρούνται στο RColorCounter. Τέλος, στην Αντίστροφη μέτρηση αποδίδεται η τιμή του μικρού μετρητή. Τα σήματα RSpotCounter, RColorCounter και Countdown μετατρέπονται όλα σε 4-bit std_logic_vectors εκτός της διαδικασίας και ωθούνται στην υπομονάδα εμφάνισης Seven Segment μέσω ενός χάρτη θύρας. Με αυτόν τον τρόπο, η οθόνη εμφανίζει τα σωστά πράγματα μέχρι να υποβάλετε μια νέα απάντηση.

Το CheckEnd State είναι για το αν έχετε κερδίσει ή χάσει. Εάν έχετε κερδίσει (και τα 4 χρώματα βρίσκονται στο σωστό σημείο, αλλιώς γνωστό ως RSpotCounter = 4), τότε το "GG" (που εμφανίζεται τεχνικά ως 66) εμφανίζεται στο Επτά Τμήμα για να δείξει ότι έχετε κερδίσει. Αν χάσατε (Η αντίστροφη μέτρηση έχει φτάσει το 0) τότε στην οθόνη του Game Over εμφανίζεται η ένδειξη "GO" (εμφανίζεται τεχνικά ως 60). Με οποιοδήποτε από τα δύο αποτελέσματα, ενεργοποιώντας το διακόπτη επαναφοράς, το μηχάνημα θα επιστρέψει στην αρχική κατάσταση για να παίξει ξανά.

Μπορείτε να βρείτε τον πηγαίο κώδικα εδώ.

Βήμα 3: Συμπέρασμα

Η ολοκλήρωση αυτού του έργου μας δίδαξε πολλά για την κατασκευή πιο περίπλοκων κυκλωμάτων. Ο αρχικός μας σχεδιασμός δεν ήταν μηχανή πεπερασμένης κατάστασης. Δυσκολευτήκαμε να εντοπίσουμε σφάλματα και να ξαναγράψουμε τον κώδικα πολλές φορές χρησιμοποιώντας διαφορετικές μεθόδους (συμπεριλαμβανομένου ενός FSM). Κατόπιν πρότασης του εκπαιδευτή, κολλήσαμε με την προσέγγιση FSM και μπορέσαμε να τελειώσουμε το παιχνίδι. Μάθαμε ότι είναι πολύ πιο αποτελεσματικό να σχεδιάζουμε τον κώδικα με βάση το υλικό παρά με μια παραδοσιακή προσέγγιση προγραμματισμού. Αντιμετωπίσαμε επίσης αρκετές προκλήσεις που σχετίζονται με την οθόνη των επτά τμημάτων. Difficultταν δύσκολη η εμφάνιση πολλών αριθμών χωρίς "φαντάσματα" και έπρεπε να χρησιμοποιήσουμε ένα διαχωριστικό ρολογιού για να το πετύχουμε. Αν θέλαμε να αναπτύξουμε περαιτέρω αυτό το έργο, θα συνδέαμε έγχρωμα LED με το Basys3, ώστε ο χρήστης να μπορεί να βλέπει χρώματα (όπως στο παραδοσιακό παιχνίδι) και όχι αριθμητικές αναπαραστάσεις χρωμάτων. Τελικά, αποκτήσαμε μεγαλύτερη κατανόηση του σύνθετου σχεδιασμού κυκλωμάτων, των εφαρμογών της πραγματικής ζωής και των προκλήσεων της χρήσης υλικού και όχι της εκτέλεσης προσομοιώσεων με τέλειες συνθήκες.

Συνιστάται: