Forum: FPGA, VHDL & Co. 32 Bit vector in ein 33 Bit unsigned überführen, wie geht das?


von Schmidt (Gast)


Lesenswert?

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

von Gustl B. (-gb-)


Lesenswert?

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
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Patrick J. (ho-bit-hun-ter)


Lesenswert?

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

von Gustl B. (-gb-)


Lesenswert?

Er möchte aber unsigned. Also ganz einfache Interpretation vom 
std_logic_vector als Binärzahl.

von S. R. (svenska)


Lesenswert?

Solltest du dann aber nicht vorne eine '0' anfügen statt einer '1'? Das 
Ziel ist doch größer als die Quelle.

von Gustl B. (-gb-)


Lesenswert?

UPS, ja klar, richtig, sorry. Vielen Dank kann es aber nichtmehr 
editieren.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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);

von Gustl B. (-gb-)


Lesenswert?

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.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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

von Gustl B. (-gb-)


Lesenswert?

Danke! Das Einerkomplement wird auch von Banken noch verwendet weil man 
da die rote und schwarze Null trennen kann.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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
von Schmidt (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.