Forum: FPGA, VHDL & Co. FPGA Synchronisation


von Philipp S. (Gast)


Lesenswert?

Ich möchte in einem getakteten Prozess ein externen signal einlesen, 
welches als trigger für einen ADC im fpga dient. Dieser trigger kommt 
von extern und ist asynchron. Der Prozess läuft mit 60MHz. Muss ich 
solche Signale synchronisieren? Im schlimmsten Fall kann doch passieren, 
dass der etwas zu spät erkannt wird, was mir egal ist, denn der trigger 
ist deutlich langsamer als der ADC.

von rossi (Gast)


Lesenswert?

Du musst vor allem sicherstellen, dass das externe Signal nur mit genau 
einem Register in die 60 Mhz Taktdomäne übernommen wird. Zwei Register 
direkt hintereinander schaden auch nicht. Metastabilität ist aber nicht 
wirklich ein relevantes Problem. Erst nach dem Samplen kannst du das 
synchronisierte Signal an beliebig viel weitere Logik verteilen.

Welchen FPGA verwendest Du?

von Vancouver (Gast)


Lesenswert?

rossi schrieb:
> Metastabilität ist aber nicht
> wirklich ein relevantes Problem.

Metastabilität hat mich schon zu viele Stunden bei der Fehlersuche 
gekostet, als dass ich diese Aussage noch unterstützen könnte. Es ist 
'Best Practice', asynchrone Signale immer über zwei Registerstufen 
einzusamplen. Das kostet praktisch keine Ressourcen und das Thema MS ist 
damit statistisch für die nächsten 100000 Jahre vom Tisch.

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


Lesenswert?

Vancouver schrieb:
> Metastabilität hat mich schon zu viele Stunden bei der Fehlersuche
> gekostet, als dass ich diese Aussage noch unterstützen könnte.
Allerdings wird richtige Metastabilität eben oft mit fehlendem 
Einsynchronisieren verwechselt. Heute sind Flipflops im FPGA nach ein 
paar ns sicher irgendwo hingekippt und nicht mehr zwischen 0 und 1 
floatend:

http://www.lothar-miller.de/s9y/archives/62-Testaufbau-Metastabilitaet.html

> Es ist 'Best Practice', asynchrone Signale immer über zwei
> Registerstufen einzusamplen.
Das Hauptproblem (das hier auch immer wieder aufschlägt) sind fast 
ausschließlich solche Effekte mit unterschiedlichen Laufzeiten von nicht 
synchronisierten Eingangssignalen im FPGA:

http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html

Und die Ausrede: "Ich habe da gar keine FSM!" fällt dann meist ganz 
schnell, wenn man sich vergegenwärtigt, dass auch schon ein simpler 
Zähler ein Zustandsautomat ist...

rossi schrieb:
> dass das externe Signal nur mit genau einem Register in die 60 Mhz
> Taktdomäne übernommen wird.
Und weil sich da ggfs. der Synthesizer mit per Register-Duplication doch 
Freiheiten herausnimmt, sind 2 Register hintereinander der Weg zum Ziel. 
Denn dann wird das erste FF sicher nicht dupliziert und es gibt nur 1 
Laufzeit bis zum 1. Register. Ab da kann dann beliebig dupliziert 
werden.

Philipp S. schrieb:
> Ich möchte in einem getakteten Prozess ein externen signal einlesen
Du denkst in Software. Ein Prozess "liest" kein Signal ein. Sondern ein 
Prozess beschreibt bestenfalls ein Flipflop, das den Zustand eines 
externen Signals abhängig von einem internen Takt speichern soll.

: Bearbeitet durch Moderator
von Messtechnikprofi (Gast)


Lesenswert?

Lothar M. schrieb:
> Allerdings wird richtige Metastabilität eben oft mit fehlendem
> Einsynchronisieren verwechselt.
Den Eindruck habe ich auch. Jeder bachelor der mal etwas von FPGAs 
gehört hat, bekommt von seinem schlecht informierten 
Was-bin-ich-so-stolz-dass-ich-mich-Professor-nennen-darf Lehrmeister an 
der dualen Hochschule etwa von Meta erzählt und findet es toll, dass er 
es bekämpfen kann.

Dabei wird verkannt, dass es oft falsch einsynchronisierte Busse und 
Signalgruppen sind, deren Zustand durch ein scheinbar technisch 
richtiges- aber aus Logiksicht unzureichendes Eintakten zerpflückt wird.

Schlecht, wenn man nicht in der Lage ist, Problemstellungen zu erfassen 
und einzuordnen.

> Heute sind Flipflops im FPGA nach ein
> paar ns sicher irgendwo hingekippt und nicht mehr zwischen 0 und 1
> floatend

"Picosenkunden" wolltest du sicher schreiben. Nano wäre etwas langsam 
:-)

von Vancouver (Gast)


Lesenswert?

