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