So erhalten Sie ein FPGA-Design, das auf jeden Fall auf der tatsächlichen Hardware funktioniert

9

Ich habe gerade angefangen, digitales Logikdesign mit FPGAs zu lernen, und habe viele Projekte erstellt. Meistens (da ich eine Art Noob bin) habe ich ein Design, das perfekt simuliert (Verhaltenssimulation), aber nicht richtig synthetisiert.

Meine Frage lautet also: "Welche Entwurfsschritte kann ich in meinen Workflow integrieren, um sicherzustellen, dass ich ein funktionierendes Design habe, das direkt auf meinem FPGA funktioniert?"

Ich habe zwei Hauptbereiche, in denen ich Ratschläge erwarte, aber dies basiert absolut auf einer sehr engen Sichtweise von mir als Anfänger, und weitere sind willkommen:

  • Welche Schritte (Anzeigen des RTL-Schaltplans, Nachsynthesesimulation, ...) sollte ich für die Best Practice lernen?
  • Was alles sollte ich beachten, wenn ich meine Logik entwerfe (z. B. FSMs oder sequentielle Schaltungen), um unerwartete Ergebnisse zu vermeiden.

Ich verwende für meine Arbeit ein Xilinx Spartan 6 FPGA und eine Xilinx ISE Design Suite.

Ironstein
quelle
1
Auf welche Probleme stoßen Sie bei der Synthese? Erreichen Sie in der Simulation einen hohen Abdeckungsgrad ?
pjc50
@ pjc50 Ich verstehe die Frage nicht. Was meinst du mit "hoher Deckungsgrad in der Simulation"?
Ironstein
1
Sie haben eine Testbench oder einen Stimulus, der die Simulation steuert. Die Coverage-Tools geben in Prozent an, wie viel des Designs tatsächlich vom Test ausgeführt wird. Wenn diese Anzahl zu niedrig ist, ist Ihre Testbench nicht ausreichend und Sie testen einige Fälle nicht, die bei der tatsächlichen Verwendung auftreten könnten.
pjc50
@ pjc50 das ist eigentlich ein sehr guter rat. Was entspricht dem in der Xilinx ISE Design Suite?
Ironstein
1
Bemerkenswert: Synthesen und "funktioniert definitiv auf tatsächlicher Hardware" sind unterschiedliche Strenge. Es gibt Muster, denen man folgen kann, um sicherzustellen, dass es synthetisiert. Wenn es jedoch darum geht, dass es auf der tatsächlichen Hardware funktioniert, muss man sich mit Sicherheit an die Maxime der Simulation erinnern: "Alle Modelle sind falsch; einige sind nützlich."
Cort Ammon

Antworten:

13

An einem Ort, an dem ich arbeitete, gab es zwei Lager von FPGA-Designern. Ein Lager, das ich simulieren, simulieren, simulieren oder gewürfelt nannte. Das andere Camp drehte sich alles um Design.

Die gewürfelten Jungs benutzten einen Simulator wie Modelsim. Sie entwickelten ein erstes Design über Codierungsmethoden und / oder Blöcke in der Design-Suite. Dann würden sie es simulieren und die Dinge finden, die nicht funktionieren würden, und dann den Code ändern. Dieser Prozess wurde mehrmals wiederholt, bis ein funktionierendes Design gefunden wurde.

Das Designcamp (das ich bevorzugt habe) würde die Wellenform auf Papier (oder digitalem Papier wie visio) entwerfen, genau das, was erforderlich war. Dann überlegen Sie sich ein Logikdiagramm. Dies ist ein selbstdokumentierender Prozess. Dann wurde das Diagramm in Code übersetzt (der Code und das Diagramm waren 1: 1, wenn etwas im Diagramm war, gab es einen Prozess dafür im Code). Dann wurde es simuliert und die Simulationswellenform wurde mit der auf Papier entworfenen Wellenform verglichen, und es wurde erwartet, dass sie dieselbe ist.

Am Ende habe ich beides gemacht, manchmal bin ich in den Cubed-Modus geraten, und es hat nicht sehr viel Spaß gemacht. Ich stellte fest, dass ich manchmal mein Ziel aus den Augen verlor. Zum Beispiel würde ich einen Zustand in einer Zustandsmaschine ändern, und die Änderung würde sich auf den nächsten Zustand auswirken, dann müsste ich das beheben. Am Ende verbrachte ich mehr Zeit als darüber nachzudenken.

In welchem ​​Lager würdest du lieber sein? Ich denke, es muss strenges Design geben, das tun, was für Sie funktioniert, aber ich denke, je detaillierter und strenger Sie entwerfen, desto weniger Probleme werden Sie auf lange Sicht haben. Ich habe einige Beispiele dafür gegeben, was möglich ist. Sie passen möglicherweise nicht zur Organisationsstruktur Ihres Arbeitsplatzes. Der Grund, warum Designdetails und sorgfältige Planung so nützlich sind, besteht darin, dass Sie darüber nachdenken müssen, was Sie tun. Es macht es einfach zu debuggen. Entwickeln Sie einen Design-Workflow, der dies ermöglicht. Machen Sie sich auch mit den Simulationswerkzeugen vertraut und schreiben Sie gute Testbenches, die alle Bedingungen testen, denen das simulierte Gerät ausgesetzt sein könnte. Dies muss natürlich mit der Zeit ausgeglichen werden. Schreiben Sie beispielsweise ADC HDL-Code, der das Gerät in Ihren Simulationen simuliert.

Das wertvollste Werkzeug für das FPGA-Design (meiner Meinung nach) ist ein gutes Testverfahren, mit dem Sie Ihr Design vollständig testen und auf Herz und Nieren prüfen können. Von einem FPGA-Design kann nicht erwartet werden, dass es "nur funktioniert". Es erfordert Mühe, um sicherzustellen, dass alle Teile funktionieren. Wenn Sie Fehler entdecken, kehren Sie zur Simulation und zum Design zurück und erfahren Sie, welche Unterschiede zwischen einem simulierten FPGA und RTL bestehen. Das hängt hauptsächlich mit der Erfahrung zusammen, aber wenn das Design in der Simulation funktioniert, aber nicht in der Hardware, müssen Sie herausfinden, warum es einen Unterschied gibt.

