FPGAs


  • daybyter
  • 628 Views 5 replies

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • 1. Einführung

    Da zumindest einige hier im Forum anscheinend wenig Erfahrung mit FPGAs haben und deshalb wohl einige Vorurteile bzgl dieser Technik haben, wollte ich hier mal eine kurze Einführung geben.

    Was sind die prinzipiellen Unterschiede zwischen Mikroprozessor und FPGA Programmierung? In einem FPGA werden im allgemeinen keine Instruktionen seriell nacheinander ausgeführt, sondern es wird anhand einer Beschreibung eine Schaltung erzeugt, in welcher die Einzelnen Komponenten (falls nicht anders verlangt) unabhängig voneinander arbeiten. D.h. eine einfache Folge von nicht-blockierenden Zuweisungen wie

    a <= 1; // Setze a auf den Wert 1
    b <= 3;
    c <= 5;

    wird _nicht_ nacheinander ausgeführt! Diese 3 Anweisungen können alle in einem Takt gemeinsam ausgeführt werden. Dadurch kann man mit FPGAs trotz niedrigerer Taktfrequenzen als bei CPUs im Endeffekt wesentlich höhere Ausführungsgeschwindigkeiten erreichen. Der Nachteil (ein Fehler, den alle CPU-Coder früher oder später machen) ist, dass Abhängigkeiten nicht wie erwartet funktionieren:

    a <= 1;
    b <= a+1; // b muss hier nicht 2 werden, da die Zuweisung an a evtl. noch gar nicht ausgeführt wurde!

    Zu diesem Tutorial: es soll keines der Tutorials und Lernseiten im Internet ersetzen, sondern nur anhand eines konkreten Beispiels etwas 'Appetit' auf das Spielen mit FPGAs machen.

    Man kann das Tutorial auch komplett ohne Hardware durchspielen und alle Programme im Simulator laufen lassen und die Ergebnisse betrachten. Auf die Einstellungen des Simulators werde ich jedoch zunächst nicht eingehen.

    Da echte Hardware mehr Spass macht, habe ich ein sehr günstiges Einsteigerboard herausgesucht, mit dem man für sehr wenig Geld FPGA Programmierung lernen und üben kann. Meine Wahl fiel auf das

    ALTERA cyclone ll EP2C5T144 Minimum Development Board

    , welches man bei ebay.com zusammen mit dem USB Blaster (zur Programmierung des Boards) für etwa 15-17 Euro bekommen kann.

    Das Board hat 4608 Logik Elemente (LEs) und 119808 Bit Block ram, also 14976 Byte. Viele werden jetzt zwar mit der Speichergrösse etwas anfangen können, aber keine Einschätzung haben, wie weit die ca 4600 LE reichen.

    Als Hausnummer kann man etwa abschätzen, dass gängige 8-Bit CPU's ca. 2000 LE brauchen, so dass etwa eine 6502 Implementierung auf dem Board durchaus möglich ist. Dies wurde z.B. hier gezeigt:

    searle.hostei.com/grant/uk101FPGA/index.html

    Hierbei bietet das Board noch genug Reserven um eine Videoausgabe und ein Tastatur-Interface zu integrieren.

    Für diese Zwecke sind 89 I/O Pins auf der Platine nach aussen geführt.

    Das Board hat einen 50 MHz Quarz an Board, der maximale Takt beträgt 300 MHz (höhere Frequenzen können als 50 MHz mit PLLs aus den 50 MHz erzeugt werden).

    Ausserdem hat das Board 3 frei verwendbare LEDs (plus eine Power-LED) an Board, sowie auch ein Taster (z.B. verwendbar als Reset-Taster o.ä.).

    Die Programmiersoftware Altera Quartus 2 kann man kostenlos aus dem Internet herunterladen (Achtung: der Download ist über 4GB gross!), so dass dafür keine weiteren Kosten anfallen.
    Hier könnte ihre Signatur stehen!
  • 2. Programmierung


    FPGAs werden heute im Wesentlichen in 2 Programmiersprachen programmiert: in Verilog oder in VHDL. Es gibt auch einige (exotischere) Arten, ein FPGA zu programmieren (u.a. gibt es auch Compiler, die C(++) in ein FPGA Core übersetzen können), aber diese will ich hier mal aussen vor lassen.


    Dieses Tutorial soll, wie bereits erwähnt, keinesfalls Tutorials für diese Sprachen ersetzen. Ein Tutorial für Verilog findet man u.a. hier:


    asic-world.com/verilog/veritut.html


    Die 2 grössten FPGA Hersteller sind Xilinx, und Altera (heute Intel, da von Intel aufgekauft).
    Sie bieten ihre jeweiligen Entwicklungsumgebungen Altera Quartus 2 und Xilinx Vivado (bzw. ISE für ältere ICs) kostenlos zum Download an. Diese beinhalten auch jeweils Simulatoren, um Code auch ohne Hardware testen zu können.


    Da das ausgewählte Board einen älteren Altera Cyclone 2 Chip beinhaltet, kommt in diesem Tutorial die Altera Quartus 2 Entwicklungsumgebung zum Einsatz. Es gibt auch die Option, die Entwicklung per Script zu erledigen und die Compiler usw der Entwicklungsumgebung aus Scripts aufzurufen. Ich benutze hier jedoch die grafische Entwicklungsumgbung.


    Altera entfernt in neueren Versionen der Entwicklungs-Software leider den Support für ältere FPGA Chips, so dass man auf eine ältere Version zurückgreifen muss. Die neuesten Quartus 2 Version, die den Cyclone 2 auf dem Minidev Board unterstützt, ist die Version 13 sp1. Man kann sie hier


    fpgasoftware.intel.com/13.0sp1/


    kostenlos herunterladen. Ich benutze die Linux 32 Bit Version in einer virtuellen Box unter einer 32 Bit Debian Version (die wiederum auf einem 64 Bit Host läuft), da ich den Simulator leider in einer 64 Bit VM nicht ans Laufen gebracht habe.


    Startet man Quartus, so erscheint zunächst ein Assistent, welcher dem User beim Erstellen eines neuen Projekts helfen soll:



    Ich werde nur die wichtigsten Punkte des Assistenten erklären, da einige Punkte wie etwa das Auswählen eines Verzeichnisses oder des Projektnamens selbsterklärend sein sollten.


    Wichtig ist die Auswahl des FPGA Typs, damit Quartus u.a. die Anzahl der verfügbaren Logikzellen kennt, und bei der Übersetzung prüfen kann, ob der erzeugte FPGA Core in das benutzte FPGA IC passen wird. Der ausgewählte Typ liefert noch einige weitere Eigenschaften, wie etwa die maximale Frequenz des FPGA. Damit kann man später ggf auch die maximale Frequenz ermitteln, mit welcher die Schaltung laufen wird. Wir wählen den passen Cyclone 2 Typ aus:



    Im nächsten Schritt werden noch passende Tools für die Übersetzung ausgewählt, sowie die bevorzugte Sprache angegeben (Details wie Timing-Analyse lass ich an dieser Stelle noch weg, da ich nichts timing-kritisches machen will):



    Ich habe das Projekt led_blink genannt, da ich die LEDs auf dem Board blinken lassen möchte:




    Als nächsten Schritt muss man eine neue (leere) Datei zum Projekt hinzufügen. Das geht über
    File => New, worauf ein Auswahlmenü erscheint. Wir wählen als Typ 'Verilog HDL' aus:




    und geben ihm den gleichen Namen, wie er für das Projekt verwendet wurde. Klickt man links auf das File, kann man es rechts im Editor-Fenster editieren. Wir geben folgenden Source-Code in das Fenster ein:

    Source Code: led_blink.v

    1. module led_blink( input CLOCK_50,
    2. output LED_0,
    3. output LED_1,
    4. output LED_2);
    5. // Zaehler, um 50 MHz zu teilen
    6. reg [25:0] clk_counter;
    7. // LED ueber das MSB des Zaehlers steuern
    8. assign LED_0 = clk_counter[23];
    9. assign LED_1 = clk_counter[24];
    10. assign LED_2 = clk_counter[25];
    11. // Bei jedem Takt
    12. always @(posedge CLOCK_50) begin
    13. clk_counter <= clk_counter + 1; // Zaehler erhoehen
    14. end
    15. endmodule
    Display All
    So sieht es dann im Editor aus:



    Dieser Code macht im Wesentlichen folgendes: als Eingabe werden die 50 MHz von dem Board Quartz benutzt. Die Zeile


    always @(posedge CLOCK_50) begin


    wird bei jeder positiven Flanke des 50 MHz Takts aufgerufen. Bei jedem Aufruf wird ein 26 Bit breiten Zähler um 1 erhöht. Dieser Zähler kann rund 64 Millionen Werte annehmen, die also in etwas über eine Sekunde durchlaufen werden. Die obersten 3 Bit dieses Zählers lege ich jeweils auf eine der 3 verfügbaren LEDs, die dadurch in unterschiedlichen Freqenzen blinken.


    Man klickt nun auf


    Processing => Start Compilation


    und die Übersetzung beginnt. Das Ergebnis sollte so aussehen:



    Hier wird rechts eine Zusammenfassung der Übersetzung angezeigt. Wichtigste Information ist die Anzahl der verwendeten Logik Elemente (26 hier) und die Anzahl der verwendeten Pins (hier 4. 1 Eingabepin für den Takt und 3 Ausgabepins für die 3 LEDs).


    Wichtig ist noch, dass man Quartus sagt, dass unser LED Blinker die Top-Level-Einheit des Projekts ist:



    Damit wird quasi der 'Einsprungspunkt' des FPGA Kerns angegeben. Ohne diese Zuordnung wird das Board den Core nicht ausführen.
    Hier könnte ihre Signatur stehen!
  • 3. Core auf die Hardware konfigurieren

    Als nächsten Schritt muss man dem FPGA sagen, welche Pins des FPGA Core welchen physikalischen Pins des IC entsprechen. Hierfür gibt es einen sogenannten Pin Planner, den man im linken, mittleren, Fenster öffnen kann (rechte Maustaste => Open)



    Jetzt öffnet sich der Pin Planner. Durch Doppelklick auf die Location Felder des jeweiligen Pins kann man hier passende Werte eintragen. Der 50 MHz Quartz ist mit Pin 17 des FPGA IC verbunden, die 3 LEDs mit den Pins 3,7 und 9. Also trägt man diese entsprechenden Werte hier ein:



    Danach kann man den Planner mit File => Close wieder schliessen.

    Man schliesst den USB Blaster an den JTag Port(!) des FPGA Board an und eine 5V Stromversorgung an den Hohlstecker des Boards. Nach Einstecken des Blasters an den PC kann man mit Tools => Programmer versuchen, den Code auf das Board zu kopieren.

    Es öffnet sich das Fenster des Programmers und man wählt zunächst links oben das Hardware Setup. Hier sollte der USB Blaster bereits angezeigt werden:



    Jetzt muss man rechts oben bei 'Currently selected hardware' auch den USB Blaster auswählen.

    Der 1. Programmierversuch unter Linux bei mir schlug leider fehl (Fehlercode 89 beim JTAG Server) . Dies scheint ein bekanntes Problem mit der Erkennung des USB Blaster unter Linux zu sein. Die Rechte des USB Device scheinen zu restriktiv gesetzt zu werden. Ein Eintrag in den udev-Regeln für den USB-Blaster löst das Problem. Die Regeln hierfür findet man auf folgender Website:

    rocketboards.org/foswiki/view/…UsingUSBBlasterUnderLinux

    Nach Hinzufügen der Regeln und einem Neustart (alternativ ein Neuladen der udev Regeln erzwingen) funktionierte der Blaster dann.

    Nach einem Klick auf den Start-Button des Programmer-Fenster sollte rechts oben ein grünes Complete erscheinen:



    Nach dem Trennen des Boards vom JTAG und einem kurzen Trennen der Stromversorgung (damit das Board einen Reset macht), läuft der Code sofort an. Nun sollten die 3 LEDs des Boards blinken:

    Hier könnte ihre Signatur stehen!
  • Wir tüfteln...

    Wie verrückt...

    Da gehen jeden Tag einige PNs rum, was ihr halt hier leider nicht seht.

    M.J. schreibt an seiner RISC CPU und ich steure auch das ein oder andere bei.

    So such ich seit Tagen nach billigem RAM für das Mini Board. Löte hier auch Stück für Stück so ein Prototypen Shield für das Mini Board zusammen, weil noch etliche Teile fehlen.
    Hier könnte ihre Signatur stehen!