Hier eine kurze Erlaeuterung, wie's funktioniert: Ein Timing-Modul erzeugt fortlaufend Adressen, die zum Auslesen des Display-Memories dienen (Textzeile fuer Textzeile, von links nach rechts und von oben nach unten). Das ausgelesene Zeichen (Kodierung wie im PC-Zeichensatz, 8 Bit breit) waehlt aus dem Character-Generator das zugehoerige Pixelmuster aus. Dieses wird, vom Timing-Modul gesteuert, Pixel fuer Pixel ueber den VGA-DAC an den Monitor gesendet. Ausserdem muss das Timing-Modul wie in der vorhergehenden Aufgabe die Synchronsignale fuer den Monitor erzeugen.
Benutzen Sie fuer den Character-Generator (und spaeter fuer das Display-Memory) das sogenannte "Block-Memory" unseres FPGAs. Im Datenblatt des FPGAs finden Sie genaue Hinweise dazu. Die Vorbelegung, die ja zumindest fuer den Character-Generator absolut notwendig ist, erledigen Sie am besten mit einer "$readmemb()"-Anweisung in Verilog, die eine Datei in einen Speicher einliest. Das ist offensichtlich nicht synthetisierbar - warum genau? Wenn Sie aber diese Anweisung innerhalb einer "initial"-Anweisung platzieren, erkennt die Synthesesoftware das als eine Vorbelegung des Block-Memories (und die wird beim Laden des Bitstrings in den FPGA mit uebertragen). Ein Zeichensatz, der aus dem BIOS eines PCs ausgelesen wurde, befindet sich in der Datei font-8x16 . Schreiben Sie am besten ein kleines Programm, das diese Spezifikation in die entsprechende Datei zur Initialisierung umwandelt (ohne Rechnerunterstuetzung ist das doch ganz schoen muehsam). Vielleicht haben Sie Verwendung fuer dieses Programm, mit dem ich die genannte Umsetzung erledigt habe.
Zum Testen ihrer Schaltung steuern Sie den Character-Generator statt mit dem Display-Memory (das es ja noch nicht gibt) mit ausgewaehlten Signalen aus dem Timing-Modul an, um die Funktion Ihrer Schaltung zu pruefen (Vorschlag: ASCII-Code = Textzeile * 8 + Textspalte). Beachten Sie dabei unbedingt, dass das Block-RAM getaktet ist: Wenn Sie ein Signal erzeugen, das gleichzeitig mit der Adresse des RAMs wechselt, dann kommt das zugehoerige Datum erst zum naechsten Takt aus dem RAM heraus. Soll also das erzeugte Signal gleichzeitig mit den Daten des RAMs wechseln, benoetigen Sie eine Verzoegerung von einem Takt (also ein D-Flip-Flop) in der Signalleitung.
Das geschilderte Prinzip nennt man "Pipelining". Meine Realisierung des Displays benutzt vierstufiges Pipelining: die erste Stufe ist das Timing-Modul, die zweite ist das Display-Memory, die dritte ist der Character-Generator, und die vierte ist die "Pixelstufe", die die RGB-Signale und die Synchronsignale noch einmal mit dem Takt synchronisiert. ACHTUNG: Bei unserem Board sind die Flip-Flops der Pixelstufe fuer die RGB-Signale bereits im VGA-DAC vorhanden, die fuer die Synchronsignale aber nicht!
Zum Testen Ihrer Loesung kann dieser Controller dienen. Er schreibt definiert Zeichen (welche?) an bestimmte Stellen des Display-Memories (wohin?). Sie koennen ausserdem den Speicher statisch vorbelegen, so wie Sie das mit dem Character-Generator auch schon tun. Dann kann man den Schreibvorgang besser beobachten. Hier ist meine Vorbelegung zusammen mit dem kleinen Programm zur Umwandlung in eine Datei passend fuer eine "$readmemh()"-Anweisung zur Initialisierung des Display-Memories.