VHDL: Konvertieren von einem INTEGER-Typ in einen STD_LOGIC_VECTOR

28

Ich habe einen Mod-16-Zähler gebaut und das Ergebnis ist ein INTEGER (in allen Beispielen wurde INTEGER verwendet).

Ich habe einen Hex-zu-7-Segment-Display-Decoder gebaut, und sein Eingang ist ein STD_LOGIC_VECTOR (schrieb es so, weil es einfach war, die Wahrheitstabelle abzubilden).

Ich möchte den Ausgang des Zählers mit dem Eingang des Decoders verbinden, aber beim Versuch, in Quartus II zu kompilieren, erhalte ich 'Typinkongruenz'-Fehler.

Gibt es eine Möglichkeit, in einer VHDL-Auflistung einen INTEGER-Typ in einen STD_LOGIC_VECTOR-Typ umzuwandeln?

J. Polfer
quelle

Antworten:

20

Wie andere gesagt haben, benutze ieee.numeric_stdniemals ieee.std_logic_unsigned, was nicht wirklich ein IEEE-Paket ist.

Wenn Sie jedoch Tools mit VHDL 2008-Unterstützung verwenden, können Sie das neue Paket verwenden ieee.numeric_std_unsigned, das im Wesentlichen dazu führt, dass das std_logic_vectorVerhalten nicht signiert ist.

Da es nicht explizit angegeben wurde, finden Sie hier ein aktuelles Codebeispiel für die Konvertierung von einer (vorzeichenlosen) Ganzzahl in eine std_logic_vector:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
wjl
quelle
16

Wie LoneTech sagt, use ieee.numeric_stdist Ihr Freund. Sie können ein std_logic_vectorin ein konvertieren integer, müssen es jedoch als signedoder unsignedzuerst umwandeln (da der Compiler keine Ahnung hat, was Sie meinen). VHDL ist eine stark typisierte Sprache. Ich habe mehr zu diesem Thema in meinem Blog geschrieben

Grundsätzlich würde ich Ihren 7seg-Konverter so ändern, dass er eine aufnimmt integer(oder tatsächlich eine natural, da es sich nur um positive Zahlen handelt) - die Konvertierung ist dann eine einfache Array-Suche. Richten Sie ein konstantes Array mit den Konvertierungen in ein und indizieren Sie es einfach mit der Ganzzahl, die Sie für die Entität als Eingabe verwenden.

Martin Thompson
quelle
Danke dafür. Ich freue mich sehr über Ihre Kommentare. Ich war in einer Art TA-Position und lernte VHDL, um einem Profi den Einstieg zu erleichtern, der ein wenig verwirrt in Sachen Programmierkonzepte war. Ich werde Ihre Informationen an ihn weitergeben - das Lehrbuch, das wir verwendet haben, hat sich nicht mit Fragen der VHDL-Moral befasst.
J. Polfer
1
Es ist weniger eine Frage der Moral als eine Garantie für Kohärenz. Die numeric_std-Bibliothek ist ein echter Standard, der vom IEEE eingeführt wurde, während die std_logic_unsigned-Bibliothek von einem Anbieter erstellt und in der Branche ohne echte formale Definition übernommen wurde. Es gibt keine Garantie für die herstellerübergreifende Kompatibilität mit den nicht standardmäßigen Bibliotheken, obwohl dies normalerweise problemlos funktioniert. Es ist jedoch eine gute Form, jetzt zum Standard überzugehen.
MattG
1

Angenommen, Ihr 4-Bit-Zähler hatte einen INTEGER-Ausgang SOME_INTEGER und Sie wollten ihn in einen 4-Bit-STD_LOGIC_VECTOR konvertieren

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

Sie können dies auch verwenden, um Vektoren mit aussagekräftigen Zahlen zu initialisieren

SOME_VECTOR <= conv_std_logic_vector(9, 4); -- instead of "1001"

Möglicherweise müssen Sie "use IEEE.STD_LOGIC_ARITH.ALL" hinzufügen. und / oder STD_LOGIC_UNSIGNED.

Die komplementäre Operation ist conv_integer (vector). Ich benutze das gerne, wenn ich Vergleiche anstelle. Also könnte ich erklären

constant SOME_CONSTANT : integer := 999;

Und später kann ich dies in einer if-Anweisung verwenden

if (conv_integer(SOME_VECTOR)=SOME_CONSTANT)
  then OTHER_VECTOR <= (others => '0');
end if;

EDIT: Sie sollten die Variable nicht als Integer deklarieren müssen. Versuchen Sie stattdessen, die Deklaration in std_logic_vector zu ändern. Die Operatoren + und - arbeiten mit std_logic_vectors.

ajs410
quelle
3
Bitte tu das nicht! Verwenden Sie numeric_std (siehe LoneTechs und meine Antworten)
Martin Thompson
Wenn Sie einen besseren Weg haben, ist das in Ordnung, aber mein Vorschlag funktioniert, so dass ich denke, dass Ihre Abwertung unnötig war. Ich benutze std_logic_arith seit Jahren und hatte nie Probleme damit. Ich denke, die Befürchtungen, dass Anbieter ihre Implementierungen ändern, sind unbegründet. Welcher Anbieter, der bei klarem Verstand ist, riskiert, die Designs seiner Kunden zu beschädigen?
Ajs410
1
Sie haben bereits eine Antwort darauf, welcher Anbieter herstellerspezifische Informationen absichtlich in den IEEE-Namespace aufnehmen wird. Es bleibt grob, insbesondere im Umgang mit vorzeichenbehafteten und nicht vorzeichenbehafteten Werten.
Yann Vernier,
"Die Operatoren + und - arbeiten mit std_logic_vectors." AFAIK, sie funktionieren nicht, es sei denn, ich verstehe deine Bedeutung falsch. Es ist normalerweise erforderlich, einen Typ zu erstellen, der zuerst signierte / nicht signierte Daten enthält.
Stanri
1

Sie könnten an der Verwendung der Typen unsignedund signedvon interessiert sein ieee.numeric_std. Sie sind kompatibel mit std_logic_vector, haben aber eine numerische Interpretation (binär oder 2-Komplement). Es gibt auch die Möglichkeit, eine solche Interpretation zu verwenden std_logic_vector, dies wird jedoch nicht empfohlen .

Yann Vernier
quelle
0

Wie die Hauptantwort sagt, lautet die empfohlene Methode wie folgt:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Ich möchte jedoch erläutern, warum dies empfohlen wird und warum VHDL eine scheinbar verschlungene Art der Konvertierung von Ganzzahlen in std_logic_vectors hat.

Es kommt darauf an, wie diese Typen von den Tools angezeigt werden.

Ein standard_logic_vector ist buchstäblich ein Bündel von Einsen oder Nullen. Ich habe 10001. Welche Nummer ist das? Es hängt davon ab. Ist es signiert oder nicht signiert? Das SLV weiß es nicht oder kümmert sich nicht darum. Wie viele Bits? Na, wie lange ist dein SLV?

Eine ganze Zahl ist vorzeichenbehaftet und normalerweise 32 Bit (wenn ich mich richtig erinnere).

Stufe 1: Verkürzen Sie meine Ganzzahl und geben Sie kein Vorzeichen ein. Das ist dieser Teil:

to_unsigned(my_int, my_slv'length));

"Ich habe diese Ganzzahl, ich möchte, dass sie ohne Vorzeichen ist und dass sie in die Länge meines SLV passt."

Stufe 2: Nehmen Sie diese Bits und verwenden Sie sie, um my_slv zu steuern.

my_slv <= std_logic_vector(...)

"Nehmen Sie diese Bits und verwenden Sie sie, um meine SLV zu fahren"

(Eine Anmerkung zur Terminologie A <= Bin VHDL wird laut vorgelesen, wenn "A wird von B gesteuert".)

In Kombination erhalten Sie:

my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

Wenn man von einem traditionellen Programmierhintergrund kommt, ist es sehr einfach, sich auf eine Programmier-Denkweise festzulegen. In VHDL hat der von Ihnen geschriebene Code jedoch physische Auswirkungen auf die Hardware. Zu wissen, warum diese Methode funktioniert und empfohlen wird, ist einen Schritt näher dran, darüber nachzudenken, was Sie hardwaremäßig schreiben.

Bonus-Tipp: Mit dem Präfix to_ gekennzeichnete Funktionen verkürzen / ändern die Operanden. Sie machen sie unsigniert oder eine bestimmte Länge oder beides. Aus diesem Grund müssen Sie bei to_unsigned die Länge angeben. Die Funktionen ohne to_ (in diesem Beispiel straight std_logic_vector (...)) werden verwendet, wenn Typen bereits direkt kompatibel sind. Msgstr "Nimm diese Bits und stopfe sie in diesen Typ, keine Modifikationen erforderlich". Diese haben kein Längenargument, da beide Seiten bereits gleich sind. Wenn ich solche Dinge konstruiere, muss ich nicht nachschlagen, sondern denke nur darüber nach, wie ich die Daten ändere.

Stanri
quelle
0

Um eine Ganzzahl in std_logic_vector umzuwandeln, haben Sie mehrere Möglichkeiten. Verwenden von numeric_std:

vect <= std_logic_vector( to_unsigned( your_int, vect'length));

oder

vect <= std_logic_vector( to_signed( your_int, vect'length));

Verwenden von std_logic_arith:

vect <= conv_std_logic_vector( your_int, vect'length);

std_logic_arith ist kein ieee-Standard, aber die meisten Tools kompilieren es in die IEEE-Bibliothek und es ist weit verbreitet.

Craig
quelle