Hallo liebe Community,
ich bin zur Zeit Praktikant in einem Unternehmen und lerne das
"Arbeiten" :) Bin in der Entwicklungsabteilung und krieg seid paar
Wochen ein Problem von meinem Kollegen mit, dass sich wohl nicht lösen
lässt.
Es handelt sich um einen Flash FPGA der Firma Actel. Die
Datenverarbeitung läuft wohl seriell, wozu man ein Schieberegister
braucht. Die Vorgabe ist ein 192 Bit Schieberegister zu bauen.
Ein 8 Bit Schieberegister arbeitet wohl einwandfrei, aber erweitert er
es auf 32 oder 192 Bit, so gibt es extreme Bitfehler. In der Simulation
klappt aber alles.
Ich selbst hab leider noch nich mit VHDL oder FPGA gearbeitet, aber ich
würd dem Kollegen helfen und eventl. Lösungsmöglichkeiten vorschlagen,
die natürlich nur durch eure Hilfe möglich wären:)
Der Kollege vermutet, dass es zu internen Laufzeitproblemen kommt. Daher
hat er die Taktfrequenz von 20 bis 2 Mhz durchgespielt. Aber überall das
gleiche.
Mich würd es freuen, wenn ihr eventl. schon solche Erfahrung gehabt habt
und mir / ihm dabei weiterhelfen könntet.
Danke schön:)
> Ein 8 Bit Schieberegister arbeitet wohl einwandfrei, aber erweitert er> es auf 32 oder 192 Bit, so gibt es extreme Bitfehler. In der Simulation> klappt aber alles.
Wenn die Simulation ok ist, liegen solche Fehler meistens am Übergang
zwischen Taktdomänen oder an irgendwelchen asynchronen kombinatorischen
Resets.
Wie ist das Schieberegister getaktet?
Hat das Schieberegister einen asynchronen Set/Reset?
Wie werden die Daten einsynchronisiert?
Kannst du Code zu dem Problem posten?
> Taktfrequenz von 20 bis 2 Mhz durchgespielt.
Das packt jedes Schieberegister in jedem FPGA.
So langsame FPGAs gibts gar nicht (mehr).
Die entity
>> RisingEdgeFlag
wird übrigens gar nicht verwendet, sondern eine Komponente namens
>> SyncRisingEdge
Aber ich vermute, da gehts so ähnlich zu... :-/
Den Code habe ich mehrmals abgeändert, deshalb überdefinierter Prozess.
In der Endversion wird er sauber!
Danke, ich dabe da das flasche Modul hochgeladen, aber es ist ähnlich,
sogar der Name ...
hier das Richtige:
Und jetzt sieht man es klar: Kombinatorik im asynchronen Reset.
Das ist "No Good Design Practice" :-/
Sehr zu Denken gibt mir diese Zeile:
1
:
2
elsif(lSignal='1'andlSignal'event)then
3
:
Da drängt sich noch wesentlich mehr die Frage auf:
Ist lSignal ein Eingangssignal (FPGA-Pin)?
Falls ja: lEdgeArrived ist nach wie vor asynchron zum lClock
Da hilft die ganze Zwischenpufferei nichts, das ist nur Sand in die
Augen gestreut.
Das sehe ich nicht so.
lSignal ist ein Eingangssignal des FPGA's.
lEdgeArrived ist auch noch asynchron zu lClock. Sinn ist, auch schnelle
Pulse, die bei nächster Flanke bereits abgefallen sein könnten, nicht zu
verlieren. Aber das Ausgangssignal des Moduls lPreSyncEdge ist synchron
zum Takt und nach einer Flanke für eine Periode des Taktsignals high.
Dieses synchronisierte Signal wird dann weiterverwendet. Ist fuer die
jetzige Anwendung etwas uebertrieben, sollte aber doch problemlos
arbeiten, oder?
> Aber das Ausgangssignal des Moduls lPreSyncEdge ist synchron> zum Takt und nach einer Flanke für eine Periode des Taktsignals high.
Falsch. Ich zitiere mich selber:
Um auf der sicheren Seite zu sein brauchst du 2 FF Stufen.
Das hier ist nur eine davon:
1
elsif(lClock='1'andlClock'event)then
2
-- Synchronisieren zu Takt
3
if(lEdgeArrived='1')then
4
-- Flanke erreicht ...
5
lPreSyncEdge<='1';-- <<< erste FF-Stufe nach einem asynchronen Signal
6
:
Das hier wird durch den Kommentar auch nicht besser:
1
-- Ausgangssynchronisation
2
lSyncEdge<=lPreSyncEdge;
Da wird nämlich gar nicht synchronisiert, sondern das Signal ganz
einfach geradeaus rausgegeben. Wenn wenigstens noch ein Takt drumrum
wäre:
1
if(lClock='1'andlClock'event)then
2
-- Ausgangssynchronisation
3
lSyncEdge<=lPreSyncEdge;
4
endif;
Das ist jetzt die zweite FF Stufe. Ab hier bist du garantiert synchron.
> Das sehe ich nicht so.
Ich habe diesen Fehler auch schon gemacht, glaubs mir ;-)
Ich glaube ich brauche jetzt Nachhilfe. Wieso sind denn für eine
Dateneingangssynchronisation bei FPGA zwei FF notwendig???? Da verliere
ich ja einen Taktzyklus! Das ist nicht immer toll.
Ragdar wrote:
> Ich glaube ich brauche jetzt Nachhilfe. Wieso sind denn für eine> Dateneingangssynchronisation bei FPGA zwei FF notwendig???? Da verliere> ich ja einen Taktzyklus! Das ist nicht immer toll.
Verlieren wirst du nix, bekommst nur einen Takt mehr Latenz rein.
Wichtig ist das, weil sonst evtl. die Setup-Zeit des FFs verletzt wird,
das FF nicht gesetzt werden kann, und bei der nächsten Flanke ist das
Eingangssignal schon wieder weg, weil da gerade so die Setup-Zeit
eingehalten wurde. Also hast du einen ganzen Puls verloren. Ich hab das
auch schon oft vergessen, die Effekte sind lustig und äußerst schwer zu
finden, weil´s eben fast immer klappt.
Wie schnell ist denn dein lClockSys und dein lSpiClockSync.
Ich glaube, du (bzw. dein Kollege ;-) könntest gut ohne diese
vertrickste Flankenmerkerei auskommen. So ein asynchrones Merker-FF
brauchst du nämlich erst, wenn der Eingangsimpuls kürzer ist (bzw. sein
kann) als der FPGA-Takt. Im Normalfall reicht Einsynchronisieren über
ein 2-Bit Schieberegister locker aus (3-Bit SR, falls eine
Flankenerkennung nötig wäre).
Ja, das ist richtig. Die Clock lSpiClockSync ist ca. 1MHz und die
lClockSys ist >= 10MHz. Für diese Anwendung brauche ich die schnelle
Flankenerkennung nicht. Ich habe einfach das fertige Modul aus meiner
Bibliothek genommen mit der festen Überzeugung es sei ok. Aber das werde
ich noch umschreiben. Für mich war wichtig, wo ich ansetzen muß. Die
Problematik mit dem Einsynchronisieren war mir bisher noch nicht ganz
klar.
Danke fuer die Unterstutzung !
> Die Problematik mit dem Einsynchronisieren war mir bisher> noch nicht ganz klar.
Das Thema wurde hier im Forum schon ein paar mal diskutiert.
Stichworte: Eintakten, Metastabilität, einsynchronisieren,
Synchronisierungs-Flipflops...
Hier ist mein Bookmark zum Thema:
http://www.lothar-miller.de/s9y/categories/5-Entprellung
Also ich hatte mal die Fehlermeldung: "Clockscew larger than datadelay".
Das heißt die Daten überholen den Takt, da er nicht an allen FF
zeitgleich ankommt und auch nicht beim letzten FF zuerst, sondern beim
ersten zuerst (wo auch die Daten reingehen). Das bringt folgendes
Problem: Bit liegt am ersten FF, erstes FF kriegt Takt, übernimmt Bit
und gibt es aus, jetzt wandert der Taktimpuls zum nächsten FF, das
übernimmt nun nicht den alten Zustand des ersten, wie es sollte, sondern
den neuen - und schwups rutscht das Bit von Anfang bis Ende mit einem
Mal durch. Abhilfe lässt sich ganz einfach schaffen: Man nimmt doppelt
so viele FF und taktet jedes zweite mit dem inversen Takt.