Hallo, habe hier ein kleine Problem mit meinem Design. Wie man in der Simulation sieht geht ram_a_data auf 'X'. Kann mir jemand sagen was ich hier in meinem Design falsch gemacht habe?
Wie sieht die Testbench aus? Wird dort auf ram_a_data eine x"00" geschrieben?
Nein, erst steht da 8'h00, dann
> Erst steht da 8'h0X und dann irgendwann 8'hXX.
Wie gesagt, meine Vermutung:
irgendwer schreibt einen Vektor voller Nullen auf ram_a_data.
Such mal nach Zeilen wie:
ram_a_data <= "00000000"
ram_a_data <= x"00"
ram_a_data <= (others=>'0')
Und weil ram_a_data ein bidirektionaler Vektor ist, kann das auch in der
Testbench passieren.
Hmm, hab die Testbench jetzt nochmal neu gemacht und plötzlich funktionierts - zumindest in der Simulation. Irgendwie ist das frustrierend... Eigentlich sollte in den SRAM 0,1,2,3,4,5... geschrieben werden. Wenn ich den SRAM aber auslese bekomme ich 0,0,2,3,4,4,7,8... Irgendjemand eine Idee?
> Eigentlich sollte in den SRAM 0,1,2,3,4,5... geschrieben werden. Wenn > ich den SRAM aber auslese bekomme ich 0,0,2,3,4,4,7,8... In der Simulation oder in der Realität? EDIT: Liegt das Problem am Schreiben oder am Lesen?
1 | ram_we <= not sram_write ; |
2 | ram_oe <= not (not sram_write ); |
Darfst du dein RAM so schnell zwischen Lesen und Schreiben und zurück umschalten? Sieh dir mal das Datenblatt an. EDIT2:
1 | ram_we <= not sram_write ; |
2 | ram_oe <= sram_write; |
Die doppelte Negation schmeißen die Tools sowieso weg ;-)
Überdenke deine Namensgebung nochmal:
> ram_we <= not sram_write ;
heißt doch: RAM Write-Enable gleich nicht SRAM write ??
Also besser statt ram_we das Signal ram_wen nennen. Dann sieht man,
dass das Steuersignal low-aktiv ist.
Ja, guter Punkt, zu meiner Verteidigung muß ich aber sagen das ich das UCF file von Digilent zum StarterKit einfach kopiert habe :-) Ansonsten will ich eigentlich den SRAM mit Daten vom ADC vollschreiben und danach erst wieder mit dem PC auslesen. Also keine abwechselnden schreib/lese zyklen. Naja, vielleicht fange ich einfach nochmal von vorne an. Irgendwie fällt mir da die Fehlersuche sehr schwer.
Ich meine, dass der we(_n) Eingang an einem (Asyncronen) SRAM während die Adresseingänge umschalten nicht "low" sein darf. http://www.hs-augsburg.de/~hhoegl/rt/skript/rt/node38.html
hoppla, ich war nicht ganz genau, nun hab ich mein NEC SRAM Datenblatt nochmal durchgelesen und fand dieses im Abschnitt über "Write Cycle Timing Chart 1 (/WE Controlled)" (...) "Cautions: /CS or /WE should be fixed to high level during address transition." das dürfte auch für (Asynchrone) SRAMs andere Hersteller gelten.
So, habe das Problem jetzt eingegrenzt und es hat nix mit den verschiedenen clock Signale zu tun. Verstehe aber nicht warum der erste Teil nicht funktioniert.... Hier die relevanten stellen: Funktioniert nicht: (Ergebnis ist 1,2,2,3,5,5,6,7,8...) -------------------- if ( state = SRWRITE ) then addr_adc <= addr_adc + 1; if (addr_adc < "111111111111111111" ) then sram_write <= '1'; ram_a_data <= addr_adc(7 downto 0); else state <= IDLE; addr_adc <= (others => '0'); end if; end if; Funktioniert: (Ergebnis ist 1,2,3,4,5,6,7,8,9,...) ------------------- if ( state = SRWRITE ) then counter <= counter + 1; if (counter < 262143) then sram_write <= '1'; ram_a_data <= conv_std_logic_vector(counter + 20, 8); addr_adc <= conv_std_logic_vector(counter, 18); else state <= IDLE; counter <= 0; end if; end if;
> Funktioniert: ...
Zufall. Ich kann in keinem der beiden Fälle einen korrekten
Schreibzyklus auf das RAM erkennen:
1. CS aktivieren
2. Daten und Adressen anlegen
3. Write aktivieren
4. Write deaktivieren
5. CS deaktivieren (optional)
Die Punkte 3 und 4 fehlen mir in deinem Code...
Die Daten werden i.A. mit der steigenden Flanke von Write ins RAM
übernommen. Alternativ kannst du auch Schreibzyklen über das CS steuern.
Aber diese Signale sind bei dir komplett statisch.
1 | ram_a_ce <= '0'; --nur ein chip aktiv; active low |
2 | ram_a_lb <= '0'; --enable lower byte; act.low |
3 | ram_a_ub <= '0'; --enable upper byte; act.low |
4 | |
5 | ram_we <= not sram_write ; |
Hast du die beiden letzten Posts (vor deinem) nicht gelesen?
Hmm, doch, langsam wird mir klar das das dann wohl doch nicht sooo einfach ist mit dem SRAM. Ich hab jetzt mal den "Write Cycle 4" des Datasheet angehängt. (Ich hoffe ich brauche die 1 - 3 nicht vorher?!). Das würde bei -10 Speedgrade bedeuten: CEn kann fest aus low bleiben OEn 1 -> 0, dann Adresse anlegen tWC Write Cycle Time 10 Adresse muß 10ns anliegen tSA Address Setup Time 0 WEn kann direkt auf low und auch low bleiben. <- was wenn ich hier 2ns warten soll? UBn WBn 8ns auf low <- wie mach ich das dem FPGA klar das er nur 8ns auf low bleiben soll?
> UBn WBn 8ns auf low <- wie mach ich das > dem FPGA klar das er nur 8ns auf low bleiben soll? Was ist dein FPGA-Takt? Du mußt das Schreiben auf (mindestens) zwei FPGA-Takte aufteilen. Im ersten Takt davon sind UBn bzw. LBn auf 0, danach auf 1. Du brauchst also eine etwas aufwendigere SM, als du bisher hast.
Der Takt ist 100MHZ. Und so schnell wollte ich auch den SRAM beschreiben (Die Daten sollen später von einem 100MHZ ADC kommen). Ich habe aber langsam das Gefühl das das nicht funktionieren wird...
> Ich habe aber langsam das Gefühl das das nicht funktionieren wird...
Ja, 100MHz und 8ns passen nicht so recht zusammen.
Du könntest mit einem DCM ein phasenverschobenes Signal erzeugen, das
dir die UBn und LBn FFs nach 8ns zurücksetzt. Aber damit kommst du in
den Bereich "wilder Hack" ;-)
Hört sich aber gut an :-) Das heißt also das man 10ns SRAM grundsätzlich nicht mit 100MHZ beschreiben kann? Oder könnte ich jetzt noch versuchen das Design irgendwie asynchron zu machen? Das sollte doch ein grundsätzliches Problem sein, oder?
Ein 10ns SRAM ist so definiert, dass du spätestens 10ns nachdem alle Signale (Adresse und Steuersingale) stabil anliegen die Daten übernehmen kannst, das betrifft also das Auslesen. Wenn du darauf Schreiben willst, mußt du das Timing laut Datenblatt einhalten...
Ein Vorschlag: wenn möglich, dann nimm zwei RAMs, dann hast du einen doppelt so breiten Datenbus und kannst die Daten mit 50 Mhz ins RAM schreiben, und dies dann auf die Art wie 5 Posts weiter oben vorgeschlagen.
> Ein Vorschlag: wenn möglich, dann nimm zwei RAMs...
Mit zwei RAMS könnte auch alternierend geschrieben werden:
ungerade Adressen auf RAM 1, gerade Adressen auf RAM 2.
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.