Hallo zusammen,
hatte schon einmal jemand Speicherfehler im BlockRAM eines Spartan?
Ich instanziiere in meinem Spartan 6 über CoreGen einen Speicher, der in
der Sekunde ungefähr 2*10^6 Mal ausgelesen wird. Ich stelle nun fest,
dass von Zeit zu Zeit, spätestens jedoch nach 15 min., ein
Speicherfehler auftritt. Erst wollte ich das gar nicht glauben, aber
dann habe ich ein Paritätsbit eingefügt und gesehen, dass tatsächlich
die Parität in diesen Fällen nicht stimmt. Es kippt übrigens immer ein
beliebiges Bit um.
Ist es üblich, dass diese Fehler auftreten? 15 min. sind immerhin fast 2
Millarden Zugriffe. Oder stimmt mein Design einfach nicht?
Grüße
Steffen
Hallo Steffen,
und das Timinig deines Designs ist okay ?
Mache mal einen detailierten timing check.
und auch die spannungsversorgung ?
Bei Blockram vielleicht ein Problem durch Dual-Ported zugriff ?
Deine HDL Quellcode und das ucf file waeren bei der Nachstellung des
Problems hilfreich.
da der sram im blockram nicht viel anders ist der sram fuer die
konfiguration
(Verbindungen und Logik). Wenn es da ein Problem im sram gibt, wuerde es
sich auf den gesamten FPGA auswirken.
LG
ein bastler
Steffen Hausinger schrieb:> Ist es üblich, dass diese Fehler auftreten?
Nein. Und 2 MHz ist ja nun fast schon beschaulich...
> Oder stimmt mein Design einfach nicht?
Der Verdacht liegt nahe...
Wieviele Takte hat dein Design?
Hallo Bastler!
bastler schrieb:> und das Timinig deines Designs ist okay ?> Mache mal einen detailierten timing check.
Wie mach ich den? Ich habe es eben mit "Analyze Timing / Floorplan
Design" in ISE versucht. Bin ich da richtig und wenn ja, was kann ich
dort tun? Mein Design steuert den Speicher aber eh nur mit 50 MHz an,
laut Datenblatt sind bis zu 200 MHz möglich.
bastler schrieb:> und auch die spannungsversorgung ?
Siehe Anhang. Ich musste leider direkt auf der 1,2V und 3,3V Verteilung
messen, das heißt vor allen Abblockkondensatoren (100µF, 4,7µF und
470nF)
bastler schrieb:> Bei Blockram vielleicht ein Problem durch Dual-Ported zugriff ?
Möglich, aber ich greife über den einen Port ausschließlich lesend zu.
Chipscope zeigt mir zudem, dass das WE-Signal nie aktiviert wird.
bastler schrieb:> Deine HDL Quellcode und das ucf file waeren bei der Nachstellung des> Problems hilfreich.
Gerne, ebenfalls siehe Anhang. In der Datei befindet sich die Entity, in
der ich den Speicher anspreche. Der relevante heißt "WrkPage_RAM". Ich
hoffe, die Kommentare erklären Aufbau und Zugriff.
Hallo Lothar!
Lothar Miller schrieb:> Der Verdacht liegt nahe...> Wieviele Takte hat dein Design?
Wenn Du hier die Taktfrequenz meinst, wovon ich jetzt einmal ausgehe:
sie beträgt 50 MHz.
Viele Grüße
Steffen
Mir ist eben noch was aufgefallen: ich hatte hier neulich nach der
Möglichkeit gefragt, auf rising_edge und falling_edge zu synchronisieren
(siehe Beitrag "Synchronisieren auf rising- und falling-edge"). Nachdem das nicht
so recht funktionierte, habe ich per DCM den Takt verdoppelt.
Die Folge: Das Signal XBus_Source_IM kommt nun mit der doppelten
Frequenz (100 MHz) an als der Rest des Speichers (50 MHz). Das wird wohl
der Fehler sein?
Hallo Steffen
Steffen Hausinger schrieb:> Wie mach ich den? Ich habe es eben mit "Analyze Timing / Floorplan> Design" in ISE versucht. Bin ich da richtig und wenn ja, was kann ich> dort tun? Mein Design steuert den Speicher aber eh nur mit 50 MHz an,> laut Datenblatt sind bis zu 200 MHz möglich.
hm ich bewege mich beim ise eigentlich nur per makefile mit den
commandline tools, die grafische oberflaeche ist halt nichts fuer einen
vernuenftigen automatisierten und reproduzierbaren flow
trace -a -e -tsi -u -v "design".ncd "timing_constraints".pcf
im design directory sollte schon mal helfen
LG
ein bastler
Steffen Hausinger schrieb:> Die Folge: Das Signal XBus_Source_IM kommt nun mit der doppelten> Frequenz (100 MHz) an als der Rest des Speichers (50 MHz). Das wird wohl> der Fehler sein?
Nein, eben ausprobiert: Der Speicherfehler tritt weiterhin auf :-(
bastler schrieb:> trace -a -e -tsi -u -v "design".ncd "timing_constraints".pcf>> im design directory sollte schon mal helfen
Werde ich ausprobieren!
bastler schrieb:> trace -a -e -tsi -u -v "design".ncd "timing_constraints".pcf
Ich komme mit der Command Line leider nicht zurecht. Folgendes konnte
ich aber über das Menü ausführen:
bastler schrieb:> Mein Design steuert den Speicher aber eh nur mit 50 MHz an,> laut Datenblatt sind bis zu 200 MHz möglich.
Die Frage ist eher, wieviel vorher deine Adresse stabil ist...
Steffen Hausinger schrieb:> habe ich per DCM den Takt verdoppelt> Das wird wohl der Fehler sein?
Hast du ein (mindestens das eine) Timing-Constraint auf den
ursprünglichen 50MHz Takt gesetzt?
Sieh dir in der statischen Timinganalyse mal den kritischen Pfad an...
BTW: sieh dir im Schematic mal an, was daraus gemacht wird
1
ifXBus_Source_IM=WPthen...
2
elsifXBus_Source_IM=MPthen...
3
elsifXBus_Source_IM=ProcRAM_RDthen....
4
elsifXBus_Source_IM=ExtRAM_RDthen...
5
elsifXBus_Source_IM=ProcRAM_WRthen...
6
elsifXBus_Source_IM=ExtRAM_WRthen....
7
endif;
Nicht, dass der Synthesizer hier tatsächliche eine "Logikkette" macht...
War da nicht mal was, dass selbst das reine Auslesen zerstörend sein
kann, wenn die Adressen nicht ausreichend Setup/Hold einhalten?
Aja, S6 Block RAM Resources User Guide, S11:
"The setup time of the block RAM address and write enable pins must not
be violated.Violating the address setup time (even if write enable is
Low) will corrupt the data contents of the block RAM."
Bezüglich der möglichen Setup-Verletzung der Adresse: sie wird vorher
einsynchronisiert. Auch die übrigen Signale des Speicherinterfaces sind
synchronisiert. Ich gehe davon aus, da die Signale nun intern sind, hat
ISE sich ums Timing gekümmert. (Unabhängig von diesem Fall bin ich
ohnehin davon ausgegangen, dass das anders nicht sauber funktionieren
würde!)
Lothar Miller schrieb:> Sieh dir in der statischen Timinganalyse mal den kritischen Pfad an...
Ok! Das wird ein wenig dauern, da ich mit dem Tool noch nie gearbeitet
habe. Ich nehme an, er zeigt mir den kritischen Pfad von selbst an?
s6 schrieb:> schau dir mal das Errata zum Spartan6 an.
Ich habe nachgeschaut: EN117, EN147 und EN148 treffen nicht zu. Ich habe
zwar tatsächlich den READ_FIRST Modus eingestellt, verwende aber einen
gemeinsamen Takt für Port A und B.
Steffen Hausinger schrieb:> Ich gehe davon aus, da die Signale nun intern sind, hat> ISE sich ums Timing gekümmert.
???
Freiwillig tut die ISE gar nichts. wenn du willst, dass sich da
irgendwer um irgendwas kümmert, dann mußt du Constraints angeben. Sonst
hat die Toolchain alle Freiheiten... :-o
Das war es, warum Lothar Miller schrieb:>>> Hast du ein ... Timing-Constraint auf den ... 50MHz Takt gesetzt?
Lothar Miller schrieb:> Freiwillig tut die ISE gar nichts. wenn du willst, dass sich da> irgendwer um irgendwas kümmert, dann mußt du Constraints angeben. Sonst> hat die Toolchain alle Freiheiten... :-o
Naja. Also Timing constraints (ausser Clock Frequenz, das ist klar) auf
rein interne Signale habe ich auch noch nie erstellt. Ich weiß auch gar
nicht, ob man Set/Hold Zeiten überhaupt für solche Signale einstellen
kann. IMHO ist das nämlich etwas, was man dem ISE überlassen können
sollte. Ansonsten müsste man ja für jedes Register solche Constraints
angeben, wenn ISE die nicht selber kennen würde. Für Signale von/nach
außen gibt man sie ja deshalb an, weil das Tool eben keine Informationen
zu den zeitlichen Begebenheiten außerhalb des Chips hat, der Entwickler
aber schon.
Torsten M. schrieb:> ausser Clock Frequenz, das ist klar
Diesen Period Constraint hatte ich gemeint. Beim Verdoppeln dieser
Frequenz mit dem Taktmanager wird automatisch ein Constraint auf die
"neue" Frequenz erzeugt.
Du wirst dein Design mal bis auf den Fehler abspecken müssen... :-/
BTW:
Entweder die (genormte) obere Lib oder
die (etablierten alten herstellerabhängigen) unteren beiden Libs:
Steffen Hausinger schrieb:> dann habe ich ein Paritätsbit eingefügt und gesehen, dass tatsächlich> die Parität in diesen Fällen nicht stimmt. Es kippt übrigens immer ein> beliebiges Bit um.
Kippt das Bit auch wieder zurück, oder ist der Speicherinhalt dann
komplett falsch?
> Ist es üblich, dass diese Fehler auftreten?
Nein.
> 15 min. sind immerhin fast 2> Millarden Zugriffe. Oder stimmt mein Design einfach nicht?
Wenn das Design flasch wäre, dürfte es eigentlich keine 100 ms laufen.
Ich würde mich auch nochmal auf die Stromversorgung und die Taktquelle
konzentrieren. Vielleicht kannst Du mit gezielten externen Störungen
einer mögliche Fehlerursache auf die Spur kommen.
Duke
Ich habe mich dieses Wochenende in meinem Kämmerlein eingeschlossen und
diverse Umbauten ausprobiert. Vorweg, keine hat endgültige Abhilfe
gebracht :-( Dennoch ist vielleicht folgendes interessant:
Meine Schaltung hat einen Eingangstakt CLK_in von 48 MHz. Diesen habe
ich bisher auf einen DCM gegeben, der daraus eine Ausgangsfrequenz
CLK_50MHz von wieder 48 MHz erzeugt (ist historisch gewachsen). Lasse
ich diesen DCM nun weg und nehme die 48 MHz direkt aus dem Eingangstakt
CLK_in, dauert es bis zum ersten Speicherfehler statt 20 min. nun 60
min.
Ist das ein Indiz für ein Timing-Problem?
Lothar Miller schrieb:>>>> Hast du ein ... Timing-Constraint auf den ... 50MHz Takt gesetzt?
Ja, ist gesetzt.
Duke Scarring schrieb:> Kippt das Bit auch wieder zurück, oder ist der Speicherinhalt dann> komplett falsch?
Der Speicherinhalt bleibt fortan gleich. Das gekippte Bit ist also
tatsächlich gespeichert.
Lothar Miller schrieb:> Entweder die (genormte) obere Lib oder> die (etablierten alten herstellerabhängigen) unteren beiden Libs
Danke für den Hinweis!
Steffen Hausinger schrieb:> Ist das ein Indiz für ein Timing-Problem?
Ziemlich sicher.
Um Hardwarefehler weitestgehend auszuschließen, könntest du ja nen
kleinen March-Algorithmus schreiben und damit den Speicher befüllen und
wieder auslesen. Also wirklich nur eine minimal Beschaltung und gucken
ob du immer das ausliest was du rein geschrieben hast.
> Lasse ich diesen DCM nun weg und nehme die 48 MHz direkt aus dem> Eingangstakt CLK_in, dauert es bis zum ersten Speicherfehler statt> 20 min. nun 60 min.
Damit hast du wohl etwas weniger Jitter auf dem Takt. Wenn das einen
Unterschied macht, ist irgendwas mit der Taktverteilung oder der
Synchronisierung der RAM-Addressen Daten ziemlich daneben. Bist du
wirklich 1000%ig sicher, dass der Takt, der die Adressen generiert, auch
der für die Blockrams ist? Notfalls per FPGA-Editor nachschauen...
D. I. schrieb:> Um Hardwarefehler weitestgehend auszuschließen, könntest du ja nen> kleinen March-Algorithmus schreiben und damit den Speicher befüllen und> wieder auslesen.
Ich bin gerade dabei, es von der anderen Seite zu probieren: Schaltung
schlanker machen, bis der Fehler nicht mehr auftritt. Wegnehmen ist hier
einfacher als neu designen ;-)
Georg A. schrieb:>> Lasse ich diesen DCM nun weg und nehme die 48 MHz direkt aus dem>> Eingangstakt CLK_in, dauert es bis zum ersten Speicherfehler statt>> 20 min. nun 60 min.>> Damit hast du wohl etwas weniger Jitter auf dem Takt.
Also da habe ich bisher das genaue Gegenteil vermutet! Durch den DCM
habe ich doch gerade einen stabileren Takt? Weil er doch durch die DLL
entkoppelt wird.
Georg A. schrieb:> Bist du> wirklich 1000%ig sicher, dass der Takt, der die Adressen generiert, auch> der für die Blockrams ist?
Seit dem Rausschmiss des DCM habe ich ja nur noch den einen ;-) Und
trotzdem treten die Fehler weiter auf :-(
Steffen Hausinger schrieb:> D. I. schrieb:>> Um Hardwarefehler weitestgehend auszuschließen, könntest du ja nen>> kleinen March-Algorithmus schreiben und damit den Speicher befüllen und>> wieder auslesen.>> Ich bin gerade dabei, es von der anderen Seite zu probieren: Schaltung> schlanker machen, bis der Fehler nicht mehr auftritt. Wegnehmen ist hier> einfacher als neu designen ;-)
Das ist ne kleine Mini-FSM in diesem Fall, das sollte mit 100 Zeilen
maximal erledigt sein. Erst neulich habe ich ein Paper zu Speichertests
gelesen. Da stehen dann ein paar Algorithmen wie man bestimme Fehler
erkennen kann, mal gucken ob ichs wieder finde, das ist dann aber schon
fortgeschrittener.
D. I. schrieb:> Paper zu Speichertests> gelesen. Da stehen dann ein paar Algorithmen wie man bestimme Fehler> erkennen kann, mal gucken ob ichs wieder finde,
Das würde mich auch mal interessieren.
Duke
Steffen Hausinger schrieb:> Ist das ein Indiz für ein Timing-Problem?>>> Duke Scarring schrieb:>> Kippt das Bit auch wieder zurück, oder ist der Speicherinhalt dann>> komplett falsch?>> Der Speicherinhalt bleibt fortan gleich. Das gekippte Bit ist also> tatsächlich gespeichert.
dann ist die Wahrscheinlichkeit fuer ein Timing-Problem seeeehr hoch.
Ueberlege mal wie eine 6T SRAM-Zelle aussieht und denke dir die
Verschaltung mit Word- und Bitlines.
Wenn deine Wordline ein Timing-Problem hat (==READ Adresse), dann
zerschiesst es dir deinen Speicher, der ueberschreibt sich beim lesen
selber...
und uebrigens:
Poste doch mal die Zeile aus deinem .ucf File, wo du die Clock auf eine
bestimmte Frequenz vorgibst.
Und, da du ja wohl bisher noch nie mit static-timing-analysis gearbeitet
hast, auch mal den ersten Pfad dieser Clock der im timing-report
ausgegeben wird.
Mir scheint, dein Place+Route schert sich nicht um deine
Clockvorgaben/-wuensche.
Duke Scarring schrieb:> Danke. Das ist ja doch etwas umfangreich. Mal sehen ob ich die nächsten> Tage Zeit finde, mir das zu Gemüte zu führen.>> Duke
wenn's kuerzer sein soll, dann schau dir mal die ~30 Folien an:
http://www.ece.uc.edu/~wjone/Memory.pdf
Ist als Einstieg kurz und knackig...
Der Quarz-Oszillator (SG-310SCF) hat eine Frequenztoleranz von +-100
ppm. Macht bei f = 48 MHz bzw. T = 20.833 ns einen Jitter von max.
+-2,083 ps.
berndl schrieb:> Und, da du ja wohl bisher noch nie mit static-timing-analysis gearbeitet> hast, auch mal den ersten Pfad dieser Clock der im timing-report> ausgegeben wird.
Du meinst vermutlich das hier (der ganze Ausschnitt ist im Anhang):