Hallo!
ich möchte ein 64-Bit breites Datenwort vom Nios II auf externe VHDL
Logik schreiben. Hierzu existiert ein Avalon Slave Modul (über das
Template von Altera) im NIOS II. Bisher habe ich 32-Bit breite Worte
genutzt, dies ist aber nicht länger ausreichend. Nun zu meinen Fragen.
1. Ist es möglich direkt auf den/einen Avalon Slave zu schreiben? Ist
der korrekte Aufruf hierfür?
2. Wie muss die Gegenseite hierzu aussehen? Reicht dies hier?
1
Externe Ports mit NIOS II Slave Modul und eigenem verbinden
2
Wenn Adresse = (Avalon Slave Basisadresse + Offset) UND Write = 1 dann:
3
Wait-Request = 1
4
switch abhängig vom Byte-Enable, dementsprechend Daten speichern
5
Daten in VHDL Modul = Avalon Write Data
6
Wait-Request = 0
7
Repeat "Wenn Adresse..." und merke dir welche Byte-Enables abgehandelt sind, wenn alle abgehandelt sind springe in nächsten FSM-State und "do foo"
3. Wie schnell muss das Wait-Request kommen? Muss es sofort anliegen
oder darf/muss es getaktet sein?
4. Ich verstehe nicht wirklich die Syntax bzw. die Wirkungsweise des
IORD/IOWR Befehls. Hier wird die Datenbreite nciht angegeben, aber die
Adresse errechnet sich irgendwie anders. Kann mir hier jemand helfen?
5. Gibt es einen anderen Weg der ggfs. sinnvoller/einfacher ist um an
das 64 Bit Datenwort zu kommen?
Ich komme irgendwie nicht richtig voran :(
Da der NIOS II ein 32-bit Prozessor ist, ist es nicht möglich ein 64-bit
Wort in einem Zyklus zu schreiben. Du musst schon 2 32-Bit Wörter
hintereinander schreiben. Sowas wie IOWR64_DIRECT gibt es nicht.
Das ist bedauerlich. Mein Schreibvorgang reagiert auf einen eingehenden
Interrupt. Ist die restliche Abfolge korrekt? Dann könnte ich den 2.
Teil des Datenwortes einfach über eine weitere Adresse meiner Logik
übergeben.
Damit entfallen die Fragen 4 und 5.
Gibt es eventuell weitere Tipps bzgl. der verbleibenden Punkte?
Vielen Dank im voraus :)
Also:
Zu 1.: Genau so wird ein 32-bit Wort auf den Bus geschrieben. Eigentlich
is dies nur ein C-Macro. Der Compiler/Assembler macht daraus den
entsprechenden Store-Befehl.
Zu 2.: Ich verstehe nicht genau was du hier meinst. Um mit dem NIOS auf
eigene Logik zugreifen zu können, braucht man einen Memory-Mapped
Avalon-Slave (was du anscheinend auch gemacht hast.) Das Altera-Template
ist eigentlich ziemlich gut dokumentiert, da kann man nicht viel falsch
machen.
Zu 4.: Das macht der Compiler eigentlich automatisch anhand der
Datentypen die gelesen/geschrieben werden, z.B.:
1
uint32*pAddr=0x40000000;
2
*pAddr=0x12345678;
schreibt das 32-bit Datenwort "0x12345678" an den Avalon-Slave mit der
Adresse 0x40000000, Da der Pointer pAddr auf einen 32bit-Datentyp zeigt.
zu 5.: Ich glaube ein Avalon-Slave darf schon mehr als 32-bit Busbreite
haben, allerdings braucht man dann auch einen entsprechenden
Avalon-Master (auch hier gibt es ein Altera-Template).
Ich habe den Avalon Slave aus dem QSys Menü hinzugefügt, auf "meiner"
Seite habe ich selbstgeschriebenen Code verwendet. Hier werde ich mir
die von dir vorgeschlagenen Templates sowie die Doku nochmal näher
ansehen. Danke!
Ich habe das ganze nun stark angepasst und vermute das mein Problem in
der falschen Abfrage der Adresse liegt (manchmal ist es ganz hilfreich
Warnings zu lesen...) Ich spendiere dem Template 8 Bit für die Adresse,
der Code hierzu sieht so aus:
Die Abfrage if (avs_s0_address = 0x01000000).. bereitet mir noch
Kopfschmerzen. Das Adressmapping von QSys legt diese Adresse fest. Wie
bereits oben erwähnt, spendiere ich dem Template ja aber nur 8Bit. Der
Wert 0x01000000 passt nur in 32Bit. Wie kann ich diesen Wert gezielt
abfragen? Oder reicht es 0x00 abzufragen da nur die unteren 8Bit
relevant sind in diesem Fall? Ich möchte einfach nur in einem C Programm
mit
1
IOWR32_DIRECT(0x01000000,0,data)
Daten an mein externes Modul schicken! Wie kann ich sicherstellen das
die richtigen Daten von meinem externen Modul übernommen werden? Ich
steh vollkommen auf dem Schlauch :(
Also, ich fasse nochmal zusammen:
Der Slave liegt im Addressbereich 0x0100000X <- nur die letzten 8 bit
werden dekodiert.
Dann fehlt dir die Abfrage des Chip-Selects. Die Dekodierung der oberen
Adressbits übernimmt eigentlich die Avalon-Switchmatrix.
Daraus wird ein chip-enable an den slave generiert. Eigentlich sollte
das durch das avs_s0_write Signal gegeben sein.
Wie prüfst du momentan ob die daten in deinem Modul ankommen, wie
wwerden sie weiterverarbeitet?
Tipp: Implementier ein Debug-Register, dass du mit dem NIOS wieder
zurücklesen kannst.
ein Versions-Register, welches bei der Synthese auf einen festen
reset-wert gesetzt wird udn read-only ist (z.b. mit dem Wert
0x12345678), ist auch immer hilfreich, dann siehst du ob das auslesen
funktioniert
Vielen Dank an dieser Stelle für die bisher gemachte Mühe :)
Genügt es das Chipselect und das avalon_write Signal zu verunden? Da
muss ich wohl noch mal in die Avalon Spezifikations PDFs reinsehen.
Ich liefere meinem Modul ein Valid Signal, wird dieses Gesetzt darf die
externe Logik die Daten übernehmen.
Entity Deklaration:
data_out:outstd_logic_vector(31downto0);--data to external logic
16
data_out_valid:outstd_logic--data valid signal
17
);
18
endentityAvalon_Bridge;
Den Tip mit dem Debugregister probiere ich heute gleich mal aus, dafür
muss ich nur zuerst das Lesen auch implementieren (also eine State
Machine basteln) :)
Ich habe gerade eben die Avalon Spezifikationen gelesen und bin über
diesen Passus gestolpert:
"The chipselect signal is not necessary; Altera does not recommend using
it."
Aus welchem Grund sollte es vermieden werden? Nach deiner Argumentation
erschien mir die Verwedendung eigentlich sehr sinnvoll.
Also das ist bei mir schon länger her, das mit dem chipselect wusste ich
nicht. Wahrischenilich meint Altera damit, man soll das chipselect nicht
mehr für neeu Designs verwenden (vielleicht weil es irgendwann mal
abgeschafft wird).
Aber du hast ja das read und write Signal. Die Avalon-spec ist an dieser
Stelle eigentlich recht ausführlich. Ein einfacher Slave (ohen Burst,
etc.) ist nicht wirklich besonders aufwendig zu implementieren.
Eine eigene Frage?
Dieser Thread ist über 14 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.