Hallo allerseits! Wie schon im Thread "Takt ausgeben" (gibt's ne Moeglichkeit nen huebschen Link zu setzen wie zu Artikeln?) geht es um einen TFT-Controller mit 64Mhz Pixelclock im Spartan-3A. Ich habe nun mit einigen Zaehlern meine Synchronisationssignale erzeugt und in der Simulation sieht auch alles gut aus soweit. Nur eine Kleinigkeit ist mir aufgefallen: Skew zwischen den verschiedenen Datenleitungen und Verzoegerung aller Datenleitungen gegenueber dem Taktausgang (DDR-FF). Zwar liegen alle diese Werte weeeeeit im gruenen Bereich fuer meine Anwendung (laut post-route simulation 0.5ns Skew zw. Daten und 1.5ns Verzoegerung zum Takt, bis zu ca. 4 ns waere OK wenn ich das Datasheet von meinem TFT richtig lese), aber ich frage mich wie ich dieses Timing in User Constraints giessen kann. Ich habe ein bisschen im Xilinx Constaints Guide <http://toolbox.xilinx.com/docsan/xilinx9/books/docs/cgd/cgd.pdf> gelesen, aber wirklich verstanden habe ich das nicht alles. Mit "OFFSET" kann ich die Verzoegerung zwischen einem Clock-Eingang und meinen Datenein-/ausgaengen festlegen. Das ist fuer synchone Design sicher wichtig, aber was mich interessiert ist das Verhaeltnis von Clock-*Aus*gang zu Datenausgaengen. Kann ich das auch festlegen? Oder haengt das nur von meinem Design ab? Gruesse, Sebastian
>gibt's ne Moeglichkeit nen huebschen Link zu setzen wie zu Artikeln? Ja, einfach indem du die URL zu dem Beitrag "Timing constraints: OFFSET?" in den Text reinkopierst. >Verhaeltnis von Clock-*Aus*gang zu Datenausgaengen. Richtig, der constraint heißt OFFSET OUT (clock to pad) Mit OFFSET OUT kannst du angeben, wieviel später das mit dem FPGA-Takt getaktete Signal am Ausgangspin stabil sein muss. Das macht Sinn, wenn du den FPGA-Takt extern zum Einlesen des Signals in ein Register (z.B. auch Schieberegister) verwendest. Allerdings ist dein Takt-Ausgang offenbar nicht der FPGA-Takt, sondern ein daraus abgeleitetes Signal (nennen wir es Clock). Deshalb musst du den Clock-Ausgang auf den FPGA-Takt constrainen und genauso den Datenausgang. Mir fällt jetzt auf Anhieb keine Möglichkeit ein, ein Signal auf ein beliebiges anderes Signal (Daten auf Clock) zu beziehen... Am einfachsten wird es sein, die Daten und den Clock vor der Ausgabe noch einmal mit dem FPGA-Takt zu synchronisieren. Dann wird dafür das FF im IO-PAD verwendet, und du hast den minimal möglichen Zeitversatz in den Signalen. Allerdings noch keinen Bezug von den Daten zum Clock... | FPGA | Platine | Daten ----------[IOB-Reg]------------O---- ^ ^ OFFSET OUT | FPGA-Takt--+----------------| | v v OFFSET OUT | Clock ----------[IOB-Reg]------------O---- | Du könntest allerdings den nach aussen gehenden Clock noch zum Synchronisieren der Daten am FPGA-Ausgang (im FPGA) verwenden. Dann könntest du diese Daten wieder auf den Clock constrainen. | FPGA | Platine (IOB-Reg) | Daten -----[Register]-----------O---- ^ ^ OFFSET OUT | FPGA-Takt--+ | | v | | Clock ---------+----------------O---- | Aber wehe, wenn ich auf das Ende sehe... Das Problem ist dann nämlich die Übernahme der Daten mit Clock ins Register.
Ok, das kann ich nachvollziehen. Die getakteten IOB-FFs wuerden genau das machen was ich will. Die Sache mit den getakteten IOB-FFs hat auch Joko/Jochen in Beitrag "Re: Takt ausgeben" schon angesprochen. Ich gebe den selben Takt aus den ich auch fuer meine Logik verwende, ueber ein DDR-FF (OFDDRCPE). Die Datenausgaenge setze ich in einem Process abhaengig von der selben Clock. Ich bin einfach mal davon ausgegangen das ISE das schon so einrichten wird, scheint aber ja nicht der Fall zu sein. Wie kann ich das in umsetzen, muss ich da irgendwelche Xilinx-Blackboxen instanziieren oder klappts einfach mit der richtigen Beschreibung in VHDL? Ich werde mal ausprobieren ob ich das "OFFSET OUT" Constraint hinbekomme und wie es sich auswirkt... Sebastian
Gast
#962695
Hi Sebatian, da DDR-FlipFlop muß (leider) instanziiert werden - eine 'behavioral' Beschreibung verstehen dir Synthese-Tolls nicht... Offset-Out ist das richtige constraint, um die Schaltung auf dem PCB "sicher" zum Laufen zu bringen - allerdings wird es Dir eine etwas zu pessimistische Angabe liefern: der OFFSET bezieht sich nämlich immer auf den verwendeten Clock-Eingang (also den Pin, der Deinen FPGA mit dem Takt versorgt). Hieraus folgt (wenn die FFs mit der steigenden Flanke betrieben werden: a) Datenausgänge ändern sich IRGENDWANN zwischen "0ns" und "Offset Out der Daten" nach der steigen Flanke am Clock-Eingangs-Pin b) Dein Clock-Eingang ändert sich IRGENDWANN zwischen "0ns" und "Offset Out des Clocks" nach der steigen Flanke am Clock-Eingangs-Pin aus a) und b) folgt, daß - wenn dein externer Baustein mit der steigenden Flanke arbeiten - Du beim Ändern der Datenbits eine fallende Flanke am Clockpin erzeugen solltest (-> Einstellung der D0,D1-Eingänge), da Du ANDERNFALLS nicht sicherstellen könntest, daß die Daten stabil sind, wenn die Clock eine steigende Flanke hat. Also: - Daten und fallende Clockflanke gleichzeitig - Offset-Out so setzen, daß steigende Flanke (mit theoretisch 0 ns Versögerung) SICHER NACH dem 'Einschwingen (Offset-Out max. der Daten) passiert => dies ist eine "worst case" Annhame und eigentlich zu pessimistisch: die minimal möglichen 'offset out' liegen Erfahrungsgemäß bei 1/3 der maximalen - aber das garantiert Dir niemand die ISE 11.1 soll angeblich ein neues constraint einführen, mit dem man diese sog. 'Source-Synchronen' Interfaces genauer beschreiben kann! (warten wir's mal ab) Gruß Jochen
>der OFFSET bezieht sich nämlich immer auf den verwendeten Clock-Eingang >(also den Pin, der Deinen FPGA mit dem Takt versorgt). War ja auch die ursprüngliche Denkweise. Da gab es einen Board-Takt, mit dem das ganze Design versorgt wird (so die Idee). Und auf diesen Takt beziehen sich alle Komponenten vor und nach dem FPGA, deshalb muss sich auch das Constraint auf diesen Takt beziehen. Wenn aber intern Takte erzeugt werden (Haarsträubender Taktgenerator oder DCM & Co) kann ich durchaus auf diese internen Takte auch constrainen.
Danke fuer die Antworten! Ich glaube ich habe das soweit alles verstanden, korriegert mich wenn ich falsch liege :-) Das OFFSET Constraint richtet sich nach einem Clock-Input-Pin am FPGA. Mein Takt sieht so aus: 16 Mhz von extern (moechte ich nicht aendern weil auf Evaluationboard aufgeloetet) werden in DCM vervierfacht (der externe Takt wird fuer nichts ausser dem DCM verwendet). Der vervierfachte Takt wird fuer die interne Logik benutzt und ausgegeben fuer das TFT. Ich kann nun ja ueber die DCM dafuer sorgen das mein interner Takt in Phase mit dem externen ist. Aber er ist immer noch viermal zo schnell. Funktioniert das OFFSET Constraint fuer diesen Fall? Jochen: Du schreibst von DDR-FFs. Solch eines habe ich fuer die Taktausgabe verwendet. Aber wie ist es mit den Daten? Wenn ich den Takt wie im anderen Thread besprochen invertiere kann ich fuer die Daten doch die normalen IOB-FFs benutzen und brauche kein double data rate. Da die Daten eine halbe Periodendauer haben um "aussen anzukommen", was ich ja offenbar ueber das OFFSET OUT Constraint sicherstellen kann. Meine Frage war nun wie ich diese normalen IOB-FFs in VHDL einbaue. Habt ihr da vielleicht ein Beispiel parat? Das ist wahrscheinlich eine relativ doofe Frage... hab ich aber noch nie gemacht und bin etwas ratlos wie ich das anstellen muss... Vielen Dank! Sebastian
Gast
#962780
@Sebastian > Das OFFSET Constraint richtet sich nach einem Clock-Input-Pin am FPGA. ja >Funktioniert das OFFSET Constraint fuer diesen Fall? ja >Du schreibst von DDR-FFs. Solch eines habe ich fuer die Taktausgabe >verwendet. gut >Aber wie ist es mit den Daten? Wenn ich den Takt wie im >anderen Thread besprochen invertiere kann ich fuer die Daten doch die >normalen IOB-FFs benutzen und brauche kein double data rate. genau > Meine Frage war nun wie ich diese normalen IOB-FFs in VHDL einbaue. hatte ich falsch verstanden > Habt ihr da vielleicht ein Beispiel parat? - ganz 'normales' - process mit rising_edge(..) - der Ausgang dieser FFs dann direkt auf den Port geben - ISE (map) sagen, daß es die IOB-FFs verwenden soll (default ist 'nein') - im FPGA-Editor (irgenwo gibt's auch nen report, aber ich verwende immer den FPGA-Editor) nachsehen, daß die IOB-FFs auch wirklich verwendet wurden Gruß Jochen
Gast
#962791
@Lothar Miller > Wenn aber intern Takte erzeugt werden (Haarsträubender Taktgenerator > oder DCM & Co) kann ich durchaus auf diese internen Takte auch > constrainen. ich teste es nicht mit JEDER ISE-Version - vielleicht geht's ja mit irgendeiner... (Glaub' ich aber nicht, da mir dieses Feature erst für die 11.1 in Aussicht gestellt wurde) In den Versionen, die ich auf dieses Feature getestet habe, hieß es immer, daß das Clock-Netz, auf das ich mich beziehen wollte, kein PAD sei => ERROR Gruß Jochen
Hi, allmaehlich wird die Sache etwas klarer. Joko wrote: [Benutzung von IOB-FFs] >> Habt ihr da vielleicht ein Beispiel parat? > - ganz 'normales' - process mit rising_edge(..) Benutze ich. > - der Ausgang dieser FFs dann direkt auf den Port geben Ist auch erfuellt. > - ISE (map) sagen, daß es die IOB-FFs verwenden soll > (default ist 'nein') Die unter "Map Properties" steht bei mir "Pack I/O Registers/Latches into IOBs" = "For Inputs and Outputs" (war auch per Defualt so, ISE 9.2i). Ich vermute du meinst diese Einstellung. > - im FPGA-Editor (irgenwo gibt's auch nen report, aber ich verwende > immer den FPGA-Editor) nachsehen, daß die IOB-FFs auch wirklich > verwendet wurden Aus dem FPGA-Editor werd ich nicht schlau, aber im Map Report steht folgendes:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
3 IOB-FFs sind etwas wenig bei 20 Ausgaengen um die es geht... mal sehen ob ich eine Moeglichkeit finde das zu verbessern. Vorschlaege? Sebastian
Sooo... mit mehr FFs kommen auch mehr IOB-FFs heraus. Mein Code sah bisher (grob zusammengestueckelt) in etwa so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
Das ergibt 3 IOB-FFs. Kleine Aenderung fuer mehr FFs:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Dies ergibt 21 IOB-FFs, passt genau zur Anzahl der AUsgaenge dieses Entities. Mit ist aber nicht klar wieso das einen Unterschied macht. Die erste Variante hat doch auch schon ein process(clk), wieso wird das nicht in IOB-FFs verwandelt?
>Meine Frage war nun wie ich diese normalen IOB-FFs in VHDL einbaue. Das macht die Toolchain automatisch, wenn du keine Kombinatorik nach dem letzten FF einbaust. Deine Zuweisungen (vermutlich concurrent) hatten offenbar noch Kombinatorik drin. Wenn du z.B. > red <= std_logic_vector(red_i); in jedem Zweig der if-Abfrage einen Wert zuweist, bekommst du Kombinatorik (Mux), kein FF. So wäre es auch gegangen, den Takt Latency hast du jetzt sowieso...
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
@ Joko
Richtig... :-(
>An OFFSET specification must use a pad signal to designate the clock.
Gast
#962901
@Sebastian > Mit ist aber nicht klar wieso das einen Unterschied macht. eben deshalb verwende ich immer den FPGA-Editor (Einarbeitung lohnt sich wirklich !) -> Reports (mit "map -detail -pr b" würde das .mrp file sagen, wo welches IOB-FF verwendet wurde) sagen einem zwar, was los ist, geben einem aber seltenst auch den Grund dafür an. Mit dem Fpga-Editor läßt sich sehr genau sehen, ob es einen konkreten Grund gibt, daß etwas nicht so gemacht werden konnte/wurde, wie gedacht. Irren ist halt menschlich - man übersieht manchmal auch einfache Zusammenhänge - als da wären (bei Dir trifft aber wohl nix zu) - die FFs wurden als Input-FFs verwendet: Input-Pad -> FF -> Output-Pad => beide möglich - das gewählte aoutput-Pad liegt in einem Tile, das bereits ein FF verwendet, das mit einer anderen Clock getaktet wird - die Synthese hast (für besserers timing) die FFs 'nach vorne' verschoben - Das ucf-file oder der VHDL-Code verwendet das attribute IOB-false etc. Gruß Jochen
Lothar Miller wrote: > Wenn du z.B. >> red <= std_logic_vector(red_i); > in jedem Zweig der if-Abfrage einen Wert zuweist, bekommst du > Kombinatorik (Mux), kein FF. Das ergibt natuerlich Sinn... habe ich nicht bedacht. Ohne Constraints aber mit IOB-FFs habe ich sowohl Skew als auch Delay von deutlich unter 100ps in der Post-Route Simulation (die komischerweise jetzt 10x so lange dauert). Scheint tatsaechlich einen gigantischen Unterschied zu machen. Damit bin ich dann auch fuer moegliche zukuenftige Anforderungen an genaueres Timing gewappnet. In dieser Anwendung brauche ich diese Praezision zwar nicht zwingend, aber mein Verstaendnis von FPGAs hat's auf jeden Fall weiter gebracht. Vielen Dank euch beiden. Wird sicher nicht lange dauern bis mir die naechste Frage einfaellt ;-) Den FPGA-Editor werde ich mir auch nochmal ansehen... vielleicht entdecke ich ja irgendwann die Bedeutung der vielen bunten Kaestchen ;-) Viele Gruesse aus dem fernen Osten, Sebastian
Gast
#962992
der FPGA-Editor ist nicht bunt - das is der Floorplanner (den verwende ich auch nicht - zu schwierig) der Editor ist (fast) selbsterklärend.. ansonsten http://toolbox.xilinx.com/docsan/xilinx10/help/iseguide/mergedProjects/fpga_editor/whskin_homepage.htm Gruß Jochen
Hallo nochmal... habe natuerlich schon die naechste Frage :-) Lothar Miller wrote: > So wäre es auch gegangen, den Takt Latency hast du jetzt sowieso... >
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
Habe den Code einem bekannten gezeigt. Der meinte (beispielsweise) enable und enable_i im selben Takt zu setzen waere unsauber. Ich bin davon ausgegangen das das der voellig normale Weg ist FFs zu erzeugen, da sich Zuweisungen auf Signale immer(?) erst im naechsten Takt des process() auswirken. Oder kann es da Probleme geben wenn z.B. das Taktsignal wg. Routing zu unterschiedlichen Zeiten ankommt? Ist dies der richtige Weg FFs zu erzeugen oder gibt es einen besseren? Se-dergernallesrichtigmachenwill-bastian
> Der meinte (beispielsweise)enable und enable_i > im selben Takt zu setzen waere unsauber. Falsch, die werden ja sowieso mit dem selben Takt gesetzt. Evtl. hat der Mensch den selben Prozess gemeint? Dann ist er wahrscheinlich einer von denen, die nach Quellcode-Zeilen abrechnen uund lieber etwas mehr hinschreiben, als nötig ist. So könnte man das bei exakt gleichem Ergebnis natürlich auch schreiben:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
> Ich bin davon ausgegangen das das der voellig normale Weg ist FFs zu > erzeugen, da sich Zuweisungen auf Signale immer(?) erst im naechsten > Takt des process() auswirken. Richtig, diese Denkweise stimmt. > Oder kann es da Probleme geben wenn z.B. > das Taktsignal wg. Routing zu unterschiedlichen Zeiten ankommt? Nein, denn FPGAs sind so aufgebaut, dass der Takt an allen FFs gleichzeitig ankommt. Sonst würde es kein synchrones (das heißt zeitgleiches) Design geben. Die FPGA-Hersteller sorgen mit nicht wenig Aufwand dafür, dass jedes geschriebene rising_edge(clk) gleichzeitig ausgeführt wird. Siehe dazu auch den Beitrag http://www.mikrocontroller.net/articles/Taktung_FPGA/CPLD
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.