Ein paar wichtige Dinge, die ich gelernt habe:
1) Bereinigen Sie Ihre Eingänge, die Takt- und Rücksetzschaltungen müssen sauber sein, sonst kann sich die Metastabilität durch Ihr System ausbreiten. Wissen, was ein Synchronisierer mit zwei Rängen ist. Es gibt viele verschiedene Topologien für Reset-Schaltungen, wissen, wie man sie verwendet (es gibt einen großartigen Artikel im Internet, den ich jedoch nicht zur Hand habe).
2) Holen Sie sich die Anforderungen des Designs im Voraus und entwerfen Sie dann um diese herum. Wenn die Leute um Sie herum Ihnen keine bestimmten Anforderungen stellen, dann überlegen Sie sich diese selbst.
3) Die Matlab-Fixpunkt-Toolbox eignet sich hervorragend zum Simulieren von Steuerungssystemen und DSP-Anwendungen. Möglicherweise haben Sie jedoch keinen Zugriff darauf. Es ist eine großartige Möglichkeit, ein Design zu beweisen, bevor Sie codieren.
4) Design kommt zuerst, dann Codierung, dann Simulation.
5) Stark typisiert, halten Sie auch die Signalnamen auf dem Leiterplattenschema und der HDL konsistent. (Aus diesem Grund bevorzuge ich VHDL gegenüber Verilog.

Spannungsspitze
quelle
2
sichmuleintichÖn3
Ganz gut: zu "rigorosem Design" würde ich "using the type system" hinzufügen. Beispiel: Ein Array-Index des entsprechenden Typs, z. B. der Bereich des Arrays, muss nicht auf Bedingungen außerhalb der Grenzen getestet werden. Ich würde nur mit "Wellenform im Vergleich zur entworfenen Wellenform auf Papier" nicht einverstanden sein ... die entworfene Wellenform sollte zu diesem Zeitpunkt in VHDL sein (oder vielleicht aus einer Textdatei gelesen werden) und der Simulator sollte den Vergleich durchführen.
Brian Drummond
Es könnte auch so gemacht werden. Ich fand es nützlich, eine Wellenform auf Papier zu entwerfen, weil sie etwas zum Vergleichen bietet. Wie bei einer ADC-Wellenform wurde das Timing entworfen und dann mit dem Modlesim-Ausgang verglichen und dann physikalisch verifiziert. Wenn die Modellausgabe korrekt ist, vergleichen Sie sie damit. Der Code war stark getippt (das habe ich vergessen zu erwähnen), aber das ist wirklich wichtig. Aus diesem Grund bevorzuge ich VHDL gegenüber Verilog. Es gibt weniger Verknüpfungen, die Sie verwenden können. Und es macht den Code viel lesbarer.
Spannungsspitze
Ja. Genau wie in anderen Bereichen wie Software oder herkömmlicher Hardware besteht der Ausgangspunkt darin, das Problem in Blöcke zu unterteilen und sich dann zu fragen: "Woher weiß ich, wann dieser Block funktioniert?". Dann tu es. Erstellen Sie Ihr Design Block für Block, setzen Sie die Blöcke zusammen und testen Sie erneut, ob das, was Sie erhalten, das ist, was erwartet wird. Manchmal stellen Sie möglicherweise fest, dass ein besseres Design auf Blockebene sauberer oder einfacher ist, und ziehen sich zurück.
Danmcb
6

Hauptsachen sind:

  • Sorgfältige Codierung, um nicht synthetisierbare Strukturen zu vermeiden
  • Minimieren Sie die Logikpegel für eine bessere Timing-Leistung (machen Sie die Logik zwischen den Registern so einfach wie möglich).
  • Testen Sie, testen Sie, testen Sie, um die Funktionskorrektheit sicherzustellen, und prüfen Sie, ob nicht initialisierte Regs und nicht angeschlossene Kabel vorhanden sind
  • Synthese und überprüfen Sie die Syntheseprotokolle auf Warnungen. Stellen Sie sicher, dass die Warnungen keine Probleme anzeigen (dh die Warnung zum entfernten Register kann beabsichtigt (kein Modulausgang verwendet) oder unbeabsichtigt (vergessen, den Modulausgang / Tippfehler / etc. zu verbinden) sein.)
  • Stellen Sie sicher, dass das FPGA nicht zu voll ist
  • Stellen Sie bei der Orts-, Routen- und Zeitanalyse sicher, dass Ihr Design mit der erforderlichen Taktrate ausgeführt wird

Ich habe mehrere ziemlich komplexe Designs beim ersten Test auf einem tatsächlichen FPGA korrekt (oder zumindest größtenteils korrekt) arbeiten lassen, indem ich den obigen Anweisungen gefolgt bin. Sie müssen das RTL-Schema nicht überprüfen, das ist nur extrem umständlich und für große Designs eine reine Zeitverschwendung. Eine Nachsynthesesimulation wäre viel nützlicher.

alex.forencich
quelle
1
Danke für ihre schnelle Antwort. Könnten Sie bitte den zweiten Punkt näher erläutern (Logikpegel minimieren).
Ironstein
5

Ihr gesamter synthetisierbarer Code muss wie folgt ausgedrückt werden können:

  • LUTs
  • Flip Flops
  • Herstellerspezifische Grundelemente

Herstellerspezifische Grundelemente werden entweder explizit instanziiert oder vom Assistenten des Herstellers generiert oder durch sehr spezifische Codierungsmuster abgeleitet, sodass dort keine Mehrdeutigkeit bestehen sollte.

In VHDL können Sie beispielsweise keinen wait forsynthetisierbaren Code verwenden. Um zu verstehen, warum, versuchen Sie, deterministisch wait for 100 nsmit LUTs oder Flip-Flops auszudrücken. Das kannst du nicht.

Das bedeutet nicht, dass Sie es nicht implementieren können, indem Sie einen Zähler mit einer bekannten Taktfrequenz (mit einer Periode, die 100 ns teilen kann) einrichten und anhand seiner Zählung wissen, wann die Zeit abgelaufen ist. Die Synthese-Engine wird dieses Schema jedoch nicht automatisch erstellen. Sie müssen die Architektur in Bezug auf kombinatorische Logik (Gates / LUTs) und Register explizit beschreiben.

Das Wichtigste, was Sie beachten müssen, um synthetisierbaren Code zu generieren, ist ein relativ klares Bild davon, wie Ihr Code zu Logikgattern und Flip-Flops wird. Das ist es wirklich.

Apalopohapa
quelle
wait until rising_edge(clk);ist sicherlich synthetisierbar, obwohl einige Tools die Verwendung einschränken.
Brian Drummond
2

Der naheliegendste erste Schritt besteht darin, die Warnungen zu überprüfen.

Xilinx-Tools erstellen Protokolldateien, die vor allem warnen, was möglicherweise nicht den Absichten des Codierers entspricht. Manchmal ist dies ärgerlich, wenn Sie unzählige Warnungen vor nicht verwendeten Signalen haben, von denen Sie genau wissen, dass sie nicht verwendet werden. Aber manchmal fängt es echte Fehler. Wenn Sie ein Neuling sind, ist die Wahrscheinlichkeit, dass Sie einen Fehler machen, erheblich höher.

Dann müssen Sie zeitliche Einschränkungen einrichten. Wie schnell muss nach einer ansteigenden Flanke auf Takt A die Datenleitung B gesetzt werden? Oder wie lange muss die Datenleitung B vor einer fallenden Flanke auf Takt A gehalten werden? Mit zeitlichen Einschränkungen können Sie all dies angeben. Wenn Sie keine zeitlichen Einschränkungen haben, kann der Compiler davon ausgehen, dass Sie sich nicht besonders darum kümmern und Ihre Signale überall weiterleiten können. Wenn Sie zeitliche Einschränkungen haben, stellt der Compiler sicher, dass Ihre Signale diese Einschränkungen erfüllen, indem Sie die Platzierung verschieben. Und wenn es die zeitlichen Einschränkungen nicht erfüllen kann, wird eine Warnung ausgegeben.

Wenn Ihr Problem darin besteht, dass die Ausgänge nicht das tun, was Sie erwarten, sehen Sie sich die E / A-Blöcke im Detail an. Jedem E / A-Pin ist ein bisschen Logik und ein Flip-Flop zugeordnet. Die Reihenfolge, in der Sie Ihre Logik- und Statusvariablen in Ihrem Code angeben, ermöglicht es möglicherweise nicht, dass Ihr Code in diese Architektur passt, sodass Sie eine zusätzliche Verzögerung von jedem Ort erhalten, an dem er gerade platziert wird. Warnungen zu Zeiteinschränkungen zeigen an, ob dies geschieht (vorausgesetzt, Sie haben Ihre Zeiteinschränkungen eingerichtet). Um dies zu beheben, müssen Sie jedoch die Hardware verstehen und wissen, wie Ihr Design der Hardware zugeordnet wird. Im Allgemeinen ist dies nur dann ein Problem, wenn Sie anfangen, hohe Taktraten zu erreichen, aber es ist erwähnenswert.

Graham
quelle