Table des matières:

VHDL Basys3 : Jeu Connect 4 : 5 étapes
VHDL Basys3 : Jeu Connect 4 : 5 étapes

Vidéo: VHDL Basys3 : Jeu Connect 4 : 5 étapes

Vidéo: VHDL Basys3 : Jeu Connect 4 : 5 étapes
Vidéo: Как мультиплексировать семисегментные дисплеи на Z80 2024, Novembre
Anonim
VHDL Basys3: Jeu Connect 4
VHDL Basys3: Jeu Connect 4

Introduction:

Il s'agit d'un jeu de logique numérique Connect 4 conçu en VHDL à l'aide du logiciel Vivado et programmé sur la carte Basys3. La construction et la conception de ce projet sont intermédiaires, mais les nouveaux arrivants peuvent copier les étapes et construire le jeu numérique.

Le jeu fonctionne comme le jeu Connect 4. Les joueurs peuvent déplacer leur curseur sur l'écran à l'aide des boutons gauche et droit du tableau. En appuyant sur le bouton du milieu du plateau, le joueur placera son marqueur sur cette colonne, puis ce sera le tour du joueur suivant. Une fois qu'un joueur a gagné, le jeu peut être réinitialisé en appuyant sur le bouton haut du plateau.

Étape 1: Détails et matériaux rapides

Détails techniques rapides:

  • Utilise trois ensembles de connexions PMOD sur la carte (JA, JB, JC)

    • 8 broches (hors broches Vcc et GND) utilisées pour chaque connecteur PMOD
    • JA - Contrôle des lignes
    • JB - Contrôle des Colonnes Vertes
    • JC - Contrôle des Colonnes Rouges
  • L'horloge de l'écran fonctionne à 960 Hz

    Seules 8 LED sont allumées à un moment donné. L'écran se rafraîchit à une vitesse d'horloge suffisamment rapide pour donner l'illusion que plus de 8 LED sont allumées à un moment donné

  • L'horloge des boutons fonctionne à 5 Hz; En option, peut être affiné en éditant le code VHDL.
  • La résistance interne des matrices Darlington est suffisante pour empêcher l'épuisement des LED

Le jeu est construit à l'aide des composants et outils suivants:

  • (1) carte Basys3
  • (2) Matrice LED Bicolore 8x5:
  • (2) ULN2803 - Réseaux de transistors Darlington - Fiche technique
  • Bobines de fil
  • Fils de cavalier
  • Pince à dénuder
  • Planches à pain (un grand carré devrait suffire)
  • Multimètre et alimentation (dépannage)

Étape 2: connexion du matériel

Connexion du matériel
Connexion du matériel
Connexion du matériel
Connexion du matériel

Des lignes directrices:

Le câblage du projet peut être extrêmement compliqué, veuillez prendre votre temps et vérifier que toutes les connexions sont correctes un jeu à la fois.

Le projet consiste à utiliser deux écrans LED mais sont combinés pour former un grand écran. Cela peut être accompli en connectant toutes les lignes au même point. Étant donné que chaque écran est bicolore, les lignes rouges et vertes d'un écran doivent également être liées aux lignes rouges et vertes de l'autre écran. En faisant cela, nous pouvons contrôler toutes les lignes avec seulement 8 broches. Les 16 autres broches sont utilisées pour contrôler les colonnes d'affichage. Les 8 broches du peuvent être connectées directement via des câbles de démarrage aux connecteurs pmod. Les connexions Pmod vont d'abord à l'entrée de l'ULN2083A et la sortie de l'ULN2083A est connectée directement à la colonne sur l'écran. Parce que la conception est un 8x8, certaines colonnes ne seront physiquement pas connectées.

  • JA: Connexions de rangées: rangée 1 à JA:1 à rangée 8 pour JA:10.
  • JA: Connexions de la colonne rouge:
  • JC: Connexions Colonne Verte

Veuillez vous référer aux images publiées pour savoir quelles broches correspondent à quelles lignes/colonnes.

Remarque: les transistors ont des résistances intégrées, de sorte que les LED ne nécessitent pas de résistance supplémentaire pour leur être connectées en série.

Étape 3: Explication technique: Écran

L'écran fonctionne sur la persistance de la vision. L'écran se rafraîchit si rapidement que l'œil humain ne peut pas détecter visiblement que certaines LED s'éteignent et s'allument rapidement. En effet, en ralentissant l'horloge d'affichage, on peut remarquer le clignotement.

