Forum: FPGA, VHDL & Co. Unsigned mit Offset zu 2 Compl VHDL


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von FPGA (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo

Meine Datenquelle liefert die Daten unsigned mit einem Offset. Die 
Datensenke benötigt ein signed 2 complement.

Wie kann dies in VHDL realisiert werden?
irgendwie so?

out <= std_logic_vector(to_signed(to_integer(unsigned(inputdata(15 
downto 0))- 32767), 16))

(0-64k soll auf -32k...+32k abgebildet werden)

von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht lesenswert
Dein signed geht von -2**15 bis +2**15-1. Damit du wirklich die -2**15 
bekommst musst du statt 32767 die 32768 abziehen.

von Josef G. (bome) (Gast)


Bewertung
3 lesenswert
nicht lesenswert
Einfach das höchste Bit invertieren.

von FPGA (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Dein signed geht von -2**15 bis +2**15-1. Damit du wirklich die
> -2**15
> bekommst musst du statt 32767 die 32768 abziehen.

Danke
Habe irgendwo gesehen, dass die Umrechnung gerne overflow macht? Geht 
dies so wie oben beschrieben oder müsste:

out <= 
std_logic_vector(resize(to_signed(to_integer(unsigned(inputdata(15
downto 0))- 32768), 16), 17);

?

von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht lesenswert
Josef G. (bome) schrieb:
> Einfach das höchste Bit invertieren.

Exakt, das ist die einfachste Lösung.

FPGA schrieb im Beitrag #6457488:
> Geht dies so wie oben beschrieben oder müsste:

Ich würde mal sagen ja, bin mir aber nicht ganz sicher.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
FPGA schrieb im Beitrag #6457488:
> Habe irgendwo gesehen
Ja, im Internet sieht man so viel...

> (0-64k soll auf -32k...+32k abgebildet werden)
Also etwa so:
   input     -->    output
dez    hex       dez      hex          
0      0000  --> -32768   8000
1      0001  --> -32767   8001
:
32767  7fff  -->     -1   ffff
32768  8000  -->      0   0000
32769  8001  -->     +1   0001
:
65534  fffe  --> +32767   7ffe
65535  ffff  --> +32768   7fff

FPGA schrieb im Beitrag #6457488:
> oder müsste:
> out <= std_logic_vector(resize(to_signed(to_integer(unsigned(inputdata(15 downto 
0))- 32768), 16), 17);

Wie sollen da aus 16 Bits auf einmal 17 werden? Warum sollte sich der 
Wertebereich verdoppeln?

> unsigned(inputdata(15 downto 0))-32768
Du kannst hier auch einfach so schreiben, wenn inputdata eh nur 16 Bit 
breit ist:
unsigned(inputdata)-32768
Und dann passiert ganau das hier:
  input   -32768 => output
dez    hex       dez      hex          
0      0000  --> -32768   8000
1      0001  --> -32767   8001
:
32767  7fff  -->     -1   ffff
32768  8000  -->      0   0000
32769  8001  -->     +1   0001
:
65534  fffe  --> +32767   7ffe
65535  ffff  --> +32768   7fff

Ergo gibt es mehrere Lösungen:
-- 1
       outval <= inval xor x"8000";
-- 2
       outval <= std_logic_vector(signed(inval)-32768);
-- 3
       outval <= std_logic_vector(unsigned(inval)-32768);
-- 4
       outval <= std_logic_vector(signed(inval)+to_signed(-32768,16));
-- 5
       outval <= std_logic_vector(signed(inval)-to_signed(-32768,16));
Die vierte "Lösung" ist dabei noch nachvollziehbar, aber zumindest die 
fünfte dann doch recht überreaschend... ;-)

Hier noch ein kurzer Test der vorgeschlagenen Lösungen:
https://www.edaplayground.com/x/bgZF
Man sieht in der Waveform, dass überall das selbe rauskommt.

Josef G. (bome) schrieb:
> Einfach das höchste Bit invertieren.
Wie wahr. Und wie elegant.

: Bearbeitet durch Moderator
von Weltbester FPGA-Pongo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Josef G. (bome) schrieb:
>> Einfach das höchste Bit invertieren.
> Wie wahr. Und wie elegant.

Auf Bit-Ebene die Daten zu manipulieren war schon immer das Schlauste, 
wenn man weiß, was man tut. Es widerspricht aber der Lesbarkeit und 
Transportierbarkeit des Codes und ich glaube nicht, dass durch einen 
sauberen Cast schaltungstechnisch etwas anderes herauskommt :-)

von FPGA (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Ergo gibt es mehrere Lösungen:-- 1
>        outval <= inval xor x"8000";
> -- 2
>        outval <= std_logic_vector(signed(inval)-32768);
> -- 3
>        outval <= std_logic_vector(unsigned(inval)-32768);
> -- 4
>        outval <= std_logic_vector(signed(inval)+to_signed(-32768,16));
> -- 5
>        outval <= std_logic_vector(signed(inval)-to_signed(-32768,16));

super Danke!

Wenn ichs richtig verstanden habe gehen alle?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.