Forum: FPGA, VHDL & Co. Ist Lesezugriff auf Cyclone II Memoryblock in einem Takt möglich


von MuePlus (Gast)


Lesenswert?

Hallo,

irgendwie komme ich nicht weiter. Der Cyclone II besitzt ja internen 
Speicher namens M4K. Diesen habe ich in ein Testprojekt von mir über den 
Wizard von Quartus als 1-Port-RAM eingebunden.

Wenn ich die Doku richtig verstanden habe, wird bei der steigenden 
Flanke des an den RAM angelegten Takts der Speicher an der zu diesem 
Zeitpunkt angelegten Adresse ausgelesen.

Dummerweise kann ich (zumindest in der Simulation) Adresse und Takt 
nicht gleichzeitig setzen. Den dann kommt der Speicherinhalt der zuvor 
angelegten Adresse.

Erst wenn ich die Adresse einen Takt vorher ausgebe, bekomme ich das 
gewünschte Datum. Dazu brauche ich aber zwei Takte für einen 
Lesezugriff.

Hat jemand eine Idee - oder habe ich vielleicht etwas übersehen?

Schon mal vielen Dank
MuePlus

von Datenblattversteher (Gast)


Lesenswert?

MuePlus schrieb:
> irgendwie komme ich nicht weiter. Der Cyclone II besitzt ja internen
> Speicher namens M4K. Diesen habe ich in ein Testprojekt von mir über den
> Wizard von Quartus als 1-Port-RAM eingebunden.
>
> Wenn ich die Doku richtig verstanden habe, wird bei der steigenden
> Flanke des an den RAM angelegten Takts der Speicher an der zu diesem
> Zeitpunkt angelegten Adresse ausgelesen.

Lt http://www.altera.com/literature/hb/cyc2/cyc2_cii51008.pdf S.9 
unterstützt M4k keinen asynchronen Memory (unregistered Input), die 
adresse wird also immer eingetaktet.

MfG,

von MuePlus (Gast)


Lesenswert?

@Datenblattversteher

Kannst du mal bitte auf die folgenden Zeilen schauen. Dann muss der 
Fehler in meiner Implementierung bzw. der Simulation stecken.

In meiner Verhaltensbeschreibung des RAMs habe ich für das Lesen 
folgendes zu stehen:

-- Lesen vom RAM
data <= q WHEN (wr = '0' AND rd = '1' AND cs = '1')
          ELSE (others => 'Z');

Wie beschrieben brauche ich bei meiner Simulation das zweite WAIT, um an 
das richtige Datum zu kommen:

WAIT UNTIL rising_edge(clk_stim);
address <= x"003";

WAIT UNTIL rising_edge(clk_stim);
cs <= '1';
rden <= '1';

Ist da ein Denkfehler?

Grüße
MuePlus

von Uwe (Gast)


Lesenswert?

> Wenn ich die Doku richtig verstanden habe, wird bei der steigenden
> Flanke des an den RAM angelegten Takts der Speicher an der zu diesem
> Zeitpunkt angelegten Adresse ausgelesen.
Dann lege doch die Adresse an der Fallenden Flanke davor an.

von MuePlus (Gast)


Lesenswert?

Das geht leider nicht. Ich brauche pro Takt einen Zugriff. Auch kann ich 
nicht den Takt invertieren, da das Schreibsignal genau anders herum, 
also zur fallenden Flanke übernimmt. Dann hätte ich das Problem 
lediglich dorthin verschoben.

Gruß
MuePlus

von Sigi (Gast)


Lesenswert?

Du schreibst wenig über deinen Testbench und über das M4K-RAM:
Kannst du die Addresse z.B. 0.5-1.0 ns vor der Clock-Flanke anlegen
(um mögliche Hold-Time-Violations zu vermeiden)?
Wie sieht in deinem M4k-RAM der Parameter "outdata_reg_a" aus?
"UNREGISTERED","CLOCK0" bzw "CLOCK1"? "UNREGISTERED" liest
das RAM sofort aus, "CLOCK*" ein Takt später.

von MuePlus (Gast)


Angehängte Dateien:

Lesenswert?

Schon einmal vielen Dank für Eure Hilfe.

Bei "outdata_reg_a" steht "UNREGISTERED". Daher ging ich (vor meinem 
Test) davon aus, das ich im selben Takt auch das Datum bekomme.

Um mein Problem besser darzustellen, habe ich einmal ein Screenshot der 
Simulation angehängt. Dort ist gut zu erkennen, das das Setzen der 
Adresse bei steigender Flanke eigentlich schon zu spät ist. Das Datum 
wird immer erst im Folgetakt ausgegeben.

