mikrocontroller.net

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


Autor: Thomas Wolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sebastian Dunst (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas Wolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas Wolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas Wolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: FPGA-User (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas Wolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: F01Qx (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Frager (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: Gast (Gast)
Datum:

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

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh ja....mich auch

Autor: Martin Kohler (mkohler)
Datum:

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

Autor: Eric (Gast)
Datum:

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

Autor: Jürgen S. (engineer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael O. (mischu)
Datum:

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

Autor: Unbekannter (Gast)
Datum:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christoph Kessler (db1uq) (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zwar nicht für VHDL, hilft aber vielleicht weiter
http://www.mikrocontroller.net/articles/Digitalfil...

Autor: Unbekannter (Gast)
Datum:

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

danke für den link

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Fischer (chefdesigner)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Unbekannter (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.