Forum: FPGA, VHDL & Co. Zustand von halbiertem Takt abfragen: Setup/Hold okay?


von Udo Weizenheim (Gast)


Lesenswert?

Eine Verständnisfrage:

Am FPGA liegt ein externer 150-Mhz-Takt an. Per DCM wird daraus ein 
interner 150Mhz-Takt und ein halbierter phasensynchroner 75MHz-Takt 
generiert.

Beispiel:
1
signal flipflop : std_logic,
2
process(Clk150) 
3
begin
4
  if (rising_edge(Clk150)) then
5
    if (Clk75 = 1) then
6
      flipflop <= '1'; 
7
    else
8
      flipflop <= '0';   
9
    end if;
10
  end if;
11
end process;

Nun kommen beide Taktflanken ja gleichzeitig.
Meine Befürchtung wäre, daß das "flipflop" mit der steigenden Flanke an 
seinem Takteingang (CLk150) an seinem Dateneingang gerade einen 
Zustandswechsel (Clk75) sieht und dadurch die Setup- bzw. Hold-Zeit 
verletzt ist.
Stimmt das? Oder ergibt dies ein ClockEnable?

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

Hallo,

dein Signal fllipflop ist für 2 Takte des 150 MHz Taktes 1 und für die 
nächsten zwei Takte 0. Das kann man auch wunderbar mit einem 2 Bit 
langen Counter realisieren. Dann gibt es auch keine Fragen mehr 
hinsichtlich Setup/Hold-Zeiten.

Tom

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Ich nehme mal an, dass Dein Beispiel stark vereinfacht war.

Eine beliebte Lösung ist die Erzeugung eines Signals, z.B. CLK75EN, dass 
der 150MHz Domain mitteilt, ob innerhalb der nächsten Phase eine CLK75 
Flanke folgt. Dadurch weiß CLK150, wann Ausgänge geändert und Eingänge 
abgetastet werden dürfen.
1
            _   _   _   _   _   _   _ 
2
   CLK150 _| |_| |_| |_| |_| |_| |_| |
3
          _     ___     ___     ___   
4
    CLK75  |___|   |___|   |___|   |__
5
            ___     ___     ___     __
6
  CLK75EN _|   |___|   |___|   |___|

Bei halbiertem Takt sieht das zwar trivial aus, aber bei anderen 
Verhältnissen macht sich der Vorteil schnell bemerkbar.

Dieses Verfahren wird beispielsweise bei ARM Kernen eingesetzt, um 
langsamere Busse anzuschließen: 
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0438e/CJHFFIHH.html

Gruß
Marcus

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Udo Weizenheim schrieb:
> Stimmt das?
Ja.
> Oder ergibt dies ein ClockEnable?
Ich frage mich: warum eigentlich so umständlich? Warum verwendest du 
das 75MHz-Signal als Clock-Enable für den 150MHz-Takt? Warum verwendest 
du nicht den 75MHz-Takt direkt?

Ich würde dein Beispiel so schreiben:
1
   flipflop  <= clk75;
Ach, so hattest du das nicht gemeint?
Was fehlt dann an deinem Beispiel, damit man dein Problem nachvollziehen 
könnte?
1
process(Clk75) begin
2
  if rising_edge(Clk75) then
3
       flipflop <= not flipflop;
4
  end if;
5
end process;
6
7
8
process(Clk150) begin
9
  if rising_edge(Clk150) then
10
       ausgang <= flipflop;    -- kein Problem, weil keine "echte" zweite Taktdomäne
11
  end if;
12
end process;
Denn du kannst ganz problemlos Signale zwischen zwei per DCM 
erzeugten Domänen hin- und her übertragen. Die Toolchain sorgt (bei 
angegebenem Constraint auf den Basistakt) für die Überwachung der 
Laufzeiten...

Marcus Harnisch schrieb:
> Dieses Verfahren wird beispielsweise bei ARM Kernen eingesetzt, um
> langsamere Busse anzuschließen:
Damit ist aber die die Richtung klar: die "schnelle" Domäne gibt den 
Takt vor. Denn dieses Enable-Signal ist ja zur "schnellen" Domäne 
synchron. Das sieht mir wie "voreilendes Einsynchronisieren" aus...

von Udo Weizenheim (Gast)


Lesenswert?

Danke für die Antworten.
Mein Beispiel war natürlich stark vereinfacht, sorry!

Meine Anwendung sieht so aus:
In mein Modul kommen 8-Bit-Daten mit 150Mhz rein und sollen als 
16Bit-Daten mit 75MHz raus. Die 8-Bit-Daten kommen als Pakete und können 
mit jeder steigenden 150MHz-Flanke beginnen.

Das Problem ist jetzt folgendes:
Wenn ein 8-Bit-Daten-Paket dann beginnt, wenn auch der 75MHz-Clock eine 
steigende Flanke hat, ist alles gut.
Wenn ein 8-Bit-Daten-Paket aber dann beginnt, wenn der 75MHz-Clock 
gerade eine fallende Flanke hat, muß ich die Daten zwischenpuffern und 
quasi einen "Wait-State" einlegen.

Daher meine Idee:
Mit jeder steigenden 150MHz-Flanke frage ich den Zustand des 75MHz-Takts 
ab.
Dann mein Zweifel:
Hab ich zum Zeitpunkt der 150MHz-Flanke überhaupt einen stabilen Zustand 
am 75MHz-Takt?
Offensichtlich nicht.

Eigentlich müßte der Code so aussehen:
1
if    (rising_edge(Clk150) and rising_edge(Clk75)) then ...
2
elsif (rising_edge(Clk150) and fallng_edge(Clk75)) then ...

