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)
Dein signed geht von -2**15 bis +2**15-1. Damit du wirklich die -2**15 bekommst musst du statt 32767 die 32768 abziehen.
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); ?
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.
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:
1 | input --> output |
2 | dez hex dez hex |
3 | 0 0000 --> -32768 8000 |
4 | 1 0001 --> -32767 8001 |
5 | : |
6 | 32767 7fff --> -1 ffff |
7 | 32768 8000 --> 0 0000 |
8 | 32769 8001 --> +1 0001 |
9 | : |
10 | 65534 fffe --> +32767 7ffe |
11 | 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:
1 | input -32768 => output |
2 | dez hex dez hex |
3 | 0 0000 --> -32768 8000 |
4 | 1 0001 --> -32767 8001 |
5 | : |
6 | 32767 7fff --> -1 ffff |
7 | 32768 8000 --> 0 0000 |
8 | 32769 8001 --> +1 0001 |
9 | : |
10 | 65534 fffe --> +32767 7ffe |
11 | 65535 ffff --> +32768 7fff |
Ergo gibt es mehrere Lösungen:
1 | -- 1
|
2 | outval <= inval xor x"8000"; |
3 | -- 2
|
4 | outval <= std_logic_vector(signed(inval)-32768); |
5 | -- 3
|
6 | outval <= std_logic_vector(unsigned(inval)-32768); |
7 | -- 4
|
8 | outval <= std_logic_vector(signed(inval)+to_signed(-32768,16)); |
9 | -- 5
|
10 | 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
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 :-)
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?
Beitrag #6504797 wurde von einem Moderator gelöscht.
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.