Forum: FPGA, VHDL & Co. FIR-, IIR-Filter in VHDL umsetzen


von Thomas Wolf (Gast)


Lesenswert?

Hallo zusammen

Ich brauche jetzt eure Hilfe. Bin kein VHDL-Experte. Wie realisiert man
einen IIR-Filter 1. Ordnung in VHDL?
Die Übertragungsfunktion ist H(z) = 1 / (1 - 0,9991*z^-1).
Sampling Frequenz = 2000 Hz
Cut Off Freuquenz = 0,3 Hz
Ich bekomme alle 500µs einen 10 Bit breiten Wert.
Der Ausgang soll ebenfalls 10 bit betragen.

Kann mir jemand helfen?

Gruss,
Thomas

von Sebastian Dunst (Gast)


Lesenswert?

Hallo Thomas

Zeichne Dir die Filterstruktur einfach auf ein Blatt Papier auf (sollte
bei diesem einfachen IIR 1.Ordnung ja kein Problem sein).

Somit hast Du die "Schaltung" bereits fertig. Diese Schaltung wird
ein 10 bit breites D-FF enthalten und einen Multiplizierer für den
Koeffizienten und das wars schon.

Nun musst Du diese Schaltung nur noch mit Hilfe von VHDL
"nachzeichnen".

Viel Erfolg,

Sebastian

von Thomas Wolf (Gast)


Lesenswert?

Hallo nochmal

Danke, Sebastian.

Was anderes:
Wie multipliziere ich ein 21 bit breites Signal mit dem Bruch
1023/1024 ?

Ich komm' nicht drauf...

Gruss,
Thomas

von Jörn (Gast)


Lesenswert?

Signal mal 1023 mittels eines Multiplizieres und anschließend um 10
Stellen nach rechts schieben, das entspricht der Division durch 1024.

Gruß Jörn

von FPGA-User (Gast)


Lesenswert?

du musst mit Festkommazahlen arbeiten, such mal nach
dem Begriff bei google bzw. "Fractional Integer Numbers",
evt. gibts da auch bei XILINX/ALTERA Infos dazu

von Hagen (Gast)


Lesenswert?

@Jörn:

oder in diesem speziellen Fall einfach das Signal mit 10
linksverschieben, dann das ursprüngliche Signal davon einmal
subtrahieren und dann wieder mit 10 nach rechts verschieben:

Result := (X << 10 - X) >> 10;

das lässt sich vereinfachen und ergibt:

Result := X - (X >> 10);

Gruß Hagen

von Hagen (Gast)


Lesenswert?

oder eben zB. bei einem Signalvektor von signal X: std_logic_vector(31
downto 0) sähe es so aus

Result := X - "0000000000" & X(31 downto 10);

Die Multiplikation mit 1023/1024 ist also ideal zu optimieren und
sollte gegenüber einer Festkomma MUltiplikation bevorzugt werden.

Gruß Hagen

von FPGA-User (Gast)


Lesenswert?

Achtung !
man muss natürlich jetzt mit mehr als 10 bit weiterarbeiten,
wie Hagen sehr gut gezeigt hat. Wenn man die LSBs gleich
wieder abschneidet um auf 10 bits zu kommen war
das ganze für die Katz (hier eigentlich trivial, die richtigen
Bitbreiten zu verwenden ist aber nicht immer so einfach)

Hier kommt man um eine Simulation nicht drumrum !
Wenn mit zu geringer Genauigkeit gearbeitet wird, schwingt
das IIR evt. oder funktioniert überhaupt nicht.
Habe mal ein IIR 2. Ordnung entwickelt, mit 12 bit signed
input und 14 bit Koeffizienten, da musste ich zwischendrin
bis auf 40 bit hochgehen, um die Funktion noch zu gewährleisten.
Taktfrequenz war 20 MHz, kritisch war z.B. der Tiefpass mit 100kHz
-> bei dieser Abtastrate natürlich ein denkbar schlechtes Verhältnis
fa / fcutoff

von Hagen (Gast)


Lesenswert?

@FPGA-User:

ich ging eigentlich schon von Anfang an davon aus das die 1024 eine 10
Bit geshiftete Festpunktzahl darstellt. D.h. es sind schon 10 Bit
zusätzliche Genauigkeit einkalkuliert worden. Ansonsten kann ich mir
den Mulitplikant von 1023/1024 nicht erklären.

Gruß Hagen

von Thomas Wolf (Gast)


Lesenswert?

Hallo zusammen

Ihr seid ja die vollen Experten!
Es ist so:
Die 1023/1024 kommen vom Pol.
Der Pol ist nämlich bei z = +0,999057966057229.
Naja, und 1023/1024 = 0,9990234375.
Ist also schon ziemlich gut angenähert.
Mache ich also einen Fehler, wenn ich das Ganze so umsetzte:
y(n) = -0,9990234375*y(n-1) + b0*x(n) + b1*x(n-1),
wobei b0=b1=1 ist.

Passt doch so, oder?

Gruss,
Thomas

von FPGA-User (Gast)


Lesenswert?

Uuuuuuups jezt hab ich nochmal ganz oben geschaut,
fs = 2000 Hz und fcutoff = 0,3 Hz -> das wird
interessant !!!
Aus dem Bauch raus würde ich behaupten, dass die
Annäherung mit 1023/1024 zu ungenau ist.
Also noch ein Argument für eine Simulation.

von Thomas Wolf (Gast)


Lesenswert?

Hallo Leute

Äh, ich komm da nicht ganz mit.
Nochmal:
IIR-Tiefpaß, 1. Ordnung.
10 bit breite Eingangsworte
Sampling Frequenz = 2000 Hz
Cut Off Frequenz = 0,3 Hz

Wieso ist 1023/1024 zu ungenau.

Nochwas:
MATLAB sagt mir irgendetwas von einem Scale Factor von
0,000471016971386.
Ich interprtiere das als 1/2048, wobei irgendwie ist das blöd.
Ich hab nur einen 10 bit breiten Vektor und muss diesen dann gleich
erst mal durch 2048 teilen. Hab da ein Verständnisproblem.
Wer kann einem Nicht-Digital-Menschen helfen?

DANKE

Gruss,
Thomas

von Hagen (Gast)


Lesenswert?

@Thomas:

das heist das du bei den Berechnungen deine realen Datenvektoren auf
der rechten Seite = LSB um exakt 11 Bits erweitern musst. Somit wird
virtuell in deinem 10+11 Bit Vektoren an 11'ter Bit Position ein
Festkomma eingefügt, man scaliert die Zahlen was gleichbedeutend mit
einer Multiplikation mit 2048 gleichkommt.

Mathematisch ist es vergleichbar so:

Teile die Zahl 25 durch zb. 6 rechne aber mit 1 dezimalen
Nachkommastelle exakt. Man multipliziert 25 * 10 und 6 und rechnet 250
/ 6 = 41. Das resultat muß dann wieder normalisiert werdenmit 10 ->
also 41 / 10 = 4.1. Man rechnet aber alle internen Berechnungen mit der
41 weiter denn alle anderen Zahlen der Berechnung sind ebenfalls um den
Faktor *10 vorher scaliert worden. Erst das Endgültige Resultat wird
durch 10 dividiert und meistens vorher noch gerundet indem man 10/2 = 5
aufaddiert.
Dieses beispiel bezieht sich auf Dezimale Zahlen, in deinem Falle sind
es aber Binäre Zahlen, also scaliert man am besten mit einer Potenz von
2, zb. eben 2^11 = 2048.

Gruß Hagen

von FPGA-User (Gast)


Lesenswert?

@Thomas

also hier mal kurz meine Erfahrungen aus dem IIR-Projekt :
je größer das Verhältnis fa / fcutoff bei einem zu real.
TP, umso größer werden auch die Probleme, da die Koeff.
z.B. sehr nahe bei 1 liegen, also 0,99999...

