Hallo,
ich hänge wohl gerade an einem Anfängerproblem und hoffe, dass ihr mir
helfen könnt.
Ich übertrage im VHDL-Modell über SPI ein 32Bit-Wort in ein Register das
als std_logic_vector (31 downto 0) deklariert und initialisiert wurde.
Das klappt laut Kompiler und Simulation.
Nun möchte ich diesen Wert in einen als unsignet (32 downto 0)
deklarierten Counter überführen, bei dem ich das oberste Bit verwenden
möchte, um beim Zählen den Überlauf zu detektieren.
Den Übertrag erledige ich durch einen Cast in der Form
counter <= unsigned(register);
Hier meckert der Kompiler, da die Länge der Wörter nicht zueinander
passen.
Wie könnte ich dem 33Bit-Register den gecasteten 32Bit-Vektor übergeben?
Hierfür müsste ich den gecasteten Wert wohl "vergrößern".
Ich hoffe auf eine kurze Hilfestellung von euch.
Mit Gruß
Schmidt
counter <= unsigned('1' & register);
oder müsste es
counter <= unsigned("1" & register);
heißen?
Vermutlich geht auch
counter <= '1' & unsigned(register);
oder
counter <= "1" & unsigned(register);
je nachdem was nun richtig ist, habe gerade keine Software zur Hand.
counter(31 downto 0) <= unsigned(register);
sollte aber immer funktionieren.
Schmidt schrieb:> Hierfür müsste ich den gecasteten Wert wohl "vergrößern".
"Verbreitern", denn man spricht von der Vektorbreite... ;-)
Ich empfehle die Funktion resize() aus der numeric_std anzusehen. Die
macht das dann richtig, egal ob signed oder unsigned.
Hi
Bitte nicht schlagen - aber bei 'signed' ist doch 'nur' ein weiteres
0-bit davor - zumindest bei positiven Zahlen.
Bei <0 das 2er Komplement, wodurch 'ganz vorne' eine 1 entsteht.
MfG
Patrick J. schrieb:> Bitte nicht schlagen - aber bei 'signed' ist doch 'nur' ein weiteres> 0-bit davor - zumindest bei positiven Zahlen.> Bei <0 das 2er Komplement, wodurch 'ganz vorne' eine 1 entsteht.
Das ganze lässt sich auch ohne Fallunterscheidung verkürzen, indem man
einfach das höchste Datenbit der Quelle vervielfältigt.
Schmidt schrieb:> Nun möchte ich diesen Wert in einen als unsignet (32 downto 0)> deklarierten Counter überführen, bei dem ich das oberste Bit verwenden> möchte, um beim Zählen den Überlauf zu detektieren.
So wie ich das verstehe hat er einen 32Bit Zähler. Und wenn der
überläuft ist das 33zigste Bit gesetzt. Wenn man aber vom 32Bit Zähler
gleich das MSB in das 33. Bit reinschreibt, dann erkennt man einen
Überlauf eines 31Bit Zählers.
Stimmt, bezogen auf die Eingangsfrage ist diese Feststellung natürlich
völlig korrekt! Patrick hatte aber gezielt signed-Werte angesprochen,
auch wenn diese hier nicht relevant sind.
Ja, stimmt. Gibt es eigentlich einen Grund dafür wieso signed generell
so definiert ist dass das signed Bit bei negativen Zahlen gesetzt ist?
Ich meine, das könnte man doch auch bei positiven Zahlen setzen. Dann
könnte man die Zahlen viel einfacher z. B. sortieren.
Gustl B. schrieb:> Ja, stimmt. Gibt es eigentlich einen Grund dafür wieso signed generell> so definiert ist dass das signed Bit bei negativen Zahlen gesetzt ist?
Ja, der Grund besteht darin, dass man durch einfaches Dekrementieren
eines auf Null stehenden Zähler eine -1 erhalten muss. Und das ist eben
in der Zweierkomplementdarstellung sehr einfach möglich.
Ein Zähler, der mit einem Vorzeichenbit und ansonsten positiven Werten
rechnen soll, müsste doch recht umfangreiche Fallunterscheiden machen,
d.h. in Abhängigkeit vom Vorzeichenbit den Betrag entweder
inkrementieren oder Dekrementieren.
Und bei der Verwendung des Einerkomplements tritt der unschöne Effekt
auf, dass man zwei Nullen erhält: +5, +4, +3, +2, +1, +0, -0, -1, -2,
usw.. Interessanterweise wird eine Variante des Einerkomplements jedoch
für die Berechnung der Prüfsummen in TCP, UDP und IP verwendet, da es
Mehrfachbitfehler mit höherer Wahrscheinlichkeit erkennt als bei der
Summation im Zweierkomplement.
https://tools.ietf.org/html/rfc1071
Gustl B. schrieb:> Danke! Das Einerkomplement wird auch von Banken noch verwendet weil man> da die rote und schwarze Null trennen kann.
Ähh, nein. Im Bankenbereich wird mit der Betrags-Vorzeichendarstellung
gearbeitet, und zwar vorzugsweise als BCD:
Bei etlichen Mikroprozessoren (x86 in der FPU, 68000, PowerPC) gibt es
sogar arithmetische Befehle für die Verarbeitung von BCD-Zahlen, ebenso
auch etliche Prozessoren der mittleren Datentechnik (VAX) und
Großrechner (etliche IBM), die ja auch historisch gesehen im
Bankenbereich sehr verbreitet sind/waren.
Hallo,
ich wollte mich für den Hinweis mit der resize() Funktion bedanken. Das
funktioniert offenbar tadellos.
@Gustl
ja,
counter(31 downto 0) <= unsigned(register);
funktioniert. Nur die Zuweisung zu einem 33stelligen unsigned klappt
nicht.
ich hatte auch schon so etwas wie
counter <= '1' & unsigned(register);
versucht. Aber der Kompiler mochte das auch nicht. Daher meine Frage
hier im Forum.
Mit vielem Dank, wieder etwas dazu gelernt.
Schmidt