Ich erstelle ein Design mit Verilog auf einem Xilinx Spartan-3E (XC3S500E), das mehrere Dual-Port-Block-RAMs verwendet, die alle durch Verilog-Primitive wie RAMB16_S18_S18
. Ich verwende einen Port sowohl zum Lesen als auch zum Schreiben (mit Write-Enable) und den zweiten nur zum Lesen (durch Setzen WEB
auf 0). Beide Ports teilen sich die gleiche Uhr. Der Block-RAM ist auf 18 Bit Breite eingestellt, aber ich ignoriere die Paritätsdaten (d. h. ich verwende nicht ihren Ausgabewert und schreibe immer Nullen in Paritätsbits).
Ich verwende Xilinx ISE 13.4 und synthetisiere/implementiere mithilfe des GUI-Workflows mit Standardeinstellungen. (Nicht-Standardeinstellungen wie aggressive Timing-Optimierung und/oder physikalische Synthese hatten keinen Unterschied in Bezug auf dieses Problem)
Ich habe Timing-Einschränkungen für mein einziges Taktnetz vorgenommen, und es stimmt mit dem tatsächlich eingegebenen Taktsignal überein (die Einschränkung gilt für 50 MHz, es gibt einen 50-MHz-Takt auf der von mir verwendeten Entwicklungsplatine, und der Timing-Bericht gibt an dass die maximale Frequenz für mein Design 64,7 MHz beträgt.Die Uhr läuft durch einen Taktmultiplexer, der als Taktfreigabe verwendet wird, bevor sie zur Gesamtheit meiner Logik geht.
In meinem Code habe ich eine Zustandsmaschine mit drei Zuständen (Übergang bei steigender Flanke desselben 50-MHz-Takts, den der Block-RAM verwendet):
reg[15:0]
der mit DIA (Daten in A) im Block-RAM verbunden ist (wobei sich die Adresse nicht ändert). Schalten Sie die Schreibfreigabe für Port A ein.Dies gelingt durchweg in einer Verhaltenssimulation in ISim und (obwohl es weniger Tests als der Simulator hatte) durchweg erfolgreich an Port A. Port B hat identische Logik (einfach Bit-Slicing für Adresse und dieselbe Konfiguration für SSR, SRVAL, INIT ), aber es gelingt ihm nicht, während dieses einen Taktzyklus zu lesen. Durch einfaches Hinzufügen eines zusätzlichen Zustands zwischen 1 und 2 (wodurch sich eine Einrichtungszeit von über einem ganzen Taktzyklus für die Adresse ergibt) funktioniert das Design, obwohl ich als Anfänger der FPGA-Entwicklung gerne wissen würde, warum und wie man dies verhindern kann.
Gemäß dem Xilinx-Datenblatt DS312 und den darin enthaltenen Timing-Diagrammen sollte dies eine akzeptable Art der Verwendung des Block-RAM sein. In demselben Datenblatt sind Setup- und Hold-Zeiten angegeben, aber die ISE-Tools sollten sich dieser bereits bewusst sein und sie während der Timing-Analyse anwenden, wenn ich mich nicht irre. Außerdem habe ich den Block-RAM-Abschnitt von UG331 (Spartan-3 Generation User Guide) einige Male erneut gelesen und konnte keine Inkonsistenzen zwischen den Anweisungen und meiner Verwendung des Block-RAM finden.
Die Timing-Berichtsliste der langsamsten Pfade listet auf mysteriöse Weise keine Pfade auf, die zum fehlerhaften RAM-Port führen.
Wenn jemand eine Empfehlung abgeben könnte, wäre ich dankbar, da ich eine ganze Weile damit verbracht habe, dies zu debuggen, und befürchte, dass ich einen Anfängerfehler machen könnte. Wenn zusätzliche Informationen benötigt werden, lassen Sie es mich bitte wissen, damit ich sie bereitstellen kann.
Neu geschriebene Daten an der steigenden Flanke sind direkt nach dieser Flanke nur am selben Port verfügbar. Tatsächlich wird der Dateneingang intern an den Datenausgang desselben RAM-Ports weitergeleitet. WRITE_FIRST
Auch Modus genannt .
Es wird jedoch nie an den Ausgang des anderen RAM-Ports weitergeleitet, unabhängig von der angegebenen WRITE_MODE
. Es steht zum Lesen zur Verfügung (natürlich bei einer weiteren steigenden Flanke), nachdem das interne Schreiben in den Speicher abgeschlossen ist. In Ihrem Beispiel ist es nur die nächste steigende Taktflanke, da die interne Schreibzeit immer kleiner (schneller) als die minimal zulässige Taktperiode ist.
Dieses Verhalten wird in XAPP 463 Using Block RAM in Spartan-3 Generation FPGAs im Abschnitt Dual-Port RAM Conflicts and Resolution beschrieben . Das dort gegebene Beispiel verwendet unterschiedliche Takte, gilt aber auch, wenn für beide Ports derselbe Takt verwendet wird.
Dieses Verhalten ist bei aktuellen FPGAs von Xilinx und Altera immer noch gleich.
Die Weiterleitung auf den anderen RAM-Port muss von Ihrer eigenen mit umgebender Logik erfolgen.
Paebbels
Nanofarad
Nanofarad
user_1818839
Nanofarad
user_1818839
user_1818839
Nanofarad
Nanofarad
user_1818839
Nanofarad
Nanofarad