Was sind die Best Practices für Hardwarebeschreibungssprachen (Verilog, VHDL usw.) [geschlossen]

StackOverflow https://stackoverflow.com/questions/326880

  •  11-07-2019
  •  | 
  •  

Frage

Welche Best Practices sollten bei der Implementierung von HDL-Code beachtet werden?

Was sind die Gemeinsamkeiten und Unterschiede im Vergleich zu gängigeren Bereichen der Softwareentwicklung?

War es hilfreich?

Lösung

Das beste Buch zu diesem Thema ist Reuse Methodology Handbuch . Es umfasst sowohl VHDL und Verilog.

Und insbesondere einige Probleme, die nicht über eine genaue Übereinstimmung in der Software haben:

  • Keine Verriegelungen
  • Seien Sie vorsichtig mit Resets
  • Überprüfen Sie Ihre internen und externen Timing
  • Verwenden Sie nur synthetisierbaren Code
  • Registrieren Sie Ihre Ausgänge aller Module
  • Seien Sie vorsichtig mit Blockierung gegen nicht-blockierenden Zuweisungen
  • Seien Sie vorsichtig mit sensiblen Listen für kombinatorische Logik (oder verwenden Sie @ (*) in Verilog)

Einige, die die gleichen sind:

sind
  • Verwenden CM
  • Haben Sie Code-Reviews
  • Test (Simulation) Code
  • Reuse Code bei Bedarf
  • Haben Sie einen up-to-date Zeitplan
  • Haben Sie eine spec oder Anwendungsfälle oder eine Agile Kunden

Andere Tipps

Irgendwie ein alter Thread, aber ich wollte meine 0,02 $ reinstecken.Dies ist nicht wirklich spezifisch für Verilog/VHDL.mehr zum Hardware-Design im Allgemeinen ...speziell synthetisierbares Design für kundenspezifische ASICs.

Das ist mein Meinung basierend auf jahrelanger Industrieerfahrung (im Gegensatz zu akademischer Erfahrung) im Design.Sie sind in keiner bestimmten Reihenfolge

