Ich hätte ein Problem mit der VHDL-Synthese bei Quartus: Ich bauen einen Datenlogger eines Microcontrollers in einem FPGA, der mit 20MHz läuft (LowPower System). Dessen 8Bit Werte müssen seriell ausgegeben werden. Die laufen jetzt mit 8/10-codierung, deshalb gibt es einen 200MHz-Takt, der das macht. Beide Datenströme sind kontinuierlich ohne Pause. Die Übergabe an den FPGA erfolgt durch den uc mit dem 20 MHz-Takt. Der FPGA macht noch andere Sachen, arbeitet aber mit 20MHz. Mit den 20MHz werden die 200MHz erzeugt, der somit alle 10 Takte mit der Flanke des 200ers theoretisch identisch ist. Selbe PLL. Ich bekomme jetzt natürlich das übliche Timingproblem. Der Synthesizer meckert 0,2ns an, die er von Langsam zu Schnell nicht packt. Wie kann ich das am Einfachsten entschärfen? Inorieren möchte ich es nicht, weil wer weiss, wie die Takte wirklich aussehen. Kann ich das mit einem MAX-Delay hinbekommen? Ich nehme an, nicht, weil die Zeit nicht reichen wird, auch wenn ich versuche, den 200er um einen halben Takt zu schieben, dass die Flanken sich nicht sehen. Ich simple Lösung, alles mit 200MHz laufen zu lassen und enables zu verwenden, scheidet aus. Wegen Power. Die "normale" Lösung, einen asynchronen Fifo dran zu setzen, bläht das design auf. Ich möchte lieber einen kleinen Puffer per Hand schreiben, den ich n mal instanziiere (den Erzeuger gibt es 16 mal). Wie müsste der arbeiten? Ich nehme an einen Wechselpuffer und den so schreiben und lesen, dass sich die Takte aus dem Weg gehen? Wie constraine ich den?
Berti schrieb: > Ich bekomme jetzt natürlich das übliche Timingproblem. Der Synthesizer > meckert 0,2ns an, die er von Langsam zu Schnell nicht packt. Das ist nach deiner Schilderung weder natürlich noch üblich. Nach deiner Schilderung sollte es kein constraint auf 200 ps geben und natürlich meckert nicht die Synthese sondern die STA oder ggf Mapper/Fitter... Setzt doch bitte mal das Logfile als Anhang hier rein das dürfte die wichtigsten Fragen (FPGA-Typ, gesetzte constraints, Nutzung von IOB, ...) beantworten. -- >Die "normale" Lösung, einen asynchronen Fifo dran zu setzen, bläht das >design auf. Ich möchte lieber einen kleinen Puffer per Hand schreiben, >den ich n mal instanziiere (den Erzeuger gibt es 16 mal). Neee, deine unfachmännische von Hand Lösung und Verniedlichung der Problems mit Gänsefüßchen und "Üblich, natürlich, ullalla" bläht das Problem auf. Es ist nicht ganz klar was du überhaupt brauchst, wenn du nich beschreibst wie die Gegen-Schnittstelle am µC aussieht.
Berti schrieb: > Synthesizer meckert 0,2ns an Der Synthesizer? Nicht eher der Router? > Synthesizer meckert 0,2ns an, die er von Langsam zu Schnell nicht packt. Hört sich irgendwie an, als ob da schlimmstenfalls ein Registersatz als "Fifo" dazwischen müsste. Oder was ist denn an Kombinatorik in dieser Übergabe von "langsam" nach "schnell" mit drin?
Berti schrieb: > Mit den 20MHz werden die 200MHz erzeugt, der somit alle 10 Takte mit der > Flanke des 200ers theoretisch identisch ist. Selbe PLL. Das ist etwas das du weisst, bzw. sicherstellst durch die Konfiguration der PLL. Der Synthesizer bzw. der Router weiss das dann aber (in den meisten Tools) noch nicht. Synplify kennt dazu eine "create_generated_clock" Constrained. Weiss gerade nicht, ob andere Tools die auch kennen oder andere Methoden haben um phasenstarre Clocks zu constrainen. (Du willst das Tool auch dazu bringen, diese Clocks so zu Routen, dass du im Design annehmen kannst, dass sie phasenstarr sind) > Ich bekomme jetzt natürlich das übliche Timingproblem. Der Synthesizer > meckert 0,2ns an, die er von Langsam zu Schnell nicht packt. [...] > Die "normale" Lösung, einen asynchronen Fifo dran zu setzen, bläht das > design auf. [...] > Wie constraine ich den? Mit "false_path" können Pfade aus der Timinganalyse ausgeklammert werden. Damit wird dem Tool gesagt, dass du als Entwickler sichergestellt hast, dass dieser Taktdomänenübergang 1. gewollt ist und 2. untersucht wurde, dass die gewählte Implementation passend ist. Teilweise sieht man dann eine false_path Constraint in etwa so: false_path -from clk20 -to clk200 Das ist zwar die Variante die wenig Aufwand gibt, aber nach meiner Meinung unsauber. Es kann dazu führen, dass fehlerhafte Taktübergänge unentdeckt bleiben.
Lothar M. schrieb: > Berti schrieb: >> Synthesizer meckert 0,2ns an > Der Synthesizer? Nicht eher der Router? Synthesizer UND Router :-) Jedenfalls wenn man Synplify einsetzt, der macht über das synthetisierte Design schon mal eine komplette Timinganalyse bzw. optimiert danach und braucht entsprechend schon alle Timingconstraints die der Router auch benötigt.
Lothar M. schrieb: >> Synthesizer meckert 0,2ns an, die er von Langsam zu Schnell nicht packt. > Hört sich irgendwie an, als ob da schlimmstenfalls ein Registersatz als > "Fifo" dazwischen müsste. Bei 0.2 Nanosekunden passt kein Register dazwischen. O.2 Nanosekunden wären 5 GHz Frequenz, ich schätze, da hat der TO einen ganz blöden Fehler gemacht oder die Fehlermeldung Sinnentstellend wiedergegeben. Der soll mal bitte,bitte den originalwortlaut der Fehlermeldung und seine Constrained hier nennen.
Christoph schrieb: > Synplify kennt dazu eine "create_generated_clock" Constrained. wenn im .sdc File ein "derive_pll_clocks"-Statement steht (was normalerweise der Fall ist), macht Quartus das von ganz alleine. Christoph schrieb: > Mit "false_path" können Pfade aus der Timinganalyse ausgeklammert > werden. Das Statement heißt "set_false_path" und hat hier nichts verloren. Bei einem Taktdomänenübergang, wo der eine Takt ein exaktes, synchrones Vielfaches des anderen ist, muss man Quartus mit multicycles (set_multicycle_path) "erklären", dass man selbst darauf achtet (z.B. mit clock enables), dass die relevante Flanke nur an den Stellen kommt, wo die andere Seite sie auch wahrnehmen kann.
Bit Spalter schrieb: > Bei 0.2 Nanosekunden passt kein Register dazwischen. O.2 Nanosekunden > wären 5 GHz Frequenz, ich schätze, da hat der TO einen ganz blöden > Fehler gemacht oder die Fehlermeldung Sinnentstellend wiedergegeben. Die 0,2ns könnten aus der Jitteranalyse kommen. Ich hatte 100ps für beide Takte gesetzt. Das ist nämlich mein Problem: Takte haben übers FPGA unterschiedliche Laufzeiten und wegen jittering kommt der schnelle Takt nur theoretisch (nicht aber praktisch1) ganz exakt auf derselben Flanke. Oder wird das berücksichtigt? Nehmen wir an, das wäre irgendwie mit drin. Tatsache ist, dass das timing nicht eingehalten wird. Das false path hilft mir ja nicht weiter. Soweit war ich auch schon. Ich bräuchte einen Tipp, wie ich es bauen muss? Brauche ich grey counter wie in den original FIFOs? Oder reicht ein einfacher Wechselbuffer, links schreiben, rechts lesen und bei Lesen der letzen Bits ist links schon geschrieben?
1 | Write Read Send |
2 | |
3 | 0 LEFT RIGHT0 "0" - start |
4 | 1 RIGHT1 RIGHT0 |
5 | 2
|
6 | 3
|
7 | 4
|
8 | 5
|
9 | 6
|
10 | 7 RIGHT7 RIGHT6 |
11 | 8 .. RIGHT7 |
12 | 9 .. "1" - stopp |
13 | 0 RIGHT LEFT0 "0" - start |
14 | 1 LEFT1 LEFT0 |
15 | 2
|
16 | 3
|
17 | 4
|
18 | 5
|
19 | 6
|
20 | 7 RIGHT7 RIGHT6 |
21 | 8 .. RIGHT7 |
22 | 9 .. "1" - stopp |
Meine Befürchtung ist, dass das Einschreiben auf den Buffer etwas zu früh(zu spät) kommt, wenn der andere beim Wechseln zu spät(zu früh) ist und gerade schon (noch) auf das falsche Byte schaut. Aber angenommen, das geht trotzdem: Was verpasse ich dem Schreibetakt? Ein multi cycle ist es irgendwie nicht, weil das in nächste Schreibfenster hineingeht? So lange darf es nicht dauern. In einer echten Schaltung hätte ich einfach den umgekehrten Takt zum Schreiben genommen, aber falling_edge möchte ich nicht einsetzen.
Berti schrieb: > Wie müsste der arbeiten? Der müsste trotzdem arbeiten, wie ein asynchroner FiFo. > Ich nehme an einen Wechselpuffer oder auch 3 oder noch mehr, wenn es die Takt/-Frequenz-Konstellation erfordert. In deinem Fall reicht sicher ein Doppelregister und Lesen nach dem gesampelten! fallenden Schreibtakt. > Wie constraine ich den? MAXPPATHDELAY von z.B. 0,75 Takten z.B. Berti schrieb: > Oder wird das berücksichtigt? Der Jitter wird selbstredend mit in Betracht gezogen, taucht an der Stelle aber nicht auf. Das ist eine offset-Verschiebung. Gfs Taktquelle <-> PLL. > Meine Befürchtung ist, dass das Einschreiben auf den Buffer etwas zu > früh(zu spät) kommt, wenn der andere beim Wechseln zu spät(zu früh) ist > und gerade schon (noch) auf das falsche Byte schaut. Das passiert nur, wenn der Lesetakt genau auf das Datum wechselt, das geschrieben wurde und auch dann hat man noch das budget der Periode - x. Das gleiche gilt für die Gegenbetrachtung. Wenn die Takte aus unterschiedlichen Quellen kommen und gleich groß sind, hat man das Problem.
Berti schrieb: > Ein multi cycle ist es irgendwie nicht, weil das in nächste > Schreibfenster hineingeht? Vielleicht verstehe ich ja nicht, was Du eigentlich treibst, aber nach meinem Verständnis hast Du ein Schieberegister, das mit 200 MHz getaktet ist. Von den 10 Bit Daten, die Du empfängst, sind nur 8 echte Nutzdaten, Du solltest dir beim Auslesen von der "langsamen" Seite aus also eigentlich zwei zusätzliche "schnelle" Takte Zeit lassen können, während denen sich die Daten nicht ändern? Das hätte ich als hold-multicycle gesehen.
Das stimmt, sehe ich jetzt auch. Durch die 10/8 Codierung habe ich sogar vorn und hinten einen Takt am Ausgang frei zum Wechseln eines Puffers. Nur wie macht man es, wenn es nicht der Fall ist? Ist das wirklich kein Problem mit den überlappenden Takten? Ein Multi Cycle Constraint entspannt doch einfach nur die Takt Situation und gibt dem Router freie Hand.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.