VHDL - Konvertieren von Typen und ganzzahlige Subtraktion

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 minist 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 d3sollten Zehnerminuten und d4Einheiten von Minuten angezeigt werden. Wie Sie wahrscheinlich schon erraten haben, minkann ich es nicht kompilieren, da es eine Länge von 5 hat ( d4akzeptiert 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_aritha std_logic_unsignedwie von Brian Drummond vorgeschlagen und dem Neudefinieren von Variablen, so dass sie jetzt naturals 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!

Bitte postet die Deklarationen all eurer Signale, sonst müssen wir davon ausgehen welchen Typ min/ d3/ d4etc. haben.
@damage: Dann wie gewünscht zusammen mit einigen anderen hinzugefügt, aber nicht allen.

Antworten (2)

Löschen Sie zuerst die Nicht-Standard- std_logic_arithund std_logic_unsignedBibliotheken 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 unsignedden <=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: minsollte als deklariert werden, unsignedist 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_stdPaket (die Paketspezifikation, kümmern Sie sich nicht um den Paketkörper). Sie werden viele Operatoren sehen, die eine direkte Interaktion ermöglichen unsignedund 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 naturalmit 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_vectorwenn 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.

Vielen Dank für Ihre Ideen. Ich hatte alle internen Variablen als natürlich neu definiert, da ich nicht an ihrer genauen Bit-Interpretation interessiert bin, und diese beiden nicht standardmäßigen Bibliotheken entfernt. Und die Ergebnisse sind so, dass sich ` d4 <= min - 50 ` immer wieder darüber beschwert, dass es keine passende Überladung für Minus hat: @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 typeIch werde jetzt Paketspezifikationen abrufen und sehen, ob mir eine Idee einfällt. Trotzdem danke!
Dank Ihrer Ideen und Hilfe habe ich diesen Teil des Codes zum Laufen gebracht, siehe Originalbeitrag EDIT2. Vielen Dank.
Gut! Jetzt verwenden Sie diese Bibliothek, anstatt blind zu programmieren und zu hoffen, dass sie funktioniert. Der Überlastungsfehler tritt auf, weil "-"(natural,natural)die Rückgabe natürlich erfolgt. Sie könnten to_unsigneddieses Ergebnis anwenden, und es könnte für den Leser sauberer sein (weniger "tricky"), aber beide Versionen sollten die gleiche Hardware erzeugen.
Da gebe ich dir vollkommen Recht :-)
+1 für die Arbeit. Ich habe kein Problem damit, eine Verbesserung vorzuschlagen, wenn Sie sich eine vernünftige Lösung ausgedacht haben, anstatt zu fragen: "Fütter mich!" Leider wird die Typtheorie und das Entwerfen von Typen heutzutage sehr schlecht gelehrt, wahrscheinlich weil Sie es in C nicht können. Daher werden wir mit unnötigen Typfehlern wie Pufferüberläufen geplagt ...
Auch die Verwendung des Codestils anderer Völker ist nicht immer die beste Vorgehensweise. Dies war das Grundproblem, da ich einen Stil von Deklarationen und Bibliotheken kopiert habe, daher kommen hier Probleme ... :-)

Anhand der von Ihnen angegebenen Informationen gehe ich davon aus, dass Sie falsche Typkonvertierungsfunktionen verwenden.
Angenommen minund d4are s sollte std_logic_vectordie 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 unsignedund integerden Funktionen to_unsigned()und to_integer()sind Ihre Freunde. Das zweite Argument von to_unsigned()ist die Länge des resultierenden unsignedWerts.

Danke für deine Idee, aber es funktioniert nicht. Ich habe es bereits versucht, aber es schlägt fehl mit der Meldung "Cast of incompatible types" und dem Hervorheben der unsigned(min). PS min ist vom Typ natural.