Forum: FPGA, VHDL & Co. Differenzengleichung in VHDL


von Thomas (Gast)


Lesenswert?

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

von Ines (Gast)


Lesenswert?

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?

von Thomas (Gast)


Lesenswert?

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

von Sven Johannes (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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.

von Sven Johannes (Gast)


Lesenswert?

Moin...

Welches Ergbnis erwatest du denn für eine 10-Bit Zahl, irgendeine, wenn
du 11-bit nach rechts verschiebst?

--
 Sven Johannes

von Thomas (Gast)


Lesenswert?

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

von Ines (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Thomas (Gast)


Lesenswert?

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.

von Michael (Gast)


Lesenswert?

Solche Chefs kenne ich auch :-)

von FPGA-User (Gast)


Lesenswert?

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

von Ines (Gast)


Angehängte Dateien:

Lesenswert?

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.

von FPGA-User (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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

von Ines (Gast)


Lesenswert?

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

von Matse (Gast)


Lesenswert?

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

von Thomas Wolf (Gast)


Lesenswert?

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

von Ines (Gast)


Lesenswert?

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.

von Ines (Gast)


Lesenswert?

Wer ist hier jetzt überhaupt wer? Thomas = Matse = Thomas Wolf?

von Thomas Wolf (Gast)


Lesenswert?

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

von Ines (Gast)


Lesenswert?

Schon gut, ich habe es auch nach einmaligem Lesen verstanden :-)

von Thomas Wolf (Gast)


Lesenswert?

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

von Ines (Gast)


Lesenswert?

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

von Thomas Wolf (Gast)


Lesenswert?

Ok, Ines, du hast ja sowieso schon viel zu viel Zeit für mich (uns)
geopfert. Ich sage DANKE.

von Ines (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Lesenswert?

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 ? ;-)))))))

von Thomas Winkel (Gast)


Lesenswert?

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 ;)

von Thomas (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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

von Ines (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Lesenswert?

@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 ?

von Thomas (Gast)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

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

von Thomas Winkel (Gast)


Lesenswert?

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

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

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

von high_speed (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

Hallo Holger (high speed)

Danke.
Kannst Du die Gleichung in VHDL umsetzen?
Ich kann's ja mittlerweile - aber es funktioniert nicht.
;-)

Thomas

von Thomas (Gast)


Lesenswert?

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

von Ines (Gast)


Lesenswert?

@ 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

von Thomas (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Angehängte Dateien:

Lesenswert?

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

von Ines (Gast)


Lesenswert?

@ FPGA-User

Wieso sollte man denn die Multiplizierer nicht auf einen beliebigen
CPLD / FPGA implementieren können?

Ines

von FPGA-User (Gast)


Lesenswert?

@Ines
schon mal auf'm CPLD probiert ?
ich meine 20 bit breit, parallel, signed ?

von Thomas (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Lesenswert?

@Thomas
PS: in Zeile 47 kannst Du ganz einfach die Frequenz des
Input-Sinus ändern (Selbst-Schulter-Klopf) ;-)))

von Thomas (Gast)


Lesenswert?

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.

von Thomas Winkel (Gast)


Lesenswert?

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.

von FPGA-User (Gast)


Lesenswert?

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 !

von Thomas (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

Hallo Thomas Winkel

Danke!!
Ich probier das mal aus...

Gruss,
Thomas

von FPGA-User (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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?

von FPGA-User (Gast)


Lesenswert?

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

von FPGA-User (Gast)


Lesenswert?

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 ?

von Thomas (Gast)


Lesenswert?

...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
Noch kein Account? Hier anmelden.