Hallo zusammen, es gibt hier im Forum ja schon einige Beispiele fuer DRAM am AVR (e.g. http://www.mikrocontroller.net/forum/read-4-121457.html, http://www.mikrocontroller.net/forum/read-1-240689.html ) Ich arbeite aber gerade an einem DRAM-Controller (als Vorprojekt fuer einen SDRAM-Controller) auf CPLD/FPGA Basis. Als Nebenprodukt habe ich mir gedacht, koennte ich auch eine Version synthetisieren, die man in eine billige CPLD (<2 Euro) packen kann, um damit Standard (Alt-)PC SIMM RAM an den AVR anzuschliessen und insbesondere zu entlasten. Nicht die Rechenleistung fuers Refresh, sondern die Anzahl (eher Unzahl) an Pins die die Beispiele benoetigen, finde ich verbesserungswuerdig. Jetzt meine Frage: Welches Interface waere fuer einen AVR an den DRAM-Controller zweckmaessig? Die Idee ist, dass diese eine moeglichst geringe Pin-Anzahl braucht und leicht zu benutzen ist. Anregungen nehme ich gern entgegen! Gruesse aus London Thorsten
Einen Sinn macht ein DRAM nur, wenn dieser folgende Punkte erfüllt: - Speicher größer als verfügbarer SRAM (also 1MB aufwärts, was bei SIMM Modulen gegen ist) - Speicher leicht nutzbar, also entweder linearer Adressraum, oder unterteilt in viele 32kB Blöcke, mit Mapping im CPLD. - Möglichst ansteuerbar über XMEM Interface (was Probleme bereiten könnte, da der AVR keinen Wait Eingang hat) - Alternative zum XMEM Interface: SPI um möglichst wenige Leitungen zu verbrauchen. Dies macht aber aufgrund von billig verfügbaren Flash Speichern mit I2C/SPI wenig Sinn bei Verwendung in Datenloggern. Das sind zumindest die Punkte, die ich versucht hatte. Mit einem 8051 und vielen HCMOS ICs ging das auch ganz gut, aber beim AVR ist das Timing und der ALE Impuls etwas ungünstig: Es ging etwa 1 von 10 SIMM Riegeln.
Statt einem (nicht vorhandenen) Wait-Eingang könnte der CLPD ja buffern während er gerade refreshed.
Ein Interface ähnlich T6963C wäre auch nicht zu verachten. Es kann ja zusätzlich auf SPI umschaltbar sein. Dann noch die Logik für Auto-Increment(/Decrement) mit getrennten Pointern für Read und Write und schon wäre FIFO-Betrieb oder Stack-Betrieb (nicht so wichtig wie FIFO) möglich. Es ist nicht so, dass ich das Teil unbedingt und sofort brauchen würde, aber wenn schon darüber diskutiert wird, sollte man auch an diesen Aspekt denken. Da das Teil eine Platine erfordert, die nicht jeder Bastler mit Heim-Mitteln realisieren kann, sollte auch daran gedacht werden, dass man die Platine (vielleicht schon mit CPLD und SIM-Sockel bestückt) zu einem fairen Preis (fair für beide Seiten) kaufen kann. ...
Hätte ich aufjedenfall auch Spass dran. So richtig toll wirds aber erst ab 16Mb Speicher :-)
aber das geht ja leider nich mit dem XMEM Interface :-(
Nunja, für XMEM-Interface sollte auch gleich ein XMEM-fähiger AVR mit auf das Board. Ansonsten werden das zu viele Strippen... Ich denke aber, dass an einem eigenständigen (großen) FIFO mehr Interesse besteht, als an der Nutzung des XMEM-Bereiches. Die meisten Programmierer hatten noch keinen Mangel an RAM für normalen Zugriff. Ein großes FIFO (vielleicht mit mehreren Pointerpaaren) schafft aber völlig neue Perspektiven (Logik-Analyzer, schneller Datenlogger...). Die Initialisierung der Pointer (vielleicht sind ja auch mehrere Pointerpaare möglich?) und deren Bereiche (Grenzpunkte, falls mehrere Pointerpaare implementiert sind) kann ja im "Command-Mode" (Pin "Command/Data") vorgenommen werden, die eigentlichen Schreib/Lesezugriffe erfolgen dann über OUT/IN am Port und L-Impuls an /WR und /RD. Aber die Idee ansich ist schonmal gut. Und die Idee, das vorher zur Diskussion zu stellen, ist noch besser. ...
Das Interface ist für mich erstmal völlig nebensächlich. Was mich brennend interessiert, für welche Anwendungen kann man überhaupt DRAM sinnvoll benutzen ??? Nur deshalb DRAM an den AVR dranpappen, damit man ihn mal drangepappt hat, finde ich persönlich völlig witzlos. Der AVR ist auch ne äußerst ungünstige Wahl, da er nur max 64kB RAM adressieren kann. Ich würde mindestens nen 8051-er nehmen, z.B. den P89C669, der kann 8MB adressieren. Oder gleich nen ARM. Peter
Die 8051 haben AUCH nur eine 64k adressraum. Also WIE macht der 8MB linear? GARNICHT. Also wieder der 'alte' trick mit memory banking. Und dies kann man dann in den CPLD einbauchen um den kompletten DRAM anzusprechen über XMEM. Ich erinnere mich an die Z80 maschienen mit 512k Ram, 256k Rom... Olaf
DRAM kann man sinnvoll nutzen, wenn man z.B. Dateisysteme verarbeitet, z.B. um die FAT Tabelle abzulegen. Ein ARM ist für einen kleinen mp3 Player etwas oversized, bzw. nicht ganz so leicht zu verwenden wie ein AVR. Hier wird z.B. ein normaler 8051 mit >32MB DRAM verwendet, und das reicht für einen mp3 Player: http://www.pjrc.com
@Olaf "Also wieder der 'alte' trick mit memory banking." Nein ! Der P89C669 hat 8 (2 je Registerbank) 3Byte-Pointer um damit sämtlichen Speicher linear adressieren zu können (code, idata, xdata). Von Maxim gibt es den DS80C390 mit 24Bit-Adressen. Man braucht allerdings einen nicht zu alten Keil C51, der die 24Bit-Adressierung unterstützt. Peter
Hallo zusammen, schonmal vielen Dank fuer die lebendige Diskussion und die konstruktiven Beitraege. Eine kurze Zusammenfassung meinerseits: * Adressierung logisch 1) Adressierung wie XMEM-Interface (bis 64 KiB) 2 Byte Adresse 2) Adressierung wie XMEM-Interface mit Banking 2 Byte Adresse und n Bits Bank 3) Adressierung linear: 2 Byte-Pointer: 64 KiB; 3 Byte-Pointer: bis 16 MiB 4) `Adressierung' als FIFO getrennte Pointer fuer Lesen/Schreiben, Auto Increment/Decrement * Adressierung Hardware: 5) `Viele' Pins: Adress/Datenbus, XMEM, 1), 2), 3) ... 6) SPI/I2C 7) T6963C aehnlich 8) FIFO mit Data/Command, /WR, /WD, Bus Kurz noch zu meiner Intention: Das boese Wort mit L ist ja schon gefallen ... Irgendwann (2010?) soll es darauf hinauslaufen. Aber fuer ein sinnvolles (Vor-)Project mit FPGA/CPLD wollte ich erstmal einen kleinen unscheinbaren Memorycontroller machen. zu 1) Nicht so interessant, da SRAM bis 64 KiB billiger ist, als CPLD + DRAM. Quelle: Reichelt: 628128-70 128Ki x 8, 2.20 Euro CPLD XC 9536XL VQ44: 1.80 Euro zu 2) Banking Bei PICs habe ich das Banking gehasst. Der hatte nur 8 Bit (?) Adressen und auch die Control Register liegen deshalb in verschiedenen Baenken. Beim Debuggen bin ich fast wahnsinnig geworden. Wenn man das fuer `Bulk-'RAM (grosse Bereiche, um Daten, z.B. Messwerte) nutzt, ist es wohl OK. zu 1), 2) und 3) Timing beim XMEM Da ist vom Timing schon anspruchsvoll ;-) Bei einem 16 MHz AVR ist die Zykluszeit 62.5 ns. SIMM aus alten Computern hat ueblicherweise 70 ns Zugriffszeit, wenn man ROW und COL setzen will. Ist man im Page-Mode (nur COL veraendern, eine Page ist 256 Byte in einem Modul), dauerts kuerzer. @Simon: was hast Du genau gemeint mit > könnte der CLPD ja buffern während er gerade refreshed. Bei wirklich wahlfreiem Zugriff auf den gesamten Speicherbereich per XMEM Interface muss ich jedes Byte binnen 70ns bereitstellen koennen. Wie kann das Buffern da helfen? @Benedikt: Wie hast Du das denn mit den HCMOS ICs gemacht? Bisher hab ich eine State-Machine, die alle 20 ns den State wechselt und entsprechend das Timing realisiert (natuerlich in Schritten zu 20, 40, 60 ns: Also: ROW setzen, RAS, COL setzen, CAS, wait, Byte einlesen. So macht es auch der SDRAM Controller von Xilinx, app134. Aber da braucht man ja auch eine Taktquelle 1/20ns). Kann man das Timing noch anders erzeugen? Mit Gatterlaufzeiten pfuschen? Das Problem ist ja, dass die Adresse stabil sein muss, bevor das Adressstrobe kommt => serieller Ablauf, oder nicht? zu 4) wo ich ja eigentlich drauf hinaus will ... zu 5) Wenn man schon viele Pins am AVR benutzen will/muss, kann man das Timing auch gleich im AVR machen. So viel kostet das Refresh ja wirklich nicht. Das einzig schoene waere das XMEM Interface, da es sehr transparant zu programmieren waere (keine put/gut Routinen). Dann muss man aber noch einen Port fuers Banking spendieren (weil 64 KiB uninteressant sind, siehe 1) und das Timing ist nicht ohne. zu 6) da schliess ich mich Benedikt an: Flash ist da ne gute Wahl. zu 7) Ja, ein brauchbares Interface. Der Adress-/Datenbus spart schonmal knapp die Haelfte der Pins ein. Hab sogar mal Code gesehen, bei dem der Grafikspeicher eines Displays zum (Mess-Daten)-Ablegen genutzt wurde ;-) zu 8) Da ist die Frage nach der maximalen Daten-Rate: Wenn man die Row wechseln will/muss, brauchts etwas laenger, das limitiert die Datenrate. Ein aynchrones Beschreiben (DRAM buffert in diesem Fall zwischen, bis Row gewechselt) ist fuer ne kleine CPLD etwas zu viel glaube ich. Den Code aus http://www.mikrocontroller.net/forum/read-1-240689.html habe ich mal um einen `Enhanced-Page-Mode-Write-Cycle' und `Enhanced-Page-Mode-Read-Cycle' (alle Cols in einer Row in einem Durchgang lese/schreiben) ergaenzt. Das hab ich aus dem Datenblatt zum TMS44400. Koennen das eigentlich alle SIMM-Bausteine? Zur Platine: ich komm an alles dran und koennte da ggf. was fertig machen. Mit SIMM mein ich die 30 poligen aus 486er Zeiten, ich hoffe alle anderen auch? Gruss Thorsten
Mein DRAM Interface für den 8051 sieht so auf und funktioniert je nach DRAM mehr oder weniger gut. Für die RAS\CAS Umschaltung verwende ich das sowiso schon vorhandene ALE Signal. IC6 dient als Latch fürs Banking. Insgesamt unterstützt die Schaltung 2MByte, aufgeteilt auf 64 Bänke. Ich verwende immer die oberen 32kB des Adressraums für den Speicher und den unteren für I/O (LCD, IDE, Speicher Mapping Register usw.) Wenn ich mir das AVR Timing anschaue, dann steht das Highbyte der Adresse schon einen oder einen halben Takt vor Aktivierung des WR\ bzw. RD\ Signals an. Daher hätte man 93ns für einen DRAM Zugriff, was eigentlich reichen sollte. Falls das nicht reicht, es gibt immer noch Wait States die man einschalten kann... Wie willst du das Problem mit dem Refresh lösen ? >die man in eine billige CPLD (<2 Euro) packen kann Wo bekommt man einen CPLD für <2 ? Reichelt hat die Preise für die Xilinx 5V CPLDs stark erhöht...
@Peter: Ok. Da habe ich wohl blödsinn erzählt. Nun ja ich bin kein fan der 8051 und so nicht mit allen vertraut. Hätte wohl man die features des P89C669 vorher ansehen sollen. ;) Olaf
@Benedikt: danke fuer den Plan. Aber das die Schaltung kann kein RAS und CAS in einem Zyklus, muss also der Prozessor wieder ran ... 3,3 Volt CPLDs sollten es auch tun ... Fuer die Spartan 3 FPGAs von Xilinx hab ich schon nachgeguckt: mit richtigen Vorwiderstaenden (zur Strombegrenzung) akzeptieren die auch 5 Volt Eingang. Der SIMM hat ein VIH von 2.4 Volt, was auch passt. Ein Schreiben oder Lesen in einer Row refreshed die ganze Row. Und sonst muss zwischendurch ein Timer im CPLD ein CBR refresh machen. Die CPLD koennte an den Takt des uC angschlossen werden. Wie hast Du das mit dem Refresh beim 8051 gemacht? Muss doch der Prozessor machen? Gruss Thorsten
Den Refresh habe ich ziemlich trickreich gemacht: Das Latch IC7A bekommt als Datensignal ein Refresh_Enable\ vom uC. Da das Latch während der steigenden Flanke speichert, wird der Ausgang und damit CAS\ Low, während ALE (=RAS\) auf High liegt. So wird ein CAS before RAS Refresh gestartet. Mit jedem uC Takt wird ein CBR gemacht. Ist zwar nicht Stromsparend, funktioniert aber. Der uC muss als aktiv nicht refreshen, sondern er muss den Refresh nur einschalten. So ist es dem Benutzer überlassen, wann er den Refresh laufen lässt. Wie willst du das ganze machen ? Wenn der CPLD am Refreshen ist, und der uC ein Byte haben möchte ?
> Wenn der CPLD am Refreshen ist, und der uC ein Byte haben möchte ?
Hmm, wie macht das denn ein DRAM Controller auf meinem Mainboard? Oder
halt bei den alten 486ern?
Im Zweifel muss der Controller dann den CBR abbrechen, also /CAS und
/RAS high ziehen, Row, RAS, ... normales Spielchen halt.
Wie das Verhalten bei einem abgebrochenen CBR ist, konnte ich aber
nicht finden. Vielleicht korrupiert das die Daten??
Wenn der Read/Write Zyklus fertig ist, kann man mit dem CBR ja
weitermachen, die Refresh-Adresse wird ja im DRAM selbst gespeichert.
Den CBR zu Ende machen geht nicht, da im unguenstigsten Fall der gerade
begonnen wurde und 130 ns braucht. Die maximale Zeit von der ersten
Adresse bis zum Liefern der Daten ist beim XMEM 190 ns. Fuer den
Speicherzugriff sind dann noch 60 ns ueber, zu knapp :-(
Was passiert aber, wenn der uC staendig und immerzu Daten haben will,
so dass der Controller gar nicht zum refreshen kommt? Wie ist sowas bei
nem `richtigen' DRAM Controller geloest?
Schoene Gruesse
Thorsten
@Simon Leider versteh ich Deine Idee immer noch nicht ... Was soll der CPLD denn buffern? Will der uC ein Byte, so ist es innerhalb von xxx ns faellig. Welches Byte das ist, kann man nicht vorhersagen. Was soll der Buffer denn buffern? Den ganzen DRAM kann es ja nicht buffern ...
Oh, ans Lesen habe ich garnicht gedacht. Hätte der CLPD das schreiben nur etwas verzögert, wäre es ja nicht das Problem gewesen. Hmm..
Und das XMEM-Interface wird wohl mit sowas wie "Busy" nicht umgehen können... - Nix iss vollkommen... ...
Mir ist noch folgende unsinnige Idee gekommen: aktuelle Page (16, 32 oder 64KiB) wird in SRAM geladen und wird dort gelesen/beschrieben. Der DRAM wird im `Hintergrund' nur refreshed. Beim Page-wechsel wird der aktuelle Inhalt des SRAM in den DRAM (an entsprechender Stelle kopiert und die neue Page aus dem DRAM in den SRAM geladen. --> Dauert zu lange?? [ Nebenrechnung: 64 KiB = 65536 B Row, Col waehlen und 1 Byte schreiben: 130ns die naechsten 255 Byte der Row schreiben (`burst'): 255 * 50ns = 12880 ns das ganze mal 256 Rows: 3330560 ns} Mal zwei (Schreiben und Lesen) = 6.6 ms???
Wie siehts aus, gibt es schon erste Fortschritte ? Mir ist da noch eine Idee wegen dem Refresh gekommen: Sobald ALE auf High geht, wird der Refresh unterbrochen, der Datentransfer ausgeführt und der Refresh fortgesetzt. Mit einem Wait sollte das Timing auch passen.
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.