Forum: FPGA, VHDL & Co. FIR Filter - mit 1 Koeffizient - Nicht erwartetes Signal


von Huber W. (sindler)


Angehängte Dateien:

Lesenswert?

Guten tag,
ich möchte einen FIR - Filter mit einem Koeffizient realisieren. Also 
das Signal Verstärken oder Schwächen um einen Bestimmten Faktor.

Das besondere ist das die Koeffizienten 0 , 0.5 , 1 funktionieren. Also 
ich erhalte jeweils kein Signal bzw. die hälfte oder das Signal.


always @(posedge clk_i) begin

mult = 27'h0;
mult = $signed(koeff[0]) * $signed(dat_i_adc_a);

dat_o1 = mult[27-1 : 27-15];

end


Ich verstehe nich aus welchem Grund manche werte Funktionieren aber die 
andern nicht. Siehe z.b. 0.3 , 0.7



Edit:.
Ich habe auch eine rect funktion angeschaut. Dabei tretten diese Fehler 
aber nicht auf. Also ich denke ich bediene das Ozilloskop falsch.
Und ich habe einen Fehler gemacht bei dem Einlesen der Koeffizienten! So 
erhalte ich ein größeres rect- Signal bei dem Koeffizient 0.4 als bei 
Koeffizient 0.5.

von user (Gast)


Lesenswert?

sieht mir nach einem Überlauf aus

von Chef (Gast)


Lesenswert?

Huber W. schrieb:
> ich möchte einen FIR - Filter mit einem Koeffizient realisieren.
Was ist denn das für ein Quark? Da wird doch nix gefiltert! (??)

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


Lesenswert?

Chef schrieb:
> Da wird doch nix gefiltert! (??)
Korrekt: es wird nur skaliert...
So wie Huber W. schrieb:
> Also das Signal Verstärken oder Schwächen um einen Bestimmten Faktor.

Huber W. schrieb:
> die Koeffizienten 0 , 0.5 , 1 funktionieren.
Wie werden diese Koeffizienten binär dargestellt?

Huber W. schrieb:
> Also ich denke ich bediene das Ozilloskop falsch.
So falsch kannst du das Oszi hat nicht bedienen, dass sowas dabei 
herauskommt. Aber warum simulierst du das nicht einfach? Da kommst du 
solchen Fehlern am einfachsten auf die Schliche...

Meine Vermutung geht auch in Richtung Überlauf oder einen falsch 
angeschlossenen DAC.

von Sindler (Gast)


Lesenswert?

Der Fehler war ein Überlauf. Ich freue mich sehr das ich den durch eure 
Hilfe gefunden habe.
Ich habe jetzt einen FIR Filter mit 5 Koeff gebildet. Aber trotz 
benutzter sweep Funktion sehe ich keine Frequenzen die gefiltert werden. 
Könnte sich jemand mal den Quelltext anschauen. Also bei einem Sinus - 
Signal nicht im Sweep sehe ich eindeutig das ich die Skallierung ändere.
programmiert habe ich es nach einem Bild des FIR - Filters.(Ich meine 
Direkt Strucktur 1)

 mult = 27'h0;

    buffer[1]= buffer[0];
    buffer[0]= dat_i_adc_a;
    mult = ($signed(koeff[0]) * $signed(buffer[0])) + mult; //ein Koeff

    buffer[2]= buffer[1];
    mult = ($signed(koeff[1]) * $signed(buffer[1])) + mult; //zwei Koeff

    buffer[3]= buffer[2];
    mult = ($signed(koeff[2]) * $signed(buffer[2])) + mult; //dritter 
Koeff

    buffer[4]= buffer[3];
    mult = ($signed(koeff[3]) * $signed(buffer[3])) + mult; //vierter 
Koeff

    buffer[5]= buffer[4];
    mult = ($signed(koeff[4]) * $signed(buffer[4])) + mult; // fünfterr 
Koeff

    dat_o1 = mult[27-1 : 27-15];


Mit dem Array buffer[] stelle ich die Zeitverzögerungsglieder da. Unter 
dem Array koeff[] sind die Koeffizienten gespeichert.
Nachdem ich die verschieden Eingangswerte mit den Koeffizienten 
multipliziert habe werden diese Summiert.
Und am ausgang dat_o1 Ausgegben.

-Buffer[] für Zeitverzögerung
-Koeff[] für die Koeffizienten
-dat_i_adc_a dort liegt das Eingangssignal an
-dat_o1 dort liegt das Ausgangssignal an

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


Lesenswert?

Sindler schrieb:
> Könnte sich jemand mal den Quelltext anschauen.
Könntest du mal den Rest auch noch posten (am besten als Anhang)?
Und: mit welcher Frequenz taktest du das Filter?
Was sind deine Koeffizienten?

> Aber trotz benutzter sweep Funktion sehe ich keine Frequenzen die
> gefiltert werden.
Aber immerhin hast du einen gewaltigen Vorteil: du siehst überhaupt 
etwas...

