CDC-Synchronisationsprimitive für ein Altera-FPGA

Ich arbeite an meinem ersten nicht-trivalen FPGA-Design und brauche endlich Clock Domain Crossing (CDC).

Es gibt mehrere Ressourcen ( unter anderem ), die verschiedene Architekturen für CDC und einige damit zusammenhängende Fragen diskutieren . Die Theorie ist in Ordnung, aber mindestens eine dieser Ressourcen listet Fallen für Unvorsichtige auf, und mindestens ein Projekt listet mehrere VHDL-Attribute auf, die für eine korrekte Synthese auf einem Xilinx-Gerät erforderlich sind.

Ich ziele auf den Altera MAX10 für dieses Projekt mit VHDL ab. Ich habe einen Push-Handshake-Synchronisierer von Hand codiert, aber ich vermute irgendwie, dass mehr dahinter steckt.

So:

  • Stellt Altera (oder eine andere angesehene Quelle) eine Bibliothek mit Synchronisationsprimitiven zur Verfügung?
  • Wenn nicht, welche Schritte müssen unternommen werden, um sicherzustellen, dass ein handgeschriebener Synchronisationsblock korrekt synthetisiert, korrekt simuliert und einer korrekten Zeitanalyse unterzogen wird?

Eine Antwort mit einem Beispiel für einen einfachen Synchronisierer (z. B. 2-Flop) wäre wünschenswert.

Welche Art von Signal möchten Sie synchronisieren? Ein Strobe, ein Flag, ein Zählerwert, ein Bitvektor oder etwas Komplexeres?
Ein std_logic_vetor. Ich habe naiverweise den vierphasigen Handshaking-Synchronisierer aus diesem Artikel implementiert , der korrekt simuliert, aber ich bin nicht überzeugt, dass ich dem FPGA alles "gesagt" habe, was es wissen muss, um korrekt zu synthetisieren.
Siehe diese Frage , wo eine Antwort mehrere Altera-Attribute für die Synchronisierung auflistet.
Ich habe die Synchronizer-Module in unserer PoC-Library aktualisiert und die ersten Änderungen auf GitHub hochgeladen. Danke für den Link zu den Attributen von Altera. Ich werde es in einem Stratix IV-Design testen und meinen Beitrag aktualisieren, wenn alles wie erwartet funktioniert. Derzeit stürzt mein Design Quartus ab, sodass es schwierig ist, die fehlerhafte Codezeile zu finden (Xilinx kompiliert meine VHDL-Dateien ohne Beanstandungen).
Hallo wieder. Ich habe die PoC-Quellen und meine Antwort aktualisiert, um die Altera-spezifischen Synchronisierer anzusprechen. Derzeit arbeiten diese Schaltungen in einem StratixIV-Design auf einem DE4-Board.

Antworten (1)

Der vorgestellte Vierphasen-Synchronisierer ist eine gute und korrekte Implementierung.

Es hat nur einen Nachteil:
Es hat einen VEingang, um dem Synchronisierer geänderte Eingänge mitzuteilen.

Dies kann durch ein n-Bit-Register in der Quelltaktdomäne und einen n-Bit-Komparator automatisiert werden: Wenn sich die Eingabe geändert hat, bestätigen Sie V=1.

Input_d  <= Input when rising_edge(Clock);
V        <= '1' when (Input_d /= Input) else '0';  -- input changed

Die Implementierung eines 2-FF-Synchronisierers – der Kern jedes Synchronisierers höherer Ebene – mit den erforderlichen Attributen und Einschränkungen kann wie folgt gefunden werden:

Was ist so besonders im Vergleich zu normalen Doppel-Flip-Flops?

  1. Es deaktiviert die Schieberegisterextraktion ( SHREG_EXTRACT = NO). Synthesis versucht, Ketten von Flip-Flops zu finden und sie in dedizierte Schieberegister wie Xilinx zu stecken SRL32. Diese dedizierten Shifter sind nicht gut für metastabile Eingänge.
  2. Markieren Sie die Register als asynchrone Register ( ASYNC_REG = TRUE). Dies wird für Post-Synthese-Simulationen benötigt, um metastabile Werte zu unterdrücken.
  3. Legen Sie Register nebeneinander ( RLOC = X0Y0). Dadurch wird der 2-FF-Synchronisierer in dieselbe Scheibe platziert.
  4. Die Flip-Flops haben eindeutige Namen und werden in eine spezielle Timing-Gruppe namens METASTABILITY_FFS. Xilinx-Einschränkungen:

    INST "*FF1_METASTABILITY_FFS"   TNM = "METASTABILITY_FFS";
    

    Alle Timing-Pfade von einem normalen FF zu einem metastabilen FF werden über die TIGBeschränkung ignoriert.

    NET "*_async"       TIG;
    INST "*_meta*"  TNM = "METASTABILITY_FFS";
    TIMESPEC "TS_MetaStability" = FROM FFS TO "METASTABILITY_FFS" TIG;
    

    Quellen: sync_Bits_Xilinx.ucf , Metastability.ucf

Bearbeiten: Altera-spezifischer 2-FF-Synchronizer:

Ich habe der generischen 2-FF- Implementierung eine neue Generate-Anweisung hinzugefügt, um eine Altera-spezifische Implementierung auszuwählen: sync_Bits_Altera.vhdl

Was ist so besonders an dieser Version?

  1. Beide Flipflops sind mit gekennzeichnet, PRESERVEum Optimierungen zu erschweren.
  2. Das erste / das metastabile Flip Flop ist kommentiert mit:

    attribute ALTERA_ATTRIBUTE of Data_meta     : signal is "-name SYNCHRONIZER_IDENTIFICATION ""FORCED IF ASYNCHRONOUS""";
    

    um diese Flip-Flops als Synchronisierschaltung zu markieren.

  3. Alle Pfade zu diesen Registern werden als gesetzt false_path:

    attribute ALTERA_ATTRIBUTE of rtl               : architecture is "-name SDC_STATEMENT ""set_false_path -to [get_registers {*|sync_Bits_Altera:*|\gen:*:Data_meta}] """;
    

    Dies ist die Inline-SDC-Einschränkungsannotationssyntax.

Synchronisierer höherer Ebene:

Natürlich hat die PoC-Library auch einen vordefinierten Synchronizer für Bitvektoren namens PoC.misc.sync.Vector , der auf dem generischen 2-FF-Synchronizer basiert. Wenn sich die Master-Bits ändern, werden alle Bits an die Empfänger-Taktdomäne übertragen.