std_logic_vector => signed zum Rechnen

Gast #2908892
Lesenswert?

Hallo zusammen,

ich habe einen 8bit std_logic_vector als Eingang.
Dieser enthält periodische signale von -100mV bis 100mV.
0x00 entspricht dabei -100mV
0x7F entspricht dabei    0mV
0xFF entspricht dabei  100mV

Wenn ich nun erst Gain und dann Offset ändern möchte, muss ich den 
Vektor ja irgendwie in ein Format bringen, der wieder 
"achsensymmetrisch" ist. Denn wenn ich von 0 auf 255 einen Faktor 
multipliziere, wird die Kurve ja nur gestaucht und der -100mV Wert wird 
z.B. so belassen, weil 0*irgendwas immer noch 0 ist.

Kann ich diesen Effekt einfach mit
1
signal input : std_logic_vector(7 downto 0);
2
signal input_signed : signed(7 downto 0);
3
... 
4
input_signed <= signed(input);
erzielen?

Dann mit einem Faktor multiplizieren
1
signal input_signed : signed(7 downto 0);
2
signal faktor : signed(7 downto 0);
3
signal result_gain : signed(15 downto 0);
4
...
5
result_gain <= input_signed * faktor;

Dann mit dem Offset addieren
1
signal result_gain : signed(15 downto 0);
2
signal offset : signed(15 downto 0);
3
signal result_offset : signed(15 downto 0);
4
...
5
result_offset <= result_gain + offset;
6
-- dann noch Überlauf abfangen etc.

Und am Ende dann wieder casten.
1
signal output  : std_logic_vector(15 downto 0);
2
signal result_offset : signed(15 downto 0);
3
...
4
output <= std_logic_vector(result_offset);

Funktioniert das in etwa so?
Habe zur zeit leider keinen Rechner dabei, auf dem die FPGA Tools sind, 
so dass ich es schnell simulieren könnte :(

Daher meine theoretischen Gedanken zu diesem Thema.

Vielen Dank!
Chris
Moderator (Firma: Titel) Persönliche Seite #2908914
Lesenswert?

Christian Z. schrieb:
> Kann ich diesen Effekt einfach mit
> signal input : std_logic_vector(7 downto 0);
> signal input_signed : signed(7 downto 0);
> ...
> input_signed <= signed(input);
> erzielen?
Wie sind signed und usigned in der Integer-Arithmetik?
Richtig: 0x80=maxneg, 0=0, 0x7f=maxpos

Also musst du vor dem Skalieren  erst mal den Offset abziehen:
> 0x7F entspricht dabei    0mV
--> ADwert-0x7f = 0x00 = 0mV
Und erst dann kannst du sorgenfrei multiplizieren und rechnen.

Was du dann zurückgibst, hängt allein davon ab, wie der Empfänger das 
Ergebnis interpretiert. Aber sinnvollerweise geht man frühestmöglich 
auf die normale vorzeichenbehaftetet Integerarithmetik über.
Moderator (Firma: Titel) Persönliche Seite #2909174
Lesenswert?

Ja, die Richtung stimmt. Allerdings wird es sinnvollerweise eher so 
sein, dass du erst nach signed wandelst und dann 0x80 subtrahierst:
input_signed <= signed(input) - 16#80;
Oder einfach:
input_signed <= signed(input) - 128;

Denn deine Skalierung ist sehr aussergewöhnlich, nichtlinear (du hast 
für 100mV mehr positive Schritte als negative, ein Integer hat aber mehr 
negative Schritte als positive) und bringt ein Problem, wenn du 0xff 
(=maxpos) - 0x7f (=0) rechnest. Dabei kommt nämlich 0x80 heraus, und das 
ist maxneg...   :-o

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren