Normalerweise initialisiere ich Statusregister meiner FSMs durch Angabe eines Anfangswertes in meinem VHDL-Code, sodass ich nach dem Start des konfigurierten FPGA keinen Rücksetzimpuls benötige. Das folgende Beispiel zeigt dies durch einen "Ringzähler", der nur alle Zustandsregister zusammenführt:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter_init is
port (
clock : in std_logic;
msb : out std_logic);
end entity counter_init;
architecture rtl of counter_init is
-- large counter to detect excessive skew on Global Write Enable (GWE)
signal counter : unsigned(255 downto 0) :=
x"55555555_55555555_55555555_55555555_55555555_55555555_55555555_55555555";
begin -- architecture rtl
counter <= counter(0) & counter(counter'left downto 1) when rising_edge(clock);
-- The counter value will be observed by an on-chip logic analyzer.
-- Output most-significant bit to prevent synthesizing away the above logic.
msb <= counter(counter'left);
end architecture rtl;
Diese Technik hat in meinen Entwürfen für Altera- oder Xilinx-FPGAs bisher funktioniert. Ich habe es explizit mit dem herstellerspezifischen On-Chip-Logikanalysator und einem Startauslöser überprüft. Hier ist ein Screenshot von ChipScope, ok, ein Zyklus wird anscheinend verpasst:
Aber nachdem ich die Dokumente gelesen habe, frage ich mich, wie es funktioniert: Wie beginnen alle Flip-Flops (die mit demselben Taktsignal verbunden sind) gleichzeitig umzuschalten?
Die Startsequenz für ein Xilinx-FPGA ist beispielsweise im 7 Series FPGAs Configuration User Guide (UG470) beschrieben . Nach der Konfiguration des FPGA wird eine Startsequenz ausgeführt, die eine "Global Write Enable (GWE)" bestätigt. Tabelle 5-12 :
Wenn aktiviert, aktiviert GWE die CLB- und IOB-Flipflops sowie andere synchrone Elemente auf dem FPGA.
und in der Fußnote:
GWE wird synchron zur Konfigurationsuhr (CCLK) aktiviert und weist einen signifikanten Versatz über das Teil auf. Daher werden sequentielle Elemente nicht synchron zur Systemuhr des Benutzers freigegeben, und beim Start können Zeitverletzungen auftreten. Es wird empfohlen, das Design nach dem Start zurückzusetzen und / oder eine andere Synchronisationstechnik anzuwenden.
Das bedeutet also tatsächlich: Wenn die Uhr an den Flip-Flops bereits umschaltet, können alle Flip-Flops zu unterschiedlichen Zeiten / Taktflanken umschalten. Vorausgesetzt, der Taktoszillator auf der FPGA-Karte läuft bereits und ich verwende einen globalen Taktpuffer ohne Freigabeeingang ( BUFG
): Schaltet der Takteingang an den Flip-Flops bereits um, bevor GWE aktiviert wird?
Ich habe in UG470 keine Informationen darüber gefunden, ob und wie Taktpuffer aktiviert sind. Im Handbuch für alle programmierbaren SoC-Bibliotheken der Xilinx 7-Serie für FPGA und Zynq-7000 für HDL-Designs (UG768) heißt es nur, dass der Taktfreigabeeingang von a BUFGCTRL
synchron aktiviert werden muss. Dies ist jedoch tatsächlich eine benutzergesteuerte Eingabe.
Für das Altera Cyclone III FPGA, das ich ebenfalls verwende, habe ich im Cyclone III-Gerätehandbuch keine relevanten Informationen gefunden .
Um es zu wiederholen: Ich habe bisher keine fehlgeschlagene Initialisierung beobachtet, aber dies scheint in den Dokumenten nicht angegeben zu sein.
quelle
Antworten:
Sie sollten davon ausgehen, dass der Takteingang Ihrer Flip-Flops umschaltet, sofern Sie nichts anderes beweisen können (durch eine garantierte Einschalt- oder Nachkonfigurationsverzögerung). Es ist nicht garantiert, dass alle Flip-Flops in einer bestimmten Taktdomäne auf derselben Taktflanke basierend auf GWE oder GSR starten. Beide wirken wie ein asynchroner Reset und verursachen potenzielle Probleme für einige Logikfunktionen (Zähler, One-Hot-State-Maschinen usw.).
Insbesondere eine One-Hot-State-Machine, die unmittelbar nach der Konfiguration übergeht, wird (eventuell) fehlschlagen (Übergang in einen ungültigen Zustand). Die Häufigkeit des Ausfalls hängt von der Taktperiode im Vergleich zum gerätespezifischen (und orts- und routenspezifischen) Versatz für Ihr Design ab.
Ein weiteres einfaches Experiment, um zu sehen, wie dieses Verhalten einen relativ schnellen Countdown-Zähler mit 10000000 initialisiert und sein Verhalten unmittelbar nach der Konfiguration überprüft. Einige Bits machen den Übergang zu 01111111 und einige Bits verpassen diesen ersten Übergang, aber die nachfolgende Zählsequenz ist korrekt.
Das Weißbuch erwähnt von Krunal Desai spricht über dieses Problem und ist eine große Referenz. Jedes SRAM-basierte FPGA hat höchstwahrscheinlich ein ähnliches Problem.
Es ist nicht erforderlich, die Register zurückzusetzen, um einen bekannten Wert zu erhalten. Wenn Sie eine Logik haben, die für alle empfindlich ist, die mit derselben Taktflanke beginnen, muss eine Synchronisationslogik hinzugefügt werden (dies kann aus einem synchron deaktivierten Reset oder einer anderen synchronen Logik bestehen). Xilinx AR44174 spricht etwas mehr über das Problem. Ich würde eine dritte Methode zur Schadensbegrenzung hinzufügen, die sicherstellen soll, dass sich die getaktete Logik während der ersten paar Taktzyklen nach dem Start nicht ändert / übergeht.
quelle
Für Xilinx-FPGAs bestätigt der Antwortdatensatz AR # 44174 Folgendes :
Wir haben also zwei Möglichkeiten:
Wenn im Design kein externer Reset- Eingang erforderlich ist, ist Lösung 1 im Antwortdatensatz für Xilinx-FPGAs hilfreich.
Ich habe diese Lösung ausprobiert, aber Chipscope hat festgestellt, dass nicht alle Flip-Flops gleichzeitig umschalten. Es scheint, dass die synchrone Aktivierung
CE
des Clock-Enable-Pins desBUFGCE
nicht so einfach ist.Ich empfehle stattdessen die zweite (folgende) Technik. Anstelle eines externen Resets (
reset_pin
unten) muss nur eine '0' Null (kein Reset) in den Reset-Synchronisierer eingespeist werden.Wenn es ohnehin zu einem externen Reset kommt , kann der Reset-Synchronisierer so initialisiert werden, dass ein Reset aktiviert wird, nachdem GWE oder ähnliches während der Startsequenz aktiviert wurde. Der Reset-Synchronisierer startet die Freigabesequenz nicht (dh Flip-Flops, die in Richtung '0' umschalten), bis GWE aktiviert ist. Die Dauer der Freigabesequenz muss länger sein als der Versatz auf der GWE. Diese Lösung funktioniert auf Xilinx- und Altera-FPGAs.
Erklärungen:
Architekturkörper (Registerkette):
Natürlich muss die Zählerlogik jetzt zurückgesetzt werden:
Der Screenshot unten zeigt Fehler aufgrund der asynchronen Zusicherung von GWE. Um diese zu provozieren, habe ich die Signalinitialisierung weggelassen, so dass alle Zähler-Flip-Flops während der Konfiguration auf '0' initialisiert wurden. Wie
reset
von Anfang an behauptet, würde man erwarten, dass sich alle Flip-Flops mit der ersten ansteigenden Taktflanke auf den angeforderten Rücksetzwert ändern, nachdem GWE aktiviert wurde. Zum Zeitpunkt 0 (T-Marker) ist der Zählerwert jedoch keine Folge von x "5". Aufgrund der Rücksetzkette wird der erwartete Rücksetzwert wiederhergestellt. Der Reset wird in Zyklus 2 (X-Marker) freigegeben, so dass alle Flip-Flops in nachfolgenden Zyklen umschalten. Die Taktfrequenz beträgt hier 200 MHz.quelle