Forum: FPGA, VHDL & Co. Genauer und schneller Sinus im FPGA


von Rolf (audiorolf)


Lesenswert?

Kennt jemand einen Algorithmus für einen Sinus, gfs als Näherung, der 
bei ähnlicher Genauigkeit schneller ist, als CORDIC?

Ich hätte da eine Ansteuerung für eine Leistungselektronik, die mehrere 
Sinusfunktionen erfordert, deren Werte sich sehr schnell ändern können. 
Der FPGA läuft aus Wärmegründen nur mit 40 MHz. Die Cordic-Funktion, die 
ich brauche, arbeitet bei der erforderlichen Genauigkeit mit 24 Takten 
und ist bei der Anzahl der Kanäle auch ziemlich ausgelastet. Es müssen 
aber 6 Phasen mit Sinus und Cosinus versorgt werden, sodas die 
Berechnungszeit in Richtung 72 Takten geht und die daraus entstehenden 
unter 500 kHz Latenz nicht reicht, um mehrere Kanäle zu steuern. Um die 
Zahl der parallelen Cordic core zu reduzieren, wäre eine schnellere 
Funktion hilfreich.

90°-RAM-Sinus ist nicht möglich, weil der BRAM für die hohe Genauigkeit 
fehlt und ein DDR zu langsam ist, für die vielen Kanäle.

Nett wäre z.B. ein Algorithmus, der pro Genauigkeitsstufe nur halb 
soviele Takte benötigt.

Wenn nicht muss ich FPGA-Takt und Gehäuse ändern.

von Rolf (audiorolf)


Lesenswert?

Ein Nachsatz noch: Ich meine mich erinnern zu können, dass es für 
Anwendungen aus früheren Zeiten, wo sie RAM sparen mussten, so einen 
Algo gegeben hat, der eine Kombi aus Auslesen und Iteration darstellte, 
also stückweise Interpolation wodurch erst die hohen und dann die 
niederen Bits berechnet wurden. Ich finde dazu aber nichts. Wenn ich 
einen Ansatz hätte, könnte ich den aufbauen und durchmessen, ob es mit 
der Genauigkeit und dem Tempo passt.

Das habe ich z.B. für den CORDIC gemacht und bin so auf die 24 Stufen / 
Bits gekommen, die ich braucht, damit es wenig genug klirrt, denn die 
Frequenz moduliert wird.

von Hendrik L. (hlipka)


Lesenswert?

Evt. hilft Dir 
https://community.element14.com/technologies/fpga-group/b/blog/posts/fpga-waves-8-fast-cordic-sine-and-cosine 
weiter? Es behauptet 'one sample per clock' (aber ich habe jetzt nicht 
weiter reingelesen wie gut das klappt).

von J. S. (engineer) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hendrik L. schrieb:
> Evt. hilft Dir
Da wäre ich skeptisch :-)
Die Version ist eine ausgerollte Version, die ebenfalls mit einer Stufe 
je Winkelsegment arbeitet. Allerdings eine mit 6 Bit. Das scheint für 
die Anwendung des Erstellers offenbar zu reichen.

Hendrik L. schrieb:
> Es behauptet 'one sample per clock'
Beim Schnellen ÜBerfliegen scheinen die Module die dort ADD-MUL heißen 
einfach hintereinander gehängt. Wenn der FPGA schnell genug ist, geht 
das mit einem sample per Clock bei den angegebenen 50MHz. Das hilft aber 
nicht weiter. Man könnte es auch registrieren und bekäme auch jeweils 
ein Sample, halt nur mit Latenz, dafür aber auch gerne mit 200 MHz, also 
effektiv rascher.

Dem Ersteller ging es da wohl um klein und kompakt. Der falsche 
Y-Offset, den man in der gelben Kurve im "Oszillogramm" sieht, scheint 
auch nicht zu stören. Das ist ein ganz offensichtlicher Fehler beim 
Interpretieren des Phasenvektors beim Vorzeichenbilden und deutet auf 
ein Misverständnis beim Zeitschema: Da wird wahrscheinlich der Y-Wert 
aus einer falschen Zeit / ein Takt zu spät geschnappt und anhand der 
aktuellen Phase geflippt.

Wie auch immer ...

