VHDL: Ganzzahlen zur Synthese?

Ich bin etwas verwirrt darüber, ob ich Integer in VHDL für Synthesesignale und Ports usw. verwenden sollte.

Ich verwende std_logic an Top-Level-Ports, aber intern habe ich überall Bereichs- Ganzzahlen verwendet. Ich bin jedoch über einige Verweise auf Leute gestolpert, die sagen, dass Sie signierten/unsignierten Code nur für synthesezielgerichteten Code verwenden sollten.

Ich habe mein aktuelles Projekt überarbeitet, um unsigniert zu verwenden ... und nun, es ist merklich hässlicher.

Ist es eine schlechte Praxis, Ganzzahlen zu verwenden? Was ist das Problem? Gibt es eine gewisse Unsicherheit darüber, auf welche Breite das Tool Ganzzahlen abbildet?

Gute Frage. Das habe ich mich auch schon gefragt. Ich begann damit, überall ganze Zahlen, positive und andere Typen zu verwenden, aber es stellte sich als sehr schwierig heraus, richtig synthetisiert zu werden. Ich hoffe, jemand kann erklären, warum alle std_logic in einer stark typisierten Sprache verwenden.
Ja. Ist das nicht verrückt? In der aktuellen Praxis führt eine hohe Typisierung tendenziell zu vielen DATA_I <= TO_UNSIGNED (32010, DATA_I'LENGTH); Schreibkram... das stört niemanden? :) Es scheint sicher eine Menge unnötiges Gepäck zu sein. (Besonders beim Hinzufügen von STD_LOGIC_VECTOR() ) Ich habe meinen Typ und meine Größe deklariert, dies sollte DATA_I <= 32010 sein; Das sollte implizit sein. Das Wechseln zwischen signiert/unsigniert usw. kann und sollte explizit sein ... aber eine direkte eindeutige Zuweisung oder Operation mit ganzen Zahlen sollte implizit sein.

Antworten (3)

Ganzzahlen sind gut in der Synthese, ich benutze sie die ganze Zeit.

Ich verwende std_logic an Top-Level-Ports, aber intern habe ich überall Bereichs-Ganzzahlen verwendet

Das ist gut!

Sei vorsichtig:

  • Sie simulieren zuerst, nicht wahr :) - Integer-Typen werden in der Simulation nicht automatisch "überrollt" - es ist ein Fehler, den Bereich zu verlassen, den Sie für sie angegeben haben. Wenn Sie Rollover-Verhalten wünschen, müssen Sie es explizit codieren.
  • Sie sind nur spezifiziert, um von zu gehen ( 2 31 1 ) zu + 2 31 1 (dh nicht ganz den gesamten Bereich einer 32-Bit-Ganzzahl, Sie können nicht verwenden 2 31 und tragbar bleiben), was manchmal etwas mühsam ist. Wenn Sie "große" Zahlen verwenden müssen, müssen Sie unsignedund verwenden signed.
  • Wenn Sie sie nicht einschränken, können Sie manchmal mit 32-Bit-Zählern enden, wo weniger ausreichen würden (wenn der Synthesizer und nachfolgende Tools nicht "sehen" können, dass sie Bits wegoptimieren könnten).

Auf der Oberseite:

  • Sie sind viel schneller zu simulieren als vorzeichenlose/vorzeichenbehaftete Vektoren
  • Sie rollen nicht automatisch in der Simulation (ja, es ist in beiden Listen :). Das ist praktisch – zum Beispiel werden Sie frühzeitig gewarnt, dass Ihr Zähler zu klein ist.

Wenn Sie Vektortypen verwenden, verwenden Sie ieee.numeric_std, nichtieee.std_logic_arith wahr?

Ich verwende integers, wo ich kann, aber wenn ich ausdrücklich "Rollover-n-Bit-Zähler" möchte, tendiere ich dazu, unsigned.

Ja, ich verwende numeric_std. Ich denke, ich mache mir hauptsächlich Sorgen um Xilinx-Tools ... sie generieren immer noch std_logic_vector für alles und "UNSIGNED" ist nicht einmal in der Syntaxhervorhebung enthalten.
@darron Mach dir keine Sorgen über die Syntaxhervorhebung. Der Editor und sein Syntax-Highlighter sind eine völlig andere Software als das Synthese-Tool. Außerdem ist unsigned "nur" ein Datentyp. Es ist Teil einer Standardbibliothek, nicht der Sprache selbst.
Ist die Untergrenze nicht stattdessen -2^32 + 1? Wenn es -2 ^ 31 - 1 wäre, bräuchten Sie nur ein weiteres Bit, um nur eine einzige Zahl darzustellen - sehr seltsam.
@Bregalad - guter Fang - das war schon eine ganze Weile falsch!
@MartinThompson Oder vielleicht können Sie es als -(2 ^ 32-1) schreiben, wenn Sie das Minuszeichen lieber behalten möchten.
Nicht nur das, ich scheine auch die Macht falsch verstanden zu haben! Es sollte -(2^31-1) sein

Jan Decaluwe hat ein ganzes Weißbuch über die Probleme von ganzen Zahlen und Bitvektoren geschrieben. Ich gehe davon aus, dass seine Antworten darin bestehen, nach Möglichkeit ganze Zahlen zu verwenden . http://www.jandecaluwe.com/hdldesign/counting.html

Es ist per se nichts falsch daran, ganze Zahlen für RTL zu verwenden , aber es gibt Gründe, warum manche es vermeiden. Das ist wirklich eine Frage der subjektiven "Best Practice" und Sie müssen letztendlich selbst herausfinden, was Sie bevorzugen. Als Hilfe dazu werde ich meine Erfahrungen und Gedanken dazu teilen.

Grundsätzlich bin ich für die Verwendung von (eingeschränkten) ganzen Zahlen, auch wenn ich für die Synthese schreibe. Ich mache es manchmal, aber in der Praxis halte ich mich normalerweise an signedund unsigned. Ich werde näher darauf eingehen, warum.

Sie werden ohnehin gezwungen sein, einen vektorisierten Datentyp in einem Teil Ihres Designs zu verwenden:

  • Kaum eine Anbieter-IP oder 3rd-Party-IP wird integerTyp für Ports verwenden

  • Wenn Sie beispielsweise Daten über BlockRam senden, müssen Sie höchstwahrscheinlich sowieso in einen vektorisierten Typ konvertieren, selbst wenn Sie darauf schließen und daher niemals eine Schnittstelle zu einem IP/Makro/Primitiven herstellen müssen

  • Selbst wenn keines der oben genannten zutrifft, müssen Sie meistens irgendwann eine Schnittstelle zu etwas anderem herstellen (wenn nichts anderes ein Top-Level-Port ist).

Da Sie nicht integerfür das vollständige Design verwenden können, möchten Sie vielleicht alles zusammen überspringen, weil:

  • An manchen Stellen müssen Sie die Konvertierungen trotzdem durchführen, und dies nimmt einen Teil des eigentlichen Verwendungszwecks integerweg

  • Außerdem werden diese Konvertierungen für die Simulation normalerweise mit Vektoren von 'U'oder aufgerufen 'X', entweder vor dem Zurücksetzen oder zu anderen Zeiten, und jeder einzelne derartige Funktionsaufruf generiert eine Warnmeldung von der Paketfunktion, wodurch Ihre Simulationswarnungen/Eingabeaufforderungen überladen werden

Nachteile der Verwendunginteger :

  • Im Gegensatz zu den vektorisierten Typen haben Ganzzahlen kein 'U'und 'X'; Ich finde diese sehr hilfreich in Simulationen. Sie sehen, wie sich nicht initialisierte Signale durch das Design ausbreiten, und Sie werden wahrscheinlich reagieren, wenn Sie nach dem Zurücksetzen viele nicht initialisierte Signale sehen. Dies ist nicht der Fall, wenn Sie ganze Zahlen verwenden.

  • Bei Ganzzahlen besteht ein größeres Risiko einer Fehlanpassung von Simulation/Synthese beim Addieren oder Subtrahieren, was zu einem Unter-/Überlauf führt. (Wie bereits von jemand anderem erwähnt.)

Typische Fälle, in denen ich integerwirklich eine gute Option finde:

  • Für Debug-Signale/Zähler, die Sie über chipScope/signalTap usw. überwachen.

  • Völlig interne Repräsentation von Zählern, die niemals in oder aus Ihrem eigenen Code gehen. Ja, es gibt solche Fälle, z. B. wenn Sie einen FIFO schreiben und Schreib-/Lesevorgänge mit Koppelnavigation durchführen, um die Signale full, empty, almostFullusw. ..)

Meine eigenen Schlussfolgerungen: Ich verwende manchmal ganze Zahlen, aber sparsam und meistens in den oben beschriebenen Fällen. Ich sehe keinen großen Overhead bei der Verwendung von unsignedund signedanstelle von Integer und bleibe daher normalerweise bei ihnen.