Forum: FPGA, VHDL & Co. [Nios] SDRAM Problem


von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

leider habe ich ein Problem damit, den SDRAM auf meinem (custom) Board 
zum laufen zu bringen.

Was ich bereits erfolgreich gemacht habe ist ein NIOS Core mit OnChip 
Memory ausgestattet und das "Hello-World" Programm gestartet. Das läuft 
soweit.

Der nächste Schritt ware dann im NIOS Core unter QSYS ein SDRAM 
Controller hinzuzufügen und anzuschließen. Ebenfalls habe ich über eine 
PLL eine weitere Clock für den SDRAM erstellt.
Im QSYS habe ich dann die Reset und Exception Vektoren von dem on-chip 
Memory auf den SDRAM gelegt.

Leider funktioniert das Design so nicht. Ich finde zwar den NIOS unter 
"Run Configurations" mit richtiger System ID und entsprechendem 
Timestamp, jedoch kann ich ihn nicht beschreiben.

Es kommt in der Konsole immer eine Fehlermeldung (Verify failed) wie im 
Anhang und anschließend die Meldung Downloading ELF Process failed. Ich 
habe ebenfalls mal meine Konfiguration des Cores mit angehängt, 
vielleicht gibt es ja hier auch noch Fehler.

Als Referenzboard für die Platine habe ich übrigens das DE0 verwendet - 
mit dem gleichen SDRAM (aber anderer FPGA). Auf diesem Development Board 
habe ich das SDRAM auch schon zum laufen gebracht.

Hat vielleicht jemand eine Idee, wie ich dem Problem auf die Sprünge 
kommen könnte? Oder benötigt ihr dazu noch weitere Informationen über 
meinen Aufbau?

Viele Grüße,
  Thomas

von Kest (Gast)


Lesenswert?

Die Frage taucht immer wieder auf. Ich kann es nur jedes Mal das Gleiche 
sagen: mache nicht so große Schritte. Wenn Du NIOS aus dem ONCHIP Ram 
zum laufen gebracht hast, dann kannst Du im nächsten Schritt einfach mal 
aus dem NIOS heraus SDRAM beschreiben und die Daten auszulesen (NIOS 
läuft immer noch aus dem ONCHIP). Wenn das schon mal funktioniert, 
machst Du halt weiter. Aber es kann sein, dass der NIOS sich gleich beim 
ersten Zugriff aufhängt, dann geht die Suche los (Clock kontrollieren, 
Pinbelegung, Frequenz messen, Phase stimmt, Datenleitungen 
kontrollieren, Reset check).

Kest

von Thomas (Gast)


Lesenswert?

Hey,

vielen Dank für den Hinweis, genau so habe ich es gemacht.

Was mir aufgefallen ist, dass viele Werte beim Lesen nicht den 
beschriebenen Werten entsprechen. Wenn ich die Phase des Clock-Signals 
verändere, verbessert bzw. verschlechtert sich das Verhalten. Es scheint 
also an der Phase des Clock-Signals zu liegen.

Ich muss gestehen das ich mich auch nicht großartig um das Timing 
gekümmert habe, da es im Beispiel-Projekt des DE0-Boards auch nicht 
gemacht wurde. Da komme ich jetzt wohl nicht mehr so einfach rum.

Jetzt ist natürlich die Frage, wie man auf die exakte Phasenverschiebung 
kommt? Vllt. finde ich etwas dazu im Internet.

Grüße,
  Thomas

von GS (chromosoma)


Lesenswert?

Das Problem hatte ich vor kurzem auch gehabt. Schaue mal hier:)


Beitrag "NIOSII mit SDRAM startet nicht."

von Thomas (Gast)


Lesenswert?

Hey,

ich bin leider immer noch nicht viel weiter gekommen :/

Wie bereits kurz erwähnt, beschreibe ich nun in meinem Test-Programm den 
SDRAM und lese die einzelnen Adressen dann aus. Bei bestimmten 
Phasenlagen (z.B. -4ns Phasenversatz) bekomme ich teilweise beim 
Auslesen der Adressen auch die richtigen Daten, immer in kleinen Paketen 
(ca. 10 Datenzellen sind richtig).

Weißt das auf ein Timing-Problem hin? Das wäre meine Vermutung.

Ebenfalls habe ich die Geschwindigkeit des NIOS Cores sowie des SDRAMs 
auf 20MHz verringert.