Was erwartest du? Und was siehst du stattdessen?


Bitte lies deine Posts vor dem Absenden nochmal so durch, wie wenn du 
dein Problem nicht kennen würdest (so geht es uns anderen Allen). Sind 
im Post alle Fragen beantwortet und nötige Informationen bereitgestellt? 
Dann kannst du auf "Absenden" drücken...

: Bearbeitet durch Moderator
von Sindler (Gast)


Lesenswert?

1
always @(posedge clk_i) begin 
2
  
3
  
4
5
  mult2 = 27'h0;
6
  
7
  
8
  
9
  buffer2[1]= buffer2[0];
10
    buffer2[0]= dat_i_adc_a;
11
    mult2 = ($signed(koeff[0]) * $signed(buffer2[0])) + mult2;
12
    
13
    for( i=2; i < 11 ; i = i+1 ) begin
14
        buffer2[i]= buffer2[i-1]; // shiften aufgrund der Zeitglieder.
15
        mult2 = ($signed(koeff[i-1]) * $signed(buffer2[i-1])) + mult2;
16
        end
17
    
18
    dat_o2 = mult2[27-1 : 27-15];
19
20
end

Ziel:
einen FIR Filter zu realisieren.

Durchführung:
Der FIR Filter in Normalstruktur 1. Ich habe ihn einfach "hinunter 
Programmiert". Also das was ich sehe in Code gepackt.
Das bedeutet das Array Buffer[] stellt die Zeitglieder da (Z-1).

Technische Voraussetzungen:
Die Taktfrequenz des Adcs beträgt 125 MHz. Da ich einen Filter im 
maximalen Bereich von 0 bis 20 MHz erzeugen will. Ist meine Taktfrequenz 
aussreichend. Siehe Nyquist-Shannon-Abtasttheorem ---> 2 * fmax.

Versuch:
Signal Sinus -> durch funktionsgenerator
Frequenz = 1 khz
Amplitude = 100 mVpp

Ich erhalte das passende Signal zu den Jeweiligen Koeffizienten. Bei 
einem Koeffizieten z.b. 0.5-> halbes Signal  1-> ganzes Signale

Wenn ich nun mehrere Koeffizienten verwende. Erhalte ich immer noch 
einen Sinus der jeweils der Verkstärkt oder Veringert ist.

Ein Beispiel für Mehrere Koeffizienten:
5 Koeffitienten alle sind 0.2 ---> selbes Signal wie bei 1 Koeffizient = 
1

Erwartung:
Die Beispiele unter Versuch treffen genau meine Erwartungen.Um zu testen 
ob mein Filter richtig Programiert wurde.

Jetzt benutzte ich den Sinus als Sweep Signal. Das von 1 hz bis 20 MHz 
geht. Ich möchte einfach sehen ob ihrgend eine Frequenz gefiltert wird. 
Aber es wird nichts gefillter egal mit welchen Koeffitienten.
z.b. 0.8 0.7 0.6 oder 0.1 0.2 0.3
Ich habe alles mögliche Versucht.
Selbst mit dieser Seite passende Koeffizienten erzeugt. etc.
http://www.arc.id.au/FilterDesign.html

PS: Es fällt mir immer schwer Dinge verständlich zu erläutern und zu 
organisieren. Danke für deinen Hinweis. Ich versuche mit jedem Beitrag 
etwas dazu zu lernen wie man passend Problemedarstellt.

von Huber W. (sindler)


Lesenswert?

Ich habe den Fehler gefunden. Ich hatte im Zwischenspeicher immer den 
selben Wert. Fehler wurde jetzt behoben. Jetzt muss ich das alles nur 
ein bisschen besser gestalten werden damit ich weniger Rechenleistung 
benötige.
1
always @(posedge clk_i) begin 
2
  
3
  
4
5
    mult2 = 27'h0;
6
  
7
  
8
  
9
        
10
    for( i=10; 0 < i ; i = i-1 ) 
11
        begin
12
        buffer2[i]= buffer2[i-1]; // shiften aufgrund der Zeitglieder.
13
        mult2 = ($signed(koeff[i]) * $signed(buffer2[i])) + mult2;
14
        end
15
    
16
    buffer2[0]= dat_i_adc_a; 
17
18
    dat_o2 = mult2[27-1 : 27-15];
19
    mult2 = ($signed(koeff[0]) * $signed(buffer2[0])) + mult2;
20
21
end

Ich freue mich darüber das der Filter funktioniert. Aber mit 10 
Koeffizienten kann ich nicht so sehr viel anfangen. Bzw nicht sehr Steil 
Filtern.
Eine Kaskadierte Form von mehreren Filter z.B. 2 Ordnung möchte ich 
nicht realisieren.
Deswegen versuche ich momentan durch $signed zeichen zu sparen. Aber 
dadurch entstehen merkwürdige VorzeichenFehler. Außerdem habe ich gehört 
das man mit <= zuweisungen parallel ablaufen lassen kann. Was denkt ihr 
darüber ?

: Bearbeitet durch User
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.