Taktung FPGA/CPLD

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Einleitung

Von den drei Signalgruppen

  • interne Signale
  • IO Signale
  • Takt (Clock)

ist letztere die mit den höchsten Anforderungen an Signalqualität und Laufzeit. Fehler im Taktnetzwerk führen zu ungewolltem, ja oft katastrophalem Verhalten der Schaltung. Um dies zu vermeiden sind besondere Aufbauregeln und Komponenten für die Taktverteilung in digitalen ICs entwickelt worden.

Grundanforderungen Taktnetzwerk

Der Takt muss möglichst störungsfrei an alle getakteten Bauelemente (FlipFlops, RAMs) im IC geführt werden. Das Taktnetzwerk muss damit sehr viele Gatter-Eingänge treiben (einige Dutzend bis einige Hundertausend!). Dazu wird ein spezieller Takttreiber genutzt (Xilinx: BUFG). Die Laufzeit vom Eingang des Takttreibers zu jedem Endpunkt des Netzes muss gleich sein. Nur so ist gewährleistet, dass alle FlipFlops zum gleichen Zeitpunkt schalten und die Synchronität gewährleistet ist.

Der Laufzeitunterschied zwischen verschiedenen Endpunkten des Taktnetzes wird Skew genannt und muss sehr klein gehalten werden (bei modernen Digitalschaltkreisen kleiner 100 ps). Dazu wird das Taktnetzwerk als Baumstruktur gestaltet (gleiche Länge von der Baumwurzel zu jeder Astspitze). Man nennt diese Schaltungstechnik "Clock Tree".

Clock tree.png

In fast jeder Digitalschaltung kommt es nun vor, dass verschiedene Bereiche nicht bei jedem Takt eine Aktion ausführen sollen. Einige laufen sogar mit einer erheblich geringeren Taktrate als der Rest der Schaltung. Dazu muss aus dem relativ schnellen Systemtakt ein langsamer Takt gewonnen werden. Was auf den ersten Blick recht einfach aussieht, wird im Detail oft falsch gemacht.

Geschaltete Takte (Gated Clock)

Dieser Begriff bezieht sich auf geschaltete, also unterbrochene (engl. "gate"), Taktleitungen. Dies kann durch die Verwendung von:

  • Multiplexern (Auswahl zwischen Taktquelle 1 und 2)

oder

  • kombinatorischer Logik (Schaltungsteile werden unter bestimmten Bedingungen vom Takt getrennt)

geschehen.

Taktmultiplexer

Falls ein völliges Abschalten des Taktes wirklich erforderlich ist, z.B. um den Leistungsbedarf zeitweilig zu drosseln, sollte der Takttreiber selbst abgeschaltet werden. Bei Xilinx würde man statt eines BUFG einen BUFGMUX einsetzen. Dieser garantiert durch seinen speziellen Aufbau, daß während des Umschaltens keine Glitches entstehen.

Kombinatorik im Taktpfad

Ein solches Design ist aus zwei Gründen problematisch:

  • es entstehen neben den gewünschten Schaltflanken zusätzliche, ultrakurze Flanken (->Glitches)
  • der langsame Takt hat eine Phasenverschiebung zum schnellen Takt (-> Skew).

Im ersten Fall können durch die Glitches unerwünschte Schaltaktivitäten an FlipFlops in folgenden Schaltungsteilen ausgelöst werden. Das ist fatal! Schon deshalb ist diese Variante nicht brauchbar. Sie wurde dennoch oft in der Vergangenheit angewendet, weil die relativ langsamen ICs die Glitches gefiltert bzw. ignoriert haben. Doch heute sind CPLDs und FPGAs extrem schnell, dass man mit dieser Methode schnell scheitert.

[Glitches, Englisch]

Im zweiten Fall erfolgt durch Skew eine Verschiebung der Schaltzeiten im langsam getakteten Schaltungsteil, die weniger Zeitreserve für Signale lässt, die aus dem langsamen Schaltungsteil wieder in den schnellen Schaltungsteil übergeben werden sollen. In der anderen Richtung, vom schnellen zum langsamen Schaltungsteil, kommt es gar zu sog. Race-Conditions, wobei die Daten vom schnellen Schaltungsteil eher an den FlipFlops des langsamen Schaltungsteils ankommen als der langsame Takt! Damit läuft ein Design "komisch" weil scheinbar ein Takt fehlt. Das ist alles andere als zuverlässig und akzeptabel.

