Entwerfen Sie die Praxis, Taktdomänen und asynchrone Signale zu kreuzen

Ich habe einige Projekte auf verschiedenen FPGAs in VHDL entworfen, und es scheint, dass meine häufigste Quelle für "schwer zu findende Fehler" darin besteht, dass ich vergesse, ein asynchrones Signal zu synchronisieren oder vergesse, ein Signal, das Taktdomänen überschreitet, neu zu synchronisieren.

Meine bisher beste Waffe war es, Blockschaltbilder der Komponenten zu zeichnen.

Meine Frage ist also, was ist die beste Designpraxis, um diese Fehler zu vermeiden?

Antworten (3)

Heutzutage können sogar FPGA-Designs extrem komplexe Taktarchitekturen und viele asynchrone Eingänge haben, was zu vielen potenziellen CDC-Problemen führt.

Ich würde sagen, dass die folgenden Punkte einen minimalen Satz von "Faustregeln" darstellen, um CDC-Fehler zu vermeiden:

  1. Verfolgen Sie alle Signale, die Taktdomänen überschreiten (Diagramme, Listen, Tabellenkalkulationen - was immer Sie bequemer finden). Asynchrone Eingangssignale sollten ebenfalls enthalten sein.
  2. Alle Signale aus der obigen Liste müssen synchronisiert werden, es sei denn, es gibt einen klaren Grund, warum dies nicht der Fall ist.
  3. Synchronisieren Sie Multibit-Signale niemals bitweise! Verwenden Sie stattdessen spezielle Synchronisationsschemata für Busse (Sync-FIFO, Zwei-Wege-Handshake usw.).
  4. Wenn es im System einen asynchronen Reset gibt und dieser Reset nicht für alle Flip-Flops gilt, sollten alle Signale, die aus dieser Reset-Domäne stammen und an die Nicht-Reset-Logik weitergeleitet werden, als asynchron behandelt werden (und in die Liste from #1)

Ich bin sicher, dass die obige Liste von Praktiken unvollständig ist und leicht erweitert werden kann.

Ich schlage auch vor, CDC-Verifizierungstools (wie Questa CDC von Mentor) in Betracht zu ziehen – diese Tools verwenden formale Techniken, um CDC-Probleme in Ihrem Design automatisch zu erkennen.

Einige Benennungspraktiken können praktisch sein:

  • An jedes Signal, das eine Taktdomäne kreuzt, sollte die Domäne, mit der es synchronisiert ist, angehängt werden. Wenn Sie also countin der Taktdomäne ein Signal haben clk(und es zu einer anderen Taktdomäne gehen muss, die von gesteuert wird other_clk), nennen Sie es count_clkund count_other_clk.

  • Bewahren Sie den gesamten Synchronisierungscode von einer Uhrendomäne zur anderen an einem Ort auf. Vielleicht einkapseln, je nachdem, wie viel es gibt. Setzen Sie klare Kommentare darum (z. B. above here is clk, this is the domain crossing from clk to other_clk, below here is other_clk)

  • _asyncAm Ende können wirklich asynchrone Signale angehängt worden sein .

Dies macht die Codeüberprüfung zumindest ein wenig einfacher, aber wenn Sie viele Domänen und viele Kreuzungen haben, wird es Ihnen zugute kommen, in einige Tools zu investieren, die Ihnen helfen (wie zum Beispiel Spyglass - das weit mehr kann, als nur Taktdomänen zu überprüfen )

Ergänzend zu den bisherigen Antworten:

Melden Sie den Zeitpunkt

Verwenden Sie Ihr Timing-Analyse-Tool in Ihrer FPGA-Toolchain, um alle Signale zu finden, die Sie vergessen haben, richtig zu handhaben.

Sie können leicht eine Liste uneingeschränkter Taktübertragungen erstellen, die alle synchronisiert und mit einem geeigneten falschen Pfad versehen werden sollten. Integrieren Sie dies idealerweise in Ihr Build-System, damit es mit einem Fehler fehlschlägt, wenn es irgendwelche uneingeschränkten Taktübertragungen gibt, dann können Sie sie nicht vergessen!

Code wiederverwenden

Haben Sie eine einzige Entität/Modul für Ihre Einzelbitsynchronisierung, verwenden Sie einen Generic/Parameter, um die Anzahl der Register in der Resync-Kette zu steuern. Möglicherweise möchten Sie einen separaten Synchronizer für Resets.

Einschränkungen einbetten

Der Vorteil der Wiederverwendung von Code – Einbetten der falschen Pfadeinschränkungen in die RTL. Auf diese Weise müssen Sie nicht daran denken, für jedes Signal Zeitbeschränkungen hinzuzufügen.

Hinweis zur Platzierung

Register in Synchronisiererketten müssen nahe beieinander platziert werden, um sicherzustellen, dass ein maximales Zeitfenster bereitgestellt wird. Altera behauptet, Synchronisiererketten automatisch zu erkennen, sodass sie keine Platzierungsbeschränkungen benötigen sollten. Wenn Sie auf Xilinx paranoid sind, können Sie RLOC-Einschränkungen verwenden, um sicherzustellen, dass Ihre Synchronizer-Register nahe beieinander platziert sind (leider unterstützt Altera keine relativen Standortbeschränkungen).