Forum: FPGA, VHDL & Co. PAR-SER-Umsetzer mit FPGA für uC wie konnektieren?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Berti (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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?

von C. A. Rotwang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
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?

von Christoph (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Christoph (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Bit Spalter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Berti (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Jürgen S. (engineer) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
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.

von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Berti (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.