Wie könnte ein einfacher Aufbau aussehen, um Metastabilität darzustellen? Ein Eingangssignal wird auf ein Flipflop ffS eingelesen und der Ausgang dieses ffS parallel auf 2 Flipflops (ffA und ffB) eingetaktet. Die Ausgänge dieser beiden Flipflops werden auf Gleichheit des eingetakteten Signals verglichen und bei unterschiedlichen Werten ein Zähler hochgezählt, der dann auf LEDs ausgegeben wird.

Falls die beiden FFs die gleichen Werte einlesen, wird auch am Ende der Schieberegisterkette immer der selbe Wert herauskommen, und der Zähler wird nicht hochzählen.
Wenn aber die beiden FFs unterschiedliche Werte einlesen, weil das ffS metastabile Zustände annimmt, dann wird der Zähler Werte ungleich 0 anzeigen. In der Verhaltenssimulation kann ein solcher Fehler nicht gefunden werden.
Und dazu die VHDL-Beschreibung
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Metastable is
Port ( clk : in STD_LOGIC;
inp : in STD_LOGIC;
leds : out STD_LOGIC_VECTOR (7 downto 0));
end Metastable;
architecture Behavioral of Metastable is
signal ffS : std_logic := '0';
signal ffA : std_logic := '0';
signal ffB : std_logic := '0';
signal cnt : unsigned(7 downto 0) := (others=>'0');
begin
process begin
wait until rising_edge(clk);
ffS <= inp; -- Sync-Flipflop
ffA <= ffS;
ffB <= ffS;
end process;
process begin
wait until rising_edge(clk);
if (ffA /= ffB) then
cnt <= cnt+1;
end if;
end process;
leds <= std_logic_vector(cnt);
end Behavioral;
Allerdings ergibt sich mit den Standardeinstellungen folgendes Ergebnis:
INFO:Xst:2261 - The FF/Latch <ffA_3> in Unit <Metastable> is equivalent to the following FF/Latch, which will be removed : <ffB_3>
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch <cnt_7> has a constant value of 0 in block <Metastable>.
WARNING:Xst:2677 - Node <sr1_0> of sequential type is unconnected in block <Metastable>.
# Counters : 1
8-bit up counter : 1
# Registers : 1
Flip-Flops : 1
# Xors : 1
1-bit xor2 : 1
Und quasi als Ausrufezeichen:
Clock Information: No clock signals found in this design
Die Synthese hat also erkannt, dass beide Flipflops ffA und ffB das selbe machen. Sie hat eines der beiden Register herausoptimiert und dann ermittelt, dass der Vergleicher überflüssig, und damit der Ausgangswert für die LEDs immer 0 ist.
Also muß erst mal das Wegoptimieren des Schieberegisters unterbunden werden.
Der Versuch, das Attribut KEEP auf die Schieberegister anzuwenden, funktioniert nicht.
Erst das Ändern der Syntheseoption --> Xilinx Specific Options --> Equivalent Register Removal auf unchecked ergibt dieses Ergenbis:
# Registers : 11
Flip-Flops : 11
Erst mit dieser Einstellung werden auch tatsächlich 3 Flipflops und der 8-Bit-Zähler implementiert.
Mit diesem Aufbau wird erkennbar, dass bei handelsüblichen Taktfrequenzen (<100MHz) der Zähler nichts zu tun hat. Es werden keine metastabilen Zustände erkannt. Bis zur jeweils nächsten Taktflanke hat sich am Ausgang des ffS ein stabiler Pegel eingestellt.
Erst bei sehr hohen Taktfrequenzen (>300MHz) zählt der Zähler cnt ab und zu hoch. Xilinx sagt in der AppNote XAPP094 dazu, dass aktuelle FFs in FPGAs sehr schnell sind und sich Metastabilität erst bei sehr hohen Taktfrequenzen bemerkbar machen kann.
Wer jetzt aber meint, externe Signale nicht mehr einsynchronisieren zu müssen, geht auf dem Holzweg. Denn was sich durchaus signifikant bemerkbar macht, sind Laufzeitunterschiede im Routing eines Signals. Hier lassen wir das Synchronisierungs-FF einfach mal weg
architecture Behavioral of Metastable is
signal ffA : std_logic := '0';
signal ffB : std_logic := '0';
signal cnt : unsigned(7 downto 0) := (others=>'0');
begin
process begin
wait until rising_edge(clk);
ffA <= inp;
ffB <= inp;
end process;
process begin
wait until rising_edge(clk);
if (ffA /= ffB) then
cnt <= cnt+1;
end if;
end process;
leds <= std_logic_vector(cnt);
end Behavioral;
Und mit dieser Implementation ist dann in der realen Hardware zu sehen, dass der Zähler bei Änderungen des Signals inp doch recht oft hochzählt. Es wird also, obwohl beide Schieberegister das selbe Eingangssignal erhalten, manchmal ein unterschiedlicher Pegel erkannt. Dies kann leicht anhand des Schaltplans erkannt werden.

Wenn die Schaltung jetzt nicht so einfach wäre, sondern z.B. eine Statemachine, dann würden diese beiden Komponenten ab und zu ein unterschiedliches Eingangssignal sehen und entsprechend falsch reagieren. Dazu näheres und ein anschauliches Beispiel im folgenden Beitrag.
Fazit: Weil Metastabilität ein statistischer Prozess ist und eigentlich 1 Flipflop schon reichen würde, aber Ingenieure gerne 100% Sicherheit einkalkulieren, gilt
Jedes asynchrone Signal sollte über mindestens zwei Flipflops eingetaktet werden.







