Hallo zusammen Kann mir jemand folgende Differenzengleichung in VHDL umsetzen? (Ich bin "Nicht-VHDL'er".) y(n) = a1*y(n-1) + b0*x(n) + b1*x(n-1) y(n) = (1023/1024)*y(n-1) + (1/2048)*x(n) + (1/2048)*x(n-1) x(n) und y(n) sollen jeweils 10 bit breit sein. Man muss doch x(n) gleich mal erweitern, um bei der Division durch 2048 keinen Informationsverlust zu erleiden, oder? Vielen vielen Dank für Eure Hilfe! Gruss, Thomas
Frage: Willst Du das Problem nur für den Spezialfall, d.h. für die zweite Zeile gelöst haben? Die Differenzengleichung soll vermutlich mit einer Abtastrate, die nicht unbedingt der Systemrate Deines FPGAs (CPLDs?) entspricht, arbeiten, oder? Anmerkung: Ich werde aber nicht sofort dazukommen, das Problem zu lösen. Bis wann bräuchtest Du denn was?
Ich will ja keine Ansprüche stellen, aber ginge es vielleicht sowohl für den Spezialfall als auch für den allgemeinen Fall? (Ich will's ja auch vertstehen...) Der Clock liegt bei 4 MHz. Die Abtastrate liegt bei 2 KHz. Danke Danke Danke
Moin... Wie willst du denn die Rehnungen in 10-bit Integer darstellen? spätestens die Division durch 2048 dürfte dir da den Hals brechen. -- Sven Johannes
Sorry, aber das verstehe ich jetzt nicht. Es gibt doch in VHDL diesen std_logic_vector. Also schreibe ich: input : in std_logic_vector(9 downto 0); Dann muss ich das Teil erweitern um später bei der Division durch 2048 keinen Fehler zu machen. Division durch 2048 ist ja dann lediglich wieder ein Rechts-Shift um 11 Stellen. Oder funktioniert das für die oben angegebene Differenzengleichung anders? T.
Moin... Welches Ergbnis erwatest du denn für eine 10-Bit Zahl, irgendeine, wenn du 11-bit nach rechts verschiebst? -- Sven Johannes
Hallo Sven Ich will einfach nur die VHDL-Beschreibung von: y(n) = a1*y(n-1) + b0*x(n) + b1*x(n-1) y(n) = (1023/1024)*y(n-1) + (1/2048)*x(n) + (1/2048)*x(n-1) Es ist mir klar, daß ein 10 bit breiter Vektor durch 2048 geteilt (also 11 mal rechts schieben) ziemlich komisch ist, also muss ich doch vorher den Input mit LSB-Nullen erweitern. Deswegen weiss ich trotzdem nicht, wie ich das in VHDL umzusetzen habe...
Hallo Thomas, da bin ich wieder. Gleich im voraus: Der Code ist mit Vorsicht zu behandeln. Ich habe ihn weder kompiliert, noch synthetisiert geschweige denn irgendwie getestet - UND er ist NICHT perfekt! Aber vielleicht hilft er Dir ja als Einstieg. Also, zunächst habe ich Deine Differenzengleichung erweitert. Am einfachsten ist es, wenn man alle Koeffizienten mit der gleichen Zweierpotenz erweitert, im Bsp. mit 2048. => yn * 2048 = yn_1 * 2046 + xn + xn_1 Die 3 Summanden habe ich dann mit dem Postfix _expanded gekennzeichnet, wobei zu beachten ist, dass yn_1_expanded dann im Bsp. 10+11 Bits lang ist (Multiplikation zweier Bitvektoren). Dann habe ich erst xn_extended mit xn_1_expanded addiert und dann das Ergebnis mit yn_1_expanded. ACHTUNG: Eigentlich muss man bei einer Addition den Ergebnisvektor um 1 Bit länger machen als den längeren Summanden um Überläufe zu vermeiden. Das habe ich hier NICHT getan! U.a. auch deswegen, weil yn_1_expanded und yn_expanded gleich lang sind. Zum Schluss kürzt man das Ergebnis noch um 2048 (was einem Rechtsshift um 11 Bits entspricht) und das war's. Ines PS: Darf man fragen, wozu Du das brauchst?
Hallo Ines Danke erst mal. Wozu ich das brauche? Chef: "Mach mal schnell einen IIR-Filter (digital) mit 2000 Sampling und Cutoff bei 0,3. Hopp! Schnell! So, jetzt muss ich mir mal deinen Vorschlag ansehen... Nochmal: Danke, Ines. T.
@Ines also bis x_add gehe ich mit aber alles was danach kommt wird nie funktionieren, du hast 4 Register in Serie im Rückkoppelzweig, wo nur 1 Register sein darf. -> Ergebnis : am Ausgang kommt nur 0 / +1 / -1 raus.
Oh, sorry, da hat sich wohl noch ein kleiner Fehler eingeschlichen. Du musst die Sample-Schleife schon nach den ersten Zuweisungen schließen. Die anderen Signale sollen ja nicht gesampelt werden, sondern nur "ge-pipeline-t" (damit Du keine Probleme mit der Systemfrequenz kriegst). Ich habe den Code angepasst. Schau's Dir mal an, ob's jetzt besser ist.
@Thomas Wie kommt Dein Chef drauf, dass Du mal schnell ein Digitalfilter baust, wenn Du kein VHDL kannst ? Oder solltest Du es mit Logik-ICs realisieren ???? Was soll dieses Filter bewirken - mit 1.Ordnung tut sich da ja fast nix im Frequenzgang.
Hallo Ines Kannst du mir bitte nochmal helfen? Kriege diese Fehlermeldung: # Error: ELAB1_0008: DzGL_v02.vhd : (116, 17): Cannot read output : "yn". Was läuft da schief? Thomas
Hallo Ines Hallo Experten Ich blick's einfach nicht. Den obigen Fehler konnte ich beheben. Allerdings kriege ich am Ausgang immer nur die Null raus. Wenn ich am Eingang für alle Zeiten einen ewigen konstanten Wert anlege, z.B. "0100000000", so muss doch genau dieser Wert auch rauskommen, denn es liegt ja immer derselbe Wert an, also keine Schwingung, also kleiner 0,3 Hz. Oder? Thomas
Hallo Thomas, naja, Du hast da ein prinzipielles Problem, was schon mit der Formel anfängt. Und zwar ist der Einfluss vom Eingang auf den Ausgang viel zu klein. Und mit Deinem 10Bit Eingagnsvektor geht das schon gar nicht. Zur Erläuterung: Der Maximalwert von x(n) ist 2^10, d.h. der max. Einfluss von x(n) auf y(n) ist 2^10 / 2048 und damit kleiner als 0. D.h. der Wert ist nicht mehr als Bitvektor darstellbar ist. Die gleiche Betrachtung gilt für x(n-1). => y(n) = (1023/1024) * y(n-1) + 0 + 0 = (1023/1024) * y(n-1) Einschub: Das gilt aber nur, weil der Faktor zu y(n-1) nahezu 1 ist, d.h. viel größer als (1/2048). Bei yn_expanded siehst Du den Einfluss ja noch! Klar? Da y(n) und damit auch y(n-1) mit 0 initialisiert ist, ist Dein Ergebnis also immer 0. :-((((( Tut mir leid, dass ich da nicht früher drauf eingegangen bin, aber ich habe mir die genauen Werte bisher nicht angesehen, sondern nur auf die prinzipielle Vorgehensweise geachtet. Gruß Ines
Hallo Ines Ja, bei yn_expanded seh ich etwas, aber dann wird's "wenig"... Was kann ich tun? Kann man etwa die Differenzengleichung y(n) = a1*y(n-1) + b0*x(n) + b1*x(n-1) y(n) = (1023/1024)*y(n-1) + (1/2048)*x(n) + (1/2048)*x(n-1) gar nicht umsetzen? Thomas
Hallo Ines Vielleicht liegt es daran, daß der eine Pol zu weit am Einheitskreis liegt? Kann es das sein? Aber das müsste doch dann trotzdem ein realisierbares System sein, oder? Thomas
Doch schon, aber eben nicht mit 10 Bit bei y. Und jetzt kommst, ich weiß, sowas hört man nicht gerne, aber wenn Du jede Änderung am Eingang, also auch ein Toggeln am LSB mitkriegen willst, dann muss y 21 Bits groß werden - eben yn_expanded. Anders gesagt, x beeinflusst nur die letzten 11 Bits von yn_expanded (setzt x einfach mal auf (others => '1') dann siehst Du es). Je mehr Du von diesen 11 Bits mit in Deinen Ausgangsvektor y mit aufnimmst, desto mehr reagierst Du auf den Eingang. Ines PS: Ich übernehme keine Gewähr für die Zahlen, die ich da gerade in den Mund - ähh in die Finger??? :-) - genommen habe. Ich habe sie nur überschlagen.
Wir sitzen zu zweit an diesem Problem und habe beide nicht viel Ahnung von der Materie. Naja, eigentlich sitzen wir zu Dritt hier, aber der Kollege hat noch weniger Ahnung - also lassen wir ihn aussen vor...
Hallo Ines Ich "speise" am Eingang konstant 1'en ein und sehe am Ausgang Null. Einfach nur Null. Lediglich yn_expanded wandert mit... Hast du's mir jetzt erklärt und ich hab's nicht verstanden, oder bin ich einfach nur ...? Hast du noch etwas Geduld? Also, ich führe dann den kompletten y_expanded nach draussen, ja? Muss ich dann noch etwas teilen, oder so? Wie gesagt, irgendwo muss ja die Eckfrequenz von 0,3 Hz "sichtbar" sein... Thomas
Ganz so einfach ist es nicht. Also Du führst y_expanded raus. Aber diesen Wert musst Du ja noch durch die 2048 teilen. D.h. nur die Bits [20:11] entsprechen dem ganzstelligen Bereich. Die unteren Bits müssten Nachkommastellen entsprechen. Aber jetzt wird's bei mir auch dünn. Das Problem hatte ich nicht, als ich mich damals mit Differenzengleichungen beschäftigt habe. Ines
Ok, Ines, du hast ja sowieso schon viel zu viel Zeit für mich (uns) geopfert. Ich sage DANKE.
Kein Problem, ich weiß ja noch, wie lange ich damals gesessen habe und so ist meine Arbeit wenigstens noch für was gut. :-) Bis zur nächsten Frage Ines
Ups! Du bist ja noch da. Also gut, dann noch etwas: Abtastfrequenz 2000Hz Eckfrequenz 0,3Hz IIR 1. Ordnung 10 Bit rein 10 Bit raus Es ist aber schon so, daß bei konstantem Eingangswert, dann genau dieser Eingangswert hinten rauspurzeln muss, ja? Und es sollte auch so sein, daß bei Änderungen fast Null hinten rauskommen muss, ja? (Nur so zum Verständnis.)
Hallo Ines Was machst du eigentlich damit? yn_1_expanded <= yn_1 * conv_std_logic_vector(2036, 11); Der Wert 2036? Und was macht conv_std_logic_vector(2036,11)? Thomas
ich habe die Diff-Gl. mit Real-Zahlen in VHDL simuliert, damit funktioniert es gut, auch mit den Näherungswerten hats noch funktioniert. Mache morgen mal einen Test mit std_logic_vector. Die Bitbreite am Ausgang lässt sich auf jeden Fall wieder auf 10 bit bringen, das ist nicht das Problem. Es muss nur die richtige Anzahl Bits gefunden werden, um die am Ende wieder skaliert wird. Welcher Preis ist für die fertige Lösung ausgelobt bzw. wie hoch ist die Gewinnbeteiligung ? ;-)))))))
Hallo Thomas, Zu den Genauigkeitsanforderungen deiner "etwas seltsamen" Konfiguration hab ich dir ja schon mal was in deinen Threads http://www.mikrocontroller.net/forum/read-10-215332.html und http://www.mikrocontroller.net/forum/read-10-215695.html geschrieben. Wenn du das einfach ignorierst, dann brauchst du dich auch nicht zu wundern wenn du in der Praxis darüber stolperst! Das würd ich mal deinem Chef verklickern, anstatt auf sein Kommando gegen die Wand zu rennen... Ansonsten liefert Matlab (womit du ja arbeitest) auch ein grafisches klicki-bunti Filter Design Tool. Dieses sollte von jedem bedienbar sein der ein bischen was von der Materie versteht, auch von jemandem der keine Ahnung von Matlab hat. Dieses Tool kann angenehmerweise direkt den passenden VHDL Code zum Filter generieren. Die Vorgehensweise dabei ist in etwa folgende: -Filter entwerfen -quantisieren -VHDL Code generieren Einfach mal "fdatool" eingeben, der Rest sollte selbsterklährend sein. Um dann den VHDL Code zu erzeugen auf "Targets" -> "Generate HDL" klicken. Aber nocheinmal: Der Fehler liegt schon in der Planung, das solltest du dringenst überdenken! Vielleicht kannst du ja auch mal was über dein Projekt schreiben: Was ist das für ein Signal? Wo kommt es her und was soll damit gemacht werden? Wie sieht das Spektrum aus? Warum mit 2kHz Abtasten? Und wieso Fg=0.3Hz? Möglicherweise ergibt das ganze dann ja sogar für mich noch Sinn ;)
Hallo FPGA-User Du schreibst: "ich habe die Diff-Gl. mit Real-Zahlen in VHDL simuliert, damit funktioniert es gut, auch mit den Näherungswerten hats noch funktioniert. Mache morgen mal einen Test mit std_logic_vector. Die Bitbreite am Ausgang lässt sich auf jeden Fall wieder auf 10 bit bringen, das ist nicht das Problem. Es muss nur die richtige Anzahl Bits gefunden werden, um die am Ende wieder skaliert wird. Welcher Preis ist für die fertige Lösung ausgelobt bzw. wie hoch ist die Gewinnbeteiligung ? ;-)))))))" Äh, kannst du mir das mal näherbringen? Was heisst jetzt, mit Real-Zahlen simuliert? Ist das Ganze dann noch synthesefähig? Welcher Preis für die fertige Lösung ausgelobt ist? Wünsch Dir was! Ich erfülle dir jeden Wunsch - wenn ich könnte. Gruss, Thomas
Hallo Thomas Winkel Worum geht's: Ich krieg ein Signal von einem Sensor. Dieses repräsentiert eine Spannung zwischen 0V und 5V. Der AD-Wandler macht daraus 10bit breite Werte. Alle 500µs soll ich nun dieses AD-Wandler nehmen und nachschauen, ob der Wert einigermassen konstant ist. Im Idealfall - also wenn das Eingangssignal konstant ist - kommt hinten das Gleiche wieder raus. Bei ganz geringen Änderungen über der Zeit eigentlich auch. Wenn nun ruckartig plötzlich ein anderer Spannungswert reinkommt, dann soll der rausgefiltert werden und hinten die Null rauskommen. Kurz, die Anforderung ist so: Es ist ein Tiefpaß 1. Ordnung mittels IIR zu realisieren, welcher mit einer Abtastfrequenz von 2KHz arbeitet. Die Eckfrequenz soll bei ca. 0,3 Hz liegen. Ich brauch auch mit Niemanden aus der Firma zu diskutieren. Die wollen das so. Also hab ich MATLAB geöffnet, folgendes eingegeben: fs = 2000 Hz fc = 0.3 Hz Butterworth IIR 1st order Naja, und krieg ich eben das: (n) = a1*y(n-1) + b0*x(n) + b1*x(n-1) y(n) = (1023/1024)*y(n-1) + (1/2048)*x(n) + (1/2048)*x(n-1) Stimmt doch, oder? Das sollte ein realisierbares System darstellen. Nur, weiss ich nicht wie man das in VHDL umsetzt. Ines hat mir ja schon sehr weitergeholfen. Thomas Winkel, ist das jetzt verständlicher geworden? Gruss, Thomas
Guten Morgen Thomas und den anderen, ich habe gerade nicht so viel Zeit - war ja noch einiges los gestern Abend und heute morgen, auf das man antworten könnte. Zu Deinen Fragen vom 08.08.2005, 19:32 Uhr: > Der Wert 2036? Der ergibt sich aus (1023/1024) * 2048, d.h. der erweiterte Faktor von y(n-1). > Und was macht conv_std_logic_vector(2036,11)? conv_std_logic_vector(x,y) convertiert hier den Integer-Wert x=2036 in einen y=11 Bit langen std_logic_vector. Gruß Ines
@Thomas 1.) Deine Gleichung ist OK. 2.) "Mit real-Zahlen simuliert" ist einfach wörtlich zu nehmen. Du kannst mit VHDL auch Code schreiben, der nicht synthesefähig ist, so wie ich das gemacht habe, als Signaltyp habe ich "real" verwendet. Das ist so ähnlich als ob ich die Gleichung in C mit "float" simulieren würde. Für ne Simulation ist das manchmal sehr praktisch. Das Programm "Filter Solutions" erzeugt mir übrigens genau dieselben Koeffizienten für das Filter wie MATLAB, naja das sollte auch so sein bei so einfachen Fitern. Wieviel Platz hast Du im FPGA oder soll das in ein CPLD ?
Danke Ines. Habe deinen Code simuliert. Wenn ich konstante Sachen einspeise, kommt das auch hinten als yx_expanded wieder raus (mit dem Faktor 2 - aber egal). Geh ich nun plötzlich auf einen total anderen Wert, also eine schnelle Änderung, dann geht dieser Wert ebenso durch. Irgendwie geht alles durch. Hm... Egal, mach dir keine Gedanken. Ich habe dich schon zu genüge belästigt. Muss jetzt selbst versuchen, mit VHDL zurecht zukommen - auch wenn's mir sehr schwer fällt - als Anfänger.
Hallo FPGA-User Der Platz spielt im Moment keine Rolle. Ich will's halt jetzt einfach nur verstehen, wie man so eine Gleichung prinzipiell in VHDL umsetzt: y(n) = a1*y(n-1) + b0*x(n) + b1*x(n-1) y(n) = (1023/1024)*y(n-1) + (1/2048)*x(n) + (1/2048)*x(n-1) Ines hat mir schon sehr weitergeholfen, aber leider funktioniert's nicht ganz. Die Koeffizienten a0, a1, b0 und b1 stimmen doch, oder? Gruss, Thomas
Hallo Thomas, klar, deine Formel stimmt und realisierbar ist das auch, man muss halt die Berechnungen mit hoher Genauigkeit dürchführen und aufpassen, dass hinten nichts rausfällt. Warum jetzt mit 2kHz abgetastet wird hab ich zwar immer noch nicht verstanden (das macht eigentlich nur Sinn, wenn das Signal Frequenzanteile bis ca. 1000Hz enthält), auch warum das unbedingt ein digitaler Filter sein soll wenn dich eh nur die Signalanteile unter 0.3Hz interessieren (ein einfacher RC Tiefpass liefert die gleichen Ergebnisse bei erheblich geringerem Aufwand) versteh ich noch nicht (soll das eine Methode sein sich den Aliasing Filter zu sparen?), aber wenn Cheffe das unbedingt so will brauchen wir ja nicht weiter darüber zu reden. Kannst ja mal ausprobieren was Matlab da für einen VHDL Code für ausspuckt, hab diese Toolbox selber noch nie benutzt, würd mich aber mal interessieren ob der das Problem erkennt und wie er damit umgeht. Hab grad gelesen, dass der auch Test Benches für ModelSim erzeugt, sehr praktisch. Thomas
Hallo Thomas Winkel, FPGA-User, Ines und alle anderen, die sich bestimmt schon lustig über mich machen Ich war/bin so frei, und habe selbst versucht die Differenzengleichung... y(n) = a1*y(n-1) + b0*x(n) + b1*x(n-1) y(n) = (1023/1024)*y(n-1) + (1/2048)*x(n) + (1/2048)*x(n-1) ...in VHDL umzusetzen. Leider funktioniert auch das nicht. Ich habe euch den Code im Anhang beigefügt. Solltet ihr Mitleid mit mir haben, so bitte ich euch, daß ihr diesen Code mal unter die Lupe nehmt. Wer Lust hat, kann auch gerne in meinem Code Änderunge vornehmen und das Ganze zum Laufen bringen. Kurz zur Erklärung: Ich erweitere die 9 Bit Eingangsdaten immer um 20 Nullen in Richtung LSB, damit ich später bei der Division keinen Informationsverlust erleide. Die Sample-Pulse habe ich von Ines übernommen. Danke für diesen Prozess, Ines. Kurz: Ich krieg's einfach nicht hin. Kann nur auf Eure Unterstützung hoffen. Danke. @Thomas Winkel: Mit unserer MATLAB Version können wir leider keinen Code rausschreiben lassen. Kannst du's? Würdest du mir ihn dann mal schicken? Gruss, Thomas
Hallo Thomas Warum benutzt du 2kSampel/s ? Sollen kurzzeitige Signaleinbrüche erkannt werden? Mein Vorschlag: Benutze für den Filter eine geringere Abtastrate. Durch einen passenden Zähler runtersetzen. Dann werden die Koeffizienten für den Filter auch nicht so klein, dass die FF so extrem ausgelegt werden müssen. MfG Holger
@Thomas keiner macht sich lustig, das würde mir nie einfallen. Für einen VHDL-Anfänger dürfte das eine sehr schwierige Aufgabe sein, ich behaupte auch viele C und C++ Programmierer müssen hier passen, weil sie es nicht gewöhnt sind, mit bit-Vektoren zu arbeiten. Kommt Zeit, kommt Lösung...
Hallo Holger (high speed) Danke. Kannst Du die Gleichung in VHDL umsetzen? Ich kann's ja mittlerweile - aber es funktioniert nicht. ;-) Thomas
Hallo FPGA-User Soll das heissen, du bietest mir im Laufe des Tages eine Lösung an? Habe nochmal versucht, den Code von Ines zu verstehen. Ich versteh' ihn mittlerweile auch etwas :-) aber ich kann die Tiefpaßwirkung nicht erkennen. Thomas
@ Thomas Entschuldige, dass ich nachfrage, aber was verstehst Du denn nicht an meinem Code. Es ist doch "nur" 1:1 die Umsetzung der DzGL. Dafür muss man erstmal noch gar nicht in Regelungstechnik denken. ??? Ines
Hallo Ines Ich hab ihn ja fast komplett verstanden. Es ist nur so, daß ich einfach keine Tiefpaßwirkung erkennen kann. Ich lege den digitalen Wert "0001100100", also dezimal 100 an. Dann sehe ich bei yn auch diesen Wert. Lege ich aber z.B. die Folge 272 dann 756 dann 362, dann 999 usw an, dann sehe ich keine Tiefpaßwirkung. Man müsste doch kleinere Werte am Ausgang sehen, oder? Gruss, Thomas
@Thomas schau Dir mal meinen Code an. Er ist weder für Timing noch für Ressourcen-Verbrauch optimiert, aber er benötigt keinerlei "Spezial-Elemente" wie Multiplizierer o.ä. D.h. man kann ihn auf ein FPGA / CPLD eines bel. Herstellers ohne Änderungen implementieren. b0, b1 und a1 wurden nur durch Schiebe- bzw. Subtraktion realisiert, zum Glück scheint trotzdem alles stabil zu sein. Als Optimum hat sich für y_q (intern) 20 bit herausgestellt, was m.E. überhaupt kein Problem ist. Dämpfung simuliert in VHDL mit ModelSim: 0,3 Hz : -2,9 dB 1 Hz : -10,6 dB 10 Hz : -30 dB Beschreibung + Testbench habe ich komplett in tb_iir eingebaut, da solltest Du mal 2 Files draus machen. Habe alles schön sortiert, hoffe es ist verständlich. Bilder der Signale liegen bei.
@ FPGA-User Wieso sollte man denn die Multiplizierer nicht auf einen beliebigen CPLD / FPGA implementieren können? Ines
Hallo FPGA-User Hallo Ines Oh Gott! Das muss ich erst mal schlucken. Das ist ja der absolute Hammer. Ines' Code war für mich schon abgedreht. Aber das was du mir jetzt da anbietest, haut mich glatt um. Gib mir Zeit. Ich muss das jetzt erst mal hier einbinden und dann versuche ich zu verstehen, was sich da alles auf dem Bildschirm bewegt. Gott im Himmel - ich habe mir die Welt der Einsen und Nullen etwas einfacher vorgestellt. Ist das jetzt der Tiefpaß 1. Ordnung? Ich verbeuge mich vor euch digitalen Genies! Thomas
@Thomas kein Grund zu erschrecken, letztendlich sind das doch nur 5 Zeilen VHDL-Code in dem Prozess ganz unten. Alles andere ist nur Beiwerk und teilweise für die Simulation nötig. Die variablen Bitgrenzen habe ich nur eingefügt, um schneller optimieren zu können. Wenns Dir hilft schicke ich nochmal eine Version mit y_q'HIGH usw. ersetzt durch Konstanten, dann liest es sich einfacher. Die Werte stehen aber auch schon im Kommentar drin.
@Thomas PS: in Zeile 47 kannst Du ganz einfach die Frequenz des Input-Sinus ändern (Selbst-Schulter-Klopf) ;-)))
Hallo FPGA-User Äh, ja ... Frage: "c" ist ja ein Sinussignal mit konstanter Frequenz, ja? "xn" ist das Gleiche - nur in anderer Darstellung, ja? Wie kann ich jetzt am Besten sehen, daß Änderungen am Eingang im Bereich kleiner 0,3 Hz komplett durchgelassen werden bzw wie kann ich am Besten sehen, daß Änderungen am Eingang größer 0,3 Hz imm weniger am Ausgang sichtbar werden, je größer die Eingangsfrequenz wird? Du schreibst: constant freq : real := 10.0; -- !!! Filter-Eingangsfrequenz in Hz Aber dann müsste ja der Ausgan yn einen ziemlich kleinen Wert annehmen und nahezu konstant bleiben, oder? Er bewegt sich aber so zwischen -9 und +25. Ist das in Ordnung? Noch eine Frage: Wie kann ich das Eingangssignal so umbauen, daß nur Werte zwischen 0 und 1023 reinkommen. Also schon ein Sinussignal, aber mit dem kleinsten Wert Null und dem größten Wert 1023? Thomas P.S. in meinem nächsten Leben will ich auch High-Low-Experte sein.
Der folgende Code schaltet die aktuelle Matlabversion völlig legal für 30 Tage komplett frei: Name:WinTrialPLP Code:14-37963-09877-19819-58714-50848-57340-10800-53938-05002-63399-2359 1-06366-33869-11998 Du brauchst mindestens folgende Toolboxen: Filter Design Toolbox Filter Design HDL Coder Das ist der Weg den ich jetzt auch gehen müsste, die HDL Coder Toolbox haben wir auch nicht lizenziert. Aber wie es aussieht hat ja FPGA-User schon eine schöne Lösung für dich. Ich hab zwar wenig Ahnung von VHDL, aber ich glaube nicht, dass Matlab einen so schön optimierten Code liefert.
c und xn unterscheiden sich nur durch den Typ, also Integer und Signed. Signed ist letztendlich ein bit-vector, wobei implizit klar ist, dass es sich um ein vorzeichen- behaftetes Signal handelt. Wenn sich der Ausgang bei 10 Hz zwischen -9 und +25 bewegt (also in Summe 34) dann würde das einer Dämpfung von 20 * log (34 / 1022) = 29,5 dB entsprechen - wenn Du das mit MATLAB vergleichst ist das voll OK ! Wenn Du nur mit Werten von 0 bis 1023 arbeitest bekommst Du einen Gleichanteil rein, der sich beim TP natürlich 1:1 zum Ausgang überträgt. Ist das gewollt? Lösung 1 : nur 9 bit verwenden, MSB = fest auf '0', also z.B. xn <= '0' & AD_Signal(9 downto 1); -- Dynamikbereich halbiert oder das Filter auf 11 bit erweitern und dann so: xn <= '0' & AD_Signal; -- 1 + 10 = 11 bit, positiv Generell erwartet das Filter am Eingang immer 2er Komplement, d.h. vorzeichenbehaftete Signale !
Hallo FPGA-User Ach so - Danke für die Erklärungen. Du schreibst: Wenn sich der Ausgang bei 10 Hz zwischen -9 und +25 bewegt (also in Summe 34) dann würde das einer Dämpfung von 20 * log (34 / 1022) = 29,5 dB entsprechen - wenn Du das mit MATLAB vergleichst ist das voll OK ! Kannst du das näher erläutern? 20 * log(34/1022) = 29.5 dB Die 20 kommt doch daher, weil es ein Filter 1. Ordnung ist. Bei einem Filter 3. Ordnung würde hier doch 20*3=60 stehen, oder? Was bedeutet aber 34/1022? Habe mal in Zeile 47 die Frequenz auf 0.3 gesetzt. xn ist auf 236, aber yn ist auf 349. Das versteh' ich nun überhaupt nicht. Der Ausgang darf/soll/kann doch nicht größer werden als der Eingang, oder? Ist das wieder mal ein Verständnisproblem meinerseits? Gruss, Thomas
Hallo Thomas Winkel Danke!! Ich probier das mal aus... Gruss, Thomas
@Thomas die 20 kommt von der Formel zur Berechnung eines log. Spannungsverhältnisses in dB, ist also immer konstant! (Bei der Leistung würde dort 10 * log ... stehen, nebenbei) Als Signalamplitude habe ich -511 ... + 511 gewählt, also das Maximum was möglich ist - die Amplitude kannst Du in Zeile 77 verändern ( 511 * ...) So, um nun die Dämpfung zu berechnen nimmst Du einfach die Formel 20 * log (Uy / Ux) wobei jeweils Uss (Spitze-Spitze) verwendet werden sollte, da am Anfang der Simulation der Ausgang noch nicht ganz symmetrisch ist und somit Uspitze zu Fehlern führen würde. Das ist aber jetzt reine Analogtechnik, nix mit Digital ! Das Eingangssignal ist Uss = 511 - (-511) = 1022 , Ausgang = Uss = 34, alles in die Formel eingesetzt = siehe oben. Wenn Du mal in Dein Filter-Design-Tool schaust, dann siehst Du, dass das Filter bei 0,3 Hz eine Phasenverschiebung von 45 Grad hat, der Ausgang kann also durchaus mal größer sein, als das Signal am Eingang. Sorry, aber Dir fehlen offenbar elementare Grundlagen, da wirds natürlich ziemlich schwer, schade ich dachte wenigstens analog wäre die Sache verstanden.
Hallo FPGA-User Danke. Vielleicht noch eine Frage: Du schreibst: Wenn Du mal in Dein Filter-Design-Tool schaust, dann siehst Du, dass das Filter bei 0,3 Hz eine Phasenverschiebung von 45 Grad hat, der Ausgang kann also durchaus mal größer sein, als das Signal am Eingang. Ist das ein ganz normales Erscheinungsbild eines (digitalen) Filters (1. Ordnung), daß der Ausgang bei der Eckfrequenz größer ist als der Eingang? Gruss, Thomas ...Kannst du www.dspguide.com empfehlen?
@Thomas das Signal bei der Eckfrequenz hat bei mir knapp 3 dB Dämpfung gegenüber dem Eingang. Du musst mal ca. 10 s lang simulieren und am Ende die Spitzenwerte beider Sinus-Schwingungen vergleichen. Natürlich hat der Eingang sein Maximum zu einem anderen Zeitpunkt als der Ausgang. Also mach in Gedanken (oder in VHDL) eine Gleichrichtung des Signals und vergleiche die Pegel. Die Phasenverschiebung ist hier ganz normal. Ein Studium des Kapitels "Digital Filters" auf www.dspguide.com kann sicher nicht schaden.
nochmal zur Sicherheit: auf dem Bild "sim_0-komma-3_Hz.jpg" ist doch deutlich zu sehen, dass das Signal am Ausgang kleiner ist als am Eingang oder nicht ?
...du hast natürlich recht, thomas. stimmt. Puh - jetzt bin ich a) glücklich und b) beeindruckt von eurem wissen und c) überwältigt von eurer spontanen bereitschaft mir zu helfen. ich sage erst mal: - danke ines !!! - danke fpga-user !!! - danke thomas winkel !!! - danke an alle, die sich an dieser diskussion beteiligt haben !!! ihr habt mir sehr weitergeholfen! danke. gruss, thomas
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.