Forum: FPGA, VHDL & Co. Clock to Pad Delay Xilinx Virtex 5


von User (Gast)


Lesenswert?

Hallo,

habe mal eine Frage zu meinem Design.

Ich habe in einem Virtex 5 eine Camera Link Full Configuration Output 
Schnittstelle implementiert.

Die Daten laufen mit 350MHz, die Sync Clock dazu durch 7, also 50MHz.

Nun will ich dass die Signale im FPGA mit dem selben (!) delay zum Pad 
gelangen.

Im Report steht folgendes:
1
Clock CLK to Pad
2
---------------+------------+-----------------------+--------+
3
               | clk (edge) |                       | Clock  |
4
Destination    |   to PAD   |Internal Clock(s)      | Phase  |
5
---------------+------------+-----------------------+--------+
6
ELLISA_CLK_X<0>|   10.980(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
7
ELLISA_CLK_X<1>|   10.980(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
8
ELLISA_CLK_Y<0>|   11.148(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
9
ELLISA_CLK_Y<1>|   11.148(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
10
ELLISA_CLK_Z<0>|   11.235(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
11
ELLISA_CLK_Z<1>|   11.235(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
12
ELLISA_X0<0>   |   13.938(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
13
ELLISA_X0<1>   |   13.938(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
14
ELLISA_X1<0>   |   14.037(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
15
ELLISA_X1<1>   |   14.037(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
16
ELLISA_X2<0>   |   14.039(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
17
ELLISA_X2<1>   |   14.039(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
18
ELLISA_X3<0>   |   14.021(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
19
ELLISA_X3<1>   |   14.021(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
20
ELLISA_Y0<0>   |   13.626(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
21
ELLISA_Y0<1>   |   13.626(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
22
ELLISA_Y1<0>   |   14.431(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
23
ELLISA_Y1<1>   |   14.431(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
24
ELLISA_Y2<0>   |   13.877(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
25
ELLISA_Y2<1>   |   13.877(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
26
ELLISA_Y3<0>   |   13.985(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
27
ELLISA_Y3<1>   |   13.985(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
28
ELLISA_Z0<0>   |   13.476(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
29
ELLISA_Z0<1>   |   13.476(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
30
ELLISA_Z1<0>   |   13.646(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
31
ELLISA_Z1<1>   |   13.646(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
32
ELLISA_Z3<0>   |   13.809(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
33
ELLISA_Z3<1>   |   13.809(R)|i_CLKx7_MICROBOLOMETER1|   0.000|
34
---------------+------------+-----------------------+--------+
CLK ist die SystemClock bzw. der Eingangstakt 100MHz
i_CLKx7_MICROBOLOMETER1 = 350MHz (Interner Takt erzeugt aus einer PLL)
ELLISA_CLK_* = 350/7 = 50MHz (synchron im Design erzeugt)
1
--             __    __    __    __    __    __    __    __    __    __    
2
--  CLK     __|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__...
3
--
4
-- COUNT      0     1     2     3     4     5     6     0     1     2     ...
5
--          __|___________                   ___________|___________      
6
--  i_CLKx1               |_________________|                       |_____...
7
CLKx1_GEN: PROCESS(CLK)
8
BEGIN
9
IF CLK = '1' AND CLK'EVENT THEN
10
  i_CLKx1 <= '1';
11
  IF COUNT < 1 THEN
12
    COUNT <= COUNT + 1;
13
  ELSIF COUNT >= 1 AND COUNT < 4 THEN
14
    i_CLKx1 <= '0';
15
    COUNT <= COUNT + 1;
16
  ELSIF COUNT >= 4 AND COUNT <= 6 THEN
17
    COUNT <= COUNT + 1;
18
    IF COUNT = 6 THEN
19
      COUNT <= 0;
20
    END IF;
21
  END IF;
22
END IF;
23
END PROCESS CLKx1_GEN;
X*/Y*/Z* Serielle Datenstrom im 350MHz Takt

Der Output der Signale erfolgt über OBUFDS Primitive, z.B.:
1
...
2
CLK_Z_OBUFDS: OBUFDS
3
  PORT MAP (
4
      O                           => CLK_Z(0),  -- Diff_p output (connect directly to top-level port)
5
      OB                         => CLK_Z(1),  -- Diff_n output (connect directly to top-level port)
6
      I                           => i_CLKx1      -- Buffer input 
7
      );
8
...
9
Y3_OBUFDS: OBUFDS                                -- Y3 diff I/O
10
  PORT MAP (
11
      O                           => Y3(0),       -- Diff_p output (connect directly to top-level port)
12
      OB                         => Y3(1),     -- Diff_n output (connect directly to top-level port)
13
      I                           => i_Y3        -- Buffer input 
14
      );
15
...

Die Frage ist, wie bekomme ich die clk (edge) to PAD Zeiten auf das 
gleiche Delay (min. < 1ns)?
Welche Constraints könnte ich da anwenden? OFFSET OUT? Wie am besten?

Als alternative zu meinem aktuellen Design hätte ich auch OSERDES 
Primitive benutzen können. Werden da die clk to PAD delay automatisch 
vom OSERDES geregelt?

Hoffe ihr könnt mir helfen

LG

von Hannes (Gast)


Lesenswert?

Schau dir mal xapp585 an 
(https://www.xilinx.com/support/documentation/application_notes/xapp585-lvds-source-synch-serdes-clock-multiplication.pdf)

Das ist prinzipiell genau dein Problem fuer Input und Output, nur fuer 
7-Series FPGAs. Fuer den Output wird fuer Daten UND Clock ein OSERDES im 
7:1-mode genutzt, der mit clk und clkdiv versorgt wird. Dieser hat ein 
recht geringes und konstantes Delay zu seinem Buffer, da das nicht ueber 
normale Routing-Resourcen geht.

Clock geht dann einfach durch einen OLERDES mit dem Pattern 1100011 und 
bleibt damit zu den Daten aligniert.

Die restlichen Delays (Buffer -> Pad -> Ball) weichen auch von Ball zu 
Ball ab. Wenn die noch relevant sind, muessen sie im PCB ausgeglichen 
werden.

von User (Gast)


Lesenswert?

So wie ich dich verstehe wäre ein OSERDES angebracht zu benutzen.
Der ist bei mir auch in Planung.

Aber nur aus Interesse würde ich gerne wissen wie ich in meinem Design 
die clk to PADs delays geregelt bekomme.

Denn mein aktuelles Design lief in einem Vorprojekt mit einer 
niedrigeren Takt einwandfrei. Da war es halt nicht so ein Problem mit 
dem to pad delays. Nun bin ich schneller und habe eine Periode unter 3ns 
und würde gerne den kompletten Output samt Clock mit dem gleichen Delay 
versehen, soweit es geht.

Hannes schrieb:
> Clock geht dann einfach durch einen OLERDES mit dem Pattern 1100011 und
> bleibt damit zu den Daten aligniert.

Was meinst du hier mit dem Pattern? Kann man das am OSERDES einstellen?
Das Pattern ist in meiner Clock schon vorhanden, das müsste doch reichen 
für den OSERDES.

von Hannes (Gast)


Lesenswert?

Der OSERDES wird mit 2 Clocks versorgt - clk und clkdiv. Dabei sollen 
beide aus der gleichen PLL kommen, und clk um deinen 
Serialisierungsfaktor schneller sein als clkdiv.

Hier also: clk @ 350MHz, clkdiv @ 50MHz.

Die Daten muessen mit der gleichen Clockingtopologie durch die OSERDES 
gehen wie auch das Clockpattern. Das Clockpattern wird uebertragen als 
Datum mit dem konstanten Wert 1100011. Da es durch die gleichen 
Strukturen mit gleicher Clock uebertragen wird wie die Daten, wird auch 
der Phasenversatz ueber PVT (Process, Voltage, Temperature) der gleiche 
bleiben.

Wenn die Clock jetzt aus einem normalen Flipflop (oder noch schlimmer - 
Kombinatorik) ausgegeben wird, wird das Signal noch ueber normales 
Routing geschickt, bevor es zur Aussenwelt geht. Das ist sehr variabel 
von build zu build. Beim OSERDES gibt es dagegen pro Ball genau eine 
Moeglichkeit, das zu routen, deswegen verhaelt es sich auch bei jedem 
Build gleich. Varianz gibt es nur bis zum SERDES.

Hoffe, das etwas besser erklaert zu haben.
Mein Wissen beschraenkt sich auf die SERDES ab 7-Series, ob dein Virtex 
5 noch andere Eigenarten hat weiss ich nicht.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Nur kurz ob ich es verstanden habe: Du suchst Timing Constraints damit 
das Output Timing der einzelnen Signale eines parallel Datenbus einen 
von dir vorgegebene minimalen zeitlichen Versatz zueinander haben?

Ein kleines, wirklich gutes Whitepaper dazu:

https://www.xilinx.com/support/documentation/white_papers/wp237.pdf

: Bearbeitet durch User
von User (Gast)


Lesenswert?

Hallo Tobias,

Tobias B. schrieb:
> Nur kurz ob ich es verstanden habe: Du suchst Timing Constraints damit
> das Output Timing der einzelnen Signale eines parallel Datenbus einen
> von dir vorgegebene minimalen zeitlichen Versatz zueinander haben?

Genau das suche ich :-)

Das Whitepaper habe ich auch schon gesehen.

Das was ich versuche zu verstehen ist, dass die clk to PAD delay zur 
Clock "CLK" referenziert wird, welches die 100MHz Eingangsfrequenz zur 
PLL ist.
Die Daten und Clocks sind aber mit dem Ausgang des PLLs (350MHz) 
generiert worden. Finde grad keinen Bezug zum "CLK" (100MHz). Daher 
suche ich nach einer Antwort :-)

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

User schrieb:
> Die Daten und Clocks sind aber mit dem Ausgang des PLLs (350MHz)
> generiert worden. Finde grad keinen Bezug zum "CLK" (100MHz). Daher
> suche ich nach einer Antwort :-)

Das was du suchst, ist ein OFFSET Out Constraint mit dem Keyword 
REFERENCE_PIN. Siehe z.B.

https://www.xilinx.com/support/documentation/sw_manuals/xilinx14_5/cgd.pdf

Seite 186. Ich installiere gerade ISE auf meinem Arbeitslaptop, dann 
kann ich mal ein Minimalbeispiel machen.

Auch zu empfehlen ist dieser Xilinx Forum Post:

https://forums.xilinx.com/t5/Timing-Analysis/REFERENCE-PIN-constraint-not-working-as-expected/td-p/162900

Du solltest dir auf jedenfall mal Gedanken machen, ob du die 50 MHz 
Clock nicht mit deiner PLL generieren moechtest und via ODDR Buffer 
ausgeben. Das ist der von Xilinx empfohlene Stil.

: Bearbeitet durch User
von User (Gast)


Lesenswert?

Tobias B. schrieb:
> Du solltest dir auf jedenfall mal Gedanken machen, ob du die 50 MHz
> Clock nicht mit deiner PLL generieren moechtest und via ODDR Buffer
> ausgeben. Das ist der von Xilinx empfohlene Stil.

Ich habe das versucht, allerdings ist der delay von clock to pad größer 
geworden.

Wie meinst du das mit dem ODDR, da habe ich doch als Output ein DDR 
Single ended. Wascheinlich ist hier ja ein OSERDES angebrachter.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

User schrieb:
> Wie meinst du das mit dem ODDR, da habe ich doch als Output ein DDR
> Single ended. Wascheinlich ist hier ja ein OSERDES angebrachter.

Du kannst auch ein LVDS Buffer hinter den ODDR schalten. ;-)

Generell werden Clocks aus einem FPGA von einem Clock Netz ueber einen 
ODDR Buffer ausgegeben. Das Stichwort dazu ist "Forwarded Clock", siehe 
z.B. hier:

https://forums.xilinx.com/t5/Timing-Analysis/Why-ODDR-for-forwarded-clock/td-p/756737

Siehe dazu auch UG190, Kapitel "Clock Forwarding".

von Blechbieger (Gast)


Lesenswert?

Irgendwo müsstest du eine Option finden um das Ausgaberegister in den 
IO-Buffer zu schieben. Dadurch hast du sehr niedrige und vor allem 
konstante und ähnliche Delays auf allen Ausgängen. Eventuell bekommst du 
dadurch aber Probleme beim Holdtiming.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Blechbieger schrieb:
> Irgendwo müsstest du eine Option finden um das Ausgaberegister in den
> IO-Buffer zu schieben. Dadurch hast du sehr niedrige und vor allem
> konstante und ähnliche Delays auf allen Ausgängen. Eventuell bekommst du
> dadurch aber Probleme beim Holdtiming.

Jep, das wuerde ich auf jedenfall machen. Das zugehoerige Constraint 
ist:
1
INST "OUTPUT_SIGNAL" IOB=FORCE;

wobei OUTPUT_SIGNAL auch Wildcards haben darf.

von User (Gast)


Lesenswert?

Möchte mich hier an alle beteiligten bedanken.

Als Fazit kann ich sagen, dass über die ODDR die clk to pad delays 
zueinander sehr klein wurden. Das ist schonmal ein korrekter Ansatz 
gewesen.

Habe aber nun OSERDESe in meinem Design eingebaut, die auch sehr kleine 
clk to pad delays aufweisen.

Letztendlich war mein Hauptproblem, das mein Timing mit 350MHz einfach 
an manchen stellen zu hart war. Daher habe ich das Konzept geändert und 
mittels der 7fach kleineren 50MHz Clock das Design abgeändert.
Nun werden sowohl die Daten als auch das Pattern "1100011" (Sync-Clock 
CameraLink) mittels OSERDESe zu den Ausgängen mit geringen clk to Pad 
delay zueinander geführt.

Mein Problem bei der ODDR Variante war das ich mit dem richtigen duty 
cycle die Daten in der 350MHz Taktdomain aufarbeiten musste, sodass das 
Timing eng wurde.
Nun übernehmen die OSERDESe diese Aufgabe und mein Design kann gechilled 
:-) die 50MHz Taktdomain verwenden.

von Hannes (Gast)


Lesenswert?

Hier gilt noch zu beachten, dass (zumindest bei der 7-Series) die 
OSERDES und die ODDR und die IOB-FDs Teil des OLOGIC sind und daher alle 
die gleichen Routing-Delays aufweisen.

Wenn man jetzt also ein ODDR oder OSERDES benutzt, um eine regenerierte 
Clock auszugeben, kann man oft mit sehr begrenztem Aufwand die 
Setup/Hold-Zeiten feintunen, in dem man eine phasenverschobene Clock an 
den Clock-ODDR gibt, aber bei den restlichen Outputs mit Offset 0 
arbeitet.

Genauso koennte man ein ODDR mit einer 4/7 Duty-Cycle Clock mit Phase 45 
Grad verwenden. Ist aber deutlich schwieriger hinzubekommen, als der 
OSERDES.

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
Noch kein Account? Hier anmelden.