Bibliotheken zur Unterstützung bei der Programmierung des Cyclone III EP3C120 FPGA-Entwicklerboards in VHDL Bachelor-Thesis 25. Oktober 2011 Department Informatik der Universität Hamburg Name: Christoph Schönfeld Matrikelnummer: 6052960 Fachbereich: Informatik Studiengang: Informatik Studienjahrgang: 2008 Erstgutachter: Dr. Andreas Mäder Zweitgutachter: Prof. Dr.-Ing. Dietmar P.F. Möller Dieses Dokument ist im Rahmen einer Bachelorarbeit an der Universität Hamburg, Fachbereich Informatik, entstanden und dient als Leitfaden und Dokumentation für das Altera Cyclone III EP3C120F Development Board. Es beinhaltet sowohl Grundlagen in VHDL, als auch zu dem Board selbst und geht erläuternd auf die in dieser Arbeit entstanden VHDL Komponenten ein, die den Umgang mit dem Entwicklungsboard und der darauf verbauten Hardware wesentlich vereinfachen. Diese Ausarbeitung versteht sich als ergänzendes Beiwerk zum zugehörigen VHDL-Code. Alle Projektdateien nden sich auch online unter http://www.sourcebar.de/bac/. Bei Fragen oder Problemen können Sie sich gern direkt per E-Mail an mich wenden: [email protected] Inhaltsverzeichnis 1. Einleitung 7 1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.2. Komponenten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2. VHDL 2.1. 2.2. 9 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.1.1. Was ist VHDL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.1.2. Warum VHDL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2.1. Allgemein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2.2. Typen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2.3. Operatoren 11 2.2.4. Strukturelemente . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2.5. Sequenzielle Anweisungen . . . . . . . . . . . . . . . . . . . . . . 14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3. Entwicklungsboard 15 3.1. User LEDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.2. Buttons / Switches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4. Bibl. / Erläuterungen 17 4.1. GNU General Public License . . . . . . . . . . . . . . . . . . . . . . . . 4.2. Aufbau 17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.3. Quartus Projekt 4.4. Verwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.5. Signal Multiplexer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.6. LCD Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.1. 2-Line Character LCD Display 4.6.2. Graphic LCD Display 17 . . . . . . . . . . . . . . . . . . . 20 . . . . . . . . . . . . . . . . . . . . . . . . 24 4.7. SRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 4.8. 7-Segement Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 A. Blockbilder 39 5 1. Einleitung Die Ausarbeitung in elektronischer Form, alle Bilder, Datenblätter und Projektdateien benden sich auf der beiliegenden Daten-CD. Da viele der verwendeten Datenblätter schwierig im Internet zu nden sind, habe ich sie separat auf meinem Blog online zur Verfügung gestellt. Die entsprechenden Links nden sich im Literaturverzeichnis am Ende dieser Ausarbeitung. Um die Übersicht über alle Dateien zu vereinfachen, sind diese teilweise unbenannt worden. Zu Beginn werden einige Konventionen und Erläuterungen aufgezeigt, um das Verständnis für diese Arbeit zu erhöhen. Das Cyclone III EP3C120F Development Board - im Folgenden (Cyclon) Entwicklungsboard Signale sind im Text kursiv hervorgehoben dargestellt low-active Signale mit der Notation Signaln werden zusätzlich wie folgt überstrichen dargestellt: Signal Hexadezimale Zahlenwerte werden durch 0x.. dargestellt Im Text sind häug Querverweise zu nden, die tiefer auf den aktuellen Kontext eingehen Diese Ausarbeitung versteht sich als Begleitdokumentation zum Entwicklungsboard und der hier vorgestellten Controller und Komponenten 1.1. Motivation Bevor ich auf die einzelnen Themen dieser Arbeit eingehe, sei als erstes auf ein paar wesentliche Punkte hingewiesen, die dazu beigetragen haben, genau dieses Thema zu wählen und für mich wesentlich und relevant sind. Im Verlauf des Studiums treten immer wieder Situationen auf, in denen es sinnvoll ist, an die Arbeit von Anderen anknüpfen zu können. Oft geht in Projektphasen viel Zeit für die erforderliche Einarbeitung in ein Thema, in Randgebieten oder die Aneignung von Wissen, das für die spezielle Aufgabenerfüllung eigentlich nicht notwendig ist, verloren. Gerade bei der Entwicklung von Software oder in diesem Fall von Hardwareentwürfen ist dieser Punkt nicht zu vernachlässigen. Auch wenn die Arbeit mit einem Entwicklungsboard ein Garant für die notwendige Basis darstellt, so folgen aus der Benutzung auch entsprechende Einschränkungen. Die Bindung an die verbauten Hardwarekomponenten macht es erforderlich für viele Aufgaben spezische Dokumente heraus zu suchen, um an Detailwissen eben dieser zu gelangen. Ohne lange 7 1.2. KOMPONENTEN KAPITEL 1. EINLEITUNG Recherchen und viele Versuche lassen sich solche Komponenten oft nicht in Betrieb nehmen. Hinzu kommt, dass viele Spezikationen nur schwer zu nden sind oder teilweise unvollständig. Das gilt besonders, wenn im Vorhinein wenig Wissen vorhanden ist und speziell dann, wenn Studenten das erste Mal mit dieser Materie in Berührung kommen. Die vorhandenen Unsicherheiten mit einer Beschreibungssprache wie VHDL vergröÿern noch zusätzlich die Kluft zwischen Idee und Umsetzung. Mit dieser Arbeit möchte ich versuchen gerade genau diese ersten Hürden und Schwierigkeiten ein wenig zu umgehen und eine Basis für Arbeiten und Projekte legen, in dem der Aufwand für die Einarbeitung in die Funktionsweise von speziellen Komponenten des Entwicklungsboards minimiert wird. Dazu werde ich eine kleine Bibliothek vorstellen, die Aufgaben wie Initialisierung und Timing für diese Komponenten übernimmt und eine einfach zu verwendende Schnittstelle für die Interaktion mit dem eigentlich Programm darstellt. Ergänzend zum Board-Manual dienen die Erläuterungen aus diesem Dokument, die zusammen mit den Beispieldateien eine Grundlage für die Arbeit mit dem Cycllone III EP3C120 Development Board bilden. 1.2. Komponenten Folgende Komponenten des Entwicklungsboards werden in dieser Arbeit behandelt: 8 User LEDs[3.1] Buttons / Switches[3.2] Multiplexer[4.5] 16-Character by 2-Line LCD Display[4.6.1] Graphics LCD Display[4.6.2] SRAM[4.7] 7-Segement Display[4.8] 2. VHDL 2.1. Einführung Bevor die einzelnen Komponenten und die zur Verfügung gestellte Bibliothek näher erläutert wird, sollen einige Erklärungen vorangestellt werden. Um diesem Dokument und den Demodateien leicht folgen zu können, ist es notwendig über Grundkenntnisse im Bereich VHDL zu verfügen. 2.1.1. Was ist VHDL? VHDL(Very High Speed Integrated Circuit Hardware Description Language) [10] ist eine Hardwarebeschreibungssprache, die verwendet werden kann um digitale Schaltungen in einer lesbaren Form zu beschreiben. VHDL selbst ist bereits seit 1987 als IEEEStandard festgelegt und wurde 1993 überarbeitet und erweitert. Die letzten Versionen stammen aus dem Jahr 2002 und 2008. Ursprünglich war VHDL nur für digitale Systeme ausgelegt, allerdings gibt es mittlerweile auch Abwandlungen die auf allgemeine Beschreibungen abstrahiert wurden. Somit lassen sich auch analoge oder gemischte Schaltungen beschreiben. [11] 2.1.2. Warum VHDL? VHDL gehört neben Verilog [8] zu den meist genutzten Beschreibungssprachen für Hardwaresysteme. Gerade im europäischen Raum ist VHDL aber weiter verbreitet. Der entscheidende Vorteil bei der Modellierung mit VHDL oder auch Verilog liegt in der Möglichkeit das Beschriebene zu simulieren und vor allem auch zu synthetisieren. Dabei ist der Sprachumfang von VHDL der sich synthetisieren lässt sehr viel beschränkter, als der Simulierbare. Viele Konstrukte lassen sich nicht direkt auf eine Netzliste übertragen, so dass eine Synthese nie losgelöst von der gegebenen Hardware betrachtet werden kann. Trotzdem bleiben die Vorteile oensichtlich. Anstatt komplette Schaltungen mit der gewünschten Logik selbst entwerfen zu müssen, muss das Verhalten nur noch beschrieben werden. Der Rest wird automatisch generiert und lässt sich auf einen programmierbaren Chip übertragen. Dabei spielen sowohl zeitliche, als auch kostentechnische Gründe eine wesentliche Rolle. Als Beispiel soll Folgendes dienen: Bei der Produktion von neuen Grakprozessoren, kann das Verhalten zuerst auf eine Reihe von wesentlich langsameren, aber frei programmierbaren Chips abgebildet werden. So können Fehler leichter behoben werden und Änderungen sind nicht permanent dem Chip aufgeprägt. Wenn das Produkt die Entwicklungsphase verlassen hat, kann ein erster 9 2.2. GRUNDLAGEN KAPITEL 2. VHDL Prototyp erstellt werden. Ohne die Möglichkeit einer Hardwarebeschreibungssprache wäre es nicht möglich solche Entwicklungsprozesse wirtschaftlich zu tragen. 2.2. Grundlagen Die folgenden Abschnitte basieren auf der VHDL Onlinedokumentation der Universität Erlangen-Nuremberg [10]. 2.2.1. Allgemein Grundsätzlich können in VHDL Anweisungen sequenziell oder auch nebenläug(durch Prozesse) modelliert werden. Der sequenzielle Ansatz ist aus den üblichen Programmiersprachen bekannt und kann analog übertragen werden. Durch Nebenläugkeit kann die Parallelität von echter Hardware nachgebildet werden. Bezeichner sind in VHDL unabhängig von der Groÿ- und Kleinschreibungen. Leider existieren nur zeilenweise Kommentare die durch ein - - eingeleitet werden. Jede Anweisung muss, wie in fast jeder Sprache, durch ein ; beendet werden. In einigen Dingen unterscheidet sich VHDL jedoch von aktuellen Programmiersprachen und lässt sich seine frühe Entstehung deutlich anmerken. So werden zum Beispiel keine Blöcke durch geschweifte Klammern abgetrennt, sondern wie in Pascal ebenfalls durch Schlüsselwörter. Ein Link auf die komplette Syntax von VHDL'93 steht im Literaturverzeichnis zur Verfügung [9]. 2.2.2. Typen Die wichtigsten logischen Typen in VHDL sind im Package std_logic_1164 vereinigt. Die darin Enthaltenen std_logic und std_logic_vector können neun verschiedene Zustände annehmen, die in Tabelle 2.1 dargestellt sind. Sie stellen praktisch die Grundlage für jede logische Schaltung zur Verfügung. Tabelle 2.1.: Zustände des std_logic Types [3] Zustand Erläuterung L schwaches Signal mit Tendenz zu 0 H schwaches Signal mit Tendenz zu 1 W schwaches Signal ohne Tendenz Z hochohmig 0 logisch 0 1 logisch 1 - unberücksichtigt U nicht initialisiert X unbekannt Jedes Signal in VHDL hat einen schon bei der Deklaration festgelegten Typ, der nicht mehr verändert werden kann. Im Standard-Package, dass in allen Projekten au- 10 KAPITEL 2. VHDL 2.2. GRUNDLAGEN tomatisch zur Verfügung steht, sind bereits einige Typen, wie Integer, Real, Boolean, Bit, etc. vordeniert. Einige Typen, wie die ersten beiden genannten, lassen sich auf bestimmte Bereich einschränken, wodurch die Optimierung durch den Compiler unterstützt wird. Zusätzlich zu den vorhanden Typen, können auch Eigene deniert werden. Ein Array mit std_logic_vector-Elementen kann zum Beispiel einen Buer oder RAM nachbilden. 2.2.3. Operatoren VHDL umfasst natürlich auch eine Vielzahl an Operatoren. Dazu gehören logische, relationale, shift und arithmetische Operatoren. Eine Übersicht darüber liefert Tabelle 2.2. Tabelle 2.2.: VHDL Operatoren [3] Typ Operator Bedeutung logisch not nicht relational shift arithmetisch and und or oder nand nicht und nor nicht oder xor exklusives oder xnor exklusives nicht oder = gleich /= ungleich < kleiner als <= kleiner gleich >= gröÿer gleich > gröÿer als sll logischer Linksshift srl logischer Rechtsshift sla arithmetischer Linksshift sra arithmetischer Rechtsshift rol Rotation links ror Rotation rechts + plus - minus * Multiplikation / Division mod Modulo rem Modulo mit Vorzeichen des ersten Operanden ** Potenz abs Absolutwert 11 2.2. GRUNDLAGEN KAPITEL 2. VHDL 2.2.4. Strukturelemente VHDL kennt die nachfolgend aufgelisteten Strukturen, die die Grundlage für jede Beschreibung darstellen. Im Folgenden werden nur diejenigen erläutert, die für das Verständnis dieser Arbeit notwendigen sind. Entity Architecture Conguration Process Signal Package Library Entity Mit einer Entity wird die Schnittstelle einer Komponente zur Auÿenwelt deniert. Dies umfasst insbesondere einen Bezeichner und die Denition der Schnittstellensignale. Als Beispiel dient die Denition, der in dieser Arbeit erstellten Multiplexer-Komponente Listing 2.1. Listing 2.1: Entity 2 zu 1-Multiplexer 1 entity 2 mux_2_1 is port ( 3 inputA : in std_logic ; 4 inputB : in std_logic ; 5 selA : in std_logic ; 6 selB : in std_logic ; output : out std_logic 7 8 9 ) ; 10 end mux_2_1 ; Der Bezeichner dieser Entity lautet mux_2_1. Über den port-Befehl sind vier Eingangssignale und ein Ausgangssignal deniert. Ein Signal kann auÿerdem als inout deniert werden. Dies kann unter anderem für einen Bus verwendet werden. Wichtig ist hierbei aber, dass zum Beispiel durch die Verwendung von Tristate-Komponenten das gleichzeitig Aktivieren von Treibern ausgeschlossen wird, da die Daten sonst auf dem Bus kollidieren. Natürlich können Eingangssignale nur gelesen und nicht beschrieben werden. Dies gilt im umgekehrten Sinn auch für Ausgangssignale. 12 KAPITEL 2. VHDL 2.2. GRUNDLAGEN Architecture Architectures beschreiben das Verhalten einer Komponente. Sie gehören immer zu einer vorher denierten Entity, auf die sie sich beziehen. In ihnen kann auch die Struktur abgebildet werden, in dem auf Subkomponenten verwiesen wird. Die Architecture der eben gezeigten Multiplexer Entity ist im Listing 4.1 des gleichnamigen Abschnitts 4.5 abgebildet. Process Prozesse in VHDL existiert innerhalb einer Architecture und laufen parallel zueinander ab. Ein wichtiger Punkt bei der Erstellung von Prozessen sind die sogenannte Sensitivitätslisten. Sie werden im Kopf von Prozessen deniert und sind dafür verantwortlich zu entscheiden welche Signaländerungen eine Aktivierung des Prozesses selbst auslösen. Bei dem nicht getakteten Multiplexer sind dies die beiden Eingangssignale, die gemappt werden und die Select-Signale. Dies ist notwendig, denn das Ausgangssignal soll nicht nur dann aktualisiert werden, wenn ein anderer Eingang gewählt wird, sondern auch, wenn sich das bereits gewählte Eingangssignal verändert. Signal In VHDL können Signale intern und extern deniert werden. Interne Signale, die innerhalb einer Architecture deniert werden, sind nicht nach auÿen sichtbar. Externe Signale können als Leitungen einer Schaltung verstanden werden, während Interne einen bestimmten Zustand innerhalb des abgeschlossenen Systems halten. Abgesehen von Signalen können auch Variablen deniert werden. Diese besitzen aber ausschlieÿlich einen lokalen Charakter. Im Gegensatz zu Variablen, die ihren Zustand unmittelbar nach einer Zuweisung ändern, geschieht dies bei Signalen erst, wenn der Prozess, in dem sie deniert sind, beendet ist. Somit haben Signale auch eine Zeiteigenschaft, die bei Variablen nicht vorhanden ist. Beide Typen behalten ihren Zustand auch nachdem ein Prozess beendet wurde und stehen beim nächsten Aufruf wieder zur Verfügung. Signale erhalten einen Wert über die Zuweisungsoperatoren <= und =>, dabei zeigt der symbolische Pfeil in Richtung der Signalzuweisung, also auf das Signal. Variablen können auf gleiche Weise mit den Operatoren := und =: gesetzt werden. Listing 2.2 zeigt, wie Busse in VHDL deniert werden können. Die geklammerte Nummerierung kann dabei, wie in diesem Beispiel in absteigender Ordnung erfolgen oder bei Verwendung des Schlüsselwortes to in Aufsteigender. Einzelne Signale oder Bündel dieses Signalbusses können ebenfalls auf die gleiche Weise angesprochen werden, um ihren Wert zu lesen oder zu verändern. Listing 2.2: Busse in VHDL 1 2 entity seven_digit is port ( 3 ... 4 output : out std_logic_vector (7 downto 0) 13 2.2. GRUNDLAGEN 5 KAPITEL 2. VHDL ) ; 6 end seven_digit ; Package In einem Package können Deklarationen von Programmteilen zusammengefasst werden, die im späteren Gebrauch öfter benötigt werden. Dies kann zum Beispiel genutzt werden, um an einer zentralen Stelle Konstanten zu denieren. Um auf die Elemente eines Package zuzugreifen muss dies durch die use-Anweisung eingebunden werden. Dabei wird der eigentliche Name des Package, gefolgt von einem . und dem Elementnamen notiert. Um alle Elemente eines Package einzubinden kann der ALL-Sux genutzt werden. Library Bibliotheken sind Container für Packages, Entities und andere kompilierte Objekte. Jedes Projekt arbeitet normalerweise mit seiner eigenen Standartbibliothek work, sofern dies nicht anders deniert wurde. Zusätzliche Bibliotheken, wie etwa ieee können über die library-Anweisung eingebunden werden. 2.2.5. Sequenzielle Anweisungen Natürlich bietet VHDL auch die Möglichkeit den sequenziellen Ablauf in Prozessen zu steuern. Die in der Programmierung üblichen Konstrukte, wie Bedingungen(if, case) und Schleifen(for, loop) sind auch in VHDL vertreten, auch wenn Letztere eher selten Verwendung nden. Eine Anweisung sei an dieser Stelle etwas näher erläutert - die wait-Anweisung. Bei der Arbeit mit und dem Entwurf von digitalen Schaltungen steht das Einhalten von bestimmen Zeitbeschränkungen oft im Vordergrund. VHDL bietet zur Beschreibung des Zeitverhaltens zwar die genannte Anweisung an, verbindet damit aber das Problem, dass diese nicht synthetisiert werden kann, obgleich sie sich für die Simulation sehr gut eignet. Ein einfaches Szenario ist die Generierung eines Taktes, um die entworfenen Komponenten zu testen. Mit der wait-Anweisung kann die Frequenz sehr einfach speziziert werden. Auÿerdem kann auch auf das Eintreten eines bestimmten Signalzustandes gewartet werden. Es ist also wichtig beim Entwurf von Beginn an darauf zu achten, dass diese Anweisung nur für Simulationszwecke geeignet ist. Eine synthetisierbare Alternative für das typische Warteproblem lässt sich durch das Mitzählen von Takten erreichen, wie es in den beiliegenden VHDL Komponenten fast ausschlieÿlich der Fall ist. 14 3. Entwicklungsboard Auf der Altera Website [2] ndet sich eine Übersicht über alle vorhanden Dokumente und eine kurze Boardbeschreibung. Darüber hinaus werden unterschiedliche Downloadpakete angeboten, die sowohl eine Dokumentation, als auch schematische Darstellungen der verbauten Komponenten beinhalten. Beide sind ebenfalls in der zurzeit aktuellsten Version im Dokumentationsordner der Daten-CD dieser Ausarbeitung enthalten. Leider sind detaillierte Beschreibung zu einzelnen Hardwarebauteilen kein fester Bestandteil der Boarddokumentation. 3.1. User LEDs Auf dem Entwicklungsboard sind sieben LEDs platziert, die frei verwendet werden können. Im Quartus-Projekt zu dieser Arbeit werden sie beispielsweise benutzt, um den Zugri auf den SRAM zu visualisieren. Jede LED verfügt über einen eigenen Ausgangspin am Cyclone FPGA, dargestellt in Tabelle 3.1 Tabelle 3.1.: Pindenition User LEDs [12] Description Schematic Signal Name User-dened LED 7 USER_LED7 Cyclone III Pin Number AF19 User-dened LED 6 USER_LED6 AG19 User-dened LED 5 USER_LED5 AC17 User-dened LED 4 USER_LED4 AE15 User-dened LED 3 USER_LED3 AD19 User-dened LED 2 USER_LED2 AF18 User-dened LED 1 USER_LED1 AE20 User-dened LED 0 USER_LED0 AD15 Bei der Ansteuerung der LEDs ist zu beachten, dass diese low-active sind. Soll ein 8-Bit breites Signal ausgegeben werden, so kann in VHDL einfach der not-Operator verwendet werden. Auf diese Weise entsprechen die LEDs auch dem logischen Bitwert. 3.2. Buttons / Switches Als Eingabemöglichkeiten auf dem Entwicklungsboard stehen zum einen fünf Drucktaster und zum anderen ein DIP Switch zur Verfügung. Diese benden sich links unten neben dem graschen LCD Display. Tabelle 3.2 zeigt die Pinbelegungen der Komponenten. 15 3.2. BUTTONS / SWITCHES KAPITEL 3. ENTWICKLUNGSBOARD Tabelle 3.2.: Pindenition User Buttons / DIP Switch Typ Schematic Signal Name Cyclone III Pin Number Button USER_PB3 AA12 Button USER_PB2 AH3 Button USER_PB1 AC12 Button USER_PB0 AD7 Button CPU_RESETn T21 Switch USER_DIPSW0 AC14 Switch USER_DIPSW1 AD18 Switch USER_DIPSW2 AG23 Switch USER_DIPSW3 AC19 Switch USER_DIPSW4 AD14 Switch USER_DIPSW5 G20 Switch USER_DIPSW6 AB15 Switch USER_DIPSW7 AF25 Abgesehen vom CPU_RESET-Drucktaster sind die übrigen Komponenten mit keiner Funktion belegt. Genau wie die User LEDs sind auch alle Taster low-active. 16 4. Bibliothek und Erläuterungen 4.1. GNU General Public License Alle von mir erstellten VHDL-Datei sind frei unter der GNU-GPL Lizenz veröentlicht. Nähere Informationen nden sich auf der GNU Webseite [4]. Ich stelle es Jedem frei diese Dateien frei zu modizieren und zu verwenden. 4.2. Aufbau Alle Funktionen, die in dieser Bibliothek zusammengefasst sind liegen in VHDL-Code vor. Zu jeder Komponente existiert auch eine Demodatei, die die Verwendung veranschaulichen soll. Nach Konvention trägt jede Demo den Namen ihrer zugeordneten Komponente plus Prex _demo und optionale Erweiterungen. Alle Dateinamen entsprechen auch dem jeweiligen Namen des verwendeten Entity. Hinter der Datei sram_controller_demo_async_async.vhd verbirgt somit das Demonstrationsbeispiel des SRAM-Controllers unter Verwendung der asynchronen Modi für lesende und schreibende Zugrie. Die Architekturen tragen den Namen behaviour und beinhalten alle Prozesse, die für die Umsetzung erforderlich sind. Diese sind ebenfalls mit einem eindeutigen Namen gekennzeichnet, der auf die jeweilige Verwendung schlieÿen lässt. Darüber hinaus beginnen alle Prozesse mit einem kleinen p. Alle Datei sind kommentiert und weitestgehend so strukturiert, dass ein schnelles Einarbeiten ermöglicht wird. Da es beim Bau von Controllern fast ausschlieÿlich um die Umsetzung von vorgegebenen Timings auf die Hardware geht, sind bestimmte Konstrukte immer wieder vorzunden. Abstrakt gesehen, verbirgt sich hinter ihnen immer ein Zustandsautomat mit einer denierten Übergangsfunktion. Alle näheren Erläuterungen zum Code nden sich im zugehörigen Abschnitt der jeweiligen Komponente. 4.3. Quartus Projekt Beiliegend zu dieser Arbeit bendet sich auf der Daten-CD das komplette QuartusProjekt(CycloneIIIEP3C120.qpf ), das kompiliert und direkt auf das Board übertragen werden kann. Es dient als Demonstrationsbeispiel und um einen ersten Überblick über die umgesetzten Komponenten zu gewinnen. Im Folgenden wird beschrieben, in welchem Zustand sich das Entwicklungsboard nach der Programmierung bendet. Das Character LCD Display ist von links nach rechts zeilenweise mit den Zeichen 17 4.4. VERWENDUNG KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN A-Z, sowie sechs weiteren Symbolen gefüllt, die fortlaufend aus der Character Liste der Displayspezikation [14] übernommen wurden Das 7-Digit Display zeigt die Ziern 1337 Im Graphic LCD Display erscheint jede zweite, dritte und siebente Zeile leer, alle anderen sind vollständig gefüllt Die sieben LED-Anzeigen auf dem Board alternieren zwischen 11000011 und 00001101 und visualisieren die Lesezugrie auf den SRAM Speicher 4.4. Verwendung Die folgenden Beschreibungen gehen davon aus, dass die API in Verbindung mit Altera Quartus [1] genutzt wird. Die VHDL-Dateien können auf zwei unterschiedliche Arten verwendet werden. 1. Einbindung der Dateien direkt in das eigene Projekt 2. als Bibliothek Die folgende Auistung bietet eine Übersicht über alle VHDL-Dateien, die benutzt werden können(keine Demos). character_lcd.vhd sram_controller.vhd graphic_lcd.vhd seven_digit.vhd Bei der direkten Einbindung gehe ich davon aus, dass ein Quartus Projekt vorliegt, in dem bereits ein Top-Level Entity deniert ist. Um die Übersicht im Projekt zu behalten bietet es sich an einen eigenen Ordner für den VHDL-Code zu verwenden, sowie einen separaten für die Bibliotheksfunktionen, wie zum Beispiel api_ep3c120. In diesem können dann alle erforderlichen Dateien abgelegt werden. Die Einbindung der Komponenten in das eigene Projekt kann entweder direkt im VHDL Code geschehen oder über die Block Diagram/Schematic File. Bei der letzterer Methode muss ein entsprechendes Symbol erzeugt werden. Dafür genügt ein Rechtsklick im Filebrowser des Projektnavigators und die Auswahl der Funktion Create Symbol Files for Current File im Kontextmenü, dargestellt in Abbildung 4.1. Danach kann das neu erstellte Symbol in das Blockdiagramm eingefügt und verwendet werden. Die API lässt sich am leichtesten als Bibliothek einbinden. Dies hat auÿerdem den Vorteil das keine Symbole manuell erzeugt werden müssen, da diese bereits in kompilierter Form vorliegen. In Quartus [1] lässt sich ein Verzeichnis mit Quelldateien als Bibliothek einbinden, das automatisch durchsucht wird. Dies kann entweder direkt bei der Projekterstellung geschehen oder im Nachhinein. 18 KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.5. SIGNAL MULTIPLEXER Abbildung 4.1.: Quartus Kontextmenü im Filebrowser Der Project Wizard erlaubt im Schritt 2/5 das Hinzufügen von User Libraries, alternativ ist dies bei bereits erstellten Projekten auch über Assignments -> Settings -> Libraries im Kontextmenü möglich. Beide Methoden führen zur gleichen Oberäche. Im Abschnitt Project libraries muss nun das work-Verzeichnis der zu dieser Ausarbeitung beiliegenden Projektdaten angegeben werden. Danach lassen sich alle erstellten Komponenten der API als Symbole direkt einbinden. 4.5. Signal Multiplexer Ein Multiplexer ist ein Baustein, der es ermöglicht eine bestimmte Anzahl an Eingangssignalen einem Ausgang zuzuordnen. Dazu wird mindestens ein zusätzliches Signal benötigt mit dem der Eingang gewählt werden kann. Listing 4.1 zeigt die Architektur eines solchen Mux in VHDL. Eine kleine Besonderheit besteht darin, dass inputA hier exklusiv verwendet wird, sollten beide Eingänge als aktiv gewählt werden. Natürlich lässt sich dies auch durch ein zwei Bit breites Signal modellieren. Da die Auswahl aber von zwei dedizierten Demo-Komponenten getrieben wird, war es naheliegender zwei separate Leitungen zu verwenden. Listing 4.1: 2 zu 1-Multiplexer 1 architecture 2 begin 3 pProcess : 4 begin 5 mux_2_1 '1 ') is inputB , selA , SelB ) then o u t p u t <= i n p u t A ; 7 e l s i f ( selB = 8 '1 ') then o u t p u t <= i n p u t B ; 9 11 of p r o c e s s ( inputA , i f ( selA = 6 10 behaviour end end end if ; process pProcess ; behaviour ; 19 4.6. LCD DISPLAYS KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.6. LCD Displays Auf dem Entwicklungsboard benden sich zwei verschiedene LCD Displays. Dies ist zum einen das vom Hersteller Lumex [5] fabrizierte zweizeilige 16 Character LCD Display LCM-S01602DSR/C [14] und zum anderen das von Optrex [6] hergestellte monochrome 128x64 Pixel Graphic LCD Display F-51852GNFQJ-LB- A*N [15]. Beide Displays werden über den selben Bus angesteuert, verfügen aber über separate Steuerleitungen(ausgenommen die Leitungen für die Daten/Instruktionswahl und das WriteEnable-Signal). Somit lassen sie sich zwar parallel, aber nicht gleichzeitig betreiben. Die Steuerung der geteilten Signalleitungen übernehmen zwei Multiplexer, die in den Blockbildern im Anhang dieser Ausarbeitung dargestellt sind[A.1A.4]. Die vorgestellten Controller beider Displays müssen explizit über das enable -Signal aktiviert werden. Diese Funktion wurde implementiert, um mögliche Datenkollisionen zu vermeiden. 4.6.1. 2-Line Character LCD Display Vorbemerkung In der Altera-Dokumentation [12] zum Board bendet sich ein Fehler bezüglich der Pindenition. Das Signal für LCD chip select (LCD_D_CS ) wird nicht über AB24, sondern über AC24 angesteuert. Diese Korrektur bezieht sich lediglich auf die Boarddokumentation und nicht auf die schematischen Darstellungen. Generell scheinen diese wesentlich fehlerfreier zu sein, als entsprechende Referenzen in der Dokumentation. Eine Verweis [14] zum verwendeten Datenblatt von Optrex ndet sich im Literaturverzeichnis, welches sich aber auf das verbaute Lumex-Fabrikat ohne Probleme übertragen lies. Pindenition Das Display verfügt über einen 8-Bit breiten Datenbus, sowie drei Steuerleitungen für die Auswahl des Zielregisters(Daten/Instruktionen), dem WriteEnable-Singnal und dem ChipSelect-Signal. Tabelle 4.1 ist ein korregierter Ausschnitt aus der Boarddokumentation. Register und Initialisierung Das Display beinhaltet zwei 8-Bit Register, ein Instruktions- und ein Datenregister. Das IR(Instruktionsregister), auf dem nur geschrieben werden kann, dient als Speicher für Steueranweisungen, wie das Leeren des Displays oder Shiftoperationen, sowie für die Adressierung des Daten- und des Zeichenspeichers. Das DR(Datenregister) ist ein Zwischenregister und hält Daten von bzw. für lesende und schreibende Zugrie auf den Daten- bzw. Zeichenspeicher. Die Auswahl des Zielregisters(IR/DR) wird durch das LCD_D_C -Signal bestimmt. Die Initialisierung des Displays kann auf zwei unterschiedliche Arten erfolgen. Dies ist sowohl durch den internen Reset-Schaltkreis auf Hardwareebene, als auch durch eine 20 KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.6. LCD DISPLAYS Tabelle 4.1.: Pindenition 2-Line Character LCD Display [12] Description Schematic Signal Name Cyclone III Pin Number LCD data bus bit 0 LCD_DATA0 AA4 LCD data bus bit 1 LCD_DATA1 AD1 LCD data bus bit 2 LCD_DATA2 V8 LCD data bus bit 3 LCD_DATA3 AB5 LCD data bus bit 4 LCD_DATA4 AE2 LCD data bus bit 5 LCD_DATA5 V5 LCD data bus bit 6 LCD_DATA6 V6 LCD data bus bit 7 LCD_DATA7 AB3 LCD data/command select LCD_D_Cn D27 LCD write enable LCD_D_WEn AC4 LCD chip select LCD_D_CSn AC24 Software-Initalisierung im 4- oder 8-Bit Modus möglich. Da der Controller manuell eine 8-Bit Initialisierung ausführt, wird im folgenden nur darauf eingegangen. Die folgenden Schritt zeigen den Ablauf [14]: 1. Mindestens 15ms warten, nachdem 4.5V Versorgungsspannung anliegen 2. Function Set-Befehl ausführen 3. Mindestens 4.1ms warten 4. Schritt 2 5. Mindestens 100µs warten 6. Schritt 2 Nach diesem letzten Befehl kann für alle weiteren lesenden und schreibenden Zugrie auf explizites Warten verzichtet werden, da jetzt das Busy-Flag überprüft werden kann. Dieses Flag gibt an, ob das Display im Moment eine Aktion ausführt oder nicht. Ist das Flag 1, so können keine neuen Befehle angenommen werden. Um den aktuellen Status auszulesen, muss eine lesende Operation auf dem Instruktionsregister ausgeführt werden. Das Busy-Flag liegt am Datenbit 7(LCD_DATA7 Tabelle 4.1) an. Bevor die Initialisierung komplett ist, müssen noch folgende Befehle geschrieben werden: 7. Interfacedaten setzen 8. Display ausschalten 9. Display leeren 10. Modus setzen 21 4.6. LCD DISPLAYS KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 11. Display einschalten Zu 7.: Das Display wird in den 8-Bit-Modus gesetzt. Auÿerdem werden auch die Anzahl der Zeilen, sowie die verwendete Schriftart konguriert. Zu 10.: Bestimmt das Verhalten beim Schreiben und Lesen vom Datenspeicher. Eine detaillierte Beschreibung der einzelnen Befehle und Funktionsweisen ndet sich in der Dokumentation zum Display [14]. Adressierung Nach der Initialisierung kann über den Set DD RAM Address-Befehl - Schreibbefehl auf den Datenspeicher - der interne Zeiger auf eine bestimmte Position gesetzt werden. Die erste Zeile des Displays beginnt bei der Adresse 0x00 und endet bei 0x07. Für die zweite Zeile entsprechend sind dies 0x40 und 0x47. Die Speicherbereiche der Zeilen liegen also nicht direkt hintereinander. Anschlieÿend können Daten an diese Position geschrieben werden. Nach einem schreibenden Zugri wird die Position des internen Zeigers automatisch erhöht, wenn diese Option vorher entsprechend bei der Initialisierung gesetzt wurde. So muss bei einem kompletten Schreibzyklus die Zeigerposition nur zu Beginn jeder Zeile neu gesetzt werden. Zeichensatz Zusätzlich zu der Verwendung der bereits vorhanden Zeichentabelle können in den Zeichenspeicher auch neue Einträge geschrieben werden. Dies können entweder acht 5x7 oder vier 5x10 groÿe Pixelzeichen sein. Das verbaute Display ist für letztere Gröÿe ausgelegt. Die Programmierung eines neuen Zeichens erfolgt zeilenweise in den Zeichenspeicher. Nähere Informationen zum genauen Ablauf sind im Datenblatt des Displays enthalten [14]. Character LCD Controller Im Rahmen dieser Arbeit entstand ein einfach zu verwendender Controller, der sich auf die wesentlichen Funktionen, wie die Initialisierung und Ausgabe auf dem Display beschränkt. Dieser wird über den 125Mhz Takt des Entwicklungsboards getrieben. Dies ist unbedingt erforderlich, da sonst die Timings des Displays nicht mehr eingehalten werden können. Tabelle 4.2 zeigt die Pinbelegung des Character LCD Controllers[A.1]. Die Inbetriebnahme des Display Controllers gestaltet sich einfach und intuitiv. Die drei Signale buf_input, buf_position und buf_write_enable steuern das darzustellende Zeichen, die Position an dem dieses erscheinen soll und signalisieren das Schreiben in den Buer des Controllers. Aktualisieren des Displayinhalts Nach der Initialisierung des Displays wartet der Controller auf einen Refresh-Befehl, über das gleichnamige Eingangssignal. Im Gegensatz zum Graphic LCD Controller[4.6.2] ist der hier vollzogene Handshake etwas oener gestaltet. Der Controller quittiert den 22 KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.6. LCD DISPLAYS Tabelle 4.2.: Pindenition Character LCD Controller Typ Pin Beschreibung Cyclone III Pin Number in clock Takteingang A14 in reset Reset T21 in buf_input[7..0] 8-Bit Dateneingang - in buf_position[4..0] 5-Bit Positionseingang - in buf_write_enable Schreibag - in enable Controlleraktivierung - inout data[7..0] Datenausgang Tabelle 4.1 out data_command_select_n Zielregister D27 out write_enable_n Schreibag AC4 out chip_select_n Aktivag AC24 Befehl lediglich durch aktivieren des refresh_done -Signals, sobald er alle erforderlichen Schritte ausgeführt hat. Ein Refresh ist im Controller dabei als vollständiges Neuschreiben aller Zeichen des Displays aus dem internen Buer umgesetzt. Dazu wird als erstes die Datenadresse auf 0x00(Anfang erste Zeile) gesetzt. Danach folgen 16 Schreibzugrie bis der Zeiger am Ende der Zeile angekommen ist. Das gleiche Verfahren wird auch für die zweite Zeile und die Startadresse 0x40 angewendet, bis alle 32 Zeichen neu geschrieben wurden. Danach bendet sich der Controller wieder im Ausgangszustand. Democode Im Demonstrationscode hält ein Array die 32 Bitcodes für die entsprechenden Zeichen. Eine komplette Liste ndet sich in der Dokumentation des Displays [14]. Listing 4.2 verdeutlicht wie der LCD Controller angesprochen wird. Zuerst werden alle 32 Zeichen in den Buer des Controllers geschrieben. Dies geschieht alle zwei Takte, wenn buf_write_enable gesetzt ist. Ist bisher kein Output aktiv(Internes Signal oe ), so wird dieser aktiviert. Die Daten für das Display stammen aus dem Zeichenarray, dass hier nicht mitgelistet ist. Die Position ist eine 5-Bit Repräsentation der Werte 0 bis 31 und entsteht hier aus der Umwandlung eines Integers in einen std_logic_vector, limitiert auf 5 Bit. Wenn der Output bereits aktiv ist, wird dieser deaktiviert. So wird sichergestellt, dass zwischen jedem schreibenden Zugri auch ein nicht schreibender Zustand existiert, in dem das buf_write_enable -Signal deaktiviert wird, auch wenn dies nicht zwingend erforderlich ist. Sind alle Zeichen an den Controller übermittelt und in dessen Zwischenspeicher, so kann die Anzeige des Displays aktualisiert werden. Dies geschieht wenn der interne Zähler 32 erreicht hat. refresh signalisiert dem Controller, dass eine Aktualisierung der Ausgabe auf dem Display ausgeführt werden soll. Wenn die Anzeige erneuert wurde, wird dies mit dem refresh_done -Signal bestätigt, so dass neue Änderungen übermittelt werden können. Das Demonstrationsbeispiel füllt das Display allerdings nur einmalig. 23 4.6. LCD DISPLAYS KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN Listing 4.2: Quellcode Character LCD Demo 1 i f ( rising_edge ( clock ) ) 2 i f ( counter < 32) then then 3 c h a r a c t e r _ m u x <= 4 i f ( oe = '0 ') '1 '; 5 o e <= '1 '; 6 b u f _ w r i t e _ e n a b l e <= 7 b u f _ o u t p u t <= d a t a ( c o u n t e r ) ; 8 b u f _ p o s i t i o n <= s t d _ l o g i c _ v e c t o r ( t o _ u n s i g n e d ( c o u n t e r , then '1 '; 5) ) ; 9 else 10 o e <= 11 b u f _ w r i t e _ e n a b l e <= 12 counter 13 := e l s i f ( counter = 32) 15 16 r e f r e s h <= '1 '; counter 33; := then 17 e l s i f ( counter = 33) then 18 i f ( refresh_done = '1 ') 19 c h a r a c t e r _ m u x <= 20 r e f r e s h <= 21 e n a b l e <= 22 end 24 end then '0 '; '0 '; '0 '; if ; end 23 '0 '; counter + 1; if ; end 14 '0 '; if ; if ; 4.6.2. Graphic LCD Display Besonderheiten Einige Signale des Displays werden direkt vom Max II CPLD bestimmt. Dieser legt das Interface bereits auf den parallelen 80 series CPU Modus fest. Die vollständige Spezikation, die für das Ansteuern des Displays erforderlich ist, ist auf drei Dokumente verteilt [15] [16] [13]. In diesen Spezikationen sind für verschiedene Spannungsniveaus auch unterschiedliche Timings angegeben. Um möglichst alle Fälle abzudecken wurde bei der Entwicklung vom pessimistischsten Fall ausgegangen, worauf sich auch die nachfolgenden Beschreibungen beziehen. Pindenition Die Pindenition des Graphic LCD Display in Tabelle 4.1 zeigt die Überschneidungen mit dem Character LCD Display auf. Auÿerdem sind die Signale LCD_SER rekt über den FSM Bus im MAX II CPLD Register verändern. 24 LCD_BS1 und nicht direkt mit dem Cyclone FPGA verbunden. Sie lassen sich nur indi- KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.6. LCD DISPLAYS Tabelle 4.3.: Pindenition Graphic LCD Display [12] Description Schematic Cyclone III Signal Name Pin Number Tabelle 4.1 LCD data bus Tabelle 4.1 LCD data/command select LCD_D_Cn D27 LCD write enable LCD_D_WEn AC4 Parallel interface selection LCD_BS1 - LCD chip select LCD_CSn AB24 LCD read enable LCD_E_RDn V7 LCD reset LCD_RSTn H7 LCD parallel/serial data select LCD_SERn - LCD write enable LCD_WEn AC4 Funktionsbeschreibung Im Initialzustand ist das Display auf dem Entwicklungsboard nicht aktiviert. Bevor es verwendet werden kann sind einige Schritte erforderlich. Über den internen Resetschaltkreis können einige Initalisierungsschritte eingespart werden. Dazu verfügt das Display über ein separates RST Reset-Signal. Dieses muss für mindestens 1,5µs low-active gehalten werden. Nach weiteren 1,5µs ist der Resetzyklus abgeschlossen und das Display bendet sich im normalen Zustand. Der interne Reset setzt die Konguration des LCD Displays auf vordenierte Standartwerte, die bei Bedarf angepasst werden müssen. Das New Japan Radio LCD Driver-Datenblatt [13] enthält eine vollständige Instruktionstabelle mit Befehlen, die an das Display geschickt werden können. Tabelle 4.4 fasst die Wichtigsten daraus zusammen. Bei allen schreibenden Zugrien muss W E gesetzt werden - also logisch 0. Entsprechendes gilt für lesende Zugrie und E _RD-Signal. Es sollten nie beide Signale gleichzeitig aktiv sein. Die Auswahl das des Daten- oder Instruktionsregisters erfolgt wie beim Character LCD Display zuvor auch über ein separates Signal D _C . Dabei entspricht logisch 0 dem Instruktions- und logisch 1 folglich dem Datenregister. Die meisten Befehle sind selbsterklärend. Die Adressierung des Speichers geschieht zeilenweise über die Seitenadresse [16]. Dabei sind immer acht Zeilen zusammengefasst. Dies ergibt bei 64 Zeilen genau acht Werte, die durch vier Bit repräsentiert werden. Die endgültigen Adressen sind abhängig von der horizontalen und vertikalen Schreibrichtung des Speichers. Bei einer links-rechts-oben-unten-Konguration beginnt die erste Zeile bei der Seitenadresse 0x00, die Letzte bei 0x07. Die Spaltenadressen umfassen bei gleicher Konguration den Bereich 0x00 bis 0x7F und werden in zwei Teile - den oberen vier und den unteren vier Bit - zerlegt. Normalerweise erhöht jeder Zugrisbefehl den internen Adresszeiger um eine Stelle. Dies kann zumindest für lesende Zugrie deaktiviert werden. Soll das Display zeilenweise komplett beschrieben werden so muss jedoch am Zeilenende mindestens die Spaltenadresse zurückgesetzt werden, gegebenenfalls auch die Zeilenadresse, wenn ein 25 4.6. LCD DISPLAYS KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN Tabelle 4.4.: Instruktionstabelle Graphic LCD [13] Befehl Bitcode Display On/O 1 0 1 0 1 1 1 [0/1] Beschreibung 1:On 0:O Page address set 1 0 1 1 D3 D2 D1 D0 4-Bit Seitenadresse Column address set 0 0 0 1 D3 D2 D1 D0 Spaltenadresse Bit 7-4 0 0 0 0 D3 D2 D1 D0 Spaltenadresse Bit 3-0 Display data write D7-D0 Schreibbefehl Display data read D7-D0 Lesebefehl ADC select 1 0 1 0 0 0 0 [0/1] Spaltenrichtung Common direction select 1 1 0 0 [0/1] * * * Upper 4-bit Column address set Lower 4-bit 0: R -> L 1: L -> R Zeilenrichtung 0: T -> B 1: B -> T Driver On/O 1 1 1 0 0 1 1 [0/1] 0: Driver O 1: Driver On achtzeiliger Abschnitt verlassen wird. Speicherzugri Zugrie auf den Speicher des Displays sind im parallelen 80 series CPU Modus, in Abbildung 4.2 dargestellt, relativ einfach implementiert. Bei Einhaltung der angegebenen Timings ist ein Auslesen des Busy-Flag nicht notwendig. Die Daten lassen sich sowohl lesend, als auch schreibend, zur steigenden Taktanke der W E- und E _RD- Signale abgreifen, bzw. schreiben. Wichtig ist allerdings die Einhaltung der zeitlichen Abstände zwischen den einzelnen Zyklen. Diese betragen je nach der anliegenden Spannung bis zu 1000ns. Graphic LCD Controller Im Gegensatz zum Character LCD, wird der Controller für das grasche Display nur mit 104Mhz getaktet(vergleich Abschnitt SRAM Bibliotheksfunktionen 4.7). Dies entspricht genau einer Periodenlänge von 10ns. Die Pinbelegung des Graphic LCD Controller ist in Tabelle 4.5 dargestellt. Der Controller initialisiert das Display entsprechend der funktionalen Beschreibung der vorangegangenen Abschnitte und wechselt dann in den Standby-State. In diesem Zustand wird auf die Aktivierung des pixel_write_enable -Signals gewartet. Wenn dieses Signal aktiv ist, tritt ein Zyklus in Kraft der genau einen Pixel aktualisiert. Vor jedem Schreib und Lesebefehl wird die Adresse neu gesetzt, um dem automatischen Weitersetzen des Adresszeigers entgegen zu wirken. Der Ablauf dieses Prozesses lässt sich in folgende Teilschritte aufgliedern. 1. Setzen der vertikalen und horizontalen Position anhand der anliegenden Signale pixel_x 26 und pixel_y KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.6. LCD DISPLAYS Abbildung 4.2.: Lese/Schreib-Timings Graphic LCD Display [15] 2. Lesen der acht vertikalen Bits an dieser Position 3. Position erneut setzen 4. Überschreiben des entsprechenden Bits anhand des pixel_y -Signals 5. Die modizierten acht Bit zurückschreiben Der Controller arbeitet über die Signale pixel_write_enable, processing und done ebenfalls mit einem Handshake-Verfahren. Die Demokomponente leitet durch das erste Signal den Aktualisierungszyklus ein. Zu diesem Zeitpunkt müssen auch die Positionen und der Status des zu schreibenden Pixels gesetzt werden. Die horizontale Position wird dabei durch sieben Bit, die vertikale Position durch acht Bit, entsprechend der Anzahl der Zeilen und Spalten, repräsentiert. Wie in der Funktionsbeschreibung angedeutet muss die aktuelle Zeile also nicht in 8-Bit Abschnitte umgerechnet werden, dies übernimmt der Controller und vereinfacht so das Befüllen des Displays. processing -Signal, dass der pixel_write_enable wieder deak- Nach diesem Schritt bestätigt der Controller über das Befehl ausgeführt wird. Zu diesem Zeitpunkt sollte tiviert werden. Der letzte Schritt besteht darin auf das Zyklenende des Controllers zu warten. Dieser signalisiert dies über das done -Signal. Die nutzende Komponente, wie im Demonstra- tionsbeispiel zu sehen, kann in diesem Schritt auch die internen Zeilen- und Spaltenwerte aktualisieren. Democode Die Demo-Architecture nutzt den Modulo-Operator, um jede zweite, dritte und siebente Zeile vollständig zu leeren und alle Übrigen zu füllen. Da pro Zyklus immer nur ein 27 4.7. SRAM KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN Tabelle 4.5.: Pindenition Graphic LCD Controller Typ Pin Beschreibung Cyclone III Pin Number in clock Takteingang megafunction ppl in reset Reset T21 in pixel_write_enable Schreibag in pixel_x x-Position in pixel_y y-Position - in pixel_on aktiv/inaktiv-Flag - in enable Controlleraktivierung - inout data[7..0] Datenausgang Tabelle 4.3 - out CSn Aktivag AB24 out D_Cn Zielregister D27 out E_RDn Leseag V7 out RSTn Reset H7 out WEn Schreibag AC4 out done Handshake - out processing Handshake - Pixel verändert wird, bleibt der Aufwand im besonderen bei kleineren Änderungen am Display gering. An diesem Beispiel wird auch demonstriert wie ein Integer mit Hilfe des ieee.numeric_std Package in einen std_logic_vector konvertiert werden kann. 4.7. SRAM Vorbemerkung In der Dokumentation [12] beginnt der Adressbus bei Bit 1. Sowohl der hier verwendete Controller, als aus auch das Demo-File denieren die 21 Adress-Bits als std_logic_vector[20..0], entsprechend ist auch die Pinbelegung zu interpretieren. Der Speicher selbst ist an einem verteilten Bus(FSM Bus) gegliedert, der darüber hinaus noch das MAX II CPLD und den Flashspeicher verbindet. Grundlage für die Erstellung ist ein Manual [17] für einen ähnlichen Speicher, da die typengenaue Dokumentation nicht verfügbar ist. Dieser ist in den wesentlichen Punkten aber analog zu verstehen. Wenn im Manual Bezug auf das M RS -Signal genommen wird, so ist dies als PS zu verstehen(Tabelle 4.6). Beschreibung Auf dem Entwicklungsboard ist ein 8MB groÿer SRAM mit einer 32-Bit Datenanbindung realisiert. Um diese Datenbreite zu erreichen wird ein 32-Bit Wort auf zwei SRAM-Bausteine aufgeteilt. Somit hält jeder davon 16-Bit. Die genaue Bezeichnung, der von Samsung [7] hergestellten SRAM-Bausteine lautet K1B3216B2E-BI70. Dieser 28 KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.7. SRAM Speicher kann maximal mit einer Frequenz von 104Mhz betrieben werden. Pindenition Der 21-Bit breite Adressbus ist mit beiden Bausteinen verbunden. Der Datenbus gliedert sich in die oberen 16- und die unteren 16-Bit auf. Da beide Bausteine synchron arbeiten müssen, teilen sie sich die selben Steuerleitungen und erhalten so die gleichen Instruktionen. Davon ausgenommen sind die separaten Byte-enabled - und Wait -Signale. Die folgende Tabelle 4.6 zeigt die Pinbelegung, sowie die Konnektivität zum Cyclone III-Chip. Tabelle 4.6.: Pindenition SRAM [12] Description Schematic Signal Name Cyclone III Pin Number Byte enables bit 0 SRAM_BEn0 AF20 Byte enables bit 1 SRAM_BEn1 AH26 Byte enables bit 2 SRAM_BEn2 AE22 Byte enables bit 3 SRAM_BEn3 AB21 AD22 Clock SRAM_CLK Chip select SRAM_CSn AB19 Output enable SRAM_OEn AD25 Power save /MRS set pin SRAM_PSn B4 Data wait bit 0 SRAM_WAIT0 AG15 Data wait bit 1 SRAM_WAIT1 AH25 Write enable SRAM_WEn AE25 Address valid SRAM_ADVn AA19 Address bit 0..20 FSA1..21 [12] Data bit 0..31 FSD0..31 [12] Initialisierung Beide Speicherbausteine müssen vor der ersten Verwendung initialisiert werden. Für diesen Prozess muss zunächst das CS - und nachfolgend das P S -Signal gesetzt werden. Dieser Zustand muss für mindestens 200µs aufrecht gehalten werden. Wird nachfolgend CS deaktiviert, so bendet sich der Speicher im normalen Operationsmodus. Die folgende Abbildung 4.3 zeigt die verschiedenen Zustände des Speichers. Nach der Initialisierung folgt das Schreiben in den Mode Register. Dieser hält Informationen über die verschiedenen Operationsmodi des Speichers wie Treiberstärke, die Modi für Schreib- und Lesezugrie, Latenzen, Refresh-Zyklen, usw. Der voreingestellte Modus, nach der Initialisierung, ist auf asynchrone Lese- und Schreibzugrie ausgelegt(4 Page Read And Asynchronous Write). Da dies laut Dokumentation nicht völlig gewährleistet werden kann, wird ausdrücklich ein manuelles Setzen der Einstellungen empfohlen. 29 4.7. SRAM KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN Abbildung 4.3.: SRAM Zustandsautomat Speicherkonguration und MRS-Mode Um den Speicher in den MRS-Mode zu bringen, muss innerhalb von 0.5µs nachdem PS deaktiviert wird ein Schreibbefehl folgen. Geschieht dies nicht, so geht der Spe- icher in den PAR-Mode über, der die einzelnen Zellen aurischt, um die Datenintegrität zu gewährleisten. Das Setzen der verschiedenen Optionen erfolgt über den Adressbus. Dazu erhält jedes Bit, bzw. jede Bitgruppe eine vorgeschriebene Bedeutung. Eine nähere Beschreibung hierzu ndet sich im Abschnitt Bibliotheksfunktionen dieses Kapitels(Tabelle 4.7). Die Boarddokumentation empehlt für den Betrieb des Speichers den 1/2 drive-Mode. Speicherzustände Bevor der Speicher in den Standby-Modus wechselt, sollte eine aktive Operation ausgeführt werden. Dies kann das Lesen an einer beliebigen Adresse sein. Von nun an wechseln die Zustände im optimalen Fall nur noch zwischen Standby, Refresh und Active. Bendet sich der Speicher im PAR-Mode, bedeutet dies, dass keine andere Anweisung ausgeführt werden kann, solange der Zyklus nicht beendet ist. Geschieht dies wiederum nicht in gewissen periodischen Abständen, so kann nicht sichergestellt werden, dass sich der Speicherinhalt nicht verfälscht. Wird der Speicher nur im asynchronen Modus betrieben, wird eine Änderung der Konguration wahrscheinlich nicht notwendig sein. Im synchronen Modus kann dies jedoch häuger passieren, zum Beispiel, wenn die Länge der Burst zugrie angepasst werden muss. Asynchrone und synchrone Operationsmodi Im Folgenden soll noch einmal näher auf die soeben angesprochenen verschiedenen Betriebsmodi des Speichers eingegangen werden. Wie bereits erwähnt, können lesende und schreibende Zugrie entweder synchron oder asynchron ausgeführt werden. Ein Wechsel im laufenden Betrieb muss explizit über den MRS-Mode konguriert werden. Im asynchronen Modus wird der Takt, ebenso wie die Signale 30 ADV und W AIT KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.7. SRAM völlig vernachlässigt und spielen für die Operationen auf dem Speicher keine Rolle. Lesende Zugrie lassen sich wie folgt unterscheiden. normale Zugrie, die ein 32-Bit Wort an einer bestimmten Adresse auslesen Zugrie, bei denen die Adresse beim lesen rotiert wird Bei der zweiten Methode können bis zu vier Werte von verschiedenen Speicherseiten gelesen werden, daher der Begri 4 Page Read Operation. Auch schreibende Zugrie können beschleunigt werden, indem zwei Bytes direkt nacheinander innerhalb einer Operation in den Speicher geschrieben werden. Wird der synchrone Modus verwendet, so lässt sich der Durchsatz des Speichers deutlich steigern. Allerdings kommen viele weitere Faktoren hinzu. Ein zentraler Begri hierbei ist die Latency oder Speicherzugriszeit. Jede Operation ist ankenges- teuert und die Latenz bestimmt die Anzahl der Taktanken zwischen dem eigentlichen Befehl und dem Anliegen der Daten. Dabei wird diese umso höher, je schneller der Speicher getaktet wird. In diesem Modus werden Zugrie in Bursts zusammengefasst. Die Burstlänge bestimmt die Anzahl der Daten, die dabei gelesen oder geschrieben werden sollen. Unterstützt werden bei diesem Speicher die Wortlängen 4, 8, 16 und 256, wobei Letzteres einer vollständigen Seite entspricht. Ein Burstzugri lässt sich auch manuell stoppen, so dass die Länge optimal an jede Situation angepasst werden kann. Auf diese Weise sind auch Bursts der Längen eins bis drei umsetzbar. Letztlich existieren noch unterschiedliche Typen von Burstsequenzen. Bei linearer Konguration wird die Zugrisadresse stückweise von der Startadresse inkrementiert. Dies ist das Verhalten was wahrscheinlich am ehesten erwartet wird. Die Sequenz kann aber auch interleaved erfolgen. Da Speicherbänke nach einem Schreibvorgang für eine gewisse Zeit nicht ansprechbar sind, geht bei sequentiellen Zugrien Zeit verloren. Dies kann durch Interleaving ausgeglichen werden. Dabei werden die Datenworte alternierend auf die zur Verfügung stehenden Speicherbänke aufgeteilt. SRAM Controller Tabelle 4.7 zeigt die verwendete Konguration des Mode Register entsprechend des SRAM Manuals [17]. Für die Generierung des Taktes mit 104Mhz wird eine megafunction aus Quartus verwendet. Dieser Baustein generiert aus dem 125Mhz Input den gewünschten Ausgangstakt. Dieser treibt sowohl den eigentlichen Controller, als auch die Demokomponente[A.1]. Der Controller verwendet für die aktiven Zugrie auf den Speicher ausschlieÿlich die asynchronen Modi. Dies bedeutet zwar im Hinblick auf die synchronen Modi einen Leistungsverlust, dieser fällt aber aufgrund des geteilten Busses(FSM Bus) weniger stark ins Gewicht. Die Leistung des Moduls sollte also für alle herkömmlichen Aufgaben genügen. Um die Verwendung weiterhin möglichst einfach zu gestalten wird beim Lesen des Speichers auch auf die Möglichkeit verzichtet mehrere Wörter von verschiedenen Seiten mit einer Operation zu lesen(4 Page Read Operation). 31 4.7. SRAM KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN Tabelle 4.7.: Mode Register SRAM [12] Description Address Value driver strength: 1/2 Drive 17..16 01 mode select: Async. 4 Page Read / Async. Write 15..14 00 wait polarity: low enable 13 `0' reserved 12 `0' 011 latency count: 7 11..9 burst type: linear 8 `0' burst length: 4 word 7..5 010 10 Partial Array Refresh: PAR Enable 4..3 Partial Array Refresh Array: Bottom Array 2 `0' Partial Array Refresh Size: Full Array 1..0 00 Refreshzyklen In der aktuellen Version des Controllers erfolgt das Erneuern der Speicherzellen alle 60ms, bzw. schnellstmöglich nach dieser Zeit, falls gerade eine Operation ausgeführt wird. Leider lieÿen sich keine konkreten Mindestwerte dafür in der Dokumentation nden. Aus eigenen Recherchen lässt sich aber schlieÿen, dass etwa 64ms die Regel sind. Im VHDL-Code des Controller bestimmt ein separater Prozess, ob ein Refresh ausgeführt werden muss oder nicht. Dazu wird nach Ablauf von 60ms ein internes Signal gesetzt, dass bei der Abarbeitung des Standby State berücksichtigt wird(Listing 4.3). Listing 4.3: Quellcode SRAM Controller 1 ... 2 when STANDBY_STATE => 3 CSn <= 4 '1 '; −− s t a r t s t a n d b y c l o c k c o u n t e r 5 6 r e s e t _ s t a n d b y _ c l o c k _ c o u n t e r <= 7 '0 '; −− l o w e r done 8 9 d o n e <= 10 '0 '; −− check i f r e s e t i s needed 11 12 i f ( need_refresh = '0 ') then −− o p e r a t e i f r e q u e s t e d 13 14 i f ( write_data = '1 ' and read_data = 15 c u r r e n t S t a t e <= ASYNC_WRITE_STATE; 16 p r o c e s s i n g <= '0 ') then −− g o t o w r i t e s t a t e '1 '; −− s i g n a l p r o c e s s i n g 17 e l s i f ( write_data = 32 '0 ' and read_data = '1 ') then KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.8. 18 c u r r e n t S t a t e <= ASYNC_READ_STATE; 19 p r o c e s s i n g <= −− g o t o read s t a t e '1 '; −− s i g n a l p r o c e s s i n g 20 21 7-SEGEMENT DISPLAY end if ; else 22 c u r r e n t S t a t e <= REFRESH_STATE ; −− g o t o r e s e t s t a t e 23 end 24 ... Das if ; processing -Signal signalisiert, dass der Controller momentan einen Befehl verar- beitet. An dieser Stelle entsteht zwischen dem Controller und der damit verbundenen Komponente, also zum Beispiel der Demo-Komponente, wie auch bereits bei den LCD Controllern, ein Handshake-Verfahren. Zunächst wird durch ein data -Signal write data - oder read processing, eine Operation angekündigt. Der Controller signalisiert über dass sich die Anfrage in Bearbeitung bendet. Wann dies geschieht ist allerdings vom aktuellen internen Zustand(Refresh) abhängig. Aus diesem Grund eignet sich diese Methode auch besonders gut, da nicht vorhergesagt werden kann ob und wenn ja, für wie lange der Controller keine neuen Befehle entgegen nehmen kann. Wenn die Operation abgeschlossen ist wird das done -Signal gesetzt. Eine lesende oder schreibende Operation auf dem Speicher unter Verwendung des Controllers besteht prinzipiell aus den folgenden drei Schritten: write data ; 1. Adresse und ggfs. Daten setzen, Schreib- oder Lesebefehl signalisieren( read data ) 2. Warten bis der Speicher den Befehl ausführt( processing ist gesetzt) und den in 1. gesetzten Befehl deaktivieren 3. Warten bis der Speicher done signalisiert und Eingaben zurücksetzen, bzw. Daten abgreifen 4.8. 7-Segement Display Beschreibung Das Entwicklungsboard verfügt über ein 7-Segment Display des Herstellers Lumex [5], bezeichnet als LDQ-M2212R1, das vom Benutzer frei angesprochen werden kann. Dieses kann vier Ziern abbilden, die sich durch einen . trennen lassen. Auÿerdem kann vor die erste Zier ein - gestellt werden. Pindenition Die Pinbelegung ist bei dieser Komponente sehr intuitiv. Mit den Select-Signalen kann der Datenausgang auf eine beliebige Konguration der vier Ziernanzeigen gelegt werden. So lassen sich zum Beispiel gleiche Ziern mit einer Operation auf mehreren 33 4.8. 7-SEGEMENT DISPLAY KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN Anzeigen abbilden. Die eigentliche Darstellung wird über die Signalleitungen A-G bestimmt. Abbildung 4.4 zeigt die Zuordnung der Signale zu den einzelnen Teilen des Displays. Eine nähere Beschreibung der Pinbelegung zum Cyclone FPGA ist in Tabelle 4.8 dargestellt. Abbildung 4.4.: Pinzuweisung 7 -Segment Display [12] Tabelle 4.8.: Pindenition 7-Segment Display [12] Description Schematic Signal Name Cyclone III Pin Number display signal A SEVEN_SEG_A AD5 display signal B SEVEN_SEG_B A3 display signal C SEVEN_SEG_C C4 display signal D SEVEN_SEG_D D4 display signal E SEVEN_SEG_E E5 display signal F SEVEN_SEG_F D5 display signal G SEVEN_SEG_G AE6 display signal dot SEVEN_SEG_ADP AD4 display select signal 1 SEVEN_SEG_SEL1 B3 display select signal 2 SEVEN_SEG_SEL2 C5 display select signal 3 SEVEN_SEG_SEL3 E4 display select signal 4 SEVEN_SEG_SEL4 C3 display signal minus SEVEN_SEG_MINUS G19 Funktionsbeschreibung Die Dateneingänge des Displays können zu einem festen Zeitpunkt nur jeweils eine Ziffer generieren. Um unterschiedliche Ziern auf alle Anzeigen zu verteilen wird ein Multiplexer verwendet, der über die vier Select-Signale die Daten entsprechend weiterleitet. Damit das Display kontinuierlich einen bestimmten Wert anzeigt ist es notwendig auf allen vier Anzeigen zyklisch zu schreiben, so dass alle Ziern sichtbar bleiben. Im Gegensatz zum Power Display erhält das User Display seine Versorgungsspannung 34 KAPITEL 4. BIBLOTHEK / ERLÄUTERUNGEN 4.8. 7-SEGEMENT DISPLAY nicht über den MAX II CPLD und wir nur mit 1.8V gespeist. Daher ist dieses Display auch wesentlich dunkler. Leider lässt sich das Power Display nicht ohne Umprogrammierung des MAX II CPLD in Betrieb nehmen. Bibliotheksfunktionen Der 7-Digit Controller besteht in VHDL aus zwei Prozessen. Einer verarbeitet dabei den Dateneingang, der andere den Datenausgang. Ein kleiner Speicher sorgt dafür, dass die Ausgabe frei deniert werden kann, ohne auf weitere Zeitbeschränkungen für die Aktualisierung zu achten. Das entsprechende Blockschaltbild ndet sich im Anhang[A.3]. Das segment_select -Singal steuert die Auswahl der Anzeige dessen Zier verän- dert werden soll. Dieses zwei Bit breite Signal wird binär von 0-3 interpretiert. Dabei entspricht 0 der äuÿeren linken und 3 der äuÿeren rechten Anzeige. is_minus segment_dot und kontrollieren die Interpunktion und das Vorzeichen. Letzteres sollte für jede Zier identisch gesetzt werden. Die Verarbeitung des input -Signals erfolgt ebenfalls auf binärer Basis. Der Controller wandelt diese 4-Bit in die entsprechende Bedeutung der Ziernsegemente um. Dabei können sinnvollerweise nur die Werte 0-9 verarbeitet werden. Alle anderen Ziern, die durch die 4-Bit Wortbreite ebenfalls möglich sind werden nicht berücksichtigt. Die Ausgabe der gespeicherten Daten auf das Display geschieht zyklisch alle 5ms. Dies bedeutet, dass jede der vier Ziern alle 15ms für jeweils 5ms aktiviert wird. In der Absicht durch kürzere Intervalle die Intensität des Displays etwas zu erhöhen, hat sich gezeigt, dass niedrigere Werte zu Flackern führten, da die LEDs nicht genügend Zeit hatten zu reagieren. Wie sich der Controller verwenden lässt, demonstriert das entsprechende DemoListing 4.4. Listing 4.4: Quellcode 7-Digit Demo 1 i f ( counter = 0) then 2 −− s e t f i r s t d i g i t 3 o u t p u t <= " 0 0 0 1 " ; 4 s e g m e n t _ s e l e c t <= " 0 0 " ; 5 s e g m e n t _ d o t <= 6 i s _ m i n u s <= 7 8 9 '0 '; '0 '; w r i t e _ e n a b l e <= '1 '; e l s i f ( counter = 1) then −− s e t second d i g i t 10 o u t p u t <= " 0 0 1 1 " ; 11 s e g m e n t _ s e l e c t <= " 0 1 " ; 12 ... 13 else 14 15 w r i t e _ e n a b l e <= end −− 1 −− 3 '0 '; if ; 35 Erklärungen Ich versichere, dass ich die Arbeit selbstständig verfasst und keine anderen, als die angegebenen Hilfsmittel - insbesondere keine im Quellenverzeichnis nicht benannten Internetquellen benutzt habe, die Arbeit vorher nicht in einem anderen Prüfungsverfahren eingereicht habe und die eingereichte schriftliche Fassung der auf dem elektronischen Speichermedium entspricht. Ich bin mit der Einstellung der Bachelor-Arbeit in den Bestand der Bibliothek des Departments Informatik einverstanden. 37 A. Blockbilder Abbildung A.1.: Blockbild Character LCD Controller 39 ANHANG A. Abbildung A.2.: Blockbild SRAM Controller 40 BLOCKBILDER ANHANG A. BLOCKBILDER Abbildung A.3.: Blockbild 7-Digit Controller 41 ANHANG A. BLOCKBILDER Abbildung A.4.: Blockbild Graphic LCD Controller 42 Literaturverzeichnis [1] Altera quartus quartus-ii-we. ii. https://www.altera.com/download/software/ [2] Cyclone iii fpga development kit. altera/kit-cyc3.html. http://www.altera.com/products/devkits/ std_logic. http://www.cs.sfu.ca/~ggbaker/reference/std_ logic/1164/std_logic.html. [3] Denition [4] Gnu licenses. http://www.gnu.org/licenses/. [5] Lumex website. http://www.lumex.com/. [6] Optrex website. http://www.optrex.com/. [7] Samsung website. [8] Verilog website. [9] Vhdl syntax. [10] Vhdl website. http://www.samsung.com/. http://www.verilog.com/. http://www.externsoft.ch/download/vhdl.html. http://www.vhdl.org. vhdl. http://de.wikipedia.org/wiki/Very_High_Speed_ Integrated_Circuit_Hardware_Description_Language. [11] Wikipedia [12] Altera. Cyclone III Development Board Reference Manual, 1.4 edition, March http://www.sourcebar.de/bac/attachment/rm_cycloneiii_dev_kit_ host_board/. 2009. [13] New Japan Radio Co., Ltd. Graphic LCD Driver, sourcebar.de/bac/attachment/nju6676_eng/. March 2004. 16-Character by 2-Line LCD Display Datasheet. [14] Optrex. sourcebar.de/bac/attachment/character_lcd_display/. [15] Optrex. Graphic LCD Module Technical Specication, http://www. http://www. nal edition, March 2005. http://www.sourcebar.de/bac/attachment/f-51852gnfqj-lb-abn/. [16] Optrex. Optrex Graphic LCD Application Note, revision b edition, April 2008. http://www.sourcebar.de/bac/attachment/optrex_application_note/. [17] Samsung. SRAM Manual K1B6416B6C, 1.0 edition, January 2005. http://www. sourcebar.de/bac/attachment/k1b6416b6c/. 43