Die Koeffizienten müssen sehr genau sein, bei mir haben
14 bit gerade so gereicht.

Du kannst Dir das grob so vorstellen (Festkomma) :
Wenn das MSB 2^0 ist, dann ist das nächste bit 2^-1,
dann 2^-2, 2^-3 usw.
D.h. bei einer 10 bit Binärzahl wäre nach obigem Schema
das LSB, also niederwertigste Bit immer noch 0,00097 !
Wenn Du den Koeffizienten genau genug realisieren willst,
dann sind also deutlich mehr 10 bit dafür nötig.

Nimm doch mal den angenäherten Koeff. 1023/1024 und mach
damit eine Simulation im MATLAB. Ich fürchte, dass die
Filtereigenschaften so stark beeinflusst werden, dass
Dein TP nicht mehr macht, was er soll.

Also m.E. wirst Du um eine Multiplikation nicht drumrum
kommen, aber dafür gibts ja Tools.
Ich habe mir von QuartusII entsprechende Multiplier
z.B. Signed 26 bit x 14 bit parallel "basteln" lassen-
das geht super.

von Thomas Wolf (Gast)


Lesenswert?

Ok Leute.
Erst mal: DANKE.
Ich kann da nicht mithalten.
Werde mich heute Nachmittag hinsetzen und das Ding in VHDL umsetzen.
Mal sehen, was dabei entsteht.

Melde mich wieder in den nächsten Tagen und freue mich schon jetzt auf
euren Super-Support!

Gruss,
Thomas
(Nicht-Digital-Mensch)

von Hagen (Gast)


Lesenswert?

Die Aufgabe ist aber wirklich nicht einfach. Nicht aus Sicht der VHDL
Programmierung sondern vom Verständnis des Programmieres der nötigen
Mathematik. Meine Lehrlinge hatten auch immer Probleme eine
Fehleranalyse von zb. Double Zahlen durchzuführen, sie waren es einfach
gewohnt mit Double zu arbeiten und falls dies nicht reichte nahmen sie
eben einfach Extended statt einfach mal über eine Fehleranalyse den
Algorithmus besser umzubauen ;) Das bezieht sich natürlich auf normale
Programmierung auf PC's, nicht in VHDL.

Gruß Hagen

von F01Qx (Gast)


Lesenswert?

Es gibt bereits ein Programm, mit dem man digitale Filter erstellen (mit
automatischer Berechnung der Koeffizienten) und das nach VHDL
exportieren kann:
http://www.digitalfilter.com/dfalz/dfalz.html

von Frager (Gast)


Lesenswert?

>Der Pol ist nämlich bei z = +0,999057966057229.
>Naja, und 1023/1024 = 0,9990234375.
>Ist also schon ziemlich gut angenähert.
Viel zu ungenau! Die Fehler kummulieren.
Der Wert muss auf bis zu 10 bit hoch 2 = 20 genau sein.

Aber (0,9990234375- 0,999057966057229) / 0,999057966057229 sind nur 
1/28000 = 15 Bit.

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


Lesenswert?

> 03.08.2005 20:03
Zombiethread :-o
Das Problem ist entweder behoben oder hat sich erledigt.

von Gast (Gast)


Lesenswert?

Mich würde mal der FPGA Code interessieren! Die Seite auf 
digitalfilter.com ist lieder tot.

von Frank (Gast)


Lesenswert?

oh ja....mich auch

von Martin K. (mkohler)


Lesenswert?

Lothar Miller schrieb:
> Zombiethread :-o
> Das Problem ist entweder behoben oder hat sich erledigt.
gilt immer noch.

von Eric (Gast)


Lesenswert?

...stimmt. Gilt immer noch... ;-)
Ergebnis würde mich auch interessieren, oder zumindest der o.g. Link mit 
der Filter2VHDL Application...

von J. S. (engineer) Benutzerseite


Lesenswert?

Der Code ist aber keine Hexerei, oder?

> Wie multipliziere ich ein 21 bit breites Signal mit dem Bruch
> 1023/1024 ?