Lothar Miller schrieb:
> Denn du kannst ganz problemlos Signale zwischen zwei per DCM
> erzeugten Domänen hin- und her übertragen. Die Toolchain sorgt (bei
> angegebenem Constraint auf den Basistakt) für die Überwachung der
> Laufzeiten...
Wenn ich Dich richtig verstehe, heißt das:
Eigentlich hab ich eine Setup/Hold-Verletzung, aber die Toolchain ist 
clever genug, um das zu berücksichtigen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Udo Weizenheim schrieb:
> Eigentlich müßte der Code so aussehen:
1
  if    (rising_edge(Clk150) and rising_edge(Clk75)) then ...
2
  elsif (rising_edge(Clk150) and falling_edge(Clk75)) then ...
3
  end if;
Ich vermute, eigentlich müsste dein Code so aussehen:
1
  if    rising_edge(Clk75) then ...
2
  elsif falling_edge(Clk75) then ...
3
  end if;
Und der Witz: das geht sogar, wenn man weiß, was dabei erlaubt ist... 
;-)
Das hatten wir letzhin im 
Beitrag "Re: Seriell-Parallel-Wandlung mit VHDL"

Udo Weizenheim schrieb:
> Das Problem ist jetzt folgendes:
> Wenn ein 8-Bit-Daten-Paket dann beginnt, wenn auch der 75MHz-Clock eine
> steigende Flanke hat, ist alles gut.
> Wenn ein 8-Bit-Daten-Paket aber dann beginnt, wenn der 75MHz-Clock
> gerade eine fallende Flanke hat, muß ich die Daten zwischenpuffern und
> quasi einen "Wait-State" einlegen.
Dann hast du eigentlich kein Problem, nur ist eben der betroffene 75MHz 
Pfad ebenfalls mit 150MHz zu constrainen. Dann haben eben die "zweiten" 
8-Bit nur 6,6ns (statt der 13,3ns) Zeit bis zum Ausgang.

Allerdings ist es bei solchen Taktraten eh' sinnvoll, sowohl den Eingang 
wie auch den Ausgang zu registieren, damit die FFs im IOB verwendet 
werden. Sonst bekommst du da nie ein brauchbares Timing hin...

> Lothar Miller schrieb:
>> Denn du kannst ganz problemlos Signale zwischen zwei per DCM
>> erzeugten Domänen hin- und her übertragen. Die Toolchain sorgt (bei
>> angegebenem Constraint auf den Basistakt) für die Überwachung der
>> Laufzeiten...
> Wenn ich Dich richtig verstehe, heißt das: Eigentlich hab ich eine
> Setup/Hold-Verletzung, aber die Toolchain ist clever genug, um das
> zu berücksichtigen.
Richtig, zum Preis einer viel höheren "virtuellen" Taktfrequenz bei 
ungünstigen Verhältnissen: wenn du z.B. 150MHz (6,666ns) über einen DCM 
auf 100MHz (10ns) wandelst (3:2), dann hast du beim Domänenübergang eine 
"virtuelle" Taktfrequenz von 300MHz (10ns-6,666ns). Und da tut sich die 
Toolchain dann schon mal schwer...

von Udo Weizenheim (Gast)


Lesenswert?

Lothar Miller schrieb:

> Ich vermute, eigentlich müsste dein Code so aussehen:
1
   if    rising_edge(Clk75) then ...
2
   elsif falling_edge(Clk75) then ...
3
   end if;
> Und der Witz: das geht sogar, wenn man weiß, was dabei erlaubt ist...
> ;-)

Ja natürlich, Du hast absolut recht!
Ich bin überhaupt nicht auf die Idee gekommen, daß ich ja wirklich auf 
die fallende Flanke triggern kann (obwohl ich es auch noch 
hingeschrieben hab, schön blöd...).
Aus irgendeinem Grund dachte ich, daß immer nur auf die steigende Flanke 
triggern kann und daher den doppelte Takt (150MHz) nehmen muß.


> Richtig, zum Preis einer viel höheren "virtuellen" Taktfrequenz bei
> ungünstigen Verhältnissen: wenn du z.B. 150MHz (6,666ns) über einen DCM
> auf 100MHz (10ns) wandelst (3:2), dann hast du beim Domänenübergang eine
> "virtuelle" Taktfrequenz von 300MHz (10ns-6,666ns). Und da tut sich die
> Toolchain dann schon mal schwer...
Das war mir so auch noch nicht bewußt.

Danke Dir!

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

Lothar Miller schrieb:
> Denn du kannst ganz problemlos Signale zwischen zwei per DCM
>
> erzeugten Domänen hin- und her übertragen. Die Toolchain sorgt (bei
>
> angegebenem Constraint auf den Basistakt) für die Überwachung der
>
> Laufzeiten...

Ich hätte erwartet, dass du aus Deiner Erfahrung heraus eher das 
Gegenteil empfiehlst, denn bei der (unnötigen!) clock-domain crosserei 
kommt der Jitter zweimal ins Spiel und liefert am Ende ein Design mit 
etwas reduzierter Frequenz.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

R. K. schrieb:
> dass du aus Deiner Erfahrung heraus eher das Gegenteil empfiehlst
Das war nicht die zugrundeliegende Frage. Meine Postulate gelten nach 
wie vor. Es ging mir hier um die prinzipielle Machbarkeit...

> denn bei der (unnötigen!) clock-domain crosserei
Bei den angegebenen Frequenzen (150MHz und 75MHz) wird doch nirgends 
eine Taktdomäne gekreuzt. Die beiden sind voneinander 
abgeleitet/abhängig und soweit recht gut bekannt. Das bisschen Jitter, 
das der DCM da reinbringt, fällt nicht nennenwert ins Gewicht...

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.