IIR Filter auf FPGA implementieren

Gast #3198934
Lesenswert?

Hallo,
ich versuche auf einem Spartan6 XC6LX16-CS324 ein IIR Filter in der 
transponierten Direktform II zu realisieren. Dabei würde ich gerne die 
internen Multiplizierer und Addierer, der 32 DSP48A1 Slices verwenden. 
Das Filter habe ich mit dem fdatool von Matlab erzeugt und quantisiere 
die Filterkoeffizienten mit 12 Bit. Auch mein abgetastetes Signal wird 
durch 12 Bit dargestellt. Jedoch handelt es sich bei den Multiplizierern 
um 18x18 Bit Multiplizierer, die ein 36 Bit Ergebnis liefern. Wie ich 
aus meinen 12 Bit 18 Bit mache, ist kein Problem, jedoch weiß ich nicht, 
wie ich meine 36 Bit „zurechtschneiden“ soll, um daraus wieder 18 Bit zu 
gewinnen.
Wäre für jede Hilfe sehr dankbar.
Grüße
Robert
Moderator (Firma: Titel) Persönliche Seite #3198955
Lesenswert?

Robert schrieb:
> Wie ich aus meinen 12 Bit 18 Bit mache, ist kein Problem,
Wie machst du das?

> jedoch weiß ich nicht, wie ich meine 36 Bit „zurechtschneiden“ soll,
> um daraus wieder 18 Bit zu gewinnen. Wäre für jede Hilfe sehr dankbar.
Schneide die hinteren Bits ab. Denn dort sind die am wenigsten 
signifikanten Informationen enthalten...

Betrachte deine 12-Bit Zahlen einfach mal so, als ob damit ein 
Zahlenbereich von -1 bis +1 abgebildet werden würde (dazu musst du diese 
Zahl einfach gedanklich durch 4096 teilen). Und wenn du jetzt was mit 
diesen Zahlen rechnest, dann kommt wieder was im Bereich zwischen -1 und 
+1 raus. Nur musst du diese Zahl jetzt gedanklich durch 4096*4096 
teilen. Das erste "Teilen" davon ist das Abschneiden der "hinteren" 
Bits.

Wenn du 12*12 Bit rechnest, dann schneidest du also 12 Bits weg. Wenn du 
18*18 Bit rechnest, dann schneidest du 18 Bits weg.
Oder: wenn du vor der Rechnung deine 12 Bit nach links in den 18er 
Vektor ausrichtest, dann schneidest du 22 Bits weg.
Zeichne das einfach mal auf und probiers aus. Es ist gar nicht so 
schwer...
Gast #3199506
Lesenswert?

Das haut irgendwie nicht hin. Ich möchte das Filter, wie in der 
angehängten Grafik darstellen. In meinem Fall ist der Koeffizient g1 = 
0.0048828125. Stelle ich diesen mit 12 Bit dar, erhalte ich den 
Bitvektor 00.0000000101. Angenommen mein Eingangssignal XN entspricht 
dem Wert 127 (000001111111) und ich multipliziere diesen mit dem 
Koeffizienten, ist das Ergebnis 0.6201171875 bzw. 
00000000000000.1001111011. Würde ich jetzt die hinteren 12 Bits 
wegschneiden, wäre mein Signal direkt nach der ersten Multiplikation 0 
und somit das Filter nutzlos. Ist mein Eingangssignal jedoch 2047 
(0111111111111) ergibt die Multiplikation  9.9951171875 
(00000000001001.1111111011) und mein Ergebnis würde durch das 
Abschneiden auf 9 abgeschnitten werden. Ich steh noch total auf dem 
Schlauch…
Angehängte Dateien:
Gast #3199558
Lesenswert?

Naja, meine Koeffizienten liegen zwischen -1.5 und 1.5. Also muss ich 1 
Bit für die 2er-Komplement Darstellung aufbringen und 1 Bit für die 1 
vor dem Komma. Somit stehen mir 10 Bit für den gebrochenen Teil zur 
Verfügung. Deswegen habe ich 1024 mal 0,005 gerechnet.
(Firma: abaxor engineering) #3200377
Lesenswert?

Robert schrieb:
> Das haut irgendwie nicht hin. Ich möchte das Filter, wie in der
> angehängten Grafik darstellen. In meinem Fall ist der Koeffizient g1 =
> 0.0048828125. Stelle ich diesen mit 12 Bit dar, erhalte ich den
> Bitvektor 00.0000000101. Angenommen mein Eingangssignal XN entspricht
> dem Wert 127 (000001111111) und ich multipliziere diesen mit dem
> Koeffizienten, ist das Ergebnis 0.6201171875 bzw.
> 00000000000000.1001111011.

Du willst erreichen
x * 0.0048828125 > 1

Das heißt

x > 1/0.0048828125 bzw. ab x > 208 ist das Ergebnis größer 1.

Warum rechnest du g1 nicht in die b1 Koeffizienten mit rein. 
Grundsätzlich sind 12 Bit zu wenig. Wenn Xilinx dir 18 Bit Mutiplizierer 
gibt, solltest du die voll ausnutzen. D.h. nach der Multiplikation hast 
du 12 Vorkommastellen und 18 Nachkommastellen. Da dein Addierer > 40 Bit 
kann, kannst du problemlos mit 12.18 Bit weiter rechnen. Dabei summieren 
sich die fünf Nachkommabeträge auf. Erst nach der letzten Summation wird 
abgeschnitten.

Grundsätzlich ist es gut, einen Algorithmus vor Implementierung in der 
Festkommaversion zu testen. Das geht gut mit einer Tabellenkalkulation. 
Da gibt es Funktionen zum Runden/Abschneiden. Da kannst du dann Schritt 
für Schritt den Algorithmus optimieren und siehst sofort das Ergebnis.

Noch ein Tipp, je nach Verhältnis von Takt- zu Samplingfrequenz kommt 
man für deine SOS (second order section) mit einem DSP-slice aus.

Tom
Persönliche Seite #3201251
Lesenswert?

Thomas Reinemann schrieb:
> D.h. nach der Multiplikation hast
> du 12 Vorkommastellen und 18 Nachkommastellen
Das wären aber dann 30 und der Spartan kann nur 18 x 25. Meintest Du 
6+12=18?

Bei den vorliegenden Resourcen würde ich durchaus mit bis 24 Bit 
Auslösung für die Koeffizienten arbeiten, weil die Fehler beim IIR 
kummulieren. Daher sollte man den breiten Anschluss für die K's nutzen. 
Beim FIR geht es auch umgekehrt. Zumindest bei grossen Filtertiefen.
(Firma: abaxor engineering) #3201471
Lesenswert?

Jürgen Schuhmacher schrieb:
> Thomas Reinemann schrieb:
>> D.h. nach der Multiplikation hast
>> du 12 Vorkommastellen und 18 Nachkommastellen
> Das wären aber dann 30 und der Spartan kann nur 18 x 25. Meintest Du
> 6+12=18?

Naja wenn man einen 18 x 25 Multiplizierer hat, hat man nach der 
Mutliplikation 43 Bit, da passen doch alle Male 30 Bit rein. Wo ist das 
Problem?

Na gut vielleicht hätte ich schreiben sollen: "Das Produkt hat 12 
Vorkommastellen und 18 Nachkommastellen."

Das geht natürlich nur, wenn g1 in die b1(x) rein gerechnet wurde.

Tom
Gast #3201631
Lesenswert?

Lothar Miller schrieb:
> Wenn du 12*12 Bit rechnest, dann schneidest du also 12 Bits weg. Wenn du
> 18*18 Bit rechnest, dann schneidest du 18 Bits weg.
> Oder: wenn du vor der Rechnung deine 12 Bit nach links in den 18er
> Vektor ausrichtest, dann schneidest du 22 Bits weg.

Kann das jemand für mich noch einmal genauer erklären? Ich hätte jetzt 
gedacht, wenn ich die 12 Bit auf 18 erweitere (linksshift um 6 bits), 
müsste ich danach nicht 22, sondern 18+6=24 Bit wegschneiden...
Persönliche Seite #3206925
Lesenswert?

In erster Betrachtung ja. In zweiter Betrachtung schneidest Du am Ende 
und bei allen Zwischenstufen soviele Bits weg, dass die Auflösung passt 
und sich die Fehler in Grenzen halten. Du must im Grunde nur den Faktor, 
den Du jeweils rein multiplizerst, irgendwo wieder abziehen.

Was die Filterkoeffs angeht, wird man die so skalieren, dass sie 
entweder am Maximum Vollaussteuerung haben, oder in der Konsequenz einen 
Produktwert ergeben, der einer Binärzahl entspricht, da man durch diese 
wieder teilen muss. Insbesondere bei FIR-Filtern kann man da schön 
jongliergen.

In Deinem Fall musst Du nur wissen, ie hoch die Verstärkung an jedem 
Punkt Deiner Filterkette ist, damit die Additionen richtig passen.
#3242691
Lesenswert?

Dieses Thema passt hervorragend zu meinen aktuellen Überlegungen. In 
meiner Sache muss der M3 des SoCs alles rechnen. Allerdings Actel und 
nicht Xilinx. Das macht er auch gut, aber auf Kosten wertvoller 
Millisekunden. Falls in dieser Sache handgestrickter VHDL-Code 
(-Fragmente) herauskommt, würde ich mich sehr über dessen 
Veröffentlichung freuen.

Viele Grüße und Filtri Heil

Silvio
Gast #3243038
Lesenswert?

du kannst in VHDL jederzeit einen Filter mit dem Coregen designen. IIR 
auf Actel wird es auch geben. Oder du nutzt Winfilter oder eines der 
anderen Programme im Netz. Die einzige Herausforderung ist die 
Auflösung.

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