Den kompaktesten und genauesten Sinus bekommt man im FPGA mit einem 
virtuellen Oszillator nach DGL 2.Ordnung. Das geht in etwa bis zur 
Frequenz Clock / N*N*N  bitgenau, wenn man alles gut genug aufgelöst 
rechnet und gut rundet. Bei 200MHz sind 15kHz bei 24 Bit und dann 48 Bit 
breiten Vektoren.  Das geht voll als pipeline in etwa 12-15 Takten, 
wegen 3 verketteten ADDs und MULs auf breiten Vektoren. Mit weniger 
Genauigkeit geht es auch mit 6 Takten, was dann die minimale 
Iterationslänge festlegt -> 6 Kanäle / Latenz. Nimmt man jetzt eine 
Länge von hier 16, bekommt man 16 Kanäle mit denen man arbeiten kann. 
Bei einem 6 Phasensystem wären eventuell 18 sinnvoll.

Der Oszillator reagiert sofort auf Parameteränderungen, allerdings eben 
wie eine realer, d.h. mit Schwingungen und einer Art "Hineingleiten" in 
den neuen Zustand (Amplitude / Frequenz).

Will man das nicht, braucht es eine DDS mit FIR-Filterung. Auch einen 
Cordic könnte man filtern.

: Bearbeitet durch User
von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

Wieviel Stützstellen werden denn benötigt? Ich bezweifle, das da 
wirklich zu wenig RAM ist. und aus den 40 MHz könnte man im FÜGA auch 
für einen bgrenzten Bereich Vielfache erzeugen und so die absolute 
Durchlaufzeit erhö
hen.

Und ein pißchen Capazität in der schaltung rundet auch die Stufen ab... 
also da sollte man vielleicht mal an ein FPGA-Evalboard eine Scope, 
Speckie anschliessen und schauen was rauskommt.

von Andreas M. (amesser)


Lesenswert?

Wenn du genug Addierer/Multiplizierer hast, dann kannst Du die Cordic 
doch einfach als Pipeline umsetzen.

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

> Wenn du genug Addierer/Multiplizierer hast, dann kannst Du die Cordic
> doch einfach als Pipeline umsetzen.

Um welchen FPGA-Typ geht es hier eigentlich, Spartan XL aus der 
Mottenkiste?.

von Gerhard H. (ghf)


Lesenswert?

Bradward B. schrieb:
>> Wenn du genug Addierer/Multiplizierer hast, dann kannst Du die Cordic
>> doch einfach als Pipeline umsetzen.
>
> Um welchen FPGA-Typ geht es hier eigentlich, Spartan XL aus der
> Mottenkiste?.

Ich habe einen DDS veröffentlicht auf opencores.org.
Der geht natürlich auch mit table lookup.
project = sincos  in der Abteilung arith.
Die opencores web site ist so langsam am Vergammeln, notfalls
kann ich ein zip schicken.

Der DDS liefert sin und cos gleichzeitig ohne weiteren Mehraufwand.
Auf einem Spartan-6-eval board aus der Mottenkiste läuft
er mit 200 MHz ohne Optimierungsgetue. Pipelinestufen sind
kombinatorisch bis ??? durch ein generic einstellbar.
Symmetrie wird ausgenutzt soweit es geht.
Reines VHDL ohne Hersteller-Macros.

Die Sunderland-Technik zum Zerlegen der Sinus-Tabelle
in 2 viel kleinere habe ich nicht gebraucht, mir kam es
auf kleine Latenz an,  für einen Demodulator auf 70 MHz.
Viel delay macht die Stabilität der digitalen PLL schwer
beherrschbar, deshalb auch kein Cordic.

Mit der Sunderland-Technik kann man die Größe der Tabelle
auf 1/10  ..  1/50 der Speicherbits insgesamt runterbringen,
je nach Rom-Abmessungen.

Beschrieben wird das in James A. Crawford:
Frequency Synthesizer Design Handbook

Er gibt einen pointer:
Sunderland, D.A. et al. CMOS/SOS Frequency synthesizer LSI
circuit for spread spectrum communications
IEEE J. Solid State Circ. Vol. SC-19   August 84  pp 495-505

Wenn Du's irgendwo erlegst, würde mich eine Kopie freuen.

Man könnte auch eine Tabelle für mehrere Kanäle multiplexen
wenn der Takt schnell genug ist.

Gerhard H

: Bearbeitet durch User
von Gerhard H. (ghf)


Angehängte Dateien:

Lesenswert?

Ich glaube, das geht noch als fair use durch.

von Matthias 🟠. (homa)


Angehängte Dateien:

Lesenswert?

Leider war die Quelle nicht besser ;-)
Hier als kleines PDF (scantailor + naps2).

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.