Forum: FPGA, VHDL & Co. Multiple Clock Domains


von Manuel (Gast)


Lesenswert?

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?

von Manuel (Gast)


Angehängte Dateien:

Lesenswert?

HIer die Simulation

von Manuel (Gast)


Angehängte Dateien:

Lesenswert?

Und das Design

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wie sieht die Testbench aus?
Wird dort auf ram_a_data eine x"00" geschrieben?

von Manuel (Gast)


Lesenswert?

Erst steht da 8'h0X und dann irgendwann 8'hXX.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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.

von Manuel (Gast)


Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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.

von Manuel (Gast)


Lesenswert?

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.

von bko (Gast)


Lesenswert?

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

von bko (Gast)


Lesenswert?

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.

von Manuel (Gast)


Angehängte Dateien:

Lesenswert?

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;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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?

von Manuel (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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.

von Manuel (Gast)


Lesenswert?

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...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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"  ;-)

von Manuel (Gast)


Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von bko (Gast)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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.

von Manuel (Gast)


Lesenswert?

Danke für eure Hilfe. Werd wohl mit 2 SRAMS arbeiten.

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.