Hey, ich implementiere z.Zt. eine Funktion, wo ein Datenpuffer mit einem anderen multipliziert wird. Die Daten liegen im q15-Format vor und ich wundere mich über die Funktion arm_mult_q15 aus der CMSIS DSP-Lib. Laut der Doku http://www.keil.com/pack/doc/CMSIS/DSP/html/group___basic_mult.html ist der Ausgangspuffer auch vom Typ q15; die Werte clippen wenn der Wertebereich eines q15 überschritten wird. Ich erkenne den Sinn darin nicht. Die Wahrscheinlichkeit dass bei der Multiplikation zweier q15 das Ergebnis nicht in einen q15 passt ist doch recht hoch!? Es existiert keine Implementierung der mult-Funktion für q15-Datenblöcke wo das Ergebnis als q31 dargestellt wird. Ich sehe keine andere Möglichkeit als das händisch mit einer for-Schleife zu realisieren. Wofür ist die Funktion zu gebrauchen? Stephan
Dürfte ein Feature sein, normale Multiplikationen saturieren in C ja sonst eher nicht. Musst du halt vorher q31 aus deinen Daten machen, dafür gibt's ja Hilfsfunktionen.
Stephan schrieb: > Die Wahrscheinlichkeit dass bei der Multiplikation zweier q15 das > Ergebnis nicht in einen q15 passt ist doch recht hoch!? Eigentlich nicht. Bedenke, das die Multiplikation im q15 Format erfolgt, d.h. das Ergebnis der Multiplikation wird intern als 32 Bit Wert berechnet und dann wieder um 15 Bits nach rechts geschiftet um wieder zu einem q15 Format zu gelangen. In Pseudo-Code sieht das so aus: int16_t a = arg1; int16_t b = arg2; int32_t product = arg1 * (int32_t) arg2; int16_t result = saturate (product>>15, 16); D.h. das Saturieren ist ehr unwarscheinlich und tritt nur in Fällen auf, wo das Ergebniss wirklich nicht mehr in das q15 Format passt. Intern läuft alles mit so hoher Genauigkeit das kein Overflow passieren kann. Caveat: Ob vor dem Shiften sauber gerundet wird oder nicht weis ich nicht. Gruß, Nils
https://courses.cs.washington.edu/courses/cse467/08au/pdfs/lectures/11-FixedPointArithmetic.pdf Gruß, Stefan
q15_t bedeutet: 1 Sign-Bit und 15 Nachkomma-Bits. D.h. der Wertebereich eines q15_t geht von -1.0 bis 0.99999.. Beim Multiplizieren zweier q15_t passt das Ergebnis immer in ein q15_t: zwei Werte kleiner 1 multipliziert ergibt immer ein Ergebnis kleiner 1. Auf Hardware-Ebene passiert das, was Nils beschrieben hat, Multiplikation und anschliessender 15-facher Shift rechts. Auf Hardwareebene Für die Min/Max-Werte: 0.999 * 0.999 -> (7FFFh * 7FFFh) >> 15 = 3FFF0001 >> 15 = 7FFE -> 0.999 -1.0 * -1.0 -> (8000h * 8000h) >> 15 = 40000000 >> 15 = 8000 -> -1.0 Im oben verlinkten Dokument ist das sehr gut beschrieben. Viele Grüße, Stefan
Vielen Dank! Bzgl. meiner Anwendung: Wenn ich das richtig interpretiere kann ich also einen Puffer aus int16-Werten (Zweierkomplement) einfach als q15-Daten übernehmen. Es ändert sich nur die Interpretation; die Abbildung der Zahlen +32767 ... -32768 auf den Wertebereich +1.0-1/2^15 ... -1.0. Demnach kann ich einen q15-Puffer also einfach mit Daten von einem AD-Wandler (liefert Werte in Zweierkomlementdarstellung) füllen, wobei dann die -1.0 einer maximalen Aussteuerung in negative Richtung entspricht? Gruß Stephan
Kommt auf das Alignment des AD-Wandlers an. Wenn der ADC left-aligned speichern kann, dann funktioniert das wie von Dir gewünscht. Bei einigen ADCs (z.B: der im STM32F) kann man das Alignement einstellen. Hat der ADC 16 Bit, dann passt es natürlich immer. Gruß, Stefan
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.