Meine übergeordnete Aussage lautet: Design für die Validierungsausführung.Beim Hardware-Design ist die Validierung von größter Bedeutung.Fehler sind viel teurer, wenn sie in echtem Silizium gefunden werden.Sie können nicht einfach neu kompilieren.Daher wird dem Vor-Silizium viel mehr Aufmerksamkeit geschenkt.

  • Kennen Sie den Unterschied zwischen Steuerpfaden und Datenpfaden.Dadurch können Sie wesentlich eleganteren und wartbareren Code erstellen.Ermöglicht außerdem das Einsparen von Gates und das Minimieren der X-Ausbreitung.Beispielsweise sollten Datenpfade nie rücksetzbare Flops benötigen, Steuerpfade hingegen immer.

  • Beweisen Sie die Funktionalität vor der Validierung.Entweder durch einen formalen Ansatz oder durch Wellenformen.Das hat viele Vorteile, ich erkläre 2.Erstens erspart es Ihnen Zeitverschwendung beim Zwiebelschälen.Im Gegensatz zu viel Design auf Anwendungsebene (insbesondere während des Lernens) und den meisten Kursarbeiten ist die Bearbeitungszeit für Codeänderungen sehr lang (je nach Komplexität zwischen 10 Minuten und Tagen).Jedes Mal, wenn Sie den Code ändern, müssen Sie die Ausarbeitung, die Flusenprüfung, das Kompilieren, das Einblenden der Wellenform und schließlich die tatsächliche Simulation durchführen.was wiederum Stunden dauern kann.Zweitens ist die Wahrscheinlichkeit, dass Sie schwer zu treffende Eckfälle haben, viel geringer.Beachten Sie, dass sich dies auf die Validierung vor dem Silizium bezieht.Diese werden mit Sicherheit im Post-Silicon-Bereich ankommen und Sie viel Geld kosten.Vertrauen Sie mir, die Vorlaufkosten für den Funktionsnachweis minimieren das Risiko erheblich und sind die Mühe wert.Dies ist manchmal schwierig, junge Hochschulabsolventen zu überzeugen.

  • Iss „Hähnchenstücke“.Chicken-Bits sind Bits in MMIO, die über den Treiber festgelegt werden, um eine Funktion im Silizium zu deaktivieren.Ziel ist es, vorgenommene Änderungen rückgängig zu machen, bei denen das Vertrauen nicht hoch ist (das Vertrauen ist direkt proportional zum Validierungsaufwand).Es ist nahezu unmöglich, jeden möglichen Zustand vor der Siliziumproduktion zu erreichen.Das Vertrauen in Ihr Design kann erst erreicht werden, wenn es sich in der Post-Silicon-Phase bewährt hat.Selbst wenn es nur einen Staat gibt, der in 0,000005 % der Fälle getroffen wird und den Fehler aufdeckt, WIRD er in der Post-Silicon-Phase, aber nicht unbedingt in der Pre-Silicon-Phase, TREFFEN.

  • Vermeiden Sie unbedingt Ausnahmen im Kontrollpfad.Jede neue Ausnahme verdoppelt Ihren Validierungsaufwand.Das ist schwer zu erklären.Nehmen wir an, es gibt einen DMA-Block, der Daten im Speicher speichert, die ein anderer Block verwenden wird.Nehmen wir an, die gespeicherte Datenstruktur hängt von der Ausführung einer Funktion ab.Wenn Sie sich entschieden haben, das Design so zu gestalten, dass die gespeicherte Datenstruktur zwischen verschiedenen Funktionen unterschiedlich ist, multiplizieren Sie einfach Ihren Validierungsaufwand mit der Anzahl der DMA-Funktionen.Wenn diese Regel befolgt wird, wäre die gespeicherte Datenstruktur eine Obermenge aller Daten, die für jede Funktion verfügbar sind, bei der die Inhaltsspeicherorte fest codiert sind.Sobald die DMA-Speicherlogik für eine Funktion validiert ist, wird sie für alle Funktionen validiert.

  • Schnittstellen minimieren (lesen Sie „Kontrollpfade minimieren“).Dies hängt mit der Minimierung von Ausnahmen zusammen.Erstens erfordert jede neue Schnittstelle eine Validierung.Dazu gehören neue Prüfer/Tracker, Behauptungen, Abdeckungspunkte und Busfunktionsmodelle in Ihrer Testbench.Zweitens kann es Ihren Validierungsaufwand exponentiell steigern!Nehmen wir an, Sie haben eine Schnittstelle zum Lesen von Daten in Caches.Nehmen wir nun an (aus irgendeinem seltsamen Grund), dass Sie sich für eine andere Schnittstelle zum Lesen des Hauptspeichers entscheiden.Sie haben Ihren Validierungsaufwand gerade vervierfacht.Sie müssen diese Kombinationen nun jederzeit validieren N:

    • Kein Cache-Lesen, kein Speicher-Lesen
    • Kein Cache-Lesen, Speicherlesen
    • Cache-Lesen, kein Speicher-Lesen
    • Cache-Lesen, Speicher-Lesen
  • Annahmen verstehen und kommunizieren.Fehlt dies, ist dies der Hauptgrund für Block-zu-Block-Kommunikationsprobleme.Sie könnten einen perfekten Block vollständig validieren lassen.Wenn Sie jedoch nicht alle Annahmen verstehen, schlägt Ihr Block fehl, wenn er verbunden ist.

  • Mögliche Zustände minimieren.Je weniger Zustände (beabsichtigt oder unbeabsichtigt) ein Entwurf hat, desto geringer ist der Aufwand für die Validierung.Es empfiehlt sich, ähnliche Funktionen in einer Funktion der obersten Ebene zu gruppieren (wie Sequenzer und Arbiter).Es ist sehr schwierig, diese High-Level-Funktion so zu identifizieren und zu definieren, dass sie möglichst viele kleinere Funktionen umfasst, aber dadurch werden Status und damit potenzielle Fehler weitgehend eliminiert.

  • Geben Sie immer ein starkes Signal, wenn Sie Ihren Block verlassen.Meistens ist ein Flop die Lösung.Sie haben keine Ahnung, was die Endpunktblöcke damit machen werden.Es könnte zu Zeitproblemen kommen, die sich direkt auf Ihre perfekte Umsetzung auswirken können.

  • Vermeiden Sie mehlige FSMs, es sei denn, dies beeinträchtigt die Leistung.Mehlige FSMs verursachen eher Timing-Probleme als Moore

  • ..und schließlich das, was mir am wenigsten gefällt:„Wenn es nicht kaputt ist, repariere es nicht“ Aufgrund des damit verbundenen Risikos und der hohen Kosten von Fehlern ist Hacken oft eine praktischere Lösung zur Lösung von Problemen.Andere haben dies umgangen, indem sie die Nutzung vorhandener Komponenten erwähnt haben.

