Forum: FPGA, VHDL & Co. FIR Filter Compiler


von Andreas K. (zero_ahnung)


Angehängte Dateien:

Lesenswert?

Hallo alle zusammen,

ich hoffe hier hat bereits jemand mit dem FIR Compiler von Altera 
gearbeiten!
ich weiss nämlich gerade nicht weiter!

In den angehängten Bildern 1 und 2 seht ihr meinen "Filter"
Ich hab hier extra nur 11 Koeffizienten gewählt, um leicht die 
"Gleichspannungsverstärkung" durch Addition der Filterkoeffizienten zu 
bestimmen.

Hier kommt etwas knapp über 1 raus.

Wenn ich jetzt aber eine konstante 1 (als ein Bit eingangswort) in den 
Filter übergebe, und das ausgangssignal mit Signaltap auslese, erscheint 
der Vektor aus Bild 3.

Eigentlich würde ich hier aber mehr oder weniger sowas wie 11 oder 12 
Einsen erwarten.

Ein überlauf schließe ich aus, weil ich es vorher mit echten Werten 
ausprobiert habe, die ebenfalls alle deutlich zu klein wieder gegeben 
wurden.


Weiss jemand weiter?

Danke

von Thosch (Gast)


Lesenswert?

Dein Filter hat keine DC-Verstärkung von 1.000, sondern von 1.0498

Du hast die Bitbreite Deiner Koeffizienten auf 10 skaliert,
d.h. 10 Bit + Vorzeichen. Der Wert 1.000 ist also als 0x0400 
darzustellen.

Das was aus dem FIR-Filter rauskommt, wenn Du eine 1.000 am Eingang 
anlegst (hier also den Wert 0x0400), ist die Koeffizientensumme.

Und die ist, wie Du leicht nachrechnen kannst, 0x0433 (= 1075)

Dein Filter arbeitet also korrekt.

Gruß,
Thosch

von Thosch (Gast)


Lesenswert?

Ähm, halt, stop!

Da hab ich mich etwas vertan,
Du hast 11 Bit Daten + Vorzeichen...

Nur die Koeffizienten sind auf 10 Bit skaliert.
Beim Mittenkoeffizient hätte ich allerdings eine 512 erwartet für 0.5
Da ist wohl auf Kosten von 2 Promille Fehler ein Bit wegoptimiert 
worden.

Wie sehen die Koeffizienten in Vektordarstellung aus?
Wie breit sind die wirklich?

Und was genau hast Du (als Vektor) reingegeben ins Filter?

Wenn der Ausgang bei 0x400 am Eingang 0x433 liefert, entspricht die 
Berechnung jedenfalls Deinen Koeffizienten.

Gruß,
Thosch

von P. K. (pek)


Lesenswert?

Mach doch mal die Impulsantwort auf einen Impuls der Stärke 1. Da 
müssten dann Deine Filterparameter 1:1 hinten wieder rauspurzeln, und Du 
hast auch die Skalierungsfrage gelöst. Und kannst erst noch schauen, ob 
Du allenfalls an Genauigkeit verlierst.

von Andreas K. (zero_ahnung)


Lesenswert?

Guten Morgen und vielen Dank für eure Antworten.

@ Thosch,
- ich weiss leider nicht recht, wie ich mir die Koeffizienten in 
Vektordarstellung anzeigen lassen, Tip?

- Als Eingangssignal in den Filter dient mir ein Std_Logic_vector(0 
downto 0) mit dem Wert '1';


- Mir ist nur nich ganz klar, warum man einen Eingangsbereich von 0 bis 
1 (1 Bit) bei 12 bit / 11 bit ohne Vorzeichen, nicht so aufteilt, dass 
die 1 einer 0x07FF entspricht?
Würde ich den Bereich von 0 bis 1 mit 2 bit quantisieren, würde ich doch 
auch von 0 bis 0.25 die 00, von 0,25 bis 0,5 die 01, 0,5 bis 0,75 die 10 
und von 0,75 bis 1 die 11 übergeben.



@ Peter,
werd mal eine Schleife implementieren und schauen ob ich so ans Ziel 
komme.
Danke


für jede sinnvolle Anmerkung weiterhin sehr dankbar

von Andreas K. (zero_ahnung)


Angehängte Dateien:

Lesenswert?

Hab jetzt mal den Versuch mit der Impulsantwort übernommen,
es ergeben sich, scheinbar richtig, meine Filterkoeffizienten.

Was mir aber weiterhin nicht klar wird, ist die Darstellung des 
konstanten '1' 1Bit eingangsdatenstrom

von Andreas K. (zero_ahnung)


Angehängte Dateien:

Lesenswert?

So,da es so scheint, als liefert der FIR Compiler ständig 
Gleichtacktverstärkungen größer 1, habe ich die Koeffizieten 0.25, 0.5, 
0.25 manuell übergeben und mit 32bit verarbeiten lassen

Das Ergeniss sieht fast so aus, wie ich es erwartet habe 0xFFFFFFFD

Es sieht also auch so aus, als sei das MSB nicht als Vorzeichenbit zu 
betrachtet, sondern wirklich 32Bit unsigned.


Was mich jetzt nur weiterhin verwundert sind die Ergebnisse der 
Filterstrukturen des FIR Compilers!

Wird hierbei irgendwie mit Vorzeichenbit ausgegeben?
oder wie sind die Ergebnisse zu verstehen?


Danke
andy

von P. K. (pek)


Lesenswert?

Wenn Du Deine Filterkoeffizienten-Skalierung anschaust, ist fadengerade 
klar, dass 1 mit 0x400 repräsentiert wird (z.b 1024 = 325 / 0.31831).

Und ganz klar ist es nicht ein unsigned (sonst könntest Du -108 als 
output der Impulsantwort nicht darstellen), sondern ein signed. So wie's 
dargestellt ist ein Zweierkomplement

von Andreas K. (zero_ahnung)


Angehängte Dateien:

Lesenswert?

Okey, mir fehlt da offensichtlich etwas...

ich geben in meinem Filter einen 12 bit Wert (in 
Zweierkomplementdarstellung) aus.
Die konstante 1, also meinen Maximalwert, codiere ich mit 0x400 oder 100 
0000 0000, warum verschenke ich also jetzt den halben Wertebereich?
Meiner meinung nach müsste es 0x7FF sein.

Elektrotechnisch gesprochen, müsste bei konstantem Eingang der 
Integrator nicht voll laufen und seinen Maximalwert erreichen???


in Bild 6 ist mal eine 4 Bit 2er komplementdarstellung.
Ich würde hierbei also den Maximalen Wert nicht als 7 sondern als 4 
codieren. (komischer Satz aber vllt. versteht man was ich meine)


und warum wird im 2. Beispiel (0.25, 0.5, 0,25) die konstante 1 als 
0xFFFFFFFD ausgegeben, somit in signed betrachtet mit negativem 
Vorzeichen?

von Thosch (Gast)


Lesenswert?

Andreas K. schrieb:
> Die konstante 1, also meinen Maximalwert, codiere ich mit 0x400 oder 100
> 0000 0000, warum verschenke ich also jetzt den halben Wertebereich?
> Meiner meinung nach müsste es 0x7FF sein.

Ach, da liegt der Haken: 1 ist nicht Dein Maximalwert!

Dein Wertebereich reicht von -2.000 bis +1.999 (0x800 ... 0x7FF)

Das eine Bit mehr spendiert man normalerweise, um im Wertebereich Platz 
für die Überschwinger der Filterapertur zu haben.

Wenn Dein Eingangswertebereich nur von -1.000 bis +0.999 reicht (0xC00 
.. 0x3FF) kannst Du ausgangsseitig das Bit 10 als Überlaufbit betrachten 
und in einem nachfolgenden Begrenzer den Wertebereich beschränken, um 
wieder auf 11 Bit insgesamt zu kommen.
Der Begrenzer muß dann alle Werte kleiner 0xC00 (0x800 .. 0xBFF) auf 
0xC00 begrenzen sowie alle Werte größer 0x3FF (0x400 .. 0x7FF) auf 
0x3FF.

Gruß,
Thosch

von Thosch (Gast)


Lesenswert?

der Begrenzer braucht nur Bit 11 und 10 des Eingangs zu betrachten:

Bit 11 = VZ (Vorzeichenbit)
Bit 10 = OF (Überlaufbit)
1
EINGANG  AUSGANG
2
VZ  OF   Bit[11..0]  Fall
3
----------------------------------------------
4
 0   0   Eingang     Positiv, im Wertebereich
5
 0   1   0x3FF       Überlauf
6
 1   0   0xC00       Unterlauf
7
 1   1   Eingang     Negativ, im Wertebereich

Gruß,
Thosch

von Andreas K. (zero_ahnung)


Lesenswert?

abermals, vielen Dank

Führen wir das ganze in die Praxis:

Ich habe ein Pulsdichtemoduliertes Eingangssignal als 1 Bit Bitstream.

Jetzt möchte ich das ganze Tiefpassfiltern, um aus dem Bitstream, das 
eigentliche Signal zurück zu gewinnen.

Um hierzu bei Kontanter 1, also damit dem Maximalwert meines zu 
rekonstruhierenden signals auch wirklich den Wertebereich des Filters 
voll auszunutzen, muss ich anders Skallieren!

Soweit richtig?

Wenn ich also möchte, dass meine Konstante 1 als 0x7FF ausgegeben wird, 
muss ich auch jeden koeffizienten mit 2047 skallieren?

Wenn also vorher galt für den Koeffizienten 0.31831 (Original Value) = 
325 (Fixed Point V) galt:
(z.b 1024 = 325 / 0.31831).

Muss der selbe Koeffizient jetzt:

2047*0.31831 = 651.58057 Lauten???


Ich müsste somit eingenständig die Koeffizienten mit 2047 skallieren?



vielen dank
Andy

von Thosch (Gast)


Lesenswert?

Thosch schrieb:
> der Begrenzer braucht nur Bit 11 und 10 des Eingangs zu betrachten

Der Begrenzer hängt am Ausgang des Filters.
Gemeint ist also: Der Begrenzer braucht nur Bit 11 und 10
seines Eingangs, also des Filterausgangs auszuwerten.

Er liefert dann entweder das durchgeschleifte
um ein Bit verkürzte Eingangssignal oder eine der Konstanten 0x3FF / 
0x400.

In der Wertetabelle hatte sich noch ein Fehler eingeschlichen, hatte den 
Ausgang nicht um ein Bit verkürzt, was ja der eigentliche Grund für den 
Begrenzer war. Hier die berichtigte Tabelle:
1
EINGANG  AUSGANG
2
VZ  OF   Bit[10..0]  Fall
3
----------------------------------------------
4
 0   0   Eingang     Positiv, im Wertebereich
5
 0   1   0x3FF       Überlauf
6
 1   0   0x400       Unterlauf
7
 1   1   Eingang     Negativ, im Wertebereich

Gruß,
Thosch

von Andreas K. (zero_ahnung)


Lesenswert?

vielen vielen Dank

da kommen mir glatt die flags overflow und sign-flag bei nem 
mikroprozessor in den kopf (leider aber nur aus der vorlesung)

Was ich jetzt aber noch begreifen muss ist das skallieren der 
Koeffizienten (siehe meinen vorhegehenden Post) sowie die Tatsache das 
bei dem einfachen 0.25, 0.5, 0.25 Filter scheinbar ein negativer Wert 
ausgegeben wird.

von Andreas K. (zero_ahnung)


Angehängte Dateien:

Lesenswert?

Wenn man bei dem besagten 3 Koeffizientenfilter den Skallierungsfaktor 
berechnet, kommt man tatsächlich auf 2^32, (32 = Wortbreite des 
Ausgangswertes)

Kann es also wirklich sein, dass der FIR Compiler nicht immer im 
2er-Komplement ausgibt?

von Thosch (Gast)


Angehängte Dateien:

Lesenswert?

Andreas K. schrieb:
> Kann es also wirklich sein, dass der FIR Compiler nicht immer im
> 2er-Komplement ausgibt?

Klar, wenn Du ihm Eingangsdaten im Format "unsigned binary" 
konfigurierst...
(siehe angehängtes Bild)

Warum sollte er dann auch Ausgangsdaten in signed machen...

Ich kenne mich mit dem Tool nicht aus, arbeite mit Xilinx, und baue 
meine FIR-Filter im Regelfall "von Hand".

Hat sich übrigens bewährt, sich bei sämtlichen 
Signalverarbeituns-Geschichten ein Bitebenen-Diagramm aufzuzeichnen, 
damit man weiß, was man eigentlich tut und wo bei welchem 
Verarbeitungsschritt z.B. Überläufe auftreten können...

Dann sieht man auch gleich, wie die Stellen gewichtet sind, also wo das 
Festkomma in den Binärdaten steht. Üblicherweise zieht man z.B. ein paar 
Nachkommastellen zur Vermeidung von Rundungsfehlern durch die 
Verarbeitungskette und rundet genau einmal am Ende.

Bei einem FIR Filter mit vielen und großen Koeffizienten kann es z.B. 
nicht mehr ausreichen, nur ein Überlaufbit zu haben, mit jeder Addition 
von gleichen Wortbreiten kommt potenziell ein Bit dazu...
Die Überlaufbits (können also durchaus mehrere werden) zieht man dann 
i.d.R. bis zu einem Limiter mit.

Gruß,
Thosch

von Andreas K. (zero_ahnung)


Lesenswert?

Guten Morgen und abermals vielen Dank,

Das am Eingang "unsigned binary" liegt, hat leider keinen Einfluss auf 
das Ausgabeformat.
In all meinen Tests lag unsigned binary an. Ich werde das einfach 
jeweils testen und dann gegebenenfalls eine Komponente instanziieren, 
die mir die Werte anpasst.

von P. K. (pek)


Lesenswert?

Andreas K. schrieb:
> Das am Eingang "unsigned binary" liegt, hat leider keinen Einfluss auf
> das Ausgabeformat.

Das macht auch Sinn. Sobald Du negative Koeffizienten hast, spielt es 
keine Rolle mehr, dass Du nur "unsigned" einspeist...

von Andreas K. (zero_ahnung)


Lesenswert?

ja, scheint so zu sein! hatte bei meinen unzähligen Versuchen gedacht 
auch mal einen gegenteiligen Fall gehabt zu haben!

Vielen Dank euch!

Gruß
Andy

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.