Mit einem Scope kann ich mir nun auch die Signale ansehen. Nur bin ich 
mir nun  gar nicht mehr so sicher, was ich eigentlich sehen will/müsste.

Und zwar sehe ich mir immer das Clock-Signal am SDRAM an sowie z.B. die 
Datenpins (oder Command-Pins). Eigentlich dachte ich, es müssten zuerst 
die Pins gesetzt werden, und dann die Clock-Flanke kommen. Wenn ich dies 
mit der Clock-Phase einstelle, bekomme ich allerdings gar keine 
richtigen Werte mehr aus meinem Testprogramm.

Wann sollte denn die Clock am SDRAM bestenfalls mit den anderen Signalen 
auftreten? Oder kann man das nicht pauschal sagen?

Viele Grüße,
  Thomas

von Kest (Gast)


Lesenswert?

20 MHz ist etwas wenig, mach ruhig 100 MHz.
Wie sieht Dein Top-Level aus? Ich meine, hast Du eine PLL?

Kest

von Thomas (Gast)


Lesenswert?

In meinem Top-Level Design habe ich auch eine PLL (siehe die Bilder im 
1. Post).

Ich habe jetzt herausgefunden, dass es scheinbar mit dem Schreib-Vorgang 
Probleme gibt. Mein Test-Code sieht etwa so aus:
1
  for (i=0; i<WRITE_CYCLES;i++)
2
    IOWR(SDRAM_BASE,i, WRITE_DATA );
3
4
nError = 0;
5
  for (i=0; i<WRITE_CYCLES;i++)
6
  {
7
    if (IORD(SDRAM_BASE,i ) != WRITE_DATA)
8
    {
9
      nError++;
10
      printf("[ERROR] Address %lu: %lu\n", i,IORD(SDRAM_BASE,i ));
11
    }
12
  }
13
14
  printf("\n\n[FINISH] %d Addresses tested, %d errors.", 
15
16
17
  //Dauer schreiben
18
19
  while(1)
20
  {
21
    for (i=0; i<WRITE_CYCLES;i++)
22
      IOWR(SDRAM_BASE,i, WRITE_DATA);    
23
  }

Kurz der Ablauf:
1) Ich schreibe N Adressen mit dem Wert X
2) Ich lese N Adressen aus und gebe das Ergebnis aus
3) Ich schreibe Dauerhaft (um mir auf dem Scope etwas ansehen zu können)

Wenn ich das Programm nun direkt hintereinander ausführe, lese ich beim 
2. mal immer mehr Speicherzellen richtig aus. Ich denke es liegt daran, 
dass ich am Ende des Programms in der Endlosschleife dauerhaft den 
richtigen Wert in die Speicherzellen schreibe.

Wodurch könnte sich ein solches Timing Problem ergeben?

Ich habe jetzt auch 50MHz und 100MHz NIOS + SDRAM Frequenzen 
ausprobiert, alle mit ähnlichem Verhaltem.

Viele Grüße,
  Thomas

von Kest (Gast)


Lesenswert?

Mach Dir bitte klar, wie SDRAM organisiert ist und mit wievielen Bits 
Avalon angebunden ist.

Was passiert, wenn Du das machst?

  for (i=0; i<WRITE_CYCLES;i++)
    IOWR(SDRAM_BASE,i, WRITE_DATA );

Musst Du nicht stattessen

  for (i=0; i<WRITE_CYCLES;i++)
    IOWR(SDRAM_BASE,i*4, WRITE_DATA );

machen?

Oder verwende gleich:
  for (i=0; i<WRITE_CYCLES;i++)
    IOWR_32DIRECT(SDRAM_BASE,i*4, WRITE_DATA );

Ansonsten könnte es ein Verdrahtungproblem sein (Bank/Adress Leitungen 
nicht richtig angebunden). Meines wissens, kalibriert sich SDRAM 
Controller selber, aber vielleicht geht da was schief.

Wenn Du nur ein Paar Mal hintereinander z.B. 16-32 Bytes ausliest, sind 
die Werte immer gleich?


Grüße
Kest

von Thomas (Gast)


Lesenswert?

Ich habe das mit der Adressierung mal abgeändert, das war mir in der Tat 
nicht klar.

Ich lese immer exakt gleiche Werte aus, wenn ich mehrfach hintereinander 
Lese. Der Lesevorgang ist also recht stabil und scheint zu 
funktionieren.

