Hallo zusammen Ich würde gerne ein SDRAM, welches sich auf meinem DE0 Board befindet, ansteuern. Dazu habe ich in den vergangenen Tagen sehr viele Dokumente gelesen und glaube dass ich das grundsätzliche Prinzip verstanden habe. Nun geht es jedoch um die Details. Im Anhang befindet sich ein Bild, welches das READ Timing zeigt. Bei diesem ist mir aufgefallen, dass die Daten nicht zeitgleich mit der steigenden CLK Flanke anliegen. Dies macht ja auch sinn, da es überall gewisse delays gibt. Nun frage ich mich jedoch, wie ich die Daten dann möglichst elegant in mein Cyclone FPGA einlesen kann/soll. Der SDRAM Controller muss nicht das maximum aus dem SDRAM herausholen. Es geht eher darum das Prinzip verstanden zu haben. Meine Ideen sind: 1) Zweiten Clock (nennen wir ihn CLK2x) mit doppelter geschwindigkeit, synchron zum haupt CLK. Einlesen des Datenbusses nach der nächsten CLK2x flanke 2) Einlesen auf die fallende Flanke von CLK. Prinzipiell das gleiche wie bei Punkt 1. Jedoch kann bei Punkt 1 auf eine steigende Flanke getriggert werden. Da weiss ich jedoch noch nicht wie man dies VHDL technisch umsetzen könnte und ob dies überhaupt "state of the art" wäre 3) die Daten bei der zweiten steigenden Flanke einlesen. Also einen Takt verzögerung einbauen. Hier bin ich mir nicht sicher, wie zuverlässig dies funktioniert. Wenn ich dem Timingdiagram glaube, dann sollte dies so machbar sein. Was meint ihr?
:
Bearbeitet durch User
Weil das RAM synchron ist, ändert sich sein Ausgang wegen des Taktes. Du kannst also bei der nächsten steigenden Taktflanke die Daten einlesen.
Lothar M. schrieb: > Weil das RAM synchron ist, ändert sich sein Ausgang wegen des > Taktes. Du kannst also bei der nächsten steigenden Taktflanke die > Daten einlesen. Vielen Dank für deine Antwort Hintergrund meiner Frage war dieser Thread: Beitrag "SDRAM again - synchrone Logik" Da wird darüber Diskutiert, dass man einen Clock haben sollte der um 90 oder 180° Phasenverschoben ist, um die Daten einzulesen. Ebenfalls wird darüber diskutiert, dass man eine CLK Rückführung machen sollte/kann um damit das Einlesen zu triggern. Da ich noch keine Praxiserfahrungen mit den RAMs gesammelt habe, weiss ich noch nicht, ob dies eine unumgehbare Praxis darstellt. Bisher gehe ich jedoch davon aus, dass ich lediglich um einen Takt verzögert die Daten einlesen muss und das wars dann auch schon. Gibt es da sonst noch was spezielles zu beachten ausser dem Refresh? Habe ich dies richtig verstanden, dass der Refresh des RAMs typischerweise alle 64ms statfinden muss? Dabei alle ROWs aktualisiet werden müssen. Deshalb muss ich schauen, wie viele Rows mein Memory hat und dann 64ms / ROWs gibt mir meine maximale Zeit, in welcher ich das Refresh Kommando ausführen muss. Richtig? Danke
Bei micron gibt es jede Menge Applikationsschriften zu SDRAMs: https://www.micron.com/support/support-documentation-and-downloads
Das was du markiert hast scheint der Ausgang (zur restlichen Logik hin) eines SDR-Controllers zu sein. Die eigentlichen Datenleitungen des SDRAM sind ganz unten DQ. Möchtest du einen eigenen Controller implementieren oder den im Whitepaper verwenden?
Blechbieger schrieb: > Das was du markiert hast scheint der Ausgang (zur restlichen Logik > hin) > eines SDR-Controllers zu sein. Die eigentlichen Datenleitungen des SDRAM > sind ganz unten DQ. Möchtest du einen eigenen Controller implementieren > oder den im Whitepaper verwenden? Ich würde gerne einen eigenen Controller implementieren. Auch DQ hat das gleiche Verhalten wie DATAOUT. Christoph db1uq K. schrieb: > Bei micron gibt es jede Menge Applikationsschriften zu SDRAMs: > https://www.micron.com/support/support-documentati... Danke für den Link. Die Theorie habe ich glaube ich soweit verstanden. Es geht mir nun um die oben beschriebenen Details.
:
Bearbeitet durch User
Holger K. schrieb: > Auch DQ hat das gleiche Verhalten wie DATAOUT. Es ist eine grundlegende Eigenschaft synchronen Designs das erst eine gewisse Zeit (clock to output delay) nach der Taktflanke sich etwas tut. Ebenso grundlegend ist das man das Signal dann mit der folgenden Taktflanke verarbeitet. Eben weil es so grundlegend ist wird es in Diagrammen oft nicht explizit dargestellt und der Einfachheit halber die Signaländerungen als sofort dargestellt. Sich daran zu halten vereinfacht sehr vieles auch wenn es manchmal einen Takt Verzögerung im Vergleich zu asynchroner Logik kostet.
Noch etwas, die zeitliche Bezüge am SDRAM-Chip sind nicht dieselben wie am FPGA da sich die Signale durch unterschiedliche Signallaufzeiten auf dem Board gegeneinander und gegenüber dem Takt verschieben. Du wirst dich noch ausführlich mit dem Thema timing constraints auseinander setzen müssen.
bei dem hier vorliegenden single data rate SDRAM macht man es genau wie von Lothar beschrieben: es ist ein synchrones Design, bei dem jeweils bei der steigenden Taktflanke die Daten umschalten, und bei der folgenden steigenden Taktflanke werden sie übernommen. Das gilt für das externe SDR DRAM genau so wie für sämtlichen FPGA-internen getakteten Signale. Der einzige Unterschied ist, dass man beim externen DRAM selbst auf den CLK-Skew auchten muss (bei den internen Flip-Flops übernimmt das Design-Toll diese Aufgabe). Ein ganz normales Eintakten mit der steigenden Taktflanke ist in diesem Fall state of the art. Anders sieht es es, wenn es um double data rate DRAM geht, besonders im Fall modernerer DDR-Varianten (also bei DDR3 und DDR4). Dort sind die Taktfrequenzen höher und man muss bei beiden Taktflanken Daten übernehmen. Deshalb wird dort wesentlich mehr Aufwand getrieben - z.B. ein extra Strobe-Signal zum Eintakten der DQ. Und Takt und Daten müssen passend gegeneinander verzögert werden, damit die Daten wirklich in der Mitte des Datenauges abgetastet werden. Wenn es dir also nur um ein funktionierendes SDR-System geht: bleib einfach bei dem Standardansatz, die Daten mit der steigenden Taktflanke zu übernehmen. Wenn du stattdessen über Flankenschieberei und Zentrierung von Datenaugen lernen willst: schau dir die Implementierungen von DDR-Speichercontrollern an.
Wenn dir die Geschwindigkeit egal ist, dann kannst du das mit der Verzögerung machen. Ansonsten musst du dich wohl mit phasenverschobenen Takten und Timing Constraints herumärgern müssen. Hier mal ein Controller für das DE0-nano: http://hamsterworks.co.nz/mediawiki/index.php/SDRAM_Memory_Controller Du musst deinen Controller auch nicht unbedingt mit 100MHz oder mehr betreiben. Der SDRAM kann bei relativ niedrigem Frequenzen laufen. In Datenblättern von Winbond findet man Werte für die max. Länge der Taktzyklen ("CLK Cycle Time") von 1000ns (=1MHz). Das ist dann aber auch schon fast unpraktisch langsam.
Mike schrieb: > Wenn dir die Geschwindigkeit egal ist, dann kannst du das mit der > Verzögerung machen. Ansonsten musst du dich wohl mit phasenverschobenen > Takten und Timing Constraints herumärgern müssen. Hier mal ein > Controller für das DE0-nano: > > http://hamsterworks.co.nz/mediawiki/index.php/SDRA... > > Du musst deinen Controller auch nicht unbedingt mit 100MHz oder mehr > betreiben. Der SDRAM kann bei relativ niedrigem Frequenzen laufen. In > Datenblättern von Winbond findet man Werte für die max. Länge der > Taktzyklen ("CLK Cycle Time") von 1000ns (=1MHz). Das ist dann aber auch > schon fast unpraktisch langsam. Vielen Dank für deine Antwort. Ich bin aktuell daran am versuchen, den folgenden Controller zum laufen zu bekommen: http://codehackcreate.com/archives/444 Leider klappts noch nicht ganz so wie ich das möchte. Ich verwende seine testbench in meinem HW-Design zum testen. Sein ablauf sieht wie folgt aus: Lesen, Schreiben, Refresh Ich mache logischerweise zuerst schreiben dann lesen und automatisch zwischendruch den refresh. Gibt es da was zu beachten wenn man, so wie ich, schreibe und dann lesen möchte? Leider bekomme ich nicht die richtigen werte ausgegegeben. Mike schrieb: > Datenblättern von Winbond findet man Werte für die max. Länge der > Taktzyklen ("CLK Cycle Time") von 1000ns (=1MHz). Das ist dann aber auch > schon fast unpraktisch langsam. Sehr interessant. Dies würde zum debuggen mit dem Logicanalyzer sehr helfen. Wobei ich mich hier frage, wie dann der Refresh ablaufen soll? Der muss ja alle 64ms gemacht werden und dies für jede row. Typischerweise hat ein SDRAM 4096 oder gar 8192 rows. Das würde bedeuten 64ms/8192 = 7.8us späteste refreshzeit. Das wären dann 128kHz. Ein Refresh dauert 8 Taktzyklen. Dies wären dann bei bei 1us Clockcycle nochmals 8us. das würde bedeutet dann der Refresh bei 8192 Rows nicht ganz eingehalten weren könnte. bei 4096 jedoch schon. Etwas anderes könnte mann dann bei 1MHz wohl nicht mehr machen. Aber ich sehe was du meinst. Mit z.B. 10 MHz wäre das ganze auch recht gut handlebar. Ich werde wohl zuerst das ganze langsamer angehen ;) Danke für den Tipp! Nochwas: Genügt es, wenn ich den SD-RAM Clk um 180 Grad phasenverschiebe gegenüber dem Clock welcher mir meine FPGA Logik taktet? oder besser 270 Grad um laufzeiten der internen Logik noch dazuzurechnen, damit ich am ende auf ca. 180 grad komme? Wie sieht das aus mit den Verhältnisen? Wenn ich nun das ganze mit 10MHz durchführe, dann kann ich mit dem LA problemlos das ganze mit 100MHz sample rate des LA messen. Nun würde ich z.B. sehen, dass alles so funktioniert wie gewollt. Kann ich nun einfach auf 100MHz erhöhen, und die Timings bleiben gleich? Danke
Mike schrieb: > Wenn dir die Geschwindigkeit egal ist, dann kannst du das mit der > Verzögerung machen. Ansonsten musst du dich wohl mit phasenverschobenen > Takten und Timing Constraints herumärgern müssen. Ich grätsche mal rein, weil ich vor dem selben Problem stehe: Mein Board (Spartan 6) hat einen SDRAM, den ich gleichzeitig für einen Framebuffer (50 MHz Pixelclock, 800x600@72) und als externen RAM für eine CPU benutzen möchte. Spezifiziert ist der SDRAM für 200 MHz. Wie hart wird das mit dem Timing?
S. R. schrieb: > Ich grätsche mal rein, weil ich vor dem selben Problem stehe: Mein Board > (Spartan 6) hat einen SDRAM, den ich gleichzeitig für einen Framebuffer > (50 MHz Pixelclock, 800x600@72) und als externen RAM für eine CPU > benutzen möchte. Spezifiziert ist der SDRAM für 200 MHz. > > Wie hart wird das mit dem Timing? Welchen Speedgrad hat der Spartan ?
C. A. Rotwang schrieb: >> Wie hart wird das mit dem Timing? > Welchen Speedgrad hat der Spartan ? Wenn ich mich nicht verlesen habe, -2C (XC6SLX9). Aber wenn du schon so fragst, wird das für mich Anfänger eher nix. :-(
S. R. schrieb: > Aber wenn du schon so fragst, wird das für mich Anfänger eher nix. :-( Ich habs inzwischen hinbekommen. Das RAM Läuft. War im Endeffekt garnicht so schwierig! Habe mit der PLL zwei Clocks generiert, welche um jeweils 180Grad verschoben sind. Nun bin ich soweit, dass ich mich fragen muss, was passiert wenn ich im Burstmode die Addresse erhöhe. Ich nehme an, dass ich selbst jeweils prüfen muss, welche Bank aktiv sein müsste und welche Row geladen werden muss? Danke
S. R. schrieb: > C. A. Rotwang schrieb: >>> Wie hart wird das mit dem Timing? >> Welchen Speedgrad hat der Spartan ? > > Wenn ich mich nicht verlesen habe, -2C (XC6SLX9). > Aber wenn du schon so fragst, wird das für mich Anfänger eher nix. :-( Der Spartan-6 hat "eingebaute" (HardCore) Memorycontroller und daher für Anfänger IMHO einfacher zu beherschen als die SoftCore-Memorycontroller: https://www.xilinx.com/support/documentation/user_guides/ug388.pdf Mit dem -2 sollten auch 200 MHz möglich sein. Problem wäre ein zu kleines package (TQG144/CPG196) oder suboptimales Routing/Pinning auf dem Evalboard.
C. A. Rotwang schrieb: > Der Spartan-6 hat "eingebaute" (HardCore) Memorycontroller In dem Link steht, dass der Controller DDR, DDR2, DDR3 und LPDDR unterstützt und beschreibt auch nur diese, mein RAM ist allerdings ein normales SDRAM. Ginge der trotzdem? Wenn meine Frage naiv klingt, dann vor allem, weil ich bisher nur SRAM und asynchrones DRAM verwendet (AVR-CP/M und so) und mich mit SDRAM noch nicht beschäftigt habe. C. A. Rotwang schrieb: > Problem wäre ein zu kleines package (TQG144/CPG196) > oder suboptimales Routing/Pinning auf dem Evalboard. Hmm, Package ist groß genug (FTG256), aber der MCG scheint feste Pins zu haben und mein UCF verweist auf völlig andere Pins (z.B. A0-A3 sind J3,J4,K3,K5). Scheint also zumindest auf dem Board nicht zu gehen, schade.
S. R. schrieb: > C. A. Rotwang schrieb: >> Der Spartan-6 hat "eingebaute" (HardCore) Memorycontroller > > In dem Link steht, dass der Controller DDR, DDR2, DDR3 und LPDDR > unterstützt und beschreibt auch nur diese, mein RAM ist allerdings ein > normales SDRAM. Ginge der trotzdem? Warum nicht? Der SDR(single data rate)-SDRAM sollte die entgegengesetzte Flanke ignorieren und ggf. wird jedes zweite Wort beim Lesen weggeworfen, respektive doppelt gesendet. >Hmm, Package ist groß genug (FTG256), aber der MCG scheint feste Pins zu >haben und mein UCF verweist auf völlig andere Pins (z.B. A0-A3 sind >J3,J4,K3,K5). Scheint also zumindest auf dem Board nicht zu gehen, >schade. Ich würd die Schlacht noch nicht verloren geben, Addressbits sind eher unkritisch; wenn die Laufzeitunterschiede zwischen den Adressleitungen zu hoch sind, kann man mit CAS-Latency noch Takt einfügen um auch den Bummelletzten noch rechtzeitig einlaufen zu lassen. Kritisch sind die Datenleitungen und data_strobe. Aber auch da kann man im Spartan-6 mit den IO-delay elementen noch einiges ausgleichen. Einfach mal ausprobieren und mit einer Testschaltung die Fehlerrate ermitteln.
C. A. Rotwang schrieb: > Warum nicht? Der SDR(single data rate)-SDRAM sollte die entgegengesetzte > Flanke ignorieren und ggf. wird jedes zweite Wort beim Lesen > weggeworfen, respektive doppelt gesendet. Hmm, stimmt auch wieder. Klingt logisch, hab ich nur nicht drüber nachgedacht. Wie gesagt, müsste man sich mal mit beschäftigen, hab ich nur vorerst nicht die Zeit zu. C. A. Rotwang schrieb: > Ich würd die Schlacht noch nicht verloren geben, > Addressbits sind eher unkritisch; Ich hab von sowas doch keine Ahnung. ;-) Soweit ich das sehe, sind Daten-, Adress- und Steuerbits kreuz und quer verdrahtet, und manche SDRAM-Pins sind komplett außerhalb. Damit dürfte der Hardcore vollständig unbenutzbar sein. Es sei denn, ich verstehe deinen Vorschlag mit der Verzögerung falsch.
S. R. schrieb: > C. A. Rotwang schrieb: >> Warum nicht? Der SDR(single data rate)-SDRAM sollte die entgegengesetzte >> Flanke ignorieren und ggf. wird jedes zweite Wort beim Lesen >> weggeworfen, respektive doppelt gesendet. > > Hmm, stimmt auch wieder. Klingt logisch, hab ich nur nicht drüber > nachgedacht. Wie gesagt, müsste man sich mal mit beschäftigen, hab ich > nur vorerst nicht die Zeit zu. Ja das könnten viele Schritte werden um zum laufenden mem-Interface zu kommen, ein erster sollte IMHO sein einen eigene Thread dazu aufzumachen, so etwa "Erfahrung mit Memory Controller im Spartan-6 gesucht". > C. A. Rotwang schrieb: >> Ich würd die Schlacht noch nicht verloren geben, >> Addressbits sind eher unkritisch; > > Ich hab von sowas doch keine Ahnung. ;-) > Soweit ich das sehe, sind Daten-, Adress- und Steuerbits kreuz und quer > verdrahtet, und manche SDRAM-Pins sind komplett außerhalb. "Kreuz und Quer im FPGA" ist bei clock synchronen Designs unproblematisch solange die FF im den IO-Pads genutzt werden und die Signale vom controller zu den Pins nicht länger als 5 ns brauchen. Und um den Code für einen memorycontroller zu erzeugen, gibt es bei Xilinx ein Extra-Tool, den MIG - Memory Interface Generator. https://www.xilinx.com/support/documentation/ip_documentation/mig/v3_8/ug416.pdf Damit könnte man mal einen DDR-Core für dein Pining durchklicken und auf 200 MHz konfigurieren. Und das Ganze mit einem optimalen Pining wiederholen. Dann fehlen zwar noch etliche Anpassungen, aber man hätte allein mit "GUI-Durchklicken" eine ersten groben Eindruck bzgl. der Machbarkeit den SDRAM auf dem Board mit 200 MHz anzusprechen.
C. A. Rotwang schrieb: > "Kreuz und Quer im FPGA" ist bei clock synchronen Designs > unproblematisch solange die FF im den IO-Pads genutzt werden und die > Signale vom controller zu den Pins nicht länger als 5 ns brauchen. Du sprichst gerade von einem aus Logik gebauten Speichercontroller, oder? Denn nach der Application Note von Xilinx hat der fertig integrierte Hardcore ein festes Pinout, was überhaupt nicht zu meinem Board passt. Die Links schaue ich mir genauer an, wenn ich nächste Woche wieder zuhause bin, danke schonmal dafür.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.