Hallo liebe Forenuser, Ich habe eine Aufgabe in der ich einen Sinusgenerator über ein instabiles Filter mit der folgenden Formel in VHDL erzeugen muss. y(n)=b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) - y(n-2) b0=sin(phi) b1=sin(OMEGA0-phi) a1=-2*cos(OMEGA0) Bsp: phi = pi/4 OMEGA0=pi/8 Meine Frage bezieht sich nur auf b0, also: b0=sin(phi) Ich weiß ich kann einen Sinus über eine Taylorreihe realisieren. Aber wie soll ich das machen wenn der Datentyp Real (Floating Datentyp) NICHT synthetisierbar ist? Was gäbe es noch für alternativen? Ich wäre euch für JEDE Hilfe wirklich sehr dankbar. lg Emtec
Auskenner schrieb: > http://de.wikipedia.org/wiki/Digital_Signal_Synthesis Ich muss den Ausgang von dem Board Pulsbreitenmoduliert über einen DAC in eine äquivalente Ausgangsspannung umwandeln. Es soll alles Digital erzeugt werden ohne eine externe Oszillatorschaltung. Trotzdem danke für die Antwort.
Mei, du hast doch bestimmt RAMs auf deinem Baustein. Bau halt einfach eine Sinus LUT von 0 bis knapp 90 Grad...
Emtec schrieb: > Ich habe eine Aufgabe in der ich einen Sinusgenerator über ein > instabiles Filter mit der folgenden Formel in VHDL erzeugen muss. Warum? Wenn unbedingt ein Sinus nötig ist, und eine Tabelle für die Genauigkeit nicht reicht, dann such mal nach Cordic... > Was gäbe es noch für alternativen? http://www.lothar-miller.de/s9y/categories/31-DDFS
Emtec schrieb: > Ich muss den Ausgang von dem Board Pulsbreitenmoduliert über einen DAC > in eine äquivalente Ausgangsspannung umwandeln. Gibts da auch Namen für die beteiligten Komponenten? Welche Genauigkeit? Welche Frequenzen? Ich hätte noch den Beitrag "Re: PWM Signal erzeugen"
berndl schrieb: > Mei, du hast doch bestimmt RAMs auf deinem Baustein. Bau halt einfach > eine Sinus LUT von 0 bis knapp 90 Grad... Ich entschuldige mich im voraus für meine Fragerei. Ich bin noch Anfänger in dem ganzen... Wie soll ich eine LUT machen? Ich nehme an Du meinst ich nehme pro Abtastwert den zugehörigen y-Wert und schreibe den in einem Array, oder? Dann lasse ich das oszillieren... Aber wie soll ich die Werte in eine LUT schreiben wenn ich "Real" nicht benutzen darf? @Lothar Miller Lothar Miller schrieb: > Emtec schrieb: > Gibts da auch Namen für die beteiligten Komponenten? > Welche Genauigkeit? > Welche Frequenzen? > > Ich hätte noch den Beitrag "Re: PWM Signal erzeugen" Danke für die Links. Die Genauigkeit weiß ich auch noch nicht, die Aufgabestellung ist noch nicht vollständig :-( Es soll die Frequenz und die Phasenlage variabel eingestellt werden welche über Bushbuttons entprellt werden. Die einzelnen Komponenten des Filters werden so dann verändert. Der Filter ist Selbstoszillierend und braucht einen Eins-Impuls zur anregung. Ich brauche nur eine teilweise annähernde Tayloraproximation für variable Werte die ich für das a1 brauche. Danke schon mal für die Hilfe. lg
Emtec schrieb: > Ich brauche nur eine teilweise annähernde Tayloraproximation Reichen 8 Bit Auflösung? Dann wärst du mit einer 90° Lookup-Tabelle am schnellsten fertig. Denn Rechnen in VHDL ist nicht unbedingt schön und einfach... > Wie soll ich eine LUT machen? Die legt dir der Synthesizer in ein Block-RAM ab. Deshalb musst du zur Laufzeit nichts berechnen, hast ein blitzschnelles und ressourcensparendes Design. Das ist aber in meiner DDFS ganz klar dargestellt...
Emtec schrieb: > Aber wie soll ich die Werte in eine LUT schreiben wenn ich "Real" nicht > benutzen darf? Du willst VHDL machen. Da gibt es kein 'Real'! Da gibt es nur xxx-bit breite Datenwoerter. Wenn du also Werte zwischen 0 und <1.0 darstellen willst und z.B. 16bit zur Verfuegung hast, dann entspraeche 65536 halt genau 1.0. Mit 16bit erreichst du aber nur 65535... Also einfach einen passenden Multiplikator erfinden...
berndl schrieb: > Du willst VHDL machen. Da gibt es kein 'Real'! ups, muss mich korrigieren. Natuerlich gibt es in VHDL auch 'Real'. Aber eben in Hardware nicht. Deshalb die Kruecke mit dem Multiplikator. Such mal nach IEEE754 im Web, das ist das, was dein PC mit Floating-Point macht. Und entschuldigen brauchst dich uebrigens auch nicht, fuer Fragen ist ein Forum ja schliesslich auch da...
berndl schrieb: > Aber > > eben in Hardware nicht. D Nichts, was es im VHDL gibt, gibt es auch in der Hardware. Auch kein INT und kein bitvektor. Ist alles Interpreation und muss zusammengebaut werden. Und selbstverständlich kann man in VHDL REAL operationen formulieren und synthetisieren.
Emtec schrieb: > y(n)=b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) - y(n-2) Das ist die Differenzengleichung für ein IIR-Filter und bei solchen sind Koeffizienten bx und ax normalerweise konstant. Und was bei dir zu den Koeffizienten steht > b0=sin(phi) > b1=sin(OMEGA0-phi) > a1=-2*cos(OMEGA0) > Bsp: phi = pi/4 > OMEGA0=pi/8 deutet auch darauf hin, dass deine Koeffizienten konstant sein sollen. Und tatsächlich kann man ein IIR-Filter dazu überreden Dauerschwingungen auszuführen, wenn es eben instabil ist. Geh noch mal in dich und versuch die Aufgabenstellung richtig zu verstehen. Am besten du implementierst diese Funktion mal mit Matlab o.ä., um überhaupt ein Gefühl zu bekommen was passieren soll. Die Berechnung von Konstanten mittels Winkelfunktionen geht problemlos in VHDL auch für die Synthese. Tom
Eigentlich ist der Rückbezug auf Werte, die zwei Takte alt sind ("y(n-2)"), nichts anderes, als eine DGL 2.Ordnung. Schon von der Anschauung her kann/muss das schwingen.
Thomas Reinemann schrieb: > Die Berechnung von Konstanten mittels Winkelfunktionen geht problemlos > in VHDL auch für die Synthese. Emtec schrieb: > Es soll die Frequenz und die Phasenlage variabel eingestellt werden > welche über Bushbuttons entprellt werden. Soviel zum Thema "konstant"... Michel schrieb: > Und selbstverständlich kann man in VHDL REAL operationen formulieren und > synthetisieren. Hast du mal ein Beispiel?
Lothar Miller schrieb: > Thomas Reinemann schrieb: >> Die Berechnung von Konstanten mittels Winkelfunktionen geht problemlos >> in VHDL auch für die Synthese. > Emtec schrieb: >> Es soll die Frequenz und die Phasenlage variabel eingestellt werden >> welche über Bushbuttons entprellt werden. > Soviel zum Thema "konstant"... Ok, ich gebe zu ich habe nur das Originalposting gelesen und da steht nichts vom Verstellen der Phase und Frequenz. Phase verstellen ohne Referenz wird aber schwer. Tom
Thomas Reinemann schrieb: > Phase verstellen ohne Referenz wird aber schwer. Wieso? Freie Auswahl. 0° ist genausogut wie 180°.... Das ist wie beim Italiener: wenn der nur Pizza "Vier Jahreszeiten" hat, dann ist ruckzuck bestellt. Wenn der aber noch 35 Varianten hat, dann dauert das eine Ewigkeit, bis man die Pizza "Vier Jahreszeiten" bestellt... ;-)
Lothar Miller schrieb: > Das ist wie beim Italiener: wenn der nur Pizza "Vier Jahreszeiten" hat, > > dann ist ruckzuck bestellt. Wenn der aber noch 35 Varianten hat, dann > > dauert das eine Ewigkeit, bis man die Pizza "Vier Jahreszeiten" > > bestellt... ;-) Auch beim dritten Lesen kapiere ich nicht, was du damit sagen willst ...
Danke an euch allen für eure Hilfe. Ich werde mein bestes versuchen und melde mich wieder wenn was nicht geht. Tut mir leid für das späte schreiben, hatte viel zu tun :( Euch allen noch einen lieben Gruß. lg
Michel schrieb: > Auch beim dritten Lesen kapiere ich nicht, was du damit sagen willst ... Ok, dann nochmal: >> Phase verstellen ohne Referenz wird aber schwer. > Das ist wie beim Italiener: wenn der nur Pizza "Vier Jahreszeiten" hat, > dann ist ruckzuck bestellt. Wenn der aber noch 35 Varianten hat, dann > dauert das eine Ewigkeit, bis man die Pizza "Vier Jahreszeiten" > bestellt... ;-) Wenn du keine Auswahl hast, dann nimmst du, was du bekommst. Das ist bei der Phase vermutlich 0°. Und wenn du die Auswahl von 0° bis 360° hast, dann kommst du nach einem langwierigen Entscheidungsprozess auch auf 0°. Das wirst du noch oft sehen: wenn es in einer Besprechung 3 verschiedene Varianten gibt, die eigentlich alle gleich gut sind, dann dauert es eine Ewigkeit, bis man eine davon auswählt (weil und obwohl fast kein Unterschied im Ergebnis ist). Glücklich zu nennen ist also der, der keine Alternativen hat...
Lothar Miller schrieb: > Glücklich zu nennen ist also der, der > > keine Alternativen hat... Darum waren in der DDR ja alle so glücklich nur eine Sorte von Autos, Obst, Parteien, Meinung
Emtec schrieb: > y(n)=b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) - y(n-2) > b0=sin(phi) > b1=sin(OMEGA0-phi) > a1=-2*cos(OMEGA0) > Bsp: phi = pi/4 , OMEGA0=pi/8 Habe es mit Excel ausprobiert. Geht nicht. Stimmt die Formel?
noname schrieb: > Emtec schrieb: >> y(n)=b0 * x(n) + b1 * x(n-1) - a1 * y(n-1) - y(n-2) > >> b0=sin(phi) >> b1=sin(OMEGA0-phi) >> a1=-2*cos(OMEGA0) > >> Bsp: phi = pi/4 , OMEGA0=pi/8 > > Habe es mit Excel ausprobiert. Geht nicht. > > Stimmt die Formel? Ja, sie stimmt. Bei mir gehts :)
Emtec schrieb: > Bei mir gehts :) Was geht? Bei mir schwingt das Ding schon, aber es schaukelt sich innerhalb kürzester Zeit in Ekstase und macht insgesamt nichts sinnvolles. Von einem Sinus mit definierter Phase und Amplitude ist da weit&breit nichts zu sehen...
Hi Lothar Miller, Lothar Miller schrieb: > Emtec schrieb: >> Bei mir gehts :) > Was geht? > Bei mir schwingt das Ding schon, aber es schaukelt sich innerhalb > kürzester Zeit in Ekstase und macht insgesamt nichts sinnvolles. Von > einem Sinus mit definierter Phase und Amplitude ist da weit&breit nichts > zu sehen... Ich habe es bis zum Wert 40 in Excel Simuliert. Mit Matlab kenne ich mich nicht so gut aus... Im Anhang habe ich ein Bild davon raufgeladen wie es mit einer Phasenverschiebung und Frequenz gehen könnte...
Ach blöd, ich habe nicht einen 10-Sprung, sondern einen 01-Sprung auf x reingelassen...
Lothar Miller schrieb: > Ach blöd, ich habe nicht einen 10-Sprung, sondern einen 01-Sprung auf x > > reingelassen... ??? Ich habe es probiert, bei mir schaukelt es sich auch auf.
noname schrieb: >> Ach blöd, ich habe nicht einen 10-Sprung, sondern einen 01-Sprung auf x >> reingelassen... > ??? Sieh dir die Werte für X in der Tabelle an. Es ist immer x=0, nur für einen einzigen Takt ist x=1...
Lothar Miller schrieb: > noname schrieb: >>> Ach blöd, ich habe nicht einen 10-Sprung, sondern einen 01-Sprung auf x >>> reingelassen... >> ??? > Sieh dir die Werte für X in der Tabelle an. > Es ist immer x=0, nur für einen einzigen Takt ist x=1... Um dies zu ergänzen: X ist kwasi nur einmal 1 zu Beginn, da dies nur zur Anregung dient. Dieser instabile Digitale Filter braucht einen Dirac Impuls zu Beginn um zu oszillieren... lg
Das kann man aber noch gehörig vereinfachen, indem man die Startwerte inklusive Startimpuls ausdrücklich vorgibt. Dann vereinfachen sich auch die Formeln. Der Generator ist dann ganz gut, wenn man statische Freuquenzen erzeugen muss oder keine exakten Frequenzen braucht, da das update der COS/SIN-Kostrukte zu aufwändig ist. Da ist dann eine DDS einfacher.
J. S. schrieb: > das update der > COS/SIN-Kostrukte zu aufwändig ist. Die liessen sich in einer Tabelle halten, wenn man z.B. nur ein paar Töne erzeugen will. Mehr geht mit einem FPGA ohnehin nicht vernünftig.
Mister LG schrieb: > Die liessen sich in einer Tabelle halten, Dann kann ich auch gleich die Sinustabelle als solche in einer Tabelle halten und DDS machen. Mister LG schrieb: > Mehr geht mit einem FPGA ohnehin nicht vernünftig. Man kann mit einigen einfachen IIR-Filtern sogar aus einem Rechteck einen passablen Sinus machen und die Tonhöhen modulieren, indem man die Phasen anpasst. Erst recht geht es mit einem interpolierten Wert aus einer Sinustabelle.
Emtec schrieb: > Ich habe es bis zum Wert 40 in Excel Simuliert. Mit Matlab kenne ich > mich nicht so gut aus... Ist es möglich, dass die "Schwingung" nur für bestimmte Werte funktioniert, also z.B: nicht beliebig fein? Beim Rumprobieren (ebenfalls Excel) fiel mir auf, dass eine geringe Modifiaktion des a-Wertes nur die Amplitude ändert, nicht aber die Abstände. Bei grösserer Variation fällt die Schwingung dann plötzlich aus.
Hallo liebe User, ich hab mich nun hier Registriert. Also ich bin der TE. Ich habe das Projekt nach einer gewissen Zeit wieder aufgenommen und hänge da wieder an einem kleines Problem mit VHDL. Also: Ich möchte anhand einer Schalterstellung die Frequenz rauslesen. Daraus erreiche ich mir dann das OMEGA = 2*PI*f/fs Das Problem das ich habe ist, dass ich nicht weiß wie ich das auf einem 1:7 Format realisieren soll. Ich habe eine Funktion fraction_mult die 2 Zahlen miteinander multipliziert. Jedoch dürfen die nicht über 1 drüber gehen da sie ja dann den Zahlenbereich überschreitet, also nicht größer als 0.1111111 (1:7). Also ich wollte das OMEGA mit einer LUT realisieren. Ich schau kwasi in einer if Verkettung nach dem OMEGA wo ich für jede Schalterstellung ein geeignetes habe. Gut, das hab ich. Aber wie kann ich zB das b1 berechnen? Das b1 setzt sich aus (-2)*cos(omega-phi) zusammen Wenn ich phi 0 mache zur einfachheit halber, dann ergibt der cos von meinem Beispiel omega = 0,39269908 0,92. Noch realisierbar. Aber dann muss er mit (-2) multipliziert werden. 2 allein ist ja schon auf einem 1:7 Format gar nicht darstellbar... Ich soll in dem 1:7 Format beleiben, da ich immer damit rechne und eine Umrechnung das ganze komplizierter machen wird... Weiß irgendwer wie ich das umgehen kann? Ich tue mich schwer mit diesem Fraction Format. Hoffe auf einen kleinen Tipp. Danke euch allen nochmal. lg
Die kannst nur im binären Zahlenformat rechnen. (unter Umständen auch im oktalen oder hexadezimal Zahlenformat) Du suchst nach einer Abbildung deines Formates). Leider kenne ich kein Zahlenformat 1:7. Das ein bit kann auch gebrochenrationale Werte entsprechen. 1bit = 1/8pi Wenn du nich auf oktal,binär, hex kommt dann musst due die Stellen erhöhen und eine Restfehler in der Umrechnung hinnehmen. Das ist der typische Rechenfehler der Numerik.
F. S. schrieb: > Ich soll in dem 1:7 Format beleiben, Sagt wer? > da ich immer damit rechne und eine Umrechnung das ganze > komplizierter machen wird... Wie willst du halbwegs aufwendige vorzeichenbehaftete Arithmetik mit 8 Bits schaffen können? > dann ergibt der cos von meinem Beispiel omega = 0,39269908 0,92. Wie rechnest du das um? 1:7 bedeutet doch: 1 Vorkommastelle, 7 Nachkommastellen (wobei die Vorkommastelle dem Vorzeichen zum Opfer fällt...), oder nicht? > Noch realisierbar. Aber schon EXTREM ungenau!
F. S. schrieb: > Ich soll in dem 1:7 Format beleiben Bei dem Algorithmus dürften 8 bit bei Weitem nicht reichen
Ihr habt Recht. Das Format ist zu klein, habs schon auf 16 Bit vergrößert. Ich hänge eher in der Multiplikations-Funktion:
1 | function fraction_mult(a : fixp; c : fixp) return fixp is |
2 | variable result_3 : fixp; |
3 | variable ergebnis : STD_LOGIC_VECTOR((bit_lenght - 1) downto 0); |
4 | variable mult_value : SIGNED(((bit_lenght * 2) - 1) downto 0); |
5 | begin
|
6 | if (a.ip = 1 and c.ip = 1) then |
7 | result_3.ip := 1; |
8 | result_3.fp := bit_lenght - 1; |
9 | result_3.nb := bit_lenght; |
10 | mult_value := SIGNED(a.value) * SIGNED(c.value); |
11 | result_3.value := mult_value(((bit_lenght * 2) - 1) downto bit_lenght); -- Unteren Werte werden abgeschnitten. |
12 | |
13 | ergebnis := STD_LOGIC_VECTOR(result_3.value); |
14 | ergebnis := STD_LOGIC_VECTOR(SHIFT_LEFT(UNSIGNED(ergebnis), 1)); |
15 | result_3.value := SIGNED(ergebnis((bit_lenght - 1) downto 0)); |
16 | |
17 | elsif (a.ip = c.ip) then |
18 | result_3.ip := (a.ip + c.ip) - 1; |
19 | result_3.fp := bit_lenght - (result_3.ip); |
20 | result_3.nb := bit_lenght; |
21 | mult_value := SIGNED(a.value) * SIGNED(c.value); |
22 | result_3.value := mult_value(((bit_lenght * 2) - 1) downto bit_lenght); -- Unteren Werte werden abgeschnitten. |
23 | |
24 | ergebnis := STD_LOGIC_VECTOR(result_3.value); |
25 | ergebnis := STD_LOGIC_VECTOR(SHIFT_LEFT(UNSIGNED(ergebnis), 1)); |
26 | result_3.value := SIGNED(ergebnis((bit_lenght - 1) downto 0)); |
27 | |
28 | -- result_3.ip := result_3.ip - 1;
|
29 | -- result_3.fp := result_3.fp + 1;
|
30 | |
31 | else
|
32 | result_3.ip := (a.ip + c.ip) - 1; |
33 | result_3.fp := bit_lenght - (result_3.ip); |
34 | result_3.nb := bit_lenght; |
35 | mult_value := SIGNED(a.value) * SIGNED(c.value); |
36 | result_3.value := mult_value(((bit_lenght * 2) - 1) downto bit_lenght); |
37 | |
38 | ergebnis := STD_LOGIC_VECTOR(result_3.value); |
39 | ergebnis := STD_LOGIC_VECTOR(SHIFT_LEFT(UNSIGNED(ergebnis), 1)); |
40 | result_3.value := SIGNED(ergebnis((bit_lenght - 1) downto 0)); |
41 | |
42 | if (result_3.value = "0000000000000000" and result_3.ip > 1) then |
43 | result_3.ip := 1; |
44 | result_3.fp := bit_lenght - 1; |
45 | result_3.nb := bit_lenght; |
46 | end if; |
47 | |
48 | -- if ((a.ip /= 1 and c.ip /= 1)) then
|
49 | -- result_3.ip := result_3.ip - 1;
|
50 | -- result_3.fp := result_3.fp + 1;
|
51 | -- ergebnis := STD_LOGIC_VECTOR(result_3.value);
|
52 | -- ergebnis := STD_LOGIC_VECTOR(SHIFT_LEFT(UNSIGNED(ergebnis), 1));
|
53 | -- result_3.value := SIGNED(ergebnis((bit_lenght - 1) downto 0));
|
54 | -- end if;
|
55 | |
56 | end if; |
57 | |
58 | return result_3; |
59 | end function fraction_mult; |
Ich weiß nicht was ich falsch mache, ich bin noch nicht so sattelfest in VHDL. Es gibt Probleme bei der Multiplikation von verschiedenen Fraction Formaten. Könnte mir bitte jemand einen Tipp geben, die Funktion funktioniert, aber irgendwie nicht für jedes beliebiges Format. Danke schon im voraus. lg F.S.
War das beim VHDL nicht so, dass signed nur 50% des Vectors auslastet und eine Multiplikation damit zu 25% führt? - also 2 Bits oben wegfallen? Muss man das so ausführlich beschreiben und warum? Ich habe das immer mit einem "*" beschrieben. Geht das beim signed / bei dieser Applikation nicht? - warum nicht?
Martin Kluth schrieb: > Geht das beim signed / bei dieser Applikation nicht? Doch, es geht. > - warum nicht? Das Problem liegt hier irgendwie beim Verständnis der Fixkommazahlen. Wenn ich bei einer Fixkommamultiplikation erst beide Faktoren gedanklich mit einem festen Faktor f multipliziere (so dass das Komma weg ist), dann eine Integermultiplikation mache (mit dem Operator *) und hinterher das Ergebnis gedanklich durch f² teile, dann habe ich letzlich nichts verändert, aber nur eine generische Operation verwendet. Und der Trick dabei ist, die gedankliche Division durch f² in eine Verdrahtungsänderung umzumünzen... In Zahlen: bei einer Multiplikation von zwei 1.7 Fixkommazahlen 1.7 = V.NNNNNNN (V=Vorkommastellen, N=Nachkommastellen) muss ich beide mental mit 128 multiplizieren. Dann ist das Komma weg: 8.0 = VVVVVVVV. Anschliessend erfolgt die reale Multiplikation, die als Ergebnis einen Integer mit 16 Bits hat: 16.0 = VVVVVVVVVVVVVVVV. Jetzt teile ich das Ergebnis wieder mental durch 16384 und erhalte eine 2.14 Fixkommazahl. 2.14 = VV.NNNNNNNNNNNNNN Wenn jetzt das Ergebnis noch keinen Überlauf und damit in einer 1.7 Fixkommazahl Platz hat, dann kann ich einfach meine 1.7 Fixkommazahl /herausschneiden/: 2.14 = VV.NNNNNNNNNNNNNN --> ||||||||| 1.7 = V.NNNNNNN Das wars. Blöd ist jetzt allerdings, wenn ein Überlauf aufgetreten ist, denn dann lässt sich diese Zahl eigentlich nicht mehr darstellen, es müsste umskaliert werden, der Schritt zur Fließkommazahl rückt in unangenehme Nähe... DSP verwenden deshalb gern das 0.8 oder 0.16, 0.24 oder 0.32 Format, das ja nur Zahlen von -1...0.9999 darstellen kann. Fazit: jede Multiplikation (ausgenommen -1*-1) ergibt zwingend ein richtiges und darstellbares Ergebnis.
Lothar Miller schrieb: > Fazit: jede > > Multiplikation (ausgenommen -1*-1) Eine 1.0 geht doch auch garnicht, wenn man voll skaliert, also Maximum = 16383/16384 z.B. ist doch immer <1
Martin Kluth schrieb: > Eine 1.0 geht doch auch garnicht, wenn man voll skaliert, also Maximum = > 16383/16384 z.B. ist doch immer <1 Klar, genau das habe ich m.E. geschrieben mit 0.9999... Aber -1 ist möglich: -16384/16384. Und -1*-1 gibt dann was? Richtig: 1. Aber genau diese 1 ist nicht darstellbar, und deshalb darf diese Rechnung sinnvollerweise nicht ausgeführt werden.
ich beschränke meinen Zahlenraum deswegen auch in der negativen Hälfte auf "n-1", da gibt es dann solche Eskapaden nicht. Noch besser ist es, von vorn herein physikalische Grenzen zu setzen und z.B. 8000 als Maximum zu nehmen und nicht 8192 (bringt eh nix). Den Rest des Zahlenraums kann man prima für overflow, underflow und andere messages nutzen. Hier beim Sinus würde ich auch nicht ans Limit gehen, selbst beim 8Bit Sinus reichen +/- 100, statt 127, oder meinetwegen 125.
Aber ein 8-Bit-Wandler erreicht eben erst bei 0 und 255 (oder -128 und +127) seine Endwerte...
Die sind aber i.d.R. nicht nutzbar, weil sie nicht von einem Überlauf zu unterscheiden sind, es sei denn, es gibt ein overflow flag. Also fallen 2 Werte ohnehin schon mal wech. Die Wegnahme gerade der - 128 reduziert das maximal mögliche Ergebnis nach der Multiplikation um ein weiteres Bit - der Endvektor muss also nicht, wie oben (2n-1) lang sein, sondern kann 2n-2) lang sein. Beispiel: n = 16. a) Länge von signed (n = 16) = 15, 2n-1 = 31, weil (-32768 * -32768) = 30.0 -> 30 downto 0, ca. 50% gefüllt b) Länge von signed (n ohne - 32768) = 14, n + n = 30, weil (-32767 * 32767) = 29.99 -> 29 downto 0, ca. 99,9% gefüllt Wenn man hinterher mit den erzeugten Werten etwas anstellen will, meinetwegen Filtern, Skalieren etc. dann hat man wieder dasselbe Problem: Wegen einem lumpigen Wert in der Aussteuerung zu Beginn der Kette braucht man ständig ein Bit mehr.
Einen Überlauf kann ich aber nicht mit ein paar "Sicherheitsschritten" auffangen. Schon eine simple Addition braucht ein ganzes Bit für einen Überlauf... Oder was sollte das helfen, wenn ich statt -128..+127 einen Bereich von -100..+100 verwende (also jedesmal mindestens 27 Reserve), aber 64+64 rechnen will? Wie will ich da was sinnvolles mit dem "Headroom" anfangen? >> Aber ein 8-Bit-Wandler erreicht eben erst bei 0 und 255 (oder -128 und >> +127) seine Endwerte... > Die sind aber i.d.R. nicht nutzbar, weil sie nicht von einem Überlauf zu > unterscheiden sind, es sei denn, es gibt ein overflow flag. Nur mit einem zusätzlichen Überlaufflag kann ich einen Überlauf erkennen. Ich nutze auf jeden Fall bei 8 Bit soweit möglich den Bereich von -128..+127.
Lothar Miller schrieb: > Nur mit einem zusätzlichen Überlaufflag kann ich einen Überlauf > > erkennen. Ich nutze auf jeden Fall bei 8 Bit soweit möglich den Bereich > > von -128..+127. Wie willst du denn eine 127 von einer überlaufenen 127 unterscheiden? Wandler haben nicht alle ein Überlaufbit und am oberen Ende sind sie oft völlig unlinear.
Pesto schrieb: > Wie willst du denn eine 127 von einer überlaufenen 127 unterscheiden? Am Overflow-Bit. Nur mit diesem zusätzlichen neunten Bit geht das zuverlässig bei einer 8-Bit-Zahl. Egal ob signed oder unsigned. Oder hast du eine Lösung für dieses Problem: Lothar Miller schrieb: > Oder was sollte das helfen, wenn ich statt -128..+127 einen Bereich von > -100..+100 verwende (also jedesmal mindestens 27 Reserve), aber 64+64 > rechnen will?
Die o.g. Lösung ist viel zu aufwändig. Einfach ein Dreieck auf ein Mehrfach IIR-Filter und fertig ist die Laube. y= x | 0 < x < n/2 y= 1 - x | n/2 < x < n mit x = omega x phi / n f1(t+1) = f1(t) * k + y(t) * (k-1) f2(t+1) = f2(t) * k + f1(t+1) * (k-1) f3(t+1) = f3(t) * k + f2(t+1) * (k-1) u.s.w.
Ich danke euch allen für diese wertvollen Beiträge. Ich arbeite nun mit 16 Bit. Was dieses Zahlenformat betrifft so habe ich mich eigentlich immer an diese Regel gehalten: - Wenn beide Zahlenformate im 1.n Format sind bleibt auch nach der Multiplikation das Format im 1.n. Was ich nicht ganz verstehe, ist, dass sich das multiplizierte Ergebnis Rechtsbündig befindet. Warum ist das so? Ich muss bei der 1.n Multiplikation um eine Stelle nach Links schiften. - Für zwei Zahlen mit unterschiedlichen Formaten gilt: (I1+I2-1).(Q1+Q2) Da verstehe ich irgendwie nicht was ich falsch mache. Ich multipliziere im Prinzip im SIGNED Modus, da das Vorzeichen bei der Multiplikation ja eine sehr große Rolle spielt. @Lothar Miller: Ein Überlauf kann beim Sinus nicht vorkommen, da der Sinus ja nicht größer als 1 ist. Bei einer 1 muss ich halt wie Du richtig sagst 0.111111111111111 rausschieben und eine Abfrage machen. Das gleiche gilt ja für 2.14 auch, oder? DANKE nochmals an alle die sich die Zeit nehmen. lg F.S.
F. S. schrieb: > Was ich nicht ganz verstehe, ist, dass sich das multiplizierte > Ergebnis Rechtsbündig befindet. Warum ist das so? Das ist so, weil du als Ergebnis der Multiplikation zweier 1.n Zahlen eine doppelt so breite 2.2n Zahl als Ergebnis bekommst.
F. S. schrieb: > Bei einer 1 muss ich halt wie Du richtig sagst > > 0.111111111111111 rausschieben und eine Abfrage machen. darf ich freundlichst zwischenfragen, wie das gemeint ist? welche Abfrage? ich glaube, hier sind zwei Fragen im Gange: a) Sinus und dessen optimale Erzeugung b) Umgang mit signed fixed point Ich habe mir das damals in Beispielen angesehen, in dem ich diese im Simulator durchrechnen habe lassen.
So wie ich es sehe, ist eine DDS-Tabelle am besten geeignet, wenn es um einen präzisen Sinus geht. Gibt es eine Möglichkeit zu berechnen, welche S/N eine Sinuswelle erzeugt, die man auf diese Weise tabelliert hat?
high tec ing schrieb: > So wie ich es sehe, ist eine DDS-Tabelle am besten geeignet, wenn es um > einen präzisen Sinus geht. Gibt es eine Möglichkeit zu berechnen, welche > S/N eine Sinuswelle erzeugt, die man auf diese Weise tabelliert hat? Wenn Du meine sin/cos-Funktion auf opencores benutzt, kannst Du die erzeugten Wellen vom Testbett in eine Datei schreiben lassen und danach mit Matlab oder sowas untersuchen. Da muss der Modelsim eben etwas ackern. Gruß, Gerhard
high tec ing schrieb: > So wie ich es sehe, ist eine DDS-Tabelle am besten geeignet, Tabellen haben nur in ihrem Stützpunkt einen Wert. Werte dazwischen werden über rechten und linken Stützwert angenähert. Oder du hast eine riesen Tabelle Am genausten geht es mit dem Cordic Algorthmus. Den benutzt auch dein Taschenrechner. > S/N eine Sinuswelle erzeugt, die man auf diese Weise tabelliert hat? Wenn du umbedingt eine Tabelle brauchst. VHDL kann auch mit Sinus und Cosinus rechnen. Das lässt sich aber nicht synthetisieren. Kann aber genutzt werden, um Tabellen zu erzeugen.
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.