Hallo, in einem FPGA Entwurf würde ich gerne den RAM der im FPGA abgebildet ist, durch ein reales externes RAM ersetzen.Probleme bereitet mir dabei der Datenbus des internen RAMs. Der externe Speicher hat einen bidirektionalen, der interne zum lesen und schreiben jeweils einen eigenen. Wie bekomme ich jetzt die beiden Datenbusse zu einem bidirektionalen ? Grüße Dirk ports des externen rams ram_a : out std_logic_vector(19 downto 0); ram_io : inout std_logic_vector(7 downto 0); ram_ce : out std_logic; ram_oe : out std_logic; ram_we : out std_logic; internes FPGA RAM: rams : for i in 0 to 3 generate u_ram : component RAMB16_S2 port map ( do => RDB((i*2)+1 downto (i*2)), addr => RAB, clk => Clk, di => RWD((i*2)+1 downto (i*2)), en => '1', ssr => '0', we => ram_we ); end generate; Meine nicht funktionierende Lösung: ram_io <= RWD when ram_wr = '0' else (others => 'Z'); ram_a(12 downto 0) <= RAB; ram_a(19 downto 13) <="0000000"; ram_ce<='0'; ram_oe<='0'; ram_we <= ram_wr;
@ Dirk > in einem FPGA Entwurf würde ich gerne den RAM der im FPGA abgebildet > ist, durch ein reales externes RAM ersetzen.Probleme bereitet mir dabei Das RAM in FPGA ist auch sehr real. ;-) > der Datenbus des internen RAMs. Der externe Speicher hat einen > bidirektionalen, der interne zum lesen und schreiben jeweils einen > eigenen. Genau. Und wahrscheinlich ist der exteren ein asynchroner SRAM. > Wie bekomme ich jetzt die beiden Datenbusse zu einem bidirektionalen ? Du musst einen Memory-Controler programmieren. Der hat nach aussen (in Richung FPGA) genau die gleich Anschlüsse wie die BRAm im FPGA. In Richtung exteren SRAM hängen alles Adress/Daten und Steuerleitungen dran. Eine Statemachine muss dann aus Zugriffsanfragen vom FPGA die entsprechenden Steuersignale für den SRAM machen. Alles machbar, aber das Verhalten des internen BRAMs wirst du nicht 100%ig genau mit dem externen SRAM nachbilden können. > Meine nicht funktionierende Lösung: > ram_io <= RWD when ram_wr = '0' else (others => 'Z'); > ram_a(12 downto 0) <= RAB; > ram_a(19 downto 13) <="0000000"; > ram_ce<='0'; > ram_oe<='0'; > ram_we <= ram_wr; Das ist der Ansatz, es fehlt aber ncoh ne Menge. Denk dran, im FPGA ist alles synchron zu einem Takt, auch die BRAMS. Der exteren SRAM ist asynchron. MfG Falk
Das externe RAM ist zwangsweise auch "synchron", da es von einem synhr. Baustein garnicht anders beschrieben werden kann.
@Falk Danke für Deine Hinweise. Ich habe jetzt ein SRAM Controller wie Du beschrieben hast entworfen, naja mehr aus einem anderen Thread hier angepasst. Funktioniert leider auch noch nicht. Vermutlich muß ich mehr auf das timing achten. Das ganze soll der Space Invaders Core von der FPGA Arcade Seite werden. Im internen RAM des Spartan 3 läufts, nur eben mit dem externen SRAM noch nicht.Ganz ohne Funktion ist der SRAM Controller nicht, denn es flimmert schon auf dem Monitor. Ich glaube da muß ich noch ein paar Hausaufgaben machen. ;-) Grüße Dirk
@ Alfred > Das externe RAM ist zwangsweise auch "synchron", da es von einem synhr. > Baustein garnicht anders beschrieben werden kann. Nur dumm, dass es keinen Takteingang hat. Und auch sonst so nicht so ganz einfach angeklemmt werden kann. @ Dirk > Funktioniert leider auch noch nicht. Vermutlich muß ich mehr auf das > timing achten. Achte vor allem darauf, dass die kritischen Signale (CS, RD, WR) direkt aus FlipFlops kommen, um ganz sicher keine Glitches dort zu haben. > Das ganze soll der Space Invaders Core von der FPGA Arcade Seite > werden. Im internen RAM des Spartan 3 läufts, nur eben mit dem externen SRAM noch nicht.Ganz ohne Funktion ist der SRAM Controller nicht, denn es Cool! Ich hab vor längerer Zeit mal den Pacman auf Spartan-II (mit externem FLASH) sowie Spartan-3 (alles interes RAM) angepasst. Und es läuft! Und wenn er nicht geplatzt ist, so frisst er noch heute (der Pacman). > Ich glaube da muß ich noch ein paar Hausaufgaben machen. ;-) Gute Einstellung! MfG Falk
So, da bin ich wieder.Inzwischen habe ich alle erdenklichen Möglichkeiten der SRAM Ansteuerung probiert und muß leider sagen daß es nicht funktioniert. Ich habe es mit State-Maschines und ganz einfachen Varianten versucht, aber nix.Es will einfach nicht. Sogar die Ansteuerung wie es im Demodesign meines Boards gezeigt wird funktioniert im Invaders nicht. Die CPU wird mit einem heruntergeteilten Takt von 10 MHz versorgt. Am RAM gibt es einen Eingang WE mit dem zwischen lesen und schreiben umgeschaltet wird.Wenn WE 1 dann wird geschrieben. Wer kann mir sagen wo bei meiner Ansteuerung der Fehler ist ? Viele Grüße Dirk ram_we <= not RWE_n; ram_a(19 downto 13) <= "0000000"; ram_a (12 downto 0) <=RAB; u_ram : entity work.SRAM port map ( reset => I_RESET_L, do => RDB, clk => Clk, di => RWD, ram_oe => ram_oe, ram_ce => ram_ce, ram_bhe => ram_bhe, ram_ble => ram_ble, ramwe => ramwe, we => ram_we, en => '1', ram_io => ram_io );
@Dirk > Sogar die Ansteuerung wie es im Demodesign meines Boards gezeigt wird > funktioniert im Invaders nicht. Nun, die Frage ist ganz einfach, welches Interface der Invader hat. Ist das der Programmspeicher, der im Original EPROM ist? Wenn ja, dann sollte man es ganz einfach 1:1 ohne nenneswerte Zwischenlogik anschliessen können. Zeig mal den Invader-Code. MFG Falk
@Falk Es ist nicht die Epromansteuerung. Ich habe mal den gesamten Code (ohne ROMS) angehängt. Grüße Dirk
Den RAM Speicher (CPU u. Video)der im original Design im FPGA(XC3S1000) angelegt ist. Ich möchte das Design auf einen FPGA(Altera 10k100) der nicht soviel internen RAM Speicher hat, portieren.Das Board hat dafür den externen SRAM. Die Eproms müssen dafür auch noch in den externen Speicher. Aber das ist Schritt 2. Grüße
Also du meinst diesen RAM in Toplevel? -- -- SRAM -- ram_we <= not RWE_n; rams : for i in 0 to 3 generate u_ram : component RAMB16_S2 port map ( do => RDB((i*2)+1 downto (i*2)), addr => RAB, clk => Clk, di => RWD((i*2)+1 downto (i*2)), en => '1', ssr => '0', we => ram_we ); end generate; MFG Falk
Nun, da wird auf 4 BRAMs ein 8kx8 RAM gestrickt. Und der ist hier synchron. Und ich fürchte, der reagiert giftig auf Latenz. Hmmm. Da muss man wohl ein wenig tricksen. Ich denk drüber nach. MfG Falk
Dann lag ich mit meinem, ist ja schnell drangestrickt, anscheinend leider etwas daneben. Vielen Dank für Deine Unterstüzung. Grüße Dirk
Hallo Falk, ich habe es eingebaut, aber es funktioniert leider auch nicht. Grüße Dirk ram_we <= not RWE_n; u_ram : entity work.ram_converter port map( sram_data => ram_io, sram_adr => ram_a(12 downto 0), sram_ce => ram_ce, sram_rd => ram_oe, sram_wr => ramwe, fpga_adr => rab, fpga_do => rwd, fpga_clk => clk, fpga_we => ram_we, fpga_di => rdb );
Das dürfte für die meisten keine Lösung sein, denn es realisiert nicht den zweiseitigen Zugriff. Wenn schon müsste ein Multiplexer her, der auf entsprechend hohem Ramtakt beide Ports emuliert. Bis zu einer bestimten Grenzfreuquenz (ca CLK/6) wäre dann ein BRAM voll in einem solchen RAM timingkopatibel abzubilden. Dann ein Multiplexer mit 6/8 physikalischen RAMs bei echter pipeline-Struktur und man hat Identität. Braucht aber für interne 150MHz volle 8 externe RAMs -> 250-300 pins :D
@Ingenieur Jaja, der Herr Ingeniööör. Viel reden ohne vorher nachzudenken. >Das dürfte für die meisten keine Lösung sein, denn es realisiert nicht >den zweiseitigen Zugriff. Wenn schon müsste ein Multiplexer her, der auf >entsprechend hohem Ramtakt beide Ports emuliert. Bis zu einer bestimten Es gibt hier nur einen Port. Und dass eben Read- und Write Daten nicht gemuxt sind. Das sollte mein Modul aber schon machen. >für interne 150MHz volle 8 externe RAMs -> 250-300 pins :D Das stand gar nicht zur Debatte. Reden ist Silber , . . . @Dirk Wie testest du denn? Auf nem S3? Läuft das Ganze auf nem S3 wenigstens erstmal im Urzustand? MfG Falk
Ich teste auf dem S3 Board nur eben mit dem geänderten Speicherzugriff. Wenn es auf dem Board richtig läuft fange ich mit der ALtera Version an. Inzwischen haben ich ja einige Versionen durchgetest und habe auch verschiedene Darstellungen auf dem Bildschirm kennengelernt. Von, geht gar nicht mehr bis stehendes Bild,ohne sinnvollen Inhalt hatte ich schon fast alles. Bei deiner Version springt die Synchronisation des Monitors an, aber es erscheinen kurzeitig senkrechte Raster die verschwinden und wieder auftauchen. Den Zustand hatte ich auch schonmal bei einer meiner Varianten. Der Speicher wird anscheinend angesprochen, aber irgendetwas ist noch faul. Ich hoffe Du konntest mit der Beschreibung etwas anfangen. ;-) Grüße Dirk
Ja, auf dem S3 Board mit internem Speicher funktioniert es 100 % Dirk
@Dirk
>Ich hoffe Du konntest mit der Beschreibung etwas anfangen. ;-)
Einigermassen. OK.
Was für SRAMs sind denn auf dem S3 Eval-Board? Genaue Typbezeichnung.
Wenn die nämlich zu schnell sind (15ns oder so) dann lassen die sich
nicht durch meinen Hack verarschen.
MFG
Falk
Uhhhh, das wird eng. Naja. Kannst du eine kleine Testumgebung bauen, in der ein einfacher Zähler ein paar Daten in den emulierten BRAM schriebt und zurückliest. Mach den Test erst mit richtigem BRAM, dann mit meinem Modul. Hast du auch alles Pins richtig zugeordnet? Den Test natürlcih auch mit den 10 MHz machen. MfG Falk
Ich werde es probieren. Dumm ist nur das mein Board keine 7 Segment Anzeige hat.Nur RS232,VGA und 4 LEDs.Ich werde den Speichertest von meinem Board für BRAM und Dein Interface anpassen.Da leuchtet dann eine LED wenn die gelesenen nicht mit den geschrieben Daten übereinstimmen. Bei der Pin Zuordnung habe ich für RAM_RD = Ram_OE genommen.Den Clk hatte ich mit 10 MHz verbunden.Die anderen Pins sind ja eindeutig. Grüße Dirk
@Falk So, ich habe den Speichertest jetzt mal komplett in allen Variationen probiert. BRAM funktioniert mit 10Mhz und 40 Mhz ohne Probleme. Mit Deinem Modul funktioniert der Test nur mit 40 Mhz, mit 10 Mhz stimmen die gelesenen mit den geschriebenen Daten nicht überein. Den Invaders Core habe ich nochmal mit Deinem Modul und 40 MHz Clk probiert. Die Darstellung sieht jetzt wieder anders aus. Das Bild steht für ein paar Sekunden, das obere Drittel des Bildschirms ist mit regelmäßigen Streifen gefüllt.Die unteren zwei Drittel mit unregelmäßigen Zeichen.Im oberen Teil läßt eine Buchstabenkombination erkennen. Dann wird das Bild für eine Sekunde schwarz und das Spielchen wiederholt sich endlos. Grüße Dirk
OK, vergiss die alte Version. Ich habs mal simuliert, kann nicht funktionieren. Hier die neue Version, die sollte mit ein wenig Glück funktionieren. MFG Falk
Boa, Leute habt ihr schon mal was von Simulieren und Testbenches gehört? Schaut mal bei IDT nach, die haben Verilog-Modelle (vielleicht auch VHDL). Die bindet ihr ein, testet und wenn es geht, geht meistens in Hardware. Gruß, Kest p.s.: macht euch mal klar, wann die Daten übernommen werden und wann der Bus Tristate ist, lest die Datenblätter, da steht ALLES :-)
@kest Danke für den Hinweis, ich werde mir das anschauen. @falk Mit 10 MHz funktioniert die neue Version leider nicht. Grüße Dirk
@Kest >habt ihr schon mal was von Simulieren und Testbenches gehört? Schaut mal Auch schau einer an? Testbenches sind was für Weicheier ;-) >bindet ihr ein, testet und wenn es geht, geht meistens in Hardware. Ja eben, meistens. >p.s.: macht euch mal klar, wann die Daten übernommen werden und wann der >Bus Tristate ist, lest die Datenblätter, da steht ALLES :-) Jawohl Herr Oberlehrer. MfG Falk
@Dirk Verwende mal für dein Testmodul die RS232, sprich gib mal ein paar HEX-Dumps der geschriebenen und gelesenen Werte aus. Dann siehst du sicher mehr. MfG Falk
Hi ich hab das externe SRAM aufm S3 Board nur mit einigen Umständen korrekt betreiben können. Mein Takt war 50MHz. Lesen ging einfach. Adresse ausgeben. Im nächsten Takt Daten übernehmen. Schreiben ging schwer. Als Problem stellte sich wohl heraus, dass WE wohl teilweise minimal kurz vor der geänderten Adresse bzw. den Daten auf 1 gesetzt wurde. Dadurch gabs jede Menge Datenmüll. Meine Lösung war dann Schreiben in 2 Taktzyklen, in beiden Flanken: 1. Takt, 1. Flanke: Adressen und Datenleitungen ändern 1. Takt, 2. Flanke: WE = 1 2. Takt, 2. Flanke: WE = 0 3. Takt, 1. Flanke: nächste Lese- oder Speicheroperation Lesen war entsprechend dieser Notation: 1. Takt, 1. Flanke: Adressen und Datenleitungen ändern 2. Takt, 1. Flanke: Daten von Datenleitung nehmen, und nächste Operation starten
@Matthias >Schreiben ging schwer. Als Problem stellte sich wohl heraus, dass WE >wohl teilweise minimal kurz vor der geänderten Adresse bzw. den Daten >auf 1 gesetzt wurde. Dadurch gabs jede Menge Datenmüll. Meine Lösung war DAS ist der Knackpunkt. Lösung ist in Arbeit, dauert aber noch bissel. MFG Falk
So, hier nun die wasserdichte Version. Ich hoffe sie läuft in der Praxis, die Simulation sieht sauber aus. Diese Version braucht einen pahsenstarren, doppelt so schnellen Takt. Aber der ist ja am Scan-Doubler schonvorhanden. Denk dran, die Steigenden Flanken des x2 Taktes müssen mit den Flanken des x1 Taktes übereinstimmen. Und zwar SEHR genau. Also sicherstellen, dass aus dem Taktteiler, der aus 40 MHz 20 und 10 MHz macht, jeweils 1 BUFG dranhängt. MfG Falk
Die neue Version habe ich gerade getestet und leider funktioniert sie auch nicht. Um sicher zu gehen das die Anforderungen an den Takt genau erfüllt werden habe ich den Xilinx Taktgenerator wieder eingebaut. Nichtmal die Monitor Synchronisation wird gestartet. Mit dem einfachen Frequenzteiler kommt wieder ein anderes Bildschirmmuster. Ich habe jetzt eine LCD Anzeige an das Board gebaut, mal sehen ob ich damit weiter komme.Die Uartübertragung laß ich erstmal, denn dann habe ich zwei Baustellen. Ich habe auch noch eine ältere Version des Invader Designs gefunden, die ist für Spartan 2 und ext Sram.Funktioniert aber auch nicht. Grüße Dirk
Naja, jetzt bis du dran. Die zweite Version sollte eigentlich wasserdicht sein. Aber dazu musst du erstmal den einfachen Testgenerator zum laufen bringen. Viel Erfolg. MFG Falk
Darum werde ich mich als nächstes kümmern. Ich danke Dir dafür das Du Dich so engagiert hast und werde Dir hier hoffentlich bald eine Erfolgsmeldung geben können. Viele Grüße Dirk
@falk Der Invaders Core mit externem SRAM läuft jetzt.Aber nur nach der Ansteuerung wie sie in einer früheren Version des Cores gemacht wurde. Dein SRAM Interface funktioniert jetzt auch, nur eben nicht im Space Invaders.Um das zu überprüfen habe ich einen Uart in das Testdesign gebastelt und die gelesenen mit den geschriebenen Daten verglichen. Das Problem lag am Speicherbaustein.Der hat einen 16 Bit Datenbus von dem ich nur die unteren 8 Bits benötige. Deshalb habe ich mit den Registern BLE,BHE für low und highbyte die oberen Byters abgeschaltet, nur leider scheint das den Speicherbaustein gar nicht zu interessieren.Wenn nicht der gesamte Datenbus aktiv ist gibts nur Müll auf der Leitung. Grüße Dirk
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.