Getestet habe ich das so:

Programmstart mit while-Schleife:
1
  while(1)
2
  {
3
4
    for (i=0; i<WRITE_CYCLES;i++)
5
      IOWR(SDRAM_BASE,i*4, WRITE_DATA);  
6
  }

Dies habe ich ausgeführt (mit WRITE_DATA = 456). Anschließend die While 
schleife entfernt, so das mein Programm nichts mehr in den SRAM 
schreibt. In dem Testcode
1
  for (i=0; i<WRITE_CYCLES;i++)
2
  {
3
    nData = IORD(SDRAM_BASE,i*4 );
4
    if (nData != WRITE_DATA)
5
    {
6
      nError++;
7
      printf("[ERROR] Address %lu: %lu\n", i, nData);
8
    }
9
  }
10
11
  printf("\n\n[FINISH] %d Addresses tested, %d errors.", WRITE_CYCLES, nError);

stimmen nun alle Speicherzellen überein. Es gibt keine Fehler - alle 
Speicherzellen enthalten den Wert 456.

Schreibe ich allerdings nur 1x die Werte in den SRAM (und nicht in einer 
endlosschleife), befindet sich in nur ca. 300 Speicherzellen der 
richtige Wert.

Irgendwie blicke ich noch nicht dahinter, wodurch sich dieses Verhalten 
ergibt. Für weitere Anregungen bin ich dankbar :)

Viele Grüße,
  Thomas

von Kest (Gast)


Lesenswert?

Ich würde Dir raten die Werte, die Du ausliest auch in HEX anzuschauen, 
die Adressen aber zugehörig auch! Es kann nämlich sein, dass gerade, 
wenn eine Bank gewechselt wird, was schief läuft (z.B. ein BA[1] Pin 
nicht richtig dran, Adresspin stimmt nicht oder es gibt Übersprechen).

Wenn SDRAM Controller angelaufen ist, dann hat er geschaff sich zu 
kalibrieren (allerdings weiß ich nicht, ob das vielleicht nicht nur bei 
einem DDR/DDR2/DDR3 so ist (bei Altera)).

Aus Erfahrung weiß ich, dass man da schon sehr viel Zeit versenken kann, 
eh es funktioniert. Der Fehler ist meistens so trivial, dass man sich 
gar nicht traut, zuzugeben, dass man so doof war ;-)

Das "komplizierteste" war bei mir mal, dass DDR2 Speicherkontroller nur 
jeweils in 128 ms falsche Werte geliefert hat. So etwas rauszufinden ist 
sehr schwierig, weil es eben "eigentlich" läuft, aber ab und zu kippt 
ein Bit/Byte.

Bei Altera gibt es für NIOS ein Memory-Test programm (template bei 
Eclipse). Dabei werden verschiedene Muster geschrieben/gelesen und man 
bekommt schnell heraus, was nun nicht stimmt, vielleicht könntest Du 
damit probieren.

Ich wünsche Dir viel Erfolg und ganz wichtig: nicht aufgeben! :-)

Grüße
Kest

von GS (chromosoma)


Lesenswert?

Ich spiele im Moment auch mit NIOSII und SDRAM auf DE1 Board

Gibt es  eigentlich ein Unterschied  zwischen

 IOWR und IOWR_16DIRECT  ?

Ich habe bemerkt, dass der SDRAM Chip zwar in 4194804 Adressen je 16 bit 
geteilt ist(so steht auch in Qsys), aber für NIOSII wird er in 8 bit 
Partitionen dargestellt. Deswegen beläuft die Adresse von 0x800000 bis 
0xFFFFFF (das doppelte von 4194804).

Schreibe ich jetzt  ein 16 bit langer Wert an die Adresse 0 mit 
IOWR_16DIRECT Befehl rein, so gehen die ersten 8 bit  des Werts in die 
Adresse 0, und die zweite Hälfte in  Adresse 1. Somit kann ich 
komischerweise nicht direkt in die Adresse 1 Schreiben, nur lesen.

 Erst in die Adresse 2 kann ein neuer Wert gespeichert werden.

Nehme ich IOWR_8DIRECT, so kann ich separat jede Adresse beschreiben.

Recht komischer Verhalten....
Vllt. liegt die Lösung zu deinem Problem in meiner Frage;)?

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.