Ein eigener IP-Core

Zynq FPGA

Nachdem wir uns jetzt bereits das Processing System angeschaut haben und in der Lage sind es zu benutzen, wollen wir mal schauen wie man eigene Schaltungsblöcke erzeugen kann, welche dann in Kombination mit dem Processing System genutzt werden können.
Diese Anleitung besteht aus zwei Schritten. Im ersten Schritt zeige ich euch wie ihr einen einfachen AXI GPIO IP-Core erstellen könnt und im zweiten Schritt wird der IP-Core dann getestet.

-> Erstellung des IP-Cores:

Zuerst öffnet ihr Vivado und sobald das Startfenster offen ist, klickt ihr auf Manage IP um den IP-Manager zu öffnen. Dort wählt ihr dann New IP Location… aus:

IP-Core(1)
Jetzt müsst ihr einen Pfad für den IP-Manager eurer IP-Cores auswählen. Ich habe mir einen Ordner mit dem Namen IP angelegt, den ich als IP Location angebe. Anschließend stellt ihr den Parameter Target Language noch auf VHDL.
Mit einem Klick auf Finish bestätigt ihr die Eingabe, woraufhin sich der IP-Manager öffnet.
Dort öffnet ihr über Tools das Menü Create and Package IP…:

IP-Core(2)
Es öffnet sich ein neues Fenster, wo ihr auf Next klickt. Anschließend wählt ihr Create a new AXI4 peripheral aus und klickt noch einmal auf Next. Jetzt müsst ihr ein paar Details zu dem IP-Core eingeben:

IP-Core(3)
Mit einem Klick auf Next gelangt ihr in das nächste Menü, wo ihr nur den Namen in GPIO ändert. Danach klickt ihr erneut auf Next und im Abschlussfenster wählt ihr Edit IP aus und schließt das Fenster über Finish.
Jetzt werden alle notwendigen Dateien angelegt und ihr könnt damit beginnen den eigentlichen IP-Core zu entwickeln.
Im Project Manager findet ihr jetzt zwei Dateien:

  • GPIO_v1_0 – arch_imp
    Dies ist das Toplayerdesign des IP-Cores. Über dieses Design werden alle Ein- und Ausgänge des Cores definiert und alle notwendigen Module eingebunden.
  • GPIO_v1_0_GPIO_inst – GPIO_v1_0_GPIO – arch_imp
    Dies ist der gegebene Funktionslayer des Cores, Ihr könnt entweder hier oder in einem weiteren Funktionslayer, den ihr dann in dieser Datei verknüpft, die Funktion des IP-Cores festlegen.

Da wir in erster Linie einen einfachen GPIO IP-Core bauen, benötigen wir erst einmal einen Ausgang im Toplayerdesign. Dazu öffnet ihr den Toplayer und fügt unter port folgendes ein:

Da der Toplayer nur die Funktion hat alle Funktionslayer miteinander zu verknüpfen und die Signale nach außen zu geben, leitet er das Ausgangssignal, welches aus dem Funktionslayer kommt, nur nach außen weiter.
Um dem Funktionslayer einen Ausgang zu geben, wird die Komponente um einen Ausgang erweitert:

Jetzt muss noch die Verknüpfung vom Ausgang des Toplayers mit dem Ausgang des Funktionslayers hergestellt werden:

Damit wäre der Toplayer fertig und kann gespeichert werden.
Nun geht es an den Funktionslayer. Auch diesen öffnet ihr und als allererstes wird dem Funktionslayer ein zusätzlicher Ausgang spendiert (wir erinnern uns…das ist der Ausgang, der im Toplayer nach außen geführt wird):

Am Ende der Datei kann dann die Funktion realisiert werden.
Alternativ kann in dieser Datei auch noch eine Verknüpfung auf eine andere Datei stattfinden – ähnlich wie beim Toplayer – und die Funktion kann dann in einer weiteren Datei stehen.
Die Funktionsbeschreibung der Hardware ist sehr übersichtlich, da der erste IP-Core einfach gehalten werden soll:

Was macht diese Funktion nun?
Der IP-Core besteht aus vier Registern á 32 Bit (wurde bei der Erstellung des IP-Cores festgelegt).
Diese Register heißen slv_regX und wir geben das erste Bit des ersten Registers auf den Ausgang des IP-Cores.
Die Register werden nachher über das AXI-Interface beschrieben.

Jetzt kann auch diese Datei gespeichert werden und anschließend klickt ihr auf Run Synthesis um die Schaltung zu synthetisieren und die Schaltung nach Fehlern zu untersuchen.
Sobald die Synthese erfolgreich durch gelaufen ist, schließt ihr das Fenster über Chancel und klickt anschließend auf Package IP.
Dort müsst ihr alle Menüs, wo kein grüner Haken vor ist, aktualisieren, indem ihr das Menü öffnet und am oberen Rand auf die Schrift im gelben Kasten klickt:

IP-Core(4)
Damit ihr den IP-Core mit dem Zynq verwenden könnt, müsst ihr noch die erlaubten Devices aktualisieren. Dazu klickt ihr auf Compatibility und über einen Linksklick in das Feld unter Family Support könnt ihr über Add Family… eine weitere Produktfamilie hinzufügen:

IP-Core(5)
In dem sich öffnenden Fenster setzt ihr bei zynq einen Haken und bestätigt die Eingabe mit OK.
Wenn ihr dies gemacht habt, klickt ihr auf Review and Package und anschließend auf Re-Package IP.
Sobald der IP-Core gepackt wurde, erscheint eine Meldung, welche ihr mit OK bestätigt.
Jetzt ist der IP-Core fertig. Schauen wir uns mal an wie man ihn einsetzt…

-> Der eigene IP-Core im Einsatz:

Als erstes erstellt ihr euch ein neues Projekt mit einem Zynq Processing System (eine Anleitung dazu gibt es hier). Unter Project Settings müsst ihr erst euer IP-Repository hinzufügen:

IP-Core(6)
Mit einem Klick auf OK bestätigt ihr auch hier die Eingabe.
Jetzt kann der IP-Core in das Design eingefügt werden:

IP-Core(7)
Im nächsten Schritt müsst ihr den HDL Wrapper und die Output Products erzeugen:

IP-Core(8)
Anschließend kann die Schaltung synthetisiert werden.
Nach der Synthese müsst ihr noch den IO für den IP-Core deklarieren:

IP-Core(9)
Danach kann der Bitstream erzeugt und ins SDK exportiert werden. Im Anschluss daran wird das SDK gestartet.
Dort müsst ihr unter Xilinx Tools / Repositories das IP-Core Repository hinzufügen:

IP-Core(10)
Im nächsten Schritt legt ihr ein neues, leeres Application Project und darin eine Datei namens main.c an:

IP-Core(11)
Das ganze Hauptprogramm sieht dann wie folgt aus:

Dieses Programm schreibt abwechselnd eine 0 oder eine 1 in das 1. Register des IP-Cores, wodurch die angeschlossene LED blinkt.
Alle Funktionen für den eigenen IP-Core werden in der Headerdatei gpio.h abgelegt. Dort könnt ihr dann auch eigene Funktionen hinzufügen, falls ihr komplexere IP-Cores entwickeln wollt.

 

Dokumentation:

 

-> Zurück zum FPGA + VHDL Tutorial

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.