Was den Vergleich mit mehr angeht traditionell Software-Design:

  • Die diskrete ereignisgesteuerte Programmierung ist ein völlig anderes Paradigma.Die Leute sehen die Verilog-Syntax und denken: „Oh, es ist genau wie C“ ...Dies kann jedoch nicht weiter von der Wahrheit entfernt sein.Obwohl die Syntax ähnlich ist, muss man anders denken.Beispielsweise ist ein herkömmlicher Debugger bei synthetisierbarem RTL praktisch bedeutungslos (das Testbench-Design ist anders).Wellenformen auf Papier sind das beste verfügbare Werkzeug.Allerdings kann das FSM-Design manchmal die prozedurale Programmierung nachahmen.Leute mit einem Software-Hintergrund neigen dazu, von FSMs verrückt zu werden (ich weiß, dass ich das zuerst getan habe).

  • System Verilog verfügt über viele, viele (sehr viele) testbenchspezifische Funktionen.Es ist vollständig objektorientiert.Was das Testbench-Design betrifft, ist es dem traditionellen Software-Design sehr ähnlich.Es ist jedoch noch eine weitere Dimension damit verbunden, nämlich die der Zeit.Rennbedingungen und Protokollverzögerungen müssen berücksichtigt werden

  • Auch die Validierung ist unterschiedlich (und gleich).Es gibt drei Hauptansätze;

    • Formale propagative Verifizierung (FPV):Sie beweisen durch Logik, dass es immer funktionieren wird
    • Gezielte Zufallstests.Legen Sie zufällig Verzögerungen, Eingabewerte und Funktionsaktivierung fest, wie durch einen Startwert definiert. gerichtet bedeutet, dass der Samen Pfaden Gewicht verleiht, die weniger Vertrauen bieten.Bei diesem Ansatz werden Abdeckungspunkte verwendet, um den Zustand anzuzeigen
    • Fokustest.Dies ähnelt dem herkömmlichen Softwaretest

...Der Vollständigkeit halber muss ich auch die besten Testbench-Designpraktiken besprechen ...aber das ist für einen anderen Tag

Sorry für die Länge..Ich war in „The Zone“ :)

HDL wie Verilog und VHDL scheint wirklich Spaghetti-Code zu fördern. Die meisten Module bestehen aus mehreren ‚immer‘ (Verilog) oder ‚Prozess‘ (VHDL) Blöcke, die in beliebiger Reihenfolge sein können. Der Gesamtalgorithmus oder Funktion des Moduls ist oft völlig verdeckt. Herauszufinden, wie der Code funktioniert (wenn man es nicht schreiben) ist ein schmerzhafter Prozess.

Vor ein paar Jahren kam ich auf dieses Papier , die eine strukturierte Methode skizziert für VHDL-Design. Die Grundidee besteht darin, dass jedes Modul nur 2 Prozessblock aufweist. Ein für kombinatorischen Code und andere für synchrone (die Register). Es ist für lesbar und wartbaren Code zu erzeugen.

  • In HDL können einige Teile des Codes gleichzeitig funktionieren, beispielsweise können zwei Codezeilen gleichzeitig „arbeiten“. Dies ist ein Vorteil und sollte sinnvoll eingesetzt werden.Dies ist etwas, das ein Programmierer, der mit zeilenweisen Sprachen vertraut ist, zunächst möglicherweise nur schwer begreift:

    • Es können lange und speziell auf Ihre Bedürfnisse zugeschnittene Pipelines erstellt werden.
    • Sie können Ihre großen Module gleichzeitig arbeiten lassen.
    • Anstatt eine Einheit für eine wiederholte Aktion an unterschiedlichen Daten zu verwenden, können Sie mehrere Einheiten erstellen und die Arbeit parallel ausführen.
  • Besonderes Augenmerk sollte auf den Bootvorgang gelegt werden – sobald Ihr Chip funktionsfähig ist, haben Sie einen großen Weg zurückgelegt.

Das Debuggen auf Hardware ist normalerweise viel schwieriger als das Debuggen von Software, daher:

  • Simple code is preferred, sometimes there are other ways to speed-up your code, after it is already running, for example using an higher speed chip, etc'.

  • Vermeiden Sie „intelligente“ Protokolle zwischen Komponenten.

  • Ein funktionierender Code in HDL ist wertvoller als in anderer Software, da die Hardware so schwer zu debuggen und daher wiederzuverwenden ist. Erwägen Sie auch die Verwendung von „Bibliotheken“ mit Modulen, von denen einige kostenlos sind und andere verkauft werden.

  • Beim Entwerfen sollten nicht nur Fehler im HDL-Code berücksichtigt werden, sondern auch Fehler auf dem Chip, den Sie programmieren, und auf anderen Hardwaregeräten, die mit dem Chip verbunden sind. Daher sollte man wirklich über ein Design nachdenken, das leicht zu überprüfen ist.

Einige Debugging-Tipps:

  • Wenn ein Design mehrere Bausteine ​​umfasst, möchte man wahrscheinlich Linien von den Schnittstellen zwischen diesen Blöcken zu Testpunkten außerhalb des Chips erstellen.

  • Sie sollten in Ihrem Entwurf genügend Zeilen speichern, um interessante Daten zur Überprüfung mit externen Geräten umzuleiten.

    Wenn Ihr Chip rekonfigurierbar ist, wird dies noch praktischer, da Sie spezifische Tests anpassen und die Ausgänge für jeden Test nach und nach neu programmieren können (das sieht bei LEDs sehr gut aus :).)

