Durch eine Recherche bei go...le stieß ich heute auf diese Art der
Sinuserzeugung. Stichwort ist "Sunderland Zerlegung", offenbar
publiziert um 1984 herum. Leider ergibt die Suche fast keine Ergebnisse
außer immer wieder denselben Bezug zu der genannten Publikation und der
Grafik oben.
Folgende Fragen:
1) Angeblich wird der Vektor (hier 12 Bit) in 3 Fragemente geteilt,
welche der Vorschrift a<2(-1) , b<2(-4) und c<(-8) gehorchen. Das schon
erkenne ich in der Grafik nicht wirklich wieder. So wie es scheint,
werden die Vektoren einfach 4-Bit-weise geteilt. Dabei wären "A" die
oberen 4, "B" die mittleren 4 und "C" die unteren 4. D'accord?
2) In den beiden Boxen finden sich dann zwei unterschiedliche
Vorschriften zur Erzeugung der Werte. Dabeit ist mir widerum nicht klar,
wie die Vektoren zugeführt werden müssen: Sind das nun beide Werte
zwischen 0 und 15 parallel oder muss der jeweils obere 4 Bits nach oben
geschiftet werden, sodass das Argument 8 Bit hat?
3) Was die Rechenvorschrift angeht: Komisch finde ich, dass der Sinus
aus (a+b) gebildet wird, wo ich eigentlich Werte von 0 ... 1 erwartet
hätte. Ich nehme an, man muss sie noch durch 16 teilen, um sie zu
skalieren? Dann läuft (a+b) aber von 0 ... 2. Wobei die PI/2 dazu passen
könnten. D'accord?
Oder sind es Werte von 0 ... 255 wegen 8 Bit CONCAT? und dann durch 256?
4) Was ist mit "nicht b" gemeint? Der Balken über dem b ist eine
Inversion der Bits, was streng genommen dazu führt, dass man die gesamte
Formel als boolsche Formel lesen müsste und das "+" als Oder lesen
sollte. Ich nehme aber an, dass das b einfach auf ein (1-b) hinausläuft?
Also 15-x oder sind es 16-x?
5) Wie ist der Ausgang zu interpretieren? Müssen die Sinuswerte noch auf
9 und 4 Bit skaliert werden? Wie werden sie verrechnet? Im Text steht
etwas von EXOR, aber das Symbol ist eher ein Connector. Werden nur die
unteren 4 Bits verrechnet oder kommt die Tabelle von oben mit 9 Bits und
hinten kommen 13 raus?
-------------------
Ich habe verschiedene Versionen probiert, komme aber zu keinem Sinus.
Nicht annähernd. Irgendwie muss sich das aber lösen lassen denke ich.
Hat jemand einen Tipp?
Die nächste Frage wäre dann:
6) Kann man die Vorschrift skalieren? Also z.B. doppelte Bits rein,
doppelte Bits raus?
Eine weitere Unklarheit: Im "FINE ROM" werden alle 3 Variablen benutzt,
um den Tabellenwert zu definieren: "a", "nicht b" und "c". Daher braucht
es dort 12 Bit = 4096 Einträge. D'accord?
Angesteuert wird die Tabelle aber nur mit A und B, also 256
Möglichkeiten. Printed man die Tabelle, ist die aber nicht von b
unabhängig.
Christoph db1uq K. schrieb:> da heisst es "Sunderland algorithm"
Das bringt leider neue Konfusion, denn da kommen hinten nicht 9,4 Bits
sondern 11, 4 heraus.
Ferner ist die sich ergebende letzlich als optimal hingestellte Struktur
nach der dortigen Publikation wieder eine etwas andere.
Wolfgang schrieb:> Der Sunderland Algorithmus stellt eine Verbesserung des Hutchison> Algorithmus dar.
Das habe ich auch schon gelesen. Die Theorie ist eigentlich auch klar.
In einer anderen Seite findet sich diese Tabelle. Das sieht schon
logischer aus, ist aber am Ende nichts anderes als ein Sinus über die
höchsten 8 der 12 Bits. Es entsteht ein Viertelbogen mit jeweils 16
identischen Werten, wegen der unteren 4 Bits.
Allerdings kriege ich die Vorschrift für das fine RAM nicht hin. So wie
es dort steht, geht es nicht. Die Zwischenbögen interpolieren nicht
sauber.
Hier ist die Summation beider Werte:
Es muss für die Werte im ROM 2, dem fine rom, ein Bogen herauskommen,
der fast eine Gerade ist und weiter oben in der STeigung abflacht. Das
Abflachen leistet der COS(c), der gegen PI gegen 0 geht. Das passt!
Die Gerade liefert der Sinus mit den unteren 4 Bits. Die Krümmung passt
aber nicht. Ist zu stark gekrümmt. Aber nur bei diesem Ausschnitt X/16 *
PI liefert er die richtige Amplitude.
Kann es sein, dass die weggelassenen Restterme / Bits die Ursache sind?
> Da frage ich mich aber, was das dann soll.
Hardware sparen und gleichzeitig schnell sein.
> Ist das linear nicht besser?
Mach mal in HW. Und im Prinzip ist das Fine-ROM doch nichts anderes -
16 unterschiedliche Interpolationssegmente, die oberen Bits wählen das
Segment aus, die unteren die Punkte des Segments.
> Eine lineare Interpolation in HW ist trivial.
Auch, wenn du direkt auf bestimmte Punkte innerhalb des
Interpolationsintervalls zugreifen willst? Also nicht inkrementell
einen Punkt nach dem anderen?
Warum nicht? Entweder, ich lese zwei Punkte aus der Tabelle und bilde
die Steigung, oder ich lege sie gleich so ab. Beim Sinus hast du dann
gleich den Cosinus. Der Rest ist Y = a * x + b.
Ob die Stufen so deutlich sichtbar sind, hängt vom Verhältnis
Taktfrequenz zu Ausgangsfrequenz ab, hier war es gerade so, dass die
still stehen. Normalerweise werden sie aber schnell wandern, dann sind
sie am Oszilloskop nicht mehr zu erkennen. Spektral ist das ja eine
ziemlich hohe Harmonische.
Außerdem habe ich ja einen kleinen Ausschnitt der Sinuskurve vergrößert.
Und der AD9835 hat nur 14 Bit und ist relativ alt.
ja die meine ich auch. Wenn ich die Frequenz verstelle, sind die Bögen
nicht mehr zu sehen.
Einige DSP-Literatur vor allem ältere, kennt den Namen Sunderland. Hier
in ISBN 9780070702561 wird von drei Tabellen gesprochen, im Gegensatz zu
Hutchison, der nur zwei hat. books.google.com findet noch mehr zum
Thema.
Markus W. schrieb:> Entweder, ich lese zwei Punkte aus der Tabelle und bilde> die Steigung,
Bei nicht näher definierten Verläufen ja, aber bei einem Sinus findet
man den Cosinus auch 90° später in der Tabelle. Geht bei einem FPGA mit
Lesen auf zwei Seiten im Block-RAM in voller Geschwindigkeit.
M. W. schrieb:> Ist das linear nicht besser?
Es kommt nur auf die Relation an! Mit der Sunderland-Methode kriegt man
pro ROM-Platz den besseren Sinus heraus. Er ist auch etwas besser, als
das Zusatz-RAM wegzulassen und linear zu interpolieren. Die Bögen, die
durch diese Interpolation (nicht) entstehen, entsprechen den Resten, die
der Sinus produziert, wenn man eine Gerade abzieht. Ich hatte vor
einiger Zeit hier eine Grafik gepostet, in der die Fehler der
Interpolation bei einfachen Tabellen aufgezeigt wird:
Beitrag "Präzise Sinus-DDS mit kleiner Tabelle"
Diese kleinen Teilbögen im Bild links oben bekommt man mit Sunderland
reduziert (wenn auch nicht weg). Und obwohl das etwas buckelig aussehen
mag, ist es mitunter besser, weil die entstehenden Oberwellen geringer
sind. Die Bögen sind runder.
Die Frage insgesamt aber ist aus meiner Sicht, ob man das überhaupt mit
einer Tabelle machen muss, weil man (wie im Artikel angedeutet) mit 1GHz
im ASIC Sinüsse generieren will, oder ob man das nicht auch komplett per
Rechnung erledigen kann. Nach meinen bescheidenen Versuchen ist es
meistens zweckmäßiger, das mit einer Ersatzrechnung zu tun, wenn man
etwas Rechenzeit hat. Ich hatte hier einen Sinus gepostet, der mit einem
8Bit-Rechner erzeugt werden kann. Der Fehler ist kleiner, als bei
Sunderland gleicher Phasen- und Amplitudenauflösung! Man braucht also
weniger Speicherfläche, sondern nur mehr Rechnerei, also etwas mehr
Kombinatorik oder in einem AVR mehr Zeit.
https://www.mikrocontroller.net/articles/Datei:Opimierte_naeherung_sinusfunktion2_js.png
Wenn man es in einer Tabelle machen möchte, wofür es bei anderen
Pulsformen mehr Berechtigung gibt, als beim Sinus, dann kann man eine
Grobtabelle aus den Werten vorgeben und hinterlegen und eine Feintabelle
mit Korrektur werten von der VHDL-Synthese berechnen lassen, indem man
die Grobwerte von den Zielwerten abzieht und sie mit dem feiner
aufgelösten Vektor ins Verhältnis setzt. Je nach Geschmack schiebt man
das ins BRAM oder in eine WHEN -Tabelle, die die Synthese dann berechnet
und ins LUTs abbildet.
Ich verfahre z.B. so bei einigen WAVE-TABLE-SYNTHESIS-Modulen, die eine
Grundfrequenz haben: Diese wird in der Soll-Tabelle abgezogen und nur
die Differenz gespeichert. Damit fallen 3-4 Bits der Amplitude weg, die
weniger gespeichert werden müssen. Mit einem BLock-RAM, das nur 18 Bit
breit ist, bekommt man so locker einen 20Bit genauen Wert. Hintendrein
muss natürlich einmal addiert werden, aber Adder ist beim Mixer mit drin
und die Wellenformen laufen eh alle parallel zu jederzeit mit, weil im
FPGA alles zur gleichen Zeit existiert. Mit etwas Geschick bekommt man
damit kostenlos eine gewaltige zusättzliche Zahl von
Wellenform-Kombinationen, die praktisch kaum mehr Speicher oder
Rechenaufwand machen.
Was reine Sinuserzeugung angeht, habe ich eine Version, die aus nur 9
18-Bit-Multiplizieren besteht und einen Sinus auf > 16 Bit genau
produziert. Hinzu kommt die Filterung und Interpolation.
Christoph db1uq K. schrieb:> ja die meine ich auch. Wenn ich die Frequenz verstelle, sind die Bögen> nicht mehr zu sehen.
Ist auch kaum anzunehmen, dass ein DDS-Chip die gleichen Fehler
produziert. Das kommt eher von den Stufen bei geringen Frequenzen und
dem Filter und seiner darauf nicht angepassten Grenzfrequenz. Das ergibt
Kondensatorladekurven.
M. W. schrieb:> Eine lineare Interpolation in HW ist trivial.
Auch eine quadratische Interpolation ist in HW nicht sonderlich
aufwändig. Man braucht dann aber 2+1 Punkte.
Ich frage mich aber gerade etwas anders:
Wenn ich die beiden Bilder vergleiche, welche die Sunderland'schen
Tabellenwerte beschreiben, dann ist oben einmal eine Geradengleichung
(a+b) mit enthalten und unten nicht. Kann es sein, dass da etwas fehlt?
Die Gleichung oben sieht nämlich irgendwie so aus, wie ich es in der
gelinkten Grafik gezeigt habe: Eine Gerade welche die Punkte linear
verbindet und den entstehenden Rest als lauter Sinusbögen, die
Sunderland versucht, mit dem Zusatz-ROM wegzunehmen.
Vielleicht muss diese Gerade in das Korrektur-ROM mit hinein?
Christoph db1uq K. schrieb:> Hier in ISBN 9780070702561 wird von drei Tabellen gesprochen,
Was nur logisch wäre, weil es drei Phasenvektoren sind. Allerdings lässt
man ja die mittleren Bits weg, wegen der Identität. Dem dürfte die
dritte Tabelle zum Opfer gefallen sind.