2. Erweiterung Morse De- und Encoders mittels VHDL und Implementierung auf einem FPGA-Entwicklungsboard

Autoren: Pauline Bußmann, Gerold Hackenfort

Einführung

Der folgend vorgestellte Code wurde im Rahmen einer Projektarbeit des Moduls Entwurf digitaler Systeme bei Herrn Prof. Dr. Udo Jorczyk erarbeitet und basiert ebenfalls auf dem Projekt Morse De- und Encoder mittels FPGA von Herrn Nessitt. Hierbei wurde eine VGA Schnittstelle, die zu Teilen von Johnnyjax aus dem Projekt  „vga-kbd-terminal“ von Github übernommen und stark angepasst wurde, implementiert. (https://github.com/Johnnyjax/vga-kbd-terminal). 

Encoder-/Decodermodus auf dem VGA

Um vom Encodermodus in den Decodermodus und umgekehrt zu schalten, wird ein switch „enable“ verwendet. Dabei wird bei jedem Umschalten zwischen Encoder- und Decodermodus ein vorgegebener Text auf dem VGA-Bildschirm ausgegeben. Schaltet man also in den Encodermodus so wird folgendes dargestellt: „E: Verschluesselter Morsecode:“. Im Falle des Decodermodus wird „D: Entschluesselter Morsecode:“ geschrieben. Dies wird mithilfe einer Case-Anweisung in der LCD-Component implementiert. Dabei wird ein Signal „switch_enc“ bzw. „switch_dec“ mit einer Range von 0 to 63 definiert. Zuvor wird des Weiteren festgelegt, dass eine steigende Flanke „en_rise = 1“ dem Encodermodus und eine fallende Flanke „en_fall = 1“ dem Decodermodus zugeordnet wird. Somit wird unter Verwendung einer If-Anweisung abgefragt welcher Modus aktuell ansteht. Im Falle, dass en_rise = 1 ist gelangt das Programm in die Case-Anweisung für den Encodermodus. Dabei wird bei jedem „when“ ein Symbol, beispielsweise ein Enter oder Buchstabe, auf den VGA geladen und switch_enc inkrementiert, um in das nächste „when“ zu gelangen. Zum Schluss, wenn der vollständige Text dargestellt ist, wird en_rise wieder auf Null gesetzt, um so sicherzustellen, dass die Case-Anweisung des Decodermodus bei einem nächsten Umschalten aufgerufen werden kann.

Quellcode - Coder auf VGA

Debouncer für den Enable-Switch

Da es beim Umschalten zwischen Encoder- und Decodermodus zu Problemen bei der Signalübertragung kam (unvollständige Textausgabe bzw. Wiederholung von bestimmten Textteilen), wurde zum Entprellen des Schalters ein Debouncer eingebaut. Hierbei wird der Input des Enable-Switches als i_switch definiert. Innerhalb eines Prozesses wird bei jeder steigenden Taktflanke des Clocks mit einer If-Anweisung abgefragt, ob i_switch ungleich dem Signal r_state ist (indem Fall, ob i_switch = 1 ist) und ob r_count kleiner des festgelegten Debounce-Limits ist. Ist dies der Fall wird der Zähler r_count inkrementiert, im anderen Fall wird der Wert von i_switch auf r_state geladen und der Zähler wieder Null gesetzt. Nach Beendigung des Prozesses wird r_state dann auf den Ausgang o_switch geladen.

Quellcode - Debouncer für den Enable-Switch

Implementierung von Sonderzeichen für VGA und LCD

Des Weiteren werden bestimmte Sonderzeichen wie Enter und Backspace in das Programm eingebaut. Hierzu wird bei Tastendruck auf dem Keyboard ein bestimmtes Hexdatensignal erfasst, beispielsweise x“5A“ bei einem Enter, wodurch folgend eine bestimmte Adresse des LCDs geladen wird. Bei einem Enter wird x“14“ bzw. 0001 0100, also ein leeres Feld, auf den LCD geladen (siehe LCD Correspondence Tabelle [1]). Gleichzeitig werden bestimmte Daten auf den VGA geladen. Diese Daten sind in der kbd_code Component festgelegt. Dort wird für jedes implementierte Sonderzeichen eine Konstante definiert, welcher ein fester Wert zugewiesen wird. Wenn diese Konstante mit dem überlieferten Wert aus der LCD Entity übereinstimmt, werden diese in „tick“ gewandelt und weiter an vga_kbd_txt Entity gegeben, wo diese dann in der Cursorpositionsberechnung benötigt werden.LCD_data-sheet.png

Zeichentabellen
Zeichentabellen
Quellcode - LCD Entity
Quellcode - In der kb_code Entity
Quellcode - In der vga-kbd_txt Entity

Farbkombinationen für den VGA

Mithilfe von Switches ist es nun möglich die Schrift-, Cursor- und Hintergrundfarbe anzupassen. Hierbei wurden insgesamt sechs Farbkombinationen ausgewählt. Es werden drei Signale „Colour_font“, „Colour_cur“ und „Colour_bck“ definiert, welchen bei bestimmten Schalterstellungen festgelegte Werte zugewiesen werden.

Quellcode - Farbkombinationen für den VGA

Implementierung der Auflösung

Zur Implementierung der Auflösung wird die Pixel Anzahl und der dazugehörige Pixel-Clock benötigt. In diesem Fall haben wir uns für 640×480, 1280×720 und 1920×1080, also SD, HD und Full HD entschieden. Diese drei Auflösungen haben feste Pixel-Clocks, die berechnet werden müssen. Mit Hilfe vom Video Timings Calculator konnten dann die Pixel-Clocks von 25MHz, 74,25 MHz und 148,5MHz und die dazugehörigen Porches und Syncs berechnet werden. Die Clocks werden dann einfachheitshalber mit dem MegaWizard Plug-In Manager erzeugt. Mit 2 Switches und If-Anweisungen können nun die Pixel und Pixel-Clocks beliebig ausgewählt werden. Hinzukommt noch, dass eine maximale Buchstabenfelderanzahl für jede Auflösung berechnet werden muss, da bei einer höheren Auflösung auch mehr Buchstaben dargestellt werden können. Ein Buchstabenfeld ist jeweils 8×16 Pixel breit und hoch (8by16 ASCII Font). Heißt bei einer Auflösung von 1920×1080 passen 1920 / 8 = 240 Buchstaben in x-Richtung und 1080 / 16 = 68 Buchstaben in y-Richtung hinein, insgesamt 16320 Buchstaben. Diese werden alle einfach von Hand berechnet und in eine If-Anweisung eingebaut.

Quellcode - Auflösung in der vga-kbd_txt
Quellcode - Auflösung in der vga-sync Entity
Quellcode - Auflösung in der vga_kbd_txt_top Entity

RAM löschen

Da ein kompletter RAM nicht mit einer Clock Flanke gelöscht werden kann, muss nach einem Reset oder ESC Event jede einzelne Speicherzelle mit jeweils einer Clock Flanke gelöscht werden. Hierfür wurde ein Counter implementiert, der bis zur maximalen RAM-Größe hochzählt und die Zelle mit „0000000“ füllt.

Quellcode - RAM löschen
Download

Projektdokumentation