# Implémentation d'une carte graphique VGA sur FPGA suivant les principes de Ben Eater
Les développeurs familiers avec le HDL apprécieront le passage des simulations dans Turing Complete à une implémentation matérielle réelle. S'inspirant des idées de Ben Eater issues de ses cours vidéo sur la logique discrète, ce projet réalise une simple carte graphique sur un FPGA. Il utilise la puce Altera EP4CE15F23C8N dotée de 15 000 éléments logiques, connectée à VGA via les timings standards 800x600@60Hz. L'horloge système de 50 MHz est divisée par 5 pour produire 10 MHz, en cohérence avec le projet original.
Le module ClockDivider gère la division d'horloge :
module ClockDivider
(
input wire clk,
output reg clk_out
);
reg [2:0] DATA;
always @(posedge clk)
begin
if(DATA == 3'd4)
begin
DATA <= 3'd0;
clk_out <= 1'd1;
end
else
begin
clk_out <= 1'd0;
DATA <= DATA + 1'd1;
end
end
endmodule
Fonctionnalités de Verilog pour le développement sur FPGA
Verilog se distingue des langages impératifs par son exécution parallèle. Les variables se répartissent en deux catégories : reg (qui conservent un état) et wire (simples connexions sans stockage). Les opérateurs d'affectation génèrent des circuits matériels différents :
- assign pour la logique combinatoire :
wire a,b,c;
assign c = a & b;
- always @(...) = (bloquant) pour une exécution séquentielle au sein d'un bloc.
- always @(posedge clk) <= (non-bloquant) pour les registres horlogés :
reg A;
always @(posedge clk)
begin
A <= ~A;
end
Les paramètres de module sont définis avec #() avec des valeurs par défaut et passés par nom lors de l'instanciation. La directive `define est déconseillée en raison des problèmes de préprocesseur.
Compteurs pour les timings VGA
Le compteur horizontal suit les pixels d'une ligne :
module HorizontalCounter
#(
parameter ENDSTRING = 0
)
(
input wire clk,
output reg [8:0] DATA
);
always @(posedge clk )
begin
if(DATA == ENDSTRING) DATA <= 9'd0;
else DATA <= DATA + 1'd1;
end
endmodule
Le compteur vertical s'incrémente à la fin de chaque ligne :
module VerticalCounter
#(
parameter ENDFRAME = 0,
parameter ENDSTRING = 0
)
(
input wire clk,
input reg [8:0] Hor_count,
output reg [10:0] DATA
);
always @(posedge clk )
begin
if(DATA == ENDFRAME) DATA <= 11'd0;
else if (Hor_count == ENDSTRING) DATA <= DATA + 1'd1;
end
endmodu
Des signaux comme Hsync, Vsync, Hblank et Vblank sont activés en fonction des timings issus de tinyvga.com (les valeurs de front et back porch sont spécifiées dans des case statements pour H_count et V_count).
Génération des données vidéo
La zone visible offre une résolution de 100x75 pixels avec une profondeur de couleur de 2 bits (4 niveaux par canal RGB, packés en 6 bits). Les images sont préparées dans Photoshop : redimensionner à 100x75, convertir en Couleur indexée avec une palette personnalisée (0x00/0x55/0xaa/0xff), et exporter en BMP 8 bits.
Un utilitaire C++ convertit le BMP en un tableau mémoire Verilog mem[] :
#include <windows.h>
#include <iostream>
// ... (full code parsera BMP with SetPixCollor for mappinga palitry in 6-bitnye values)
La fonction SetPixCollor encode les valeurs RGB en bits (R2R1 G2G1 B2B1). Le fichier de sortie mem_block.txt est chargé dans une ROM du FPGA, adressée via Hor_count[6:0] et V_count[6:0].
- Charger le BMP et valider les en-têtes (bfType=0x4D42, biBitCount=8).
- Lire la palette RGBQUAD[256].
- Analyser les pixels et les mapper vers des valeurs 6 bits.
- Générer du code Verilog accompagné d'une visualisation ASCII.
Intégration et débogage
L'assemblage se fait dans Quartus Prime : les modules sont instanciés avec des paramètres comme ENDSTRING=799 et ENDFRAME=624. USB Blaster nécessite un firmware personnalisé pour un fonctionnement fiable. Le simulateur Quartus remplace les débogueurs traditionnels, affichant des oscillogrammes des signaux comme clk_out, H_count et RGB.
Points clés :
- Le parallélisme de Verilog impose les affectations non-bloquantes lors du travail avec des registres.
- Les timings VGA sont critiques : horloge pixel de 10 MHz pour 800x600@60Hz.
- La couleur 2 bits simplifie la ROM (7500x6 bits) tout en préservant les dégradés.
- La configuration FPGA est économique : une carte minimale sans extras + câbles VGA standards.
- Le débogage se fait entièrement en simulation, évitant les problèmes d'exécution.
— Editorial Team
Aucun commentaire pour le moment.