Bearbeiten:

Mit intelligenten Protokollen meine ich, dass zwei Ihrer physischen Einheiten, wenn sie sich verbinden, mit dem einfachsten verfügbaren Kommunikationsprotokoll kommunizieren sollten.das heißt, verwenden Sie zwischen ihnen keine ausgefeilten, selbst erstellten Protokolle.

Aber wenn Ihre Daten nicht so bei Ihnen ankommen, wie Sie es möchten, und Sie herausfinden müssen, warum ...Sie müssen sich an die Leitungen anschließen, und das ist nicht so einfach.

Es ist schwierig, einen Fehler in den Leitungen zu finden, da Sie mit speziellen Geräten eine Verbindung zu den Leitungen herstellen müssen, die den Zustand der Leitungen zu unterschiedlichen Zeiten aufzeichnen, und Sie müssen sicherstellen, dass Ihre Leitungen gemäß dem Protokoll funktionieren.

Wenn Sie über FPGAs verfügen, können Sie, falls die ursprüngliche Taktrate für parallele Daten zu hoch ist, die Geschwindigkeit entsprechend Ihren Experimenten steuern, indem Sie beispielsweise dafür sorgen, dass die Daten auf Leitungen von mindestens „t“ Taktzyklen usw. bleiben.Ich gehe davon aus, dass die parallele Datenübertragung einfacher ist, da Sie mit niedrigeren Taktraten arbeiten und die gleiche Leistung erzielen können, ohne Ihre Daten auf einer Einheit aufteilen und auf der anderen wieder zusammensetzen zu müssen.(Hoffentlich gibt es keine Verzögerung zwischen der „Uhr“, die jede Einheit empfängt.)Auch das ist wahrscheinlich zu komplex :)

Regarding SPI, I2C etc' I haven't implemented any of them, I can say that I've connected legs of two FPGA's running from the same clock, (don't remember the exact formation of resistors in the middle), at much higher rates, so I really can't think of a good reason to use those, as the main way to pass data between your own FPGA's, unless the FPGA's are located very far one from another, which is one reason to use a serial rather than a parallel bus.

JTAG wird von einigen FPGA-Unternehmen zum Testen/Programmieren ihrer Produkte verwendet, es ist jedoch nicht sicher, ob es zum Transport von Daten mit hoher Geschwindigkeit verwendet wird, und es handelt sich um ein Protokoll ...(immer noch eines, das möglicherweise über eine integrierte On-Chip-Unterstützung verfügt).

Wenn Sie ein bekanntes Protokoll implementieren müssen, sollten Sie die Verwendung eines vorgefertigten HDL-Codes in Betracht ziehen, den Sie finden oder kaufen können.

Dies ist die Frage, die JBDAVID der 10 Gebote für Hardware-Design erfordert.

  1. Verwenden Revision / Versionskontrolle, wie in Software. SVN und Hg sind frei.
  2. Erfordern der Code-Syntax vor dem Check-in Überprüfung übergeben. Ein LINT-Tool ist besser.
  3. Verwenden Sie eine volle Stärke Hardware Verification Sprache für Design Verification. System-Verilog ist fast eine sichere Wahl.
  4. Track Bugs. Bugzilla und GNATS sind kostenlose Tools. FogBugz erfordert ein wenig $.
  5. Verwenden Sie Assertions Probleme mit falschem Gebrauch zu fangen.
  6. Die Coverage Triad sorgt für eine stabile Konstruktion: Messen Codeabdeckung, Funktionsabdeckung und Assertion Abdeckung sowohl in Simulation und formalen Tool
  7. .
  8. Leistung ist König. Verwenden CPF oder UPF zu erfassen, durchzusetzen und zu überprüfen, Ihre Power-Intent
  9. das eigentliche Design ist oft gemischte Signal, Verwenden Sie eine Mixed-Signal-Sprache das analoge mit der digitalen zu überprüfen. Verilog-AMS ist eine solche Lösung. Aber nicht über Bord gehen. Realnumber Modellierung können die meisten der funktionalen Aspekte von Mixed-Signal-Verhalten erreichen.
  10. Verwenden von Hardwarebeschleunigung, um die Software zu validieren, die mit dem Silizium arbeiten muß!
  11. Syntax Aware Texteditoren für Ihre HDL / HVL sind eine Mindestanforderung für Entwickler IDE.

Für FPGAs, hat Xilinx Diese Seite . Fast alle anderen FPGA-Anbieter gelten würde, oder würde gleichwertige Regeln. Ein großer Teil ist auf ASIC-Design.

Intel hat empfohlen HDL Coding Styles und Design-Empfehlungen (PDF) unter dieser Seite .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top