Wie Hagen richtig darstellt, funktioniert eine Multiplikation mit 1023 
am Besten mit x (1024 -1), oder im vorliegenden Fall zieht man gleich 
1/1024 ab. Damit das korrket funktioniert, muss das Zwischenergebnis 
aber genau genug sein, hier mindestens 10 Bit. Also braucht man 20+1 Bit 
breite Zwischenergebnisse mit Rundungsbehandlung.

Hinzu kommt die Auflösung des Koeffizienten, der auf noch bis zu 10 
zusätzliche Bits fordert, wenn er auf 1 digit sinken darf.

von Michael O. (mischu)


Lesenswert?

Der link scheint (laut Mikrocontroller.net :)) zu heißen
http://www.digitalfilter.com/products/dfalz/dfalz1.zip

von Unbekannter (Gast)


Lesenswert?

Kann man das irgendwie direkt aus Formeln beziehen, wie die Filter 
einzustellen sind? (die Koeffizienten)

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


Lesenswert?

Unbekannter schrieb:
> Kann man das irgendwie direkt aus Formeln beziehen, wie die Filter
> einzustellen sind? (die Koeffizienten)
Musst du jetzt jeden alten Zombie Filter Thread nach oben holen?

von Duke Scarring (Gast)


Lesenswert?

Unbekannter schrieb:
> Kann man das irgendwie direkt aus Formeln beziehen, wie die Filter
> einzustellen sind? (die Koeffizienten)
Ja. Besorg Dir ein gutes Buch über digitale Signalverarbeitung oder 
lerne google.

DUke

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

zwar nicht für VHDL, hilft aber vielleicht weiter
http://www.mikrocontroller.net/articles/Digitalfilter_mit_ATmega

von Unbekannter (Gast)


Lesenswert?

Wenn ich einen neuen thread aufgemacht hätte, würde ja wieder gemeckert 
werden.

danke für den link

von Ralf (Gast)


Lesenswert?

Bei mir funzt der link. Habe es auch ausprobiert und eine Frage:

Die einzelnen Taps / Berechungen müssen dann für jeden einzelen 
Datenfortschritt neu berechnet werden?

Bei 128 Taps bräuchte ich dann 128 Takte mit jeweils einer 
Multiplikation und Aufsummierung, um zum Endwert zu kommen, hätte also 
1/128 Clockfrequenz als maximalen Takt für neue Daten?
üpipelinen lässt sich das wohl nicht, oder?

von Duke Scarring (Gast)


Lesenswert?

Ralf schrieb:
> Die einzelnen Taps / Berechungen müssen dann für jeden einzelen
> Datenfortschritt neu berechnet werden?
Ja.

> Bei 128 Taps bräuchte ich dann 128 Takte mit jeweils einer
> Multiplikation und Aufsummierung, um zum Endwert zu kommen, hätte also
> 1/128 Clockfrequenz als maximalen Takt für neue Daten?
Kommt darauf an. Wenn Du nur einen Multiplizierer hast ja. Wenn Du 128 
Multiplizierer nimmst, bist Du in einem Takt fertig. Verschiedene 
Mischformen sind auch denkbar.
Mit geeigneten Filterkoeffizienten (Nullstellen, gespiegelte 
Koeffizienten, ...) kann man auch noch optimieren.

> üpipelinen lässt sich das wohl nicht, oder?
Nur über Paralellisierung. Aber im Prinzip hast Du schon eine Pipeline. 
Nach 128 Berechungen hast Du Dein erstes "echtes" Ergebnis.

Duke

von A. F. (chefdesigner)


Lesenswert?

Die pipeline lässt sich nur dann weiter nutzen, wenn man Kanäle 
multiplext, was dazu führt, dass du eine niedrigere Datenrate bekommst.

von Unbekannter (Gast)


Lesenswert?

Wie soll das gehen? Die einzelen Stufen haben ja Speicherregister. Die 
müsste man ja mit multiplexen.

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.