# Implementierung einer VGA-Grafikkarte auf einem FPGA nach Ben Eaters Prinzipien
Entwickler, die mit HDL vertraut sind, werden den Wechsel von Simulationen in Turing Complete zu einer realen Hardware-Implementierung zu schätzen wissen. Basierend auf Ben Eaters Ideen aus seinen Videokursen zu diskreter Logik baut dieses Projekt eine einfache Grafikkarte auf einem FPGA auf. Es verwendet den Altera EP4CE15F23C8N-Chip mit 15.000 Logikelementen, der über Standard-VGA-Timings 800x600@60Hz mit VGA verbunden ist. Die 50-MHz-Systemtaktfrequenz wird durch 5 geteilt, um 10 MHz zu erzeugen, passend zum Originalprojekt.
Das ClockDivider-Modul übernimmt die Taktteilung:
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
Verilog-Features für die FPGA-Entwicklung
Verilog unterscheidet sich von imperativen Sprachen durch seine parallele Ausführung. Variablen gibt es in zwei Kategorien: reg (die Zustände speichern) und wire (einfache Leitungen ohne Speicher). Zuweisungsoperatoren erzeugen unterschiedliche Hardware-Schaltungen:
- assign für kombinierende Logik:
wire a,b,c;
assign c = a & b;
- always @(...) = (blockierend) für sequenzielle Ausführung innerhalb eines Blocks.
- always @(posedge clk) <= (nicht-blockierend) für getaktete Register:
reg A;
always @(posedge clk)
begin
A <= ~A;
end
Modulparameter werden mit #() inklusive Standardwerten definiert und bei der Instanziierung namentlich übergeben. Die `define-Direktive wird aufgrund von Preprocessor-Problemen abgeraten.
Zähler für VGA-Timings
Der horizontale Zähler zählt die Pixel in einer Zeile:
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
Der vertikale Zähler inkrementiert am Ende jeder Zeile:
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
Signale wie Hsync, Vsync, Hblank und Vblank werden basierend auf Timings von tinyvga.com assertiert (Front- und Back-Porch-Werte sind in Case-Statements für H_count und V_count festgelegt).
Erzeugung der Videodaten
Der sichtbare Bereich hat eine Auflösung von 100x75 Pixeln mit 2-Bit-Farbtiefe (4 Stufen pro RGB-Kanal, gepackt in 6 Bits). Bilder werden in Photoshop vorbereitet: auf 100x75 vergrößern, in Indizierten Farben mit benutzerdefinierter Palette (0x00/0x55/0xaa/0xff) umwandeln und als 8-Bit-BMP exportieren.
Ein C++-Tool konvertiert das BMP in ein Verilog-Speicherarray mem[]:
#include <windows.h>
#include <iostream>
// ... (full code parsera BMP with SetPixCollor for mappinga palitry in 6-bitnye values)
Die SetPixCollor-Funktion kodiert RGB-Werte in Bits (R2R1 G2G1 B2B1). Die Ausgabe mem_block.txt wird in ein FPGA-ROM geladen, adressiert mit Hor_count[6:0] und V_count[6:0].
- BMP laden und Header validieren (bfType=0x4D42, biBitCount=8).
- RGBQUAD[256]-Palette lesen.
- Pixel parsen und auf 6-Bit-Werte mappen.
- Verilog-Code zusammen mit einer ASCII-Visualisierung erzeugen.
Integration und Debugging
Die Montage erfolgt in Quartus Prime: Module werden mit Parametern wie ENDSTRING=799 und ENDFRAME=624 instanziiert. USB Blaster benötigt eine angepasste Firmware für zuverlässigen Betrieb. Der Quartus-Simulator ersetzt herkömmliche Debugger und zeigt Oszillogramme von Signalen wie clk_out, H_count und RGB.
Wichtige Punkte:
- Verilogs Parallelität erfordert nicht-blockierende Zuweisungen bei der Arbeit mit Registern.
- VGA-Timings sind entscheidend: 10-MHz-Pixel-Takt für 800x600@60Hz.
- 2-Bit-Farbe hält das ROM einfach (7500x6 Bits), bei Erhalt von Verläufen.
- FPGA-Setup ist günstig: Minimalboard ohne Extras + Standard-VGA-Kabel.
- Debugging erfolgt vollständig in der Simulation, ohne Laufzeitprobleme.
— Editorial Team
Noch keine Kommentare.