Derived Clock

Eine geringfügige Verbesserung des Gated Clock erreicht man durch das Anfügen eines FlipFlops hinter den kombinatorischen Dekoder. Durch diese Zwischenspeicherung wird der Takt zumindest frei von Glitches. Wenn im FPGA/CPLD nur ein langsamer Takt gebraucht wird, oder der langsame Schaltungsteil keine logische Verbindung zum schnellen Schaltungsteil hat, dann ist diese Lösung akzeptabel und sicher. Wenn jedoch zwischen dem langsamen Schaltungsteil und schnellen Schaltungsteil Daten oder Steuersignale ausgetauscht werden, dann muss man zu einer anderen Entwurfsmethode greifen.

Clock Enable

Jedes FlipFlop in FPGAs/CPLDs hat einen synchronen Steuereingang namens CE (Clock Enable). Damit kann man festlegen, ob das FlipFlop bei der nächsten Taktflanke neue Daten speichern oder die alten behalten soll. Da es sich um einen synchronen Eingang handelt, ist es vollkommen unkritisch, wenn diese Signal Glitches enthält. Es muss nur kurz von vor der Taktflanke (Setup Time, Aufbauzeit) bis kurz danach (Hold Time, Haltezeit) stabil anliegen. Eine Verschiebung dieses Signals zum Takt ist auch unkritisch, denn jedes normale Steuersignal ist phasenverschoben zum Takt (Schaltzeit der FlipFlops, Durchlaufzeit der Logik, Laufzeit der Verdrahtung (Routing)). Das CE-Signal kann von der Entwurfssoftware wie ein normales Steuersignal behandelt werden und vereinfacht damit erheblich die automatische Analyse der maximalen Schaltfreqeunz (Timing Analyses).

Beispiele

Im nachfolgenden Bild sind alle drei Typen von Takt kurz skizziert. Der schnelle Takt treibt einen 4Bit Zähler (CNT1). Dessen Ausgänge werden über eine UND-Gatter (Gate1) kombinatorisch verknüpft. Der Ausgang des UND-Gatters ist nur dann HIGH, wenn alle Eingänge HIGH sind. Das ist nur einmal alle 16 Takte der Fall, wenn der Zählerstand binär 1111 erreicht ist. Dieses Signal als Takt zu verwenden wäre sträflich, denn es ist ein Gated Clock. Wenn er jedoch noch einmal mittels FlipFlop (FF1) zwischengespeichert wird ist es ein Derived Clock. Der beste und sinnvollste Weg ist jedoch die Verwendung des CE-Eingangs der FlipFlops (FF2) wie es ganz unten im Bild dargestellt ist.

Clock types.png

Umsetzung in VHDL

<vhdl> -- Die Verwendung von "Clock Enable" in VHDL -- die Signale clk und ce sind hier natürlich nur Beispiele -- es kann dafür jeder beliebige Signalname verwendet werden

-- Das hier muss in die Signaldeklaration zwischen -- achitecture ... und begin

constant cnt_div: integer:=16; -- Teilerverhältnis signal cnt: integer range 0 to cnt_div-1; -- Zähler für Teiler signal ce: std_logic;

-- die Prozesse logischerweise nach begin der Achritecture

-- Prozess mit langsamen Clock Enable

process(clk) begin

 if rising_edge(clk) then
   if ce='1' then
   -- Aktionen hier einfügen, welche mit langsamen Takt laufen    
   end if;
 end if;

end process;

-- Clock Enable Generator

process(clk) begin

 if rising_edge(clk) then
   if cnt=cnt_div-1 then
     ce  <= '1';
     cnt <= 0;
   else
     ce  <= '0';
     cnt <= cnt +1 ;
   end if;
 end if;

end process;

</vhdl>

Clock Skew

Mithilfe der clock skew Einstellung kann ein Synthesewerkzeug angewiesen werden, den Zeitpunkt der Taktflanke entsprechend den Erfordernissen der Schaltungsverzögerungen einzustellen. Dies schafft mehr Reserven.