Ja, vermutlich ist die fehlende Synchronisation meistens die 
Fehlerursache. Aber wir hatten vor einigen Jahren im Labor mal echte 
Metastabilität fabriziert, auf einem Virtex-5, der CPU-Steuersignale in 
eine 100MHz-Domain einsamplen sollte. Hin und wieder erschien satt des 
Signalzustandes auf dem Logi völlig wirres Zeug und der FPGA verhielt 
sich teilweise, sagen wir... indeterministisch und die Stromaufnahme 
stieg drastisch an. Eine FSM blieb z.B. in einem ungültigen Zustand 
hängen usw. Blieb nur der Reset. Das Problem verschwand, nachdem ich 
meine Hausaufgaben gemacht und alle Signale 2-stufig einsynchronisiert 
hatte.

Das Problem mit der Metastabilität ist, dass sie sich, auch wenn sie nur 
kurz dauert, mit einer gewissen Wahrscheinlichkeit in die nächste Stufe 
überträgt und dann zur Logik-Demenz führt.

von rossi (Gast)


Lesenswert?

Vancouver schrieb:
> Das Problem mit der Metastabilität ist, dass sie sich, auch wenn sie nur
> kurz dauert, mit einer gewissen Wahrscheinlichkeit in die nächste Stufe
> überträgt und dann zur Logik-Demenz führt.

"Kurz" sind aber wirklich nur Nanosekunden oder noch viel weniger. Schon 
1997 hat Xilinx bei damals aktuellen FPGAs in 0.5 Mikron Technik keine 
Probleme bei < 100 MHz Takt gesehen. [XAPP 094 November 24, 1997 
(Version 2.1)] Da war der metastabile Zustand lange aufgelöst, bevor die 
nächste Taktflanke kommt.

Das echte Problem ist die automatische Register-Duplizierung, die Lothar 
M. angesprochen hat und das selbst bei trivialen Sachen das asynchrone 
Signal einen Fanout größer 1 hat.
1
process(clk)
2
begin
3
  if rising_edge(clk) then
4
    if (trigger_async = '1') then
5
      next_adc_sample <= adc_data(15 downto 0);
6
    end if;
7
  end if;
8
end process;
Sowas kann schon schief gehen, wenn trigger_async zu unterschiedlichen 
Zeiten an den einzelnen Registern für die Bits ankommt.

von Ole W. (ole_w)


Lesenswert?

Also wenn du Vivado nutzt, dann gibt es da ganz händische Blöcke die das 
Einsynchronisieren für dich gleich übernehmen.
1
  xpm_cdc_async_rst_inst : xpm_cdc_async_rst
2
  GENERIC MAP(
3
    DEST_SYNC_FF => 4, -- integer;
4
    INIT_SYNC_FF => 0, -- integer; 
5
    RST_ACTIVE_HIGH => 1 -- integer; 
6
  )
7
  PORT MAP(
8
    src_arst => FPGA_RESET_ASYNC
9
    dest_clk => FPGA_MAIN_CLK,
10
    dest_arst => FPGA_RESET_SYNC
11
  );

Hat für mich den Job bis jetzt wunderbar erledigt.

Gruß,
Ole

von rossi (Gast)


Lesenswert?

Wenn man Vivado verwendet, kann man das Attribut ASYNC_REG für die 
Register in einer Synchronisierungskette setzen. Das sorgt dafür, das 
die Register nicht wegoptimiert werden und nahe beieinander platziert 
werden.

https://www.xilinx.com/content/dam/xilinx/support/documents/sw_manuals/xilinx2021_2/ug912-vivado-properties.pdf

von Martin S. (strubi)


Lesenswert?

Fuer externe (!) Triggereingaenge nehme ich gerne sowas (allerdings 
architekturabhaengig):
1
entity pulsestrobe is
2
    port (
3
        trigger : in std_ulogic;
4
        strobe : out std_ulogic;
5
        en : in std_ulogic;
6
        clk : in std_ulogic
7
    );
8
end entity pulsestrobe;
9
10
architecture myhdl_emulation of pulsestrobe is
11
    -- Local type declarations
12
    -- Signal declarations
13
    signal pset : std_ulogic := '0';
14
    signal pout : std_ulogic := '0';
15
    signal clk_fb97 : std_ulogic;
16
    signal reset : std_ulogic;
17
begin
18
    
19
trigger_strobe:
20
    process(clk_fb97, reset)
21
    begin
22
        if reset = '1' then
23
            pset <= '0';
24
        elsif rising_edge(clk_fb97) then
25
            if (en = '1') then
26
                pset <= '1';
27
            end if;
28
        end if;
29
    end process;
30
    
31
trigger_ff:
32
    process(clk)
33
    begin
34
        if rising_edge(clk) then
35
            pout <= pset;
36
        end if;
37
    end process;
38
    clk_fb97 <= trigger;
39
    reset <= pout;
40
    strobe <= pout;
41
end architecture myhdl_emulation;

Nimmt allerdings auch jeden Glitch mit und 'verschwendet' allenfalls 
etwas Clock-Routing-Resourcen, somit ist es nicht optimal portabel. MS 
kann natuerlich von pset -> pout noch auftreten.
Ansonsten moechte man vielleicht sowieso entprellen, damit hat sich 
obige Thematik erledigt.

von Hannes B. (Gast)


Lesenswert?

Mach dir doch nicht ins Hemd wegen Trigger glitches. Da passiert nichts 
und da muss auch nichts einsynchronisiert werden. EInen Trigger in einem 
getakteten Prozess zu nutzen ist vollkommen in Ordnung.

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.