L'affichage s'allume sur les huit lignes en fonction des données stockées pour ces lignes, et l'affichage s'allume sur une colonne. Ensuite, il passe rapidement à l'entrée de données suivante pour les huit lignes et active la colonne suivante, tout en désactivant toutes les autres colonnes. Ce processus se poursuit à une vitesse d'horloge suffisamment rapide pour que le scintillement de la LED devienne imperceptible.

Le stockage des données pour l'affichage est initialisé immédiatement après l'architecture dans le fichier VHDL de la manière suivante:

signal RedA, RedB, RedC, RedD, RedE, RedF, RedG, RedH: std_logic_vector (7 jusqu'à 0):= "00000000";

signal GreenA, GreenB, GreenC, GreenD, GreenE, GreenF, GreenG, GreenH: std_logic_vector (7 jusqu'à 0):= "00000000"; -- Données de ligne selon la colonne: VERT

Voici un petit extrait du processus qui contrôle la matrice d'affichage LED.

-- Process that Controls LED display matrixdisplay: process (ColCLK) -- 0 - 16 pour rafraîchir à la fois la variable de matrice 8X8 RED et 8x8 GREEn RowCount: plage d'entiers 0 à 16:= 0; begin if (rising_edge(ColCLK)) then if (RowCount = 0) then DORow <= RedA; -- Données de ligne pour la colonne DOCol correspondante <= "1000000000000000"; -- Déclencheur de colonne -- Répétez ce code jusqu'à "000000000000001" -- Changez pour RedB, RedC…GreenA, GreenB…GreenH

À la fin du GreenH, juste avant la fin du processus, cet extrait est inclus pour réinitialiser le RowCount à zéro.

if (RowCount = 15) then -- Redémarrer l'actualisation à partir de la colonne A RowCount:= 0; else RowCount:= RowCount + 1; -- Shift à travers les colonnes end if;

Maintenant, pour expliquer l'horloge qui est dans la liste de sensibilité du processus d'affichage. La carte Basys3 possède une horloge interne fonctionnant à 100MHz. Pour nos besoins, c'est une horloge trop rapide, nous devrons donc diviser cette horloge en une horloge de 960 Hz en utilisant le processus suivant.

-- Processus d'horloge fonctionnant à 960HzCLKDivider: variable process (CLK) clkcount: plage entière de 0 à 52083:= 0; begin if (rising_edge(CLK)) then clkcount:= clkcount + 1; if (clkcount = 52083) alors ColCLK <= not(ColCLK); clkcount:= 0; fin si; fin si; processus final;

Étape 4: Explication technique: Modification des informations affichées

Explication technique: Modification des informations affichées
Explication technique: Modification des informations affichées

Dans le code VHDL, les informations ou les données qui seront affichées à l'écran sont contrôlées par le processus du curseur, qui a une horloge différente dans sa liste de sensibilité. Ce code s'appelait BtnCLK, une horloge conçue pour minimiser le débouchage des boutons lorsqu'ils sont enfoncés. Ceci est inclus afin que si un bouton est enfoncé, le curseur sur la ligne du haut ne se déplace pas très rapidement à travers les colonnes.

-- Processus d'horloge fonctionnant à 5 Hz. ButtonCLK: variable de processus (CLK) btnclkcount: plage entière de 0 à 10000001:= 0; begin if (rising_edge(CLK)) then if (btnclkcount = 10000000) then btnclkcount:= 0; BtnCLK <= pas(BtnCLK); sinon btnclkcount:= btnclkcount + 1; fin si; fin si; processus final;

Avec la sortie du signal BtnCLK de ce processus, nous pouvons maintenant expliquer le processus du curseur. Le processus curseur n'a que BtnCLK dans sa liste de sensibilité mais dans le bloc de code, l'état des boutons est vérifié et cela entraînera le changement des données pour le RedA, RedB…GreenH. Voici un extrait du code du curseur, qui comprend le bloc de réinitialisation et le bloc de la première colonne.

curseur: processus (BtnCLK) variable OCursorCol: STD_LOGIC_VECTOR (2 jusqu'à 0):= "000"; -- OCursorCol garde la trace de la variable de colonne précédente NCursorCol: STD_LOGIC_VECTOR (2 jusqu'à 0):= "000"; -- NCursorCol définit le début de la nouvelle colonne du curseur --condition RESET (bouton UP) --La carte est effacée pour que le jeu redémarre si (rising_edge(BtnCLK)) then if (RST = '1') then RedA <= "00000000"; RougeB <= "00000000"; RougeC <= "00000000"; RougeD <= "00000000"; RougeE <= "00000000"; RedF <= "00000000"; RougeG <= "00000000"; RougeH <= "00000000"; VertA <= "00000000"; VertB <= "00000000"; VertC <= "00000000"; VertD <= "00000000"; VertE <= "00000000"; VertF <= "00000000"; VertG <= "00000000"; GreenH if (Lbtn = '1') then NCursorCol:= "111"; -- Column H elsif (Rbtn = '1') then NCursorCol:= "001"; -- Colonne B elsif (Cbtn = '1') then NCursorCol:= OCursorCol; -- La colonne reste la même NTurnState <= not(TurnState); -- Déclenche le tour du joueur suivant -- Vérifie la colonne actuelle de bas en haut et allume la première LED qui n'est pas allumée. La couleur dépend de la couleur du curseur du joueur actuel. pour ck dans 7 jusqu'à 1 boucle si (RedA(0) = '1') et (RedA(ck) = '0') et (GreenA(ck) = '0') alors RedA(Ck) <= '1'; RougeA(0) <= '0'; SORTIR; fin si;

si (VertA(0) = '1') et (RougeA(ck) = '0') et (VertA(ck) = '0') alors

VertA(Ck) <= '1'; VertA(0) -- Joueur rouge VertA(0) <= '0'; if (NCursorCol = OCursorCol) then -- Si rien n'a été pressé RedA(0) <= '1'; elsif (NCursorCol = "111") then -- Si Lbtn a été pressé RedH(0) <= '1'; RougeA(0) <= '0'; elsif (NCursorCol = "001") then -- Iff Rbtn a été pressé RedB(0) <= '1'; RedA(0) -- Joueur vert RedA(0) <= '0'; if (NCursorCol = OCursorCol) then GreenA(0) <= '1'; elsif (NCursorCol = "111") puis GreenH(0) <= '1'; VertA(0) <= '0'; elsif (NCursorCol = "001") puis GreenB(0) <= '1'; VertA(0) <= '0'; fin si; cas d'extrémité;

Notez que la première instruction case appelée: OCursorCol (qui signifie Old Cursor Column) est le début de la machine à états finis. Chaque colonne de l'affichage est traitée comme son propre état dans le FSM. Il y a 8 colonnes, donc un ensemble de nombres binaires de 3 bits a été utilisé pour identifier chaque colonne en tant qu'état. La façon dont le FSM se déplace entre les états dépend du bouton enfoncé. Dans l'extrait ci-dessus, si le bouton gauche est enfoncé, le FSM passera à "111" qui serait la dernière colonne de l'affichage. Si le bouton droit est enfoncé, le FSM passera à "001" qui serait la deuxième colonne de l'affichage.

Si le bouton du milieu est enfoncé, le FSM ne passera PAS à un nouvel état mais déclenchera à la place un changement dans le signal TurnState, qui est un signal d'un bit pour noter à quel joueur c'est le tour. De plus, le bouton du milieu exécutera un bloc de code qui vérifie s'il y a une ligne vide tout en bas jusqu'en haut. Il essaiera de placer un marqueur dans la rangée la plus basse et non remplie. N'oubliez pas qu'il s'agit d'un jeu de connexion à quatre.

Dans l'instruction de cas imbriquée appelée: TurnState, nous modifions la couleur du curseur et la colonne de la première ligne pour laquelle nous voulons modifier les données afin que le processus d'affichage puisse refléter le changement.

Nous répétons ce code de base pour les sept cas restants. Le diagramme FSM peut être utile pour comprendre comment les états changent.

Étape 5: Coder

Code
Code

Il s'agit du code fonctionnel du Connect 4 qui peut être compilé en VHDL à l'aide du logiciel Vivado.

Une contrainte est également fournie pour vous permettre de lancer le jeu.

Nous avons fourni un schéma fonctionnel qui explique comment les entrées et les sorties de chaque processus sont interconnectées.

Conseillé: