Ich bereite ein Programm in VHDL vor und bin bei der Typkonvertierung hängen geblieben. Ich habe die Google-Suche und auch hier beim Stack-Austausch versucht, aber ich bin ziemlich verwirrt, da eine Antwort der anderen widerspricht und ich keine zur Arbeit bringen kann. Aber zum Schluss noch zu meiner Frage: Ich muss ganz normale Digitaluhren anzeigen. Ich habe von meinem Professor einen Decoder für 7-Segment-Anzeige bekommen, der als Eingang nimmt std_logic_vector(3 downto 0)
. Und mein Teil besteht darin, Daten (genauer gesagt eine Reihe von Ziffern) zur Anzeige bereitzustellen. std_logic_vector(4 downto 0)
Die meiste Arbeit ist bereits erledigt, aber ich habe Mühe, meine Variablen, z. B. Minuten (es ist ) in zwei Dezimalstellen umzuwandeln . Ich habe die Trennung auf diese Weise durchgeführt:
if (min >= 50) then
d3 <= 5;
d4 <= min - 50;
elsif (min >= 40) then
d3 <= 4;
d4 <= min - 40;
elsif
...
end if;
(Der Maximalwert von min
ist 59 und wenn er so hoch wird, wird er auf 0 zurückgesetzt und der Stundenzähler erhält +1, genau wie gewöhnliche Uhren). Daher d3
sollten Zehnerminuten und d4
Einheiten von Minuten angezeigt werden. Wie Sie wahrscheinlich schon erraten haben, min
kann ich es nicht kompilieren, da es eine Länge von 5 hat ( d4
akzeptiert eine Länge von 4 Tops). Meine Idee ist also, in eine Ganzzahl umzuwandeln min
, eine Zahl (z. B. 50) zu subtrahieren und mit der richtigen Länge wieder umzuwandeln std_logic_vector
(der tatsächliche Wert wäre im Bereich von 0 bis 9, also kein Problem mit einer Länge von vier Bit). Ich habe versucht, so etwas vorzuformen:
d4 <= std_logic_vector(unsigned(integer(unsigned(min)) - 50));
aber ohne Erfolg. Ich hatte immer Fehler wie unbekannte Funktion, Typkonflikt oder keine übereinstimmende Überladung für Methode, egal welche Kombination ich ausprobierte. Anscheinend habe ich irgendwo einen trivialen Fehler, aber ich sehe ihn nicht. Ich benutze die:
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
Können Sie mich bitte in die richtige Richtung weisen? Mir gehen die Ideen aus.
Vielen Dank für Ihre Zeit, Michael
BEARBEITEN: Eingaben, Ausgaben, Variablendeklarationen wie gewünscht sind:
port (sw2, sw1, sw0: in std_logic; -- input switches
clock: in std_logic;
reset: in std_logic;
d0, d1, d2, d3, d4, d5, d6, d7: out std_logic_vector(3 downto 0); -- outputs for eight units of 7segment display decoders
dp0, dp1, dp2, dp3, dp4, dp5, dp6, dp7: out std_logic); -- outputs for decimal points
attribute loc : string;
attribute loc of sw0 : signal is "P7";
attribute loc of sw1 : signal is "P9";
attribute loc of sw2 : signal is "P10";
attribute loc of clock : signal is "P2";
attribute loc of reset : signal is "P11";
end main_1048;
architecture main_1048arch of main_1048 is
begin
process(sw2, sw1, sw0, clock, reset)
variable yrs: std_logic_vector(11 downto 0);
variable min, sec: std_logic_vector(4 downto 0);
variable hrs, day, mth: std_logic_vector(3 downto 0);
begin
EDIT2: Nach dem Löschen von libs std_logic_arith
a std_logic_unsigned
wie von Brian Drummond vorgeschlagen und dem Neudefinieren von Variablen, so dass sie jetzt natural
s sind. Neue Fehler waren keine übereinstimmende Überladung für "-". Gemäß den Spezifikationen, die ich gefunden habe, sollte "-" funktionieren:
function "-" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
-- Result: Subtracts an UNSIGNED vector, R, from a non-negative INTEGER, L.
Also Endbearbeitung war dran d4 <= std_logic_vector(min - to_unsigned(50,4));
(mit Deklaration variable min: natural range 0 to 59;
) und das (bezüglich Typumwandlung) funktioniert.
Vielen Dank für Ihre Hilfe!
Löschen Sie zuerst die Nicht-Standard- std_logic_arith
und std_logic_unsigned
Bibliotheken und lassen Sie std_logic und numeric_std.
Abgesehen davon, dass sie nicht standardisiert sind, verursachen sie Probleme durch eine VHDL-Regel, die - wenn zwei Definitionen eines Typs (oder einer Prozedur oder eines Operators oder was auch immer) sichtbar sind - wie oder - VHDL versuchen wird, herauszufinden, welche Sie beabsichtigt haben (z. B. durch unsigned
den <=
Parameter Typen des Operators, da überladene Operatoren zulässig sind).
Aber wenn zwei Definitionen sichtbar und nicht unterscheidbar sind, gelten beide als verborgen. Auf diese Weise BEHEBEN Sie das Problem, anstatt dem Compiler zu erlauben, einen - wahrscheinlich falschen - zufällig auszuwählen.
Wenn Sie also nur die Standardbibliotheken verwenden, werden die Dinge viel einfacher.
Eine weitere Grundregel lautet nun: Wenn Sie mit vielen Typkonvertierungen kämpfen, wird etwas als falscher Typ deklariert, was auf einen Designfehler hinweist.
Ich werde den Fehler erraten: min
sollte als deklariert werden, unsigned
ist es aber nicht. (Dito d3 usw.). Es stellt eine vorzeichenlose Zahl in Bitform (std_logic) dar. Also deklariere es als solches.
Beheben Sie das und sehen Sie, was passiert. Aber suchen Sie zuerst die Quelle für das numeric_std
Paket (die Paketspezifikation, kümmern Sie sich nicht um den Paketkörper). Sie werden viele Operatoren sehen, die eine direkte Interaktion ermöglichen unsigned
und ermöglichen integer
.
Dann würde ich erwarten, dass Ihr Code-Snippet direkt funktioniert, ohne Typkonvertierungen.
Wenn Sie die Bits von nicht wirklich benötigen min
, gehen Sie weiter und deklarieren Sie sie als Untertyp von natural
mit einem Bereich von 0 bis 59. Es gibt keinen Grund, dies nicht zu tun, selbst für die Synthese und für Ports auf einer Komponente.
Es ist normalerweise angemessen unsigned
(oder sogar std_logic_vector
wenn Sie müssen) für Ports auf der obersten Ebene, wo Sie jedes Bit mit einem FPGA-Pin verbinden müssen. Konvertieren Sie jedoch intern so schnell wie möglich in die Typen, die für das Design am besten geeignet sind.
@E: CD371 :"E:\main_1048.vhd":197:17:197:24|No matching overload for "-" ?"-"(variable:min, 20) @E: CD308 :"E:\main_1048.vhd":197:17:197:24|Unable to evaluate expression type
Ich werde jetzt Paketspezifikationen abrufen und sehen, ob mir eine Idee einfällt. Trotzdem danke!"-"(natural,natural)
die Rückgabe natürlich erfolgt. Sie könnten to_unsigned
dieses Ergebnis anwenden, und es könnte für den Leser sauberer sein (weniger "tricky"), aber beide Versionen sollten die gleiche Hardware erzeugen.Anhand der von Ihnen angegebenen Informationen gehe ich davon aus, dass Sie falsche Typkonvertierungsfunktionen verwenden.
Angenommen min
und d4
are s sollte std_logic_vector
die zu berechnende Zeile wie folgt aussehen:d4
d4 <= std_logic_vector(to_unsigned(to_integer(unsigned(min)) - 50, d4'length));
Beim Konvertieren zwischen den Typen unsigned
und integer
den Funktionen to_unsigned()
und to_integer()
sind Ihre Freunde. Das zweite Argument von to_unsigned()
ist die Länge des resultierenden unsigned
Werts.
unsigned(min)
. PS min ist vom Typ natural
.
andrsmlr
min
/d3
/d4
etc. haben.Rao