Gestion de l'affichage

Avant de développer le jeu proprement dit, nous allons compléter le module SquashDisplay. Il s’appuiera sur un module VGAController chargé de gérer le balayage de l’écran.

Le module VGAController

La documentation de la carte Basys3 présente des explications détaillées sur le fonctionnement d’un écran VGA. Initialement, le standard VGA définissait des signaux adaptés au fonctionnement d’un écran cathodique. Pour des questions de compatibilité, de nombreux écrans LCD supportent encore ce standard, bien que leur principe de fonctionnement soit différent.

En résumé, la gestion de l’écran se passe comme si nous avions un écran de 800×525 pixels dans lequel il y aurait une partie visible de 640×480 (fond bleu sur l’image ci-dessous) et une partie invisible correspondant aux périodes de rafraîchissement (en noir et en gris).

Synchronisation d'un écran VGA

Le module VGAController aura les ports suivants :

Entrées/sorties du module VGAController

Port Direction Taille Rôle
clk_i Entrée 1 Signal d’horloge à 25 MHz
x_o Sortie 10 Coordonnée X du pixel courant
y_o Sortie 10 Coordonnée Y du pixel courant
blanking_o Sortie 1 Indicateur de rafraîchissement
hsync_n_o Sortie 1 Commande de synchronisation horizontale de l’écran
vsync_n_o Sortie 1 Commande de synchronisation verticale de l’écran

Les coordonnées x_o et y_o représentent la localisation du pixel courant au cours du balayage de l’écran. Elles seront gérées par deux compteurs en cascade : le compteur x_o comptera de 0 à 799 et sera mis à jour au rythme de l’horloge clk_i ; le compteur y_o comptera de 0 à 524 et sera mis à jour à chaque fois que x_o terminera un cycle de comptage.

La sortie blanking_o vaudra 1 lorsque les coordonnées courantes sortent de la région visible de l’écran (x_o ≥ 640 ou y_o ≥ 480). Les sorties hsync_n_o et vsync_n_o, en logique négative, produiront des impulsions pendant les périodes de rafraîchissement. Les tableaux ci-dessous spécifie les intervalles de temps à respecter :

x_o 0 à 639 640 à 658 659 à 755 756 à 799
hsync_n_o 1 1 0 1
y_o 0 à 479 480 à 492 493 à 494 495 à 524
vsync_n_o 1 1 0 1

Complétez le module VGAController de manière à réaliser ce comportement. Utilisez les constantes définies dans le fichier SquashCommon.v.

Pour réaliser cette étape, vous devrez appliquer les notions suivantes :

Simuler le fonctionnement du module VGAController

Dans la console Tcl de Vivado, exécutez les commandes suivantes :

  1. Indiquer que le module VGAController est le module principal à simuler :
set_property top VGAController [get_filesets sim_1]
  1. Démarrer la simulation :
launch_simulation
restart
  1. Créer une horloge de fréquence 25 MHz (période 40 ns) :
add_force -repeat_every 40ns clk_i 0 0ns 1 20ns
  1. Simuler pendant 17 millisecondes :
run 17ms
  1. Après avoir observé les chronogrammes, fermer la session de simulation :
close_sim -force

Le module SquashDisplay

Créez une instance de VGAController dans le module SquashDisplay. Effectuez les connexions nécessaires, en déclarant les signaux manquants.

Déclarez et affectez un signal in_ball et un signal in_paddle indiquant si le pixel courant, de coordonnées (x, y), fait partie de la balle ou de la raquette. On rappelle ci-dessous les informations disponibles :

Coordonnées des objets du jeu

Dans un premier temps, la balle sera dessinée sous la forme d’un rectangle.

Une fois l’affichage validé, vous pourrez réfléchir à une solution pour dessiner une forme circulaire.

La sortie vga_rgb_o respectera le codage de couleurs suivant :

Valeur Couleur
3'b000 Noir
3'b100 Rouge
3'b010 Vert
3'b001 Bleu
3'b110 Jaune
3'b101 Magenta
3'b011 Cyan
3'b111 Blanc

Affectez la sortie vga_rgb_o de manière à obtenir ce comportement :

Pour réaliser cette étape, vous devrez appliquer les notions suivantes :

Le module SquashCore

Complétez le module SquashCore en affectant toutes ses sorties. Pour les coordonnées de la balle et de la raquette, utilisez les coordonnées initiales définies dans SquashCommon.v. Pour game_over_o et success_o, vous pouvez tester différentes combinaisons en les reliant à des boutons :

Sortie Constante ou entrée
ball_x_o BALL_X_INIT
ball_y_o BALL_Y_INIT
paddle_x_o PADDLE_X
paddle_y_o PADDLE_Y_INIT
game_over_o btn_down_i
success_o btn_up_i

Synthétiser le circuit

Configurer les optimisations

  1. Ouvrez la fenêtre des paramètres de Vivado : Flow NavigatorProject ManagerSettings.

Accès aux réglages de Vivado

  1. Dans la catégorie Synthesis, sous le titre Options, le champ Strategy propose une liste des stratégies d’optimisation disponibles à l’étape de synthèse logique du circuit. Choisissez la stratégie Flow RuntimeOptimized.

Accès aux réglages de Vivado, synthèse

  1. Dans la catégorie Implementation, sous le titre Options, modifiez le champ Strategy en choisissant également la stratégie Flow RuntimeOptimized.

Accès aux réglages de Vivado, implémentation

Synthétiser et implémenter le circuit

Exécutez cette commande dans la console Tcl pour réduire la gravité de certains messages concernant les affectations de broches :

set_msg_config -id {Common 17-55} -new_severity {WARNING}

Générez le fichier binaire à charger dans le FPGA : Flow NavigatorProgram and DebugGenerate Bitstream.

Vivado generate bitstream

Vivado va enchaîner toutes les étapes d’analyse des fichiers sources, de synthèse logique, de placement et routage, pour terminer par la génération d’un fichier binaire à charger dans le FPGA.

À la fin des opérations, la boîte de dialogue Bitstream Generation Completed s’affiche. Choisissez Open Hardware Manager.

Configurer le FPGA

Vérifiez que l’interrupteur d’alimentation de votre carte Basys3 est en position OFF. Le cavalier situé à côté de l’interrupteur doit être en position USB.

Reliez le connecteur micro-USB de la carte à un port USB de votre PC. Mettez la carte sous tension.

En haut du panneau Hardware Manager, pressez Open target et choisissez Auto Connect.

Vivado open target

Pressez ensuite Program Device.

Vivado program device