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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch Moderator
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
Er möchte aber unsigned. Also ganz einfache Interpretation vom std_logic_vector als Binärzahl.
Solltest du dann aber nicht vorne eine '0' anfügen statt einer '1'? Das Ziel ist doch größer als die Quelle.
UPS, ja klar, richtig, sorry. Vielen Dank kann es aber nichtmehr editieren.
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.
1 | counter <= unsigned(register'left & register); |
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
Danke! Das Einerkomplement wird auch von Banken noch verwendet weil man da die rote und schwarze Null trennen kann.
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:
1 | Dezimal Zweierkompl. Einerkompl. Betrags-V. BCD |
2 | 10 0 0000 1010 0 0000 1010 0 0000 1010 0 0000 1010 |
3 | 2 0 0000 0010 0 0000 0010 0 0000 0010 0 0000 0010 |
4 | +0 0 0000 0000 0 0000 0000 0 0000 0000 0 0000 0000 |
5 | -0 1 1111 1111 1 0000 0000 1 0000 0000 |
6 | -5 1 1111 1011 1 1111 1010 1 0000 0101 1 0000 0101 |
7 | -14 1 1111 0010 1 1111 0001 1 0000 1110 1 0001 0100 |
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.
:
Bearbeitet durch User
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.