Inhoudsopgave:
Video: Mastermind-spel in VHDL: 3 stappen
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:18
Voor ons project hebben we het spel "Mastermind" in VHDL gemaakt om op het Basys3-bord te spelen. Mastermind is een codebrekend spel dat traditioneel gespeeld wordt met pinnen en een spelbord. Speler één plaatst pinnen van verschillende kleuren in een rij van 4, verborgen voor speler twee. Speler twee heeft dan een 'x' aantal gissingen die pinnen op het bord in een rij plaatsen die zichtbaar zijn voor speler één. Na elke gok krijgt speler twee 2 getallen: hoeveel van de pinnen hebben de juiste kleur en hoeveel pinnen zitten op de juiste positie in de rij. Met behulp van die aanwijzingen moet speler twee de juiste reeks pinnen raden die speler één in het toegewezen aantal heeft geplaatst.
In onze implementatie is het spel single player. Het programma genereert een willekeurige combinatie van pinnen en de speler moet het Basys3-bord gebruiken om de juiste volgorde te raden. Er zijn vier "kleuren", weergegeven door binaire waarden. Het 7-segments display toont drie waarden: resterende beurten, aantal pinnen in de juiste positie en aantal pinnen met de juiste kleur in de verkeerde positie (deze waarden beginnen bij 9, 0 en 0). De speler gebruikt de schakelaars op het bord om de binaire waarden voor zijn/haar gok te selecteren, en zet een andere schakelaar om om de gok uit te voeren. Als ze correct zijn, eindigt het spel en toont het 7-segmentsdisplay "GG". Zo niet, dan wordt de beurtteller met 1 verlaagd en krijgt de speler feedback op basis van hoeveel pinnen in hun gok overeenkomen met de kleur of positie van de pinnen in de combinatie. Als de speler geen beurten meer heeft zonder correct te raden, toont het display "GO" (wat staat voor game over). De speler kan ook de reset-schakelaar omdraaien om op elk moment opnieuw te beginnen.
Stap 1: Materialen
Omdat het hele spel op het bord zelf kan worden gespeeld, zijn de enige materialen die nodig zijn het Basys3-bord, een micro-USB-kabel om op het bord aan te sluiten en een computer/laptop die je kunt gebruiken om te coderen!
Stap 2: De code
Om ervoor te zorgen dat dit spel op de FPGA werkt, is de eenvoudigste manier om het te schrijven het creëren van een staatsmachine. Het hebben van een state-machine zorgt voor de opeenvolgende en interactieve ervaring die nodig is om het spel echt te laten werken. Om alles soepel te laten verlopen, zal de statusmachine gebaseerd zijn op het interne kloksignaal van de FPGA, zodat alles synchroon loopt. De hoofdmodule is een toestandsmachine met vier toestanden; Initial State (Initial), SubmitAnswer State (SubAns), Display State (Dis) en de CheckEndGame State (CheckEnd). Samen met de statusmachine heeft de hoofdmodule twee submodules, een 4-cijferige Seven Segment Display (die zijn eigen ClkDivider-submodule heeft) en de Random Number Generator (eigenlijk een pseudo-willekeurige nummergenerator). Er is ook een basisprocesblok om de LED's boven elke schakelaar te laten branden wanneer ze worden ingeschakeld, zodat mensen gemakkelijker kunnen zien wat ze invoeren. Een basisoverzicht van de code is te zien in de afgebeelde mindmap.
Het eerste onderdeel om naar te kijken is de Random Number Generator (randomgen). Aangezien het technisch niet mogelijk is om echte willekeurige getallen te krijgen die door hardware worden gegenereerd, was de eenvoudigste oplossing om de randomgen in feite een Linear-feedback Shift Register (LFSR) te laten zijn. De LFSR heeft een ingang van clk en een uitgang "a" (een 12-bits getal). Elke klokcyclus wordt een nieuw 12-bits nummer gegenereerd vanaf "0000000000001", waarbij uiteindelijk alle combinaties van 12-bits van enen en nullen worden doorlopen voordat het zichzelf herhaalt. De uitgang "a" krijgt elke klokcyclus, dus deze loopt continu door. De clk wordt toegewezen aan de Clk van de hoofdmodule en "a" wordt toegewezen aan het signaal RandNum in de hoofdmodule.
De tweede submodule is het 4-cijferige Seven Segment Display. Dit is een vrij eenvoudige manier om een 4-cijferig display met zeven segmenten weer te geven. Het display is ingesteld op de Clk van de hoofdmodule, maar deze submodule heeft zijn eigen submodule van een ClkDivider. De ClkDivider (ingesteld op 1298 Hz) wordt gebruikt om de klok voor het Zeven Segment te versnellen, zodat alle cijfers tegelijkertijd lijken te staan (aangezien er maar één cijfer tegelijk aan kan staan). De variabele "cijfer" wordt gebruikt om door de punten op het scherm te bladeren, en met elk cijfer komen de voorwaarden van een standaard 4-bits invoerscherm, met opties om de cijfers 0 tot 9 en ook niets weer te geven. Het meest linkse cijfer op het scherm is ingesteld op niets omdat het niet in dit spel wordt gebruikt.
De hoofdmodule bestaat uit de staatsmachine. De vier statussen in het proces zijn Initial, SubAns, Dis en CheckEnd. In de beginstatus, als de SubmitBtn (schakelaar die wordt gebruikt om uw antwoord ter controle in te dienen) is ingesteld op '1', gaat de machine naar de SubAns-status. Telkens wanneer Rbtn (schakelaar die wordt gebruikt om de machine te resetten) is ingesteld op '1', keert de machine terug naar de beginstatus. Wanneer in de SubAns-status, wanneer de SubmitBtn = '0' opnieuw, gaat het verder naar de Dis-status. In de Dis-status, als de Countdown = 0 (De resterende beurten om te raden vallen op 0) of als de RSpotCount = 4 (wat betekent dat de speler alle juiste kleuren op de juiste plaatsen heeft), gaat de machine naar de CheckEnd-status. Als geen van beide optreedt, gaat het, wanneer SubmitBtn = '1' weer, terug naar de SubAns-status om nog een gok toe te staan. In de CheckEnd-status is dit het einde van het spel, en de enige uitweg is om op de reset te drukken en terug te keren naar de beginstatus. Dit is gemakkelijk te zien in het toestandsmachinediagram. Gedragsmatig initialiseert de Initial State alles terug naar de startpositie. De Countdown (signaal dat opslaat hoeveel beurten de speler nog heeft) is ingesteld op 9, RSpotCount (signaal dat opslaat hoeveel van de door jou geraden kleuren op de juiste plek zitten) is ingesteld op 0, RColorCount (signaal dat opslaat hoeveel van de kleuren die je geraden hebt zijn goed, maar op de verkeerde plek) is ingesteld op 0, en het kleine aftellen (signaal dat uiteindelijk wordt toegewezen aan Countdown, dat elke beurt in latere staten daadwerkelijk verandert) is ingesteld op 9. Ook is in de begintoestand het RandNum (psuedo-willekeurig gegenereerd getal) wordt opgesplitst in vier verschillende controles (één voor elke 3-bits kleur) en opgeslagen in de signalen check1, check2, check3, check4. Deze controles zijn waar uw gok eigenlijk mee wordt vergeleken, dus hoewel de LFSR er altijd voor zorgt dat RandNum elke cyclus verandert, blijven de controles hetzelfde zodra u de beginstatus verlaat, waardoor een opgeslagen waarde uw antwoord kan vergelijken. Dit betekent ook dat elke keer dat de machine wordt gereset, de speler een nieuwe waarde kan raden.
De SubmitAnswer State (SubAns) verandert de countdown-enabler (signaal "verandering") in '1'. Dit is later nodig om het volgen van de beurt te laten werken. Daarna vergelijkt de status de spelerinvoer van de schakelaars met de controles die in de bovenstaande status zijn uitgevoerd. Signaal rs1, rs2, rs3, rs4 en signalen rc1, rc2, rc3, rc4 zijn integer-types die, afhankelijk van de If-statements, op 1 of 0 worden gezet. Het signaal rs is voor de juiste plek en rc voor de juiste kleur. Als de gok van de speler van kleur 1 bijvoorbeeld gelijk is aan de check1 van het RandNum, dan is rs1 = 1 omdat dat betekent dat de juiste kleur op de juiste plek staat. Als kleur 1 niet gelijk is aan check1, maar wel aan een van de andere checks, dan rc = 1. Dit wordt gedaan voor elke kleur en elke check.
De Display State (Dis) zoekt eerst naar de countdown-enabler. Als het '1' is, gaat smallcountdown 1 naar beneden (dus bij de eerste beurt gaat het van 9 naar 8 enz.). Anders verandert de beurt niet. Ongeacht die inschakeling, worden alle rs-waarden van boven opgeteld en toegewezen aan RSpotCounter-signaal. Ook worden alle rc-waarden toegevoegd en toegewezen aan de RColorCounter. Ten slotte krijgt Countdown de waarde smallcountdown toegewezen. De signalen RSpotCounter, RColorCounter en Countdown worden allemaal buiten het proces geconverteerd naar 4-bit std_logic_vectors en via een poortkaart naar de zevensegmentendisplay-submodule gepusht. Zo laat het display de juiste dingen zien totdat je een nieuw antwoord instuurt.
De CheckEnd-status geeft aan of je hebt gewonnen of verloren. Als je hebt gewonnen (alle 4 de kleuren staan op de juiste plek, ook wel bekend als RSpotCounter = 4), dan wordt "GG" (technisch weergegeven als 66) weergegeven op het Zeven Segment om aan te geven dat je hebt gewonnen. Als je hebt verloren (Countdown heeft 0 bereikt), wordt "GO" (technisch weergegeven als 60) weergegeven op het display voor Game Over. Met beide uitkomsten, zal het indrukken van de reset-schakelaar op aan de machine terugbrengen naar de beginstatus om opnieuw te spelen.
Broncode is hier te vinden.
Stap 3: Conclusie
Het voltooien van dit project heeft ons veel geleerd over het bouwen van meer gecompliceerde circuits. Ons oorspronkelijke ontwerp was geen eindige-toestandsmachine. We vonden het moeilijk om fouten te debuggen en hebben de code een aantal keren herschreven met verschillende methoden (waaronder een FSM). Op voorstel van de instructeur bleven we bij de FSM-aanpak en konden we het spel afmaken. We hebben geleerd dat het veel effectiever is om de code te ontwerpen op basis van de hardware dan met een traditionele programmeeraanpak. We werden ook geconfronteerd met verschillende uitdagingen met betrekking tot het display met zeven segmenten. Het was moeilijk om meerdere nummers weer te geven zonder "ghosting" en we moesten een klokverdeler gebruiken om dit te bereiken. Als we dit project verder zouden ontwikkelen, zouden we gekleurde LED's aansluiten op de Basys3 zodat de gebruiker kleuren kan zien (zoals in het traditionele spel) in plaats van numerieke weergaven van kleuren. Uiteindelijk hebben we meer inzicht gekregen in het ontwerp van complexe circuits, toepassingen in het echte leven en de uitdagingen van het gebruik van hardware in plaats van het uitvoeren van simulaties met perfecte omstandigheden.
Aanbevolen:
Mastermind Star Wars met Arduino MEGA - Ajarnpa
Mastermind Star Wars met Arduino MEGA: dit zijn ongunstige tijden voor rebellie. Hoewel de Death Star is vernietigd, gebruiken de keizerlijke troepen gratis hardware en Arduino als geheim wapen. Dat is het voordeel van gratis technologieën, iedereen (goed of slecht) kan ze gebruiken. Ik
PID-regelaar VHDL: 10 stappen
PID-controller VHDL: Dit project was mijn laatste project om mijn Honours Bachelor Degree van het Cork Institute of Technology af te ronden. Deze zelfstudie is opgedeeld in twee secties, de eerste behandelt het hoofdgedeelte van de PID-code, het hoofddoel van het project en de sec
Ontwerp van UART in VHDL: 5 stappen
Ontwerp van UART in VHDL: UART staat voor Universal Asynchronous Receiver Transmitter. Het is het meest populaire en eenvoudigste seriële communicatieprotocol. In deze instructable leert u hoe u een UART-module in VHDL ontwerpt
Videoverwerking met VHDL en een Zybo: 10 stappen
Videoverwerking met VHDL en een Zybo: FPGA's zijn sneller te verwerken dan CPU's, omdat ze veel parallel kunnen rekenen. Opmerking: dit project is nog in aanbouw en zal worden verbeterd (zodra ik tijd heb). Ondertussen reis ik de wereld rond
Mastermind met een 8x8 RGB LED-matrix - Ajarnpa
Mastermind Met een 8x8 RGB LED Matrix: Benodigde onderdelen: Basys3 FPGA 8x8 RGB LED Matrix by GEEETECH9V batterij2N3904 transistors (x32)1K weerstand (x32)100 Ohm weerstand (x1)50 Ohm weerstand (x1)De LED Matrix is een gemeenschappelijke anodematrix met 32 totaal pinnen. De gemeenschappelijke anode betekent dat elke rij