Ich habe ebenfalls das Projekt mit angehangen. Vielleich hat ja jemand 
eine Idee.

Viele Grüße
MuePlus

von Sigi (Gast)


Lesenswert?

Ich kenne zwar nicht alle deine Einstellungen, würde aber
mal sagen, dass das das ist was ich als Ausgabe erwartet
habe. Du setzt z.B. zur 2. steigenden Flanke addresse=03,
worauf dann in der 3. st. Flanke 03 im internen Addr.Reg
steht und "kurz" darauf 03030303 als Wert ausgegeben
wird. (Bem: zur 3. Flanke kannst du natürlich die nächste
Addresse anlegen etc..)
Du erwartest wohl, dass 03030303 in der 2. Taktperiode
(d.h. kurz nach der 2. st.Flanke) ausgegeben wird. Dafür
müsstest du aber das interne Addr-Register der M4K
ausschalten können (ist aber nicht möglich).

Mögliche Lösung: Falls dein Design nicht gerade gross
über 100MHz läuft, dann kannst du ja per PLL eine 2X-Clk
generieren und damit das M4K antreiben. Dein Wert wird
dann mitten in der Taktperiode geliefert.

von Datenblattversteher (Gast)


Lesenswert?

MuePlus schrieb:
> Bei "outdata_reg_a" steht "UNREGISTERED". Daher ging ich (vor meinem
> Test) davon aus, das ich im selben Takt auch das Datum bekomme.

Du hast die Register am Eingang übersehen. Im Datenblatt steht dazu:

"All M4K memory blocks are fully synchronous, meaning
that you must send all inputs through a register, but you can either 
send
outputs through a register (pipelined) or bypass the register
(flow-through)".

Leider kann man bei cyclone nicht statt aus M4K-Blöcken deinen 
RAM-Speicher aus den LUT's im Speichermode (ähnlich distributed ram bei 
spartan) bauen.

von Klaus F. (kfalser)


Lesenswert?

MuePlus schrieb:
> Um mein Problem besser darzustellen, habe ich einmal ein Screenshot der
> Simulation angehängt. Dort ist gut zu erkennen, das das Setzen der
> Adresse bei steigender Flanke eigentlich schon zu spät ist. Das Datum
> wird immer erst im Folgetakt ausgegeb

Entschuldige, aber das ist doch bei jedem Standard FF so.
Es wird immer der Zustand von VOR der Taktflanke übernommen. Wenn eine 
synchrone Schaltung die Ausgänge schaltet, dann liegen diese nach der 
Durchlaufzeit an den Eingängen wieder an und bestimmen das 
Schaltverhalten für die NÄCHSTE Flanke.

Zugriffszeit 1 Takt heißt trotzdem weiterhin, dass die Adressen vor der 
Taktflanke anliegen müssen.

von Lassmiranda Densiwillja (Gast)


Lesenswert?

Hallo MuePlus,

habe in meinem momentanen Projekt einen DCFIFO mit unterschiedlicher 
Eingangs und Ausgangsbreite und dort ist es so, dass ich die Daten zu 
Negativer Flanke anlege und auf Positive Flanke übernimmt sie der 
DCFIFO... Aber denke mal das es dann allgemein bei Altera so ist das die 
Daten auf steigende Flanke in den FIFO's/Buffer übernommen werden.

Allerdings hab ich das Problem im moment das ich kein richtiges rdused 
Signal (Füllstandssignal des DCFIFO) bekomme...

von J. S. (engineer) Benutzerseite


Lesenswert?

Was bitte versprichst Du Dir von der RAM-Lesefunktion, wenn Du den Bus 
auf "Z" setzt???

Es gibt im FPGA intern kein "hochohmig" - die Zeiten bidirektionaler 
Busse in solchen Logikbausteinen sind längst vorbei. Du hast immer einen 
Schreib- UND einen Leseanschluss.

Woher kommt diese Beschreibung?

---

Bei den Altera-RAMs kann man i.d.R. auch unregistriert zugreifen, 
allerdings geht das nur unterhalb einer meist unakzeptablen Frequenz. In 
der Regel wird man aber immer registriert einschreiben, weil Daten und 
Adressen ja irgendwo her kommen und das WE synchron gesetzt wird. Im 
nächsten Takt wird eingeschrieben und beim Lesen auf derselben Adresse 
auch transparent ausgegeben (wenn man das zulässt und nutzt).


Am Besten nutzt Du das vom Megawizzard generierte RAM-Modell. Da ist die 
parametrierte Taktverzögerung wie sie eingestellt ist, auch simulierbar.

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.