Forum: FPGA, VHDL & Co. Cyclone V SoC, Register (Variable) in FPGA mit HPS auslesen, wie?


von Schubert (Gast)


Lesenswert?

Guten Tag,

leider bin ich im Umgang mit SoCs noch etwas unerfahren und hänge an 
einem Problem. Daher würde ich euch gerne um etwas Hilfe bitten. 
Vielleicht reicht bereits das eine oder andere Schlagwort, um weiter zu 
kommen. Die Hardware ist ein DE0-nano-SoC.

Mit Hilfe des FPGA-Teils möchte ich ADUs und serielle Signale 
kontinuierlich erfassen. Hierfür sind bereits Schnittstellen 
implementiert. Die so gewonnenen Daten werden periodisch aus den 
entsprechenden FIFOs in 16Bit-Register abgelegt. Z.B. ADU1 und SER1.

Nun möchte ich aus dem HPS-Teil, auf welchem Linux läuft, unter C++ auf 
diese Register zugreifen können. Doch deren virtuellen Speicheradressen 
sind mir(Linux) natürlich unbekannt. Zudem müsste ich vor dem Zugriff 
verhindern, dass die Register während des Zugriffs durch den FPGA 
beschrieben werden und somit schreibend den Refresh sperren.

Wie kann ich also die Adressen von ADU1 und SER1 
identifizieren/festlegen, um hierauf mit dem HPS-Teil lesend und 
schreibend zugreifen zu können?

Läuft diese Kommunikation über die HPS2FPGA / LWHPS2FPGA Brücke?

Leider ist das Thema offenbar recht komplex. Könntet Ihr mich daher auf 
Beispiele verweisen?


Mit vielem Dank

von Blechbieger (Gast)


Lesenswert?

Schubert schrieb:
> Wie kann ich also die Adressen von ADU1 und SER1
> identifizieren/festlegen, um hierauf mit dem HPS-Teil lesend und
> schreibend zugreifen zu können?
>
> Läuft diese Kommunikation über die HPS2FPGA / LWHPS2FPGA Brücke?

Ich gehe mal davon aus das mit dem Platformdesigner zusammen klickst und 
nich masochistisch händisch von Hand. D.h. du hast für deine FPGA-Cores 
schon passende hw.tcl Dateien erstellt. Anhand dieser Dateien baut 
Platform Designer die Adressmap und verschiedene Dateien, u.a. eine 
.sopcinfo Datei. Daraus generiert man mit sopc2dts einen Device Tree in 
Source-Form der mit einem weiteren Tool in ein Device Tree Binary 
kompiliert wird. Dieser wird dann vom Bootloader an den Linuxkernel beim 
Start übergeben. Ab diesem Zeitpunkt stehen dann Infos wie Namen, 
Adressen und Interrupts im Kernel zur Verfügung.

Ab da geht es am saubersten, aber auch aufwendigsten, mit einem von dir 
zu schreitenden Kerneltreiber weiter der eine Schnittstelle für dein 
Userspace Programmm zur Verfügung stellt. Aber es gibt wohl auch Wege 
wie man aus dem Userspace auf reale Adresse zugreift.

Sehr viel Infos dazu gibt es auf https://rocketboards.org/ . Schau dir 
auch das Referenzdesign (GSRD) an. Das ganze ist ein spannendes Thema 
aber ein großer Brocken.

Wenn es nur um einzelne Register geht ist die LWHPS2Bridge ausreichend . 
Bei mehr nötigen Durchsatz die normale Bridge aber dann sollte dein 
Slave auch Features wie Burst unterstützen.

von Schubert (Gast)


Lesenswert?

Hallo,

vielen Dank für deine Antwort.

Naja, den VHDL-Code habe ich schon händisch geschrieben :). Also keine 
fertigen IP-Cores. Das hatte sich bisher als praktisch erwiesen.

Ich verstehe deinen Ansatz, die Ausführung hingegen natürlich noch 
nicht. Ist eine direkter Verweis zwischen dem programmierten Register 
und einem Speicheraddressbereich möglich, auch ohne höhere 
Systemprogramme?

Es wird etwa um zehn 16-Bit-Register gehen, die mit max. 100kHz 
beschrieben werden. Auf einen Trigger hin sollen diese Register vom HPS 
übernommen und ausgewertet werden. Es fallen somit maximal 16MBit/s an.

Einen Kerneltreiber für Linux zu schreiben würde meine Studienarbeit 
sprengen, da die mit dem SoC gewünschte Funktion nur der Datengewinnung 
dient. Die eigentliche Arbeit kommt danach... :( Daher muss ich sehen, 
wie ich aus dem Userspace über den virtuellen Speicheradressbereich 
zugriff erlange.

Ich werde deine Quelle durchstöbern.

Vielen Dank für den Hinweis.

von Samuel C. (neoexacun)


Lesenswert?

Am einfachsten hast du's wohl, wenn du dir in Vivado einen 
AXI-Lite-Slave generieren lässt und da deinen VHDL-Code dazubastelst.

http://www.fpgadeveloper.com/2014/08/creating-a-custom-ip-block-in-vivado.html

von Gustl B. (-gb-)


Lesenswert?

Er nutzt aber Altera/Intel.

von Samuel C. (neoexacun)


Lesenswert?

Wups, da hab ich wohl zwei Threads vermischt. Sorry.

von Blechbieger (Gast)


Lesenswert?

Ohne Treiber gibt es den Weg über /dev/mem und mmap. Kapitel 11 von 
https://rocketboards.org/foswiki/Documentation/EmbeddedLinuxBeginnerSGuide 
hat ein Beispiel.

von Blechbieger (Gast)


Lesenswert?

Samuel C. schrieb:
> Am einfachsten hast du's wohl, wenn du dir in Vivado einen
> AXI-Lite-Slave generieren lässt und da deinen VHDL-Code dazubastelst.

AXI wird auch von Intel/Altera unterstützt aber das native Interface ist 
Avalon. Ein simpler Avalon-MM Slave ist genauso leicht zu implementieren 
wie ein AXI-Lite. Aber ich habe den Fragesteller so verstanden dass er 
das eh schon hat und es ihm um den Zugriff aus Linux raus auf seinen 
eigenen IP-Core geht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.