Forum: FPGA, VHDL & Co. Arithmetischen Mittelwert bestimmen


von Chris2k (Gast)


Lesenswert?

Hallo zusammen,

die Überschrift verrät das Problem. Ich habe ein demoduliertes Signal 
vorliegen, welches rechteckförmig ist. Das demodulierte Signal bewegt 
sich von -900 bis +900, fast alle Werte halten sich aber bei +/- 850 
(+/- 5% um 850) auf. Ich möchte über ein Window von insgesamt 512 Werten 
den arithmetischen Mittelwert sowohl der positives Samples als auch der 
negatives Samples bestimmen. Also zunächst feststellen, ob Wert positiv 
oder negativ ist, und anschließend den Wert des Samples auf den pos. 
Akkumulator oder neg. Akkumulator aufaddieren. Dann den neg. oder pos. 
Sample-Zähler inkrementieren. Wenn 512 Samples vorhanden sind, den 
positiven Akku durch den pos. Sample-Zähler teilen, das gleiche mit 
negativem Akku und neg. Sample-Zähler.

Offensichtliches Problem ist die Division, da der Divisor nun nicht mehr 
ein Vielfaches von 2**n ist.

Zur geforderten Genauigkeit: Sollte recht hoch sein, da mit der 
Berechnung der arithmetische Mittelwert der +/- Samples bestimmt werden 
und das dann als DC-Offset von den Samples abgezogen werden soll.

Ich stehe gerade aufm Schlauch, vielleicht kann jemand einen Denkanstoß 
geben.

von Chris2k (Gast)


Lesenswert?

Ich habe noch etwas vergessen:

Sprache ist VHDL. Device ist ein MachXO2-7000 von Lattice. Verwendete 
Software ist Lattice Diamond. Es gibt natürlich keinen Hardware-Divider 
und auch keinen IP-Core zur Division in der Software.

Platzbedarf: Darf nicht zu üppig werden (kann ich ja dann ausprobieren), 
v.a. weil es sich nur um zwei Mittelwerte handelt und ich hatte 
eigentlich noch was anderes mit dem FPGA vor... ;)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris2k schrieb:
> Offensichtliches Problem ist die Division, da der Divisor nun nicht mehr
> ein Vielfaches von 2**n ist.
Erst mal die Division:
http://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.html

> Zur geforderten Genauigkeit: Sollte recht hoch sein
Hast du da noch genauere Angaben? Eine Integer-Division liefert 
traditionell eine Ganzzahl und den Rest...

von Chris2k (Gast)


Lesenswert?

Hallo Lothar :)

die Division von deiner Seite zu nehmen wäre natürlich die einfachste 
Variante. Aber dann benötige ich ein paar Clocks nur für diesen 
dämlichen Mittelwert. Ist schon ärgerlich, wenn man wissentlich nur 
durch 2**n teilen möchte, und dann sowas dazwischenkommt...
Daher dachte ich, jemand hat einen tollen Algorithmus parat, der von mir 
aus einen gleitenden Mittelwert implementiert, und zudem noch mit nicht 
erheblichem Ressourcenbedarf daherkommt. Gut, das hört sich jetzt wie 
die eierlegende Wollmilchsau an :)

Zur Genauigkeit. Mir reichen zum jetzigen Zeitpunkt Integer-Werte, auf 
Nachkommastellen kann ich verzichten. Das meintest du doch, oder? Wenn 
ein Algorithmus nun nicht 100% genau den Mittelwert bestimmt und die 
letzte Integer-Stelle etwas verfälscht, ist das vorerst auch nicht ein 
großes Problem.

von amateur (Gast)


Lesenswert?

>da der Divisor nun nicht mehr ein Vielfaches von 2**n ist.

Vorsicht außer zufällig zum "Zeitpunkt": 2,4,8,16 .. 512 ist kein 
Divisor ein Vielfaches von 2**n. "Wir sind in der Minderheit".

von P. K. (pek)


Lesenswert?

Wenn das Signal kontinuierlich wäre und Du die ersten 512 Worte nicht 
brauchst, gäbe es einen einfachen Ansatz, der mit einem 
512-Worte-Block-Memory auskommt:

Initialisierung:
Du addierst die ersten 512 samples, das gibt Dir die erste "Summe".

Bei jedem weiteren Sample:
Summe = Summe + Sample(t) - Sample(t-512)
Moving AVERAGE = hinterste 9 bit weglassen

von Chris2k (Gast)


Lesenswert?

Danke, ich denke, das wird der sparsamste Ansatz sein.

amateur schrieb:
>>da der Divisor nun nicht mehr ein Vielfaches von 2**n ist.
>
> Vorsicht außer zufällig zum "Zeitpunkt": 2,4,8,16 .. 512 ist kein
> Divisor ein Vielfaches von 2**n. "Wir sind in der Minderheit".

???

von profi (Gast)


Lesenswert?

Chris2k schrieb:
>> Vorsicht außer zufällig zum "Zeitpunkt": 2,4,8,16 .. 512 ist kein
>> Divisor ein Vielfaches von 2**n. "Wir sind in der Minderheit".
> ???
aus genau dem Grund ist Alkohol während der Arbeit in den meisten Firmen 
verboten

Das einfachste wäre man dehnt den Messbereich auf soviele Samples aus, 
dass es wieder 512 werden.

Was ich nicht verstehe: Warum werden pos / neg extra gezählt?
Wo ist da der Sinn?

Warum nimmt man nicht den echten Mittelwert?

Ungeachtet dessen meine ich, dass man sich die halbe Arbeit sparen kann, 
wann man EIN Datenfenster berechnet hat. Das andere ist dann irgendwie 
komplementär.

von Chris2k (Gast)


Lesenswert?

Ich habe es versucht einfach zu halten, daher ist der Sinn des ganzen 
natürlich nicht auffindbar :)

Es handelt sich bei den Samples um ein demoduliertes Signal, positive 
Werte stellen eine "1" dar, negative eine "0". Die Werte sind noch nicht 
dezimiert, sprich: es gibt vier Samples pro realem Datenbit (das Signal 
ist 4-fach überabgetastet). Für weitergehende statistische Analysen des 
Signals soll die Verteilung der demodulierten, nicht-dezimierten Samples 
betrachtet werden, und zwar in ihrer Gesamtheit (und nicht etwa auf die 
nur positiven oder negativen Werte). Und das über ein Window von 512 
Samples.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris2k schrieb:
> Und das über ein Window von 512 Samples.
Ist nicht schon das auch eine willkürliche Annahme? Warum kannst du dann 
nicht willkürlich irgendwas anderes annehmen, was besser passt...

von P. K. (pek)


Lesenswert?

Chris2k schrieb:
> Und das über ein Window von 512 Samples.

Na also, sieht kontinuierlich aus. Damit kannst Du das mit dem "moving 
average" erschlagen, was dich 1 Addition und 1 Subtraktion pro Datenwort 
kostet plus etwas Speicher (und die Tasache, dass die ersten N=512 Worte 
noch nicht brauchbar sind).
Wenn Du's generisch aufbaust, kannst Du auch einfach nach einem 
beliebigen anderen N=2^M wechseln, falls nötig.

von Lattice User (Gast)


Lesenswert?

Einfach alle 512 Werte aufsummieren, bzw gleitenter Mittelwert 
funktionier nur wenn die 0 und 1 gleichverteilt sind, d.h. der Bitstrom 
ist gleichspannungsfrei. Ich vermute mal dass dem nichr so ist, und es 
auch deswegen Probleme mit der Demodulation gibt, die hier durch 
Bestimmen des Offsets aus den Min/Max Werten gelöst werden sollen.

Ich empfehle einen Schritt zurück zu gehen und eine gleichspannungsfreie 
Codierung der Daten zu verwenden, z.B. Manchester oder 10b8b mit 
Disparity. Dann kann manch sich solche Klimmzüge sparen.

von Chris2k (Gast)


Lesenswert?

Lothar Miller schrieb:
> Ist nicht schon das auch eine willkürliche Annahme? Warum kannst du dann
> nicht willkürlich irgendwas anderes annehmen, was besser passt...

Das Window muß hinreichend groß sein, um für folgende Statistik eine 
ausreichende Datenmenge zu haben. 512 (bzw. 2**n) hatte ich gewählt, 
weil im späteren Verlauf durch die Anzahl der Samples geteilt werden 
muss.

Lattice User schrieb:
> Einfach alle 512 Werte aufsummieren, bzw gleitenter Mittelwert
> funktionier nur wenn die 0 und 1 gleichverteilt sind, d.h. der Bitstrom
> ist gleichspannungsfrei. Ich vermute mal dass dem nichr so ist, und es
> auch deswegen Probleme mit der Demodulation gibt, die hier durch
> Bestimmen des Offsets aus den Min/Max Werten gelöst werden sollen.
>
> Ich empfehle einen Schritt zurück zu gehen und eine gleichspannungsfreie
> Codierung der Daten zu verwenden, z.B. Manchester oder 10b8b mit
> Disparity. Dann kann manch sich solche Klimmzüge sparen.

Einen Schritt zurück: Das modulierte Ausgangssignal ist ein 
O-QPSK-Signal (IEEE 802.15.4), welches auch als MSK interpretiert werden 
kann. Die Demodulation erfolgt über arctan(Q/I) (-> CORDIC). In der Tat 
klappt die Demodulation nicht zu 100% zufriedenstellend - den Grund habe 
ich noch nicht herausgefunden. Aber ich denke, das ist ein ganz anderes 
Thema :-)

Aber der Hintergrund ist, wie beschrieben, eine Statistik über die 
Verteilung aufzustellen. Ich möchte damit keine Demodulationsfehler o.ä. 
ausmerzen oder sonstwie an der Demodulation herumfeilen.

von Lattice User (Gast)


Lesenswert?

Chris2k schrieb:
> Aber der Hintergrund ist, wie beschrieben, eine Statistik über die
> Verteilung aufzustellen.

Wie wäre es einfach die Anzahl der positiven Werte, die Summe der 
postiven Werte, das gleiche für die negativen weitergeben und die 
Division der Auswertesoftware überlassen?

von Chris2k (Gast)


Lesenswert?

Lattice User schrieb:

> Wie wäre es einfach die Anzahl der positiven Werte, die Summe der
> postiven Werte, das gleiche für die negativen weitergeben und die
> Division der Auswertesoftware überlassen?

Das wäre ja zu einfach ;-) Das soll auf dem FPGA laufen. Ja, nicht 
gerade der optimale Anwendungsfall für einen FPGA, aber es ist auch eher 
eine "Machbarkeitsstudie", ob das Projekt in Hardware realisiert werden 
kann und welche Ressourcen dafür verbraucht werden.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wenn sowieso die positiven und die negativen Werte getrennt angeschaut 
werden, warum schaust du dir dann nicht einfach 512 aufeinanderfolgende 
positive und 512 aufeinanderfolgende negative Werte an? Klar, dass 
dieses "Fenster" dann nicht direkt was mit dem 512er "Gesamtfenster" zu 
tun hat...

von Chris2k (Gast)


Lesenswert?

Genau das mach ich ja jetzt. Die Gleichanteile der positiven und 
negativen Samples ändert sich nicht sprungartig, daher kann ich, 
unabhängig von der eigentlich gewünschten Window Size, über die letzten 
2**n Samples die Mittelwerte berechnen. Für positiv und negativ 
getrennt.

Im nachhinein hätte ich auch selbst drauf kommen können :-)

von S. (Gast)


Lesenswert?

Lattice User schrieb:
> Einfach alle 512 Werte aufsummieren, bzw gleitenter Mittelwert
>
> funktionier nur wenn die 0 und 1 gleichverteilt sind, d.h. der Bitstrom
>
> ist gleichspannungsfrei.

Dann bräuchte man garnichts zu summieren, denn dann käme der 
"gleichspannungsfreie" Wert, nämlich Null heraus.

Chris2k schrieb:
> über die letzten
>
> 2**n Samples die Mittelwerte berechnen. Für positiv und negativ
>
> getrennt.

jetzt stimmt die Dezimation nicht mehr!

von exseler (Gast)


Lesenswert?

... statt der Division vielleicht eine Multiplikation, wobei der 
Multiplikator passend aus einer LUT genommen wird, mit der Anzahl der 
Samples als Index?

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.