Inhoudsopgave:

VHDL Basys3: Connect 4 Game - Ajarnpa
VHDL Basys3: Connect 4 Game - Ajarnpa

Video: VHDL Basys3: Connect 4 Game - Ajarnpa

Video: VHDL Basys3: Connect 4 Game - Ajarnpa
Video: 4.FPGA FOR BEGINNERS- Combining logic gates in VHDL (DIGILENT Basys3) 2024, November
Anonim
VHDL Basys3: Connect 4 Game
VHDL Basys3: Connect 4 Game

Invoering:

Dit is een Connect 4 Digital Logic Game ontworpen in VHDL met behulp van de Vivado-software en geprogrammeerd op het Basys3-bord. De constructie en het ontwerp van dit project is intermediair, maar nieuwkomers kunnen de stappen kopiëren en het digitale spel bouwen.

De game werkt als de Connect 4-game. Spelers kunnen hun cursor over het scherm bewegen met de linker- en rechterknoppen op het bord. Door op de middelste knop op het bord te drukken, plaatst de speler zijn marker op die kolom en is het de beurt aan de volgende speler. Zodra een speler wint, kan het spel worden gereset door op de omhoog-knop op het bord te drukken.

Stap 1: Snelle details en materialen

Snelle technische details:

  • Maakt gebruik van drie sets van de PMOD-aansluitingen op het bord (JA, JB, JC)

    • 8 pinnen (exclusief Vcc- en GND-pinnen) gebruikt voor elke PMOD-connector
    • JA - Controle van rijen
    • JB - Controle van groene kolommen
    • JC - Controle van rode kolommen
  • Schermklok werkt op 960Hz

    Er branden slechts 8 LED's tegelijk. Het scherm wordt vernieuwd met een kloksnelheid die hoog genoeg is om de illusie te wekken dat er op een bepaald moment meer dan 8 LED's branden

  • Knopklok werkt op 5Hz; Optioneel kan worden afgesteld door VHDL-code te bewerken.
  • Interne weerstand van Darlington Arrays is voldoende om doorbranden van LED's te voorkomen

Het spel is gebouwd met behulp van de volgende componenten en hulpmiddelen:

  • (1) Basys3-bord
  • (2) LED Matrix Bi-color 8x5:
  • (2) ULN2803 - Darlington-transistorarrays - Gegevensblad
  • Spoelen van draad
  • Doorverbindingsdraden
  • Draadstripper
  • Breadboards (groot vierkant zou genoeg moeten zijn)
  • Multimeter en voeding (probleemoplossing)

Stap 2: De hardware aansluiten

De hardware aansluiten
De hardware aansluiten
De hardware aansluiten
De hardware aansluiten

Richtlijnen:

De bedrading van het project kan extreem ingewikkeld zijn, neem de tijd en controleer of alle verbindingen één voor één correct zijn.

Het project omvat het gebruik van twee LED-schermen, maar worden gecombineerd tot één groot scherm. Dit kan worden bereikt door alle rijen op hetzelfde punt aan te sluiten. Omdat elk scherm tweekleurig is, moeten de rode en groene rijen van het ene scherm ook worden gekoppeld aan de rode en groene rijen van het andere scherm. Door dit te doen, kunnen we alle rijen besturen met slechts 8 pinnen. De andere 16 pinnen worden gebruikt om de weergavekolommen te bedienen. De 8 pinnen voor de kunnen rechtstreeks via startkabels worden aangesloten op de pmod-connectoren. Pmod aansluitingen gaan eerst naar de ingang van de ULN2083A en de uitgang van de ULN2083A wordt direct aangesloten op de kolom op het scherm. Omdat het ontwerp een 8x8 is, zullen sommige kolommen fysiek niet worden aangesloten.

  • JA: Rijverbindingen: Rij 1 tot JA:1 tot Rij 8 voor JA:10.
  • JA: Rode Kolom aansluitingen:
  • JC: Groene kolomverbindingen

Raadpleeg de geplaatste afbeeldingen om te weten welke pinnen overeenkomen met welke rijen/kolommen.

Opmerking: de transistors hebben ingebouwde weerstanden, zodat de LED's geen extra weerstand nodig hebben om in serie te worden aangesloten.

Stap 3: Technische uitleg: Scherm

Het scherm werkt op de persistentie van het gezichtsvermogen. Het scherm ververst zo snel, dat het menselijk oog niet zichtbaar kan detecteren dat sommige LED's snel aan en uit gaan. Door de weergaveklok te vertragen, kunt u het knipperen zelfs opmerken.

Het display schakelt alle acht rijen in volgens de gegevens die voor die rijen zijn opgeslagen, en het display schakelt één kolom in. Daarna gaat het snel over naar de volgende gegevensinvoer voor de acht rijen en schakelt de volgende kolom in - terwijl alle andere kolommen uitgeschakeld zijn. Dit proces gaat door met een kloksnelheid die hoog genoeg is om het flikkeren van de LED onmerkbaar te maken.

Gegevensopslag voor het display wordt onmiddellijk na de architectuur in het VHDL-bestand op de volgende manier geïnitialiseerd:

signaal RedA, RedB, RedC, RedD, RedE, RedF, RedG, RedH: std_logic_vector (7 tot 0):= "00000000";

signaal GroenA, GroenB, GroenC, GroenD, GroenE, GroenF, GroenG, GroenH: std_logic_vector (7 tot 0):= "00000000"; -- Rijgegevens afhankelijk van kolom: GROEN

Hierna volgt een klein fragment van het proces dat de LED-displaymatrix bestuurt.

-- Proces dat LED-display bestuurt matrixdisplay: proces (ColCLK) -- 0 - 16 om zowel de 8X8 RED als 8x8 GREEn matrixvariabele te verversen RowCount: integer bereik 0 tot 16:= 0; begin if (rising_edge(ColCLK)) dan if (RowCount = 0) then DORow <= RedA; -- Rijgegevens voor overeenkomstige kolom DOCol <= "1000000000000000"; -- Column Trigger -- Herhaal deze code voor helemaal naar beneden tot "000000000000001" -- Wijzig in RedB, RedC…GreenA, GreenB…GreenH

Aan het einde van de GreenH, vlak voordat het proces eindigt, wordt dit fragment toegevoegd om de RowCount weer op nul te zetten.

if (RowCount = 15) then -- Herstart refresh van kolom A RowCount:= 0; anders RowCount:= RowCount + 1; -- Shift door kolommen end if;

Nu, om de klok uit te leggen die in de gevoeligheidslijst van het weergaveproces staat. Het Basys3-bord heeft een interne klok die werkt op 100 MHz. Voor onze doeleinden is dit een te snelle klok, dus we zullen deze klok moeten verdelen in een 960Hz-klok met behulp van het volgende proces.

-- Klokproces dat werkt op 960HzCLKDivider: proces (CLK) variabele clkcount: geheel getal bereik 0 tot 52083:= 0; begin if (rising_edge(CLK)) dan clkcount:= clkcount + 1; if (clkcount = 52083) dan ColCLK <= niet(ColCLK); clkcount:= 0; stop als; stop als; eindproces;

Stap 4: Technische uitleg: de weergegeven informatie wijzigen

Technische uitleg: de weergegeven informatie wijzigen
Technische uitleg: de weergegeven informatie wijzigen

In de VHDL-code wordt de informatie of gegevens die op het scherm worden weergegeven, bestuurd door het cursorproces, dat een andere klok in zijn gevoeligheidslijst heeft. Deze code heette BtnCLK, een klok die is ontworpen om het loslaten van de knoppen te minimaliseren wanneer ze worden ingedrukt. Dit is opgenomen zodat als een knop wordt ingedrukt, de cursor op de bovenste rij niet erg snel over de kolommen beweegt.

-- Klokproces werkend op 5 Hz. ButtonCLK: proces (CLK) variabele btnclkcount: integer bereik 0 tot 10000001:= 0; begin if (rising_edge(CLK)) then if (btnclkcount = 10000000) then btnclkcount:= 0; BtnCLK <= niet(BtnCLK); anders btnclkcount:= btnclkcount + 1; stop als; stop als; eindproces;

Met de BtnCLK-signaaluitgang van dit proces kunnen we nu het cursorproces uitleggen. Het cursorproces heeft alleen BtnCLK in zijn gevoeligheidslijst, maar in het codeblok wordt de status van de knoppen gecontroleerd en hierdoor zullen de gegevens voor de RedA, RedB…GreenH veranderen. Hier is een fragment van de cursorcode, die het resetblok en het blok voor de eerste kolom bevat.

cursor: proces (BtnCLK) variabele OCursorCol: STD_LOGIC_VECTOR (2 tot 0):= "000"; -- OCursorCol houdt de vorige kolomvariabele NCursorCol bij: STD_LOGIC_VECTOR (2 tot 0):= "000"; -- NCursorCol stelt nieuwe cursorkolom in --RESET-voorwaarde (UP-knop) --Het bord wordt gewist om het spel opnieuw te starten als (rising_edge(BtnCLK)) en vervolgens als (RST = '1') en dan RedA <= "00000000"; RoodB <= "00000000"; RedC <= "00000000"; RoodD <= "00000000"; RoodE <= "00000000"; RoodF <= "00000000"; RoodG <= "00000000"; RoodH <= "00000000"; GroenA <= "00000000"; GroenB <= "00000000"; GroenC <= "00000000"; GroenD <= "00000000"; GroenE <= "00000000"; GroenF <= "00000000"; GroenG <= "00000000"; GreenH if (Lbtn = '1') dan NCursorCol:= "111"; -- Kolom H elsif (Rbtn = '1') dan NCursorCol:= "001"; -- Kolom B elsif (Cbtn = '1') dan NCursorCol:= OCursorCol; -- Kolom blijft hetzelfde NTurnState <= not(TurnState); -- Activeert de beurt van de volgende speler -- Controleert de huidige kolom van onder naar boven en zet de eerste LED aan die niet brandt. Kleur hangt af van de cursorkleur van de huidige speler. for ck in 7 downto 1 loop if (RedA(0) = '1') and (RedA(ck) = '0') and (GreenA(ck) = '0') then RedA(Ck) <= '1'; RoodA(0) <= '0'; UITGANG; stop als;

als (GroenA(0) = '1') en (RedA(ck) = '0') en (GroenA(ck) = '0') dan

GroenA(Ck) <= '1'; GroenA(0) -- Rode speler GroenA(0) <= '0'; if (NCursorCol = OCursorCol) then -- Als er niets is ingedrukt RedA(0) <= '1'; elsif (NCursorCol = "111") dan -- Als Lbtn werd ingedrukt RedH(0) <= '1'; RoodA(0) <= '0'; elsif (NCursorCol = "001") dan -- Als op Rbtn is gedrukt RedB(0) <= '1'; RedA(0) -- Groene speler RedA(0) <= '0'; if (NCursorCol = OCursorCol) dan GroenA(0) <= '1'; elsif (NCursorCol = "111") en vervolgens GroenH(0) <= '1'; GroenA(0) <= '0'; elsif (NCursorCol = "001") en vervolgens GreenB(0) <= '1'; GroenA(0) <= '0'; stop als; eindgeval;

Let op, de eerste case-statement genaamd: OCursorCol (wat staat voor Old Cursor Column) is het begin van de eindige-toestandsmachine. Elke kolom van het display wordt behandeld als zijn eigen status in de FSM. Er zijn 8 kolommen, dus een set van 3 bits binaire getallen werd gebruikt om elke kolom als een staat te identificeren. Hoe de FSM tussen statussen beweegt, is afhankelijk van de knop die wordt ingedrukt. In het bovenstaande fragment, als de linkerknop wordt ingedrukt, zal de FSM naar "111" gaan, wat de laatste kolom van het display zou zijn. Als de rechterknop wordt ingedrukt, zal de FSM naar "001" gaan, wat de tweede kolom van het display zou zijn.

Als de middelste knop wordt ingedrukt, zal de FSM NIET naar een nieuwe staat gaan, maar in plaats daarvan een verandering in het TurnState-signaal teweegbrengen, wat een een-bits signaal is om te noteren welke speler aan de beurt is. Bovendien voert de middelste knop een codeblok uit dat controleert of er helemaal onderaan helemaal bovenaan een lege rij is. Het zal proberen een markering in de laagste, ongevulde rij te plaatsen. Onthoud dat dit een connect four-game is.

In de geneste case-instructie met de naam: TurnState, wijzigen we wat de cursorkleur is en voor welke kolom op de eerste rij we de gegevens willen wijzigen, zodat het weergaveproces de wijziging kan weerspiegelen.

We herhalen deze basiscode voor de overige zeven gevallen. Het FSM-diagram kan nuttig zijn om te begrijpen hoe de toestanden veranderen.

Stap 5: Coderen

Code
Code

Dit is de functionele code voor de Connect 4 die kan worden gecompileerd in VHDL met behulp van de Vivado Software.

Er wordt ook een beperking geboden om u in staat te stellen het spel aan de gang te krijgen.

We hebben een blokdiagram geleverd waarin wordt uitgelegd hoe de in- en uitgangen van elk proces met elkaar zijn verbonden.

Aanbevolen: