Forum: FPGA, VHDL & Co. IIR Filter auf FPGA implementieren


von Robert (Gast)


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

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


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...

von high tec ingenieur (Gast)


Lesenswert?

Ich würde zunächst mehr Bits über lassen, dann Summieren und zum Schluss 
abschneiden. Wie man schneidet, hängt von der Amplitude der 
Koeffizienten ab.

von Robert (Gast)


Angehängte Dateien:

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…

von hti (Gast)


Lesenswert?

Robert schrieb:
> In meinem Fall ist der Koeffizient g1 =
> 0.0048828125. Stelle ich diesen mit 12 Bit dar, erhalte ich den
> Bitvektor 00.0000000101.

Allein durchs Kopfrechnen bekomme ich bei 0,005 x 4096 schon rund 20 und 
nicht nur 5.

von Robert (Gast)


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.

von J. S. (engineer) Benutzerseite


Lesenswert?

Die Auflösung Deiner Koeffezienten scheint mir zu gering. Je nachdem, 
wie stark die beitragen, bekommst Du einen akkumulierenden Fehler. 
Schreibe Dir das mal in einem Excel hin und prüfe die absoluten 
Abweichungen. Die statistische Gesamtabweichung ist dann ungefähr das 
mittlere Delta x Wurzel n). Da kommt was zusammen.

von Thomas R. (Firma: abaxor engineering) (abaxor)


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

von J. S. (engineer) Benutzerseite


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.

von Thomas R. (Firma: abaxor engineering) (abaxor)


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

von J. S. (engineer) Benutzerseite


Lesenswert?

Thomas Reinemann schrieb:
> Naja wenn man einen 18 x 25 Multiplizierer hat, hat man nach der
> Mutliplikation 43 Bit
Ich meinte damit, dass das nicht unbeschnitten in die Folgestufe gehen 
darf. Ist ja letztlich eine Rückkopplung auf den / die Multplier in der 
Filterkette.

Als Produkt selbst passen die 30 natürlich rein, klar.

von didi (Gast)


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...

von J. S. (engineer) Benutzerseite


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.

von Silvio K. (exh)


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

von hitec ing (Gast)


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.

von Michael (Gast)


Lesenswert?

Hallo hitec ing,

ich glaube das Winfilter nur Code für FIR erzeugen kann,
und nicht für IIR. Hast Du mal Beispiele für die anderen
Programme im Netz?

Gruß,
Michael

von Edi M. (Gast)


Lesenswert?

DFALZ

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.