mikrocontroller.net

Forum: FPGA, VHDL & Co. DDS Compiler - Phase nur bis 16 Bit?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Markus W. (elektrowagi78) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Ich werd' noch mal blöde mit dem Xilinx:

Gerade auf die Schnelle versucht, eine Sinustabell mit dem DDS-Compiler 
zu erzeugen, die mit uc-programmierten Frequenzen läuft und 
festgestellt, dass die nur bis 16 bit Phasenauflösung geht. Gibt es das?

von Achim S. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Gerade auf die Schnelle versucht, eine Sinustabell mit dem DDS-Compiler
> zu erzeugen, die mit uc-programmierten Frequenzen läuft und
> festgestellt, dass die nur bis 16 bit Phasenauflösung geht. Gibt es das?

Du meinst der Phasenakkumulator schafft nur 16 Bit Auflösung? Das fände 
ich sehr  seltsam.

Oder meinst du, dass die Sinustabelle "nur" 2^16 Einträge schafft? Das 
könnte schon sein, schließlich ist der Speicherplatz in deinem FPGA 
begrenzt.

Welches FPGA nutzt du denn, wieviel Speicherressourcen hat das?

von Markus W. (elektrowagi78) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Genannt ist nur die Phase. Kann sein es ist die LUT-Adress-Breite, keine 
Ahnung. Chip ist Kintex, Platz sollte rechnerisch für 20 solche Tabellen 
sein.

von Achim S. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Genannt ist nur die Phase. Kann sein es ist die LUT-Adress-Breite, keine
> Ahnung.

Ja, es ist die LUT-Adressbreite. Wenn du oben statt "LUT-Only" eine 
andere Option wählst siehst du, dass der Phasenakkumulator wesentlich 
breiter sein könnte. Und tatsächlich definiert ja zunächst mal der 
Phasenakkumulator die Phasenauflösung der DDS, nicht die Größe der 
Sinustabelle.

Bei der Sinustabelle wird tatsächlich auf eine Adressbreite von 16 Bit 
begrenzt. Das hat vielleicht auch was mit der Spannungsauflösung zu tun 
(in deinem Bild der "Output Width"). Der DDS-Compiler will vielleicht 
nicht beliebig viel Speicherplatz für die Sinustabelle verwenden, wenn 
in der Tabelle in benachbarten Stellen dann ohnehin jeweils lauter 
identische Werte stehen würden.

Findet sich denn im Datenblatt des DDS-Compilers nichts dazu?

von my2ct (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Gerade auf die Schnelle versucht, ...

Markus W. schrieb:
> Genannt ist nur die Phase. Kann sein es ist die LUT-Adress-Breite, keine
> Ahnung.

Dann solltest du vielleicht erstmal letzteres Ändern.
Nimm dir etwas Zeit und arbeite dich etwas in die Funktionsweise eines 
DDS ein, statt blind auf irgendwelchen Tools rumzuklicken.

von Markus W. (elektrowagi78) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Achim S. schrieb:
> Bei der Sinustabelle wird tatsächlich auf eine Adressbreite von 16 Bit
> begrenzt. Das hat vielleicht auch was mit der Spannungsauflösung zu tun
> (in deinem Bild der "Output Width").
Leider nein, auch wenn ich auf 20 bit und mehr aufziehe, ergibt sich 
keine andere Konfigurationsoption. Die "Rasterung", was immer das sein 
soll, schränkt sogar auf 4 Bits ein. Auch andere Optionen ändern das 
nicht.

> Der DDS-Compiler will vielleicht
> nicht beliebig viel Speicherplatz für die Sinustabelle verwenden,
Es steht genug RAM zur Verfügung.

> wenn in der Tabelle in benachbarten Stellen dann ohnehin jeweils lauter
> identische Werte stehen würden.
Das wäre nicht der Fall, da die 24 Bit diese Auflösung hergeben. Lässt 
sich ja ausprobieren. Die Werte ändern sich von Phasenwert zu Phasenwert


Achim S. schrieb:
> Und tatsächlich definiert ja zunächst mal der
> Phasenakkumulator die Phasenauflösung der DDS, nicht die Größe der
> Sinustabelle.
Dann würde auch eine 10 Bit DDS dasselbe ausgeben, wie eine 20 Bit DDS? 
Hauptsache der Phasenvektor ist gross genug?


my2ct schrieb:
> Dann solltest du vielleicht erstmal letzteres Ändern.
Kann ich nicht. Ich benötige die Auflösung.

> Nimm dir etwas Zeit und arbeite dich etwas in die Funktionsweise eines
> DDS ein
Ich kenne DDS sehr genau und habe auch den Core immer mal wieder 
verwendet.

Ich sehe nur, dass er scheinbar nur noch AXI kann, statt auch das 
frühere Interface. Da gab es diese Einschränkung nicht. Hängt es gfs 
damit zusammen, dass die AXI-Phase nut 16 Bit kann?

von Achim S. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Ich sehe nur, dass er scheinbar nur noch AXI kann, statt auch das
> frühere Interface. Da gab es diese Einschränkung nicht.

habe es eben mit der ISE 14.7 ausprobiert. Da kann die Phasenbreite zwar 
bis 26 Bit eingestellt werden (was beim aktuellen DDS-Compiler 
wahrscheinlich immer noch geht), aber die Adressbreite für die 
Sinustabelle geht auch bei dieser ziemlich uralten ISE nur maximal bis 
16 Bit. War also auch früher schon genau so.

Dafür werden im Datenblatt dann verschiedene Methoden genannt, wie man 
die daraus evtl. entstehenden Signalverfälschungen reduzieren kann 
(Phase Dither, ...)

Markus W. schrieb:
> my2ct schrieb:
>> Dann solltest du vielleicht erstmal letzteres Ändern.
> Kann ich nicht. Ich benötige die Auflösung.

Na ja.

Es geht dir also einfach darum, einen möglichst großen Speicher im FPGA 
mit einer Sinustabelle vorzubelegen? Wenn dir der DDS-Compiler dabei 
nicht weit genug geht, dann kannst du ja selbst einen entsprechend 
großen Block-RAM instanziieren und die Sinuswerte über ein 
Koeffizientenfile vorbelegen. Um Sinus-Werte zu berechnen brauchst du ja 
nicht zwingend den DDS-Compiler, das kannst du auch unabhängig von 
Xilinx z.B. per Excel erledigen.

Wenn der Router es dann noch schafft, alle Ram-Blöcke wie von dir 
gewünscht zu verdrahten, hast du die benötigte Auflösung deines 
Problems.

von my2ct (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> my2ct schrieb:
>> Dann solltest du vielleicht erstmal letzteres Ändern.
> Kann ich nicht. Ich benötige die Auflösung.

Für die Phase des DDS oder für den Analogwert bei Ausgabe der 
Sinuskurve?

von Jürgen S. (engineer) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Achim S. schrieb:
> einen großen Block-RAM instanziieren und die Sinuswerte über ein
> Koeffizientenfile vorbelegen. Um Sinus-Werte zu berechnen brauchst du ja
> nicht zwingend den DDS-Compiler, das kannst du auch unabhängig von
> Xilinx z.B. per Excel erledigen.

Exakt. Mache ich schon immer so. Der DDS-Compiler scheint auch so seine 
Eigenheiten zu haben, bzw. die Firma Xilinx hat ein eigenes Verständnis, 
wie Sinuswerte auszusehen haben, damit man sie sequenziell ausgeben 
kann. Ich habe vor etwa 10 Jahren dazu schon einen Artikel gepostet, in 
welchem ich auf die Unterschiede hingewiesen habe. Es scheint sich um 
Rundungsfehler zu handeln, bzw. ich runde anders, als Xilinx es tut. 
Mein Phasenoffset ist auch ein anderer und orientiert sich an dem 
Prinzip, dass ein Phasenwert X immer die Mitte eines Phasenbereiches 
abdeckt, also die 0 repräsentiert den Bereich von 0 bis 1,  die 1 den 
von 1 bis 2. Damit ist der richtige Sinuswert Y der des Wertes X in der 
Mitte, also z.B. 0.5, 1.5 etc. Der erledigt das Problem eines impliziten 
Offsets und einer möglichen Änderung des Verhaltens wenn der Vektor mal 
aufgebohrt wird. Auch sind die Sinuswellen unterschiedlicher Auflösungen 
so immer auf derselben Phasenlage. Siehe auch meine Ausführungen im 
Artikel
Digitale Sinusfunktion.

Der Nachteil einer selbst erzeugten Tabelle ist leider die extreme 
Synthesezeit bei langen Tabellen, wenn man es nicht im BRAM, sondern 
unter z.B. Mitbenutzung von LUTRAM bauen will. Ich erlebe das auch 
gerade wieder bei meinen fest verbauten Wellenformen. Die haben z.B. 20 
Bit-Phasen und synthetisieren ewig. Ich will die aber in LUT haben, 
damit sie klein bleiben. Typisch lassen sich die Umfänge ja stark 
reduzieren, wenn die Logik optimiert wird.

Wenn es nur ein Sinus sein soll, dann tut gfs auch der CORDIC. Der hat 
dann eben wieder Latenzen und den Nachteil, dass man nur binäre 
Auflösungen erzeugen kann.

von Gerhard H. (ghf)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe in 2010 eine Sinustabelle in reinem VHDL nach

<  https://opencores.org/projects/sincos      >

hochgeladen. Die hat keine künstlichen Beschränkungen.
Wenn du das RAM /ROM hast, dann bekommt er es voll.
Das Testbett enthält als Beispiel einen DDS.
Reines portables VHDL, kein ise/vivado/matlab, was auch immer.

Es werden alle möglichen Symmetrien ausgenutzt und man
bekommt Sinus & Cosinus gleichzeitig ohne Mehraufwand.
(Na ja, ein paar Pipelineregister).

Die Anzahl der Pipelinestufen kann man einstellen von 0
(rein kombinatorisch) bis 10, WIMRE. Die werden halbwegs
sinnvoll an den richtigen Stellen eingefügt, weil der
Register-balancer zumindest damals bei der ISE nicht
viel getaugt hat.

Bei der Compilation wird gecheckt, dass alle Werte
korrekt bis zum letzten Bit gerundet sind; das heisst
der Fehler ist max. ein halbes Bit.

Die einzigen Beschwerden die bisher gekommen sind,
waren dass Leute es nicht geschafft haben ihren
Modelsim auf ps einzustellen.

Wenn man z.B. wirklich niedriges Phasenrauschen
braucht, dann muss man eben den Speicher opfern.

Wenn man Phasen/Frequenzmodulation/sweeps machen will,
dann bekommt man beim Cordic Latenz-Probleme.

Die Sinustabelle ist dieses Jahr bisher 139 mal runter-
geladen worden. Meist in Clustern. Ich vermute,
immer dann, wenn passende Hausaufgaben verteilt werden. :-)

Gruß, Gerhard

: Bearbeitet durch User
von Markus W. (elektrowagi78) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Klingt nicht schlecht, die hatte ich auch schon gefunden. Nur hat mich 
das "Development status:Beta" abgeschreckt. Auch ist OC nicht die 
präferrierte Quelle für Sourcen wegen der Rechtesituation dort. Wir 
hatten schon echten Ärger mit Kunden und Kundeskunden, weil OC-SW 
verwendet wurde. Wird in Aufträgen auch regelmäßig ausgeschlossen.

von Gerhard H. (ghf)


Bewertung
0 lesenswert
nicht lesenswert
BSD ist doch letztlich "Mach damit was du willst, aber lass mich in
Ruhe und behaupte nicht, es wäre von dir."
Entgegenkommender kann man kaum sein.

Ja, ich wollte eigentlich noch erweitern auf BCD, damit man aus einer
100 MHz clock auch EXAKT und phasenstarr 0.999 MHz machen kann, aber
wenn nie eine Rückmeldung kommt, ausser wenn jemand Probleme mit
seinen Werkzeugen hat, dann verschwindet der Antrieb recht schnell.

Gruß, Gerhard

(BCD gestrichen, auf stable gesetzt)

von Markus W. (elektrowagi78) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Habe es mal versucht, zu analysieren und zu implementieren. Scheitere 
aber an diese float_fixed_lib. Ist die aus dem Xilinx_Lib pool zu 
ziehen?

Mit float möchte ich eigentlich nicht arbeiten.

Ich finde mich auch ehrlich gesagt nicht zurecht. Sind erstaunlich viele 
files. Welche brauche ich davon denn?

Ich erkenne auch nicht, wo ich die Bitbreiten einstellen soll. Ich hätte 
jetzt sowas wie generic erwartet.

?

von Gerhard H. (ghf)


Bewertung
0 lesenswert
nicht lesenswert
Ah, Sonntag morgen um 00:45....

Float ist ein ganz normaler VHDL-Datentyp, und der wird nur
zur Compilationszeit auf deinem PC benutzt. Im FPGA landet
keinerlei Gleitkomma-Arithmetik. Die Funktion init_sintabxxxx()
macht zwar intern jede Menge Gleitkomma-Turnerei, aber was
sie letztendlich abliefert ist nur ein ROM-Image, mit dem man
ein konstantes Dingens vom Typ sintab initialisieren kann.
Und sie ist beim Compilieren geschwätzig.

VHDL ist eine Simulationssprache, von der ein Teil
synthetisierbar ist. VHDL kann alles was C oder Pascal
können. Die libraries sind halt beschissen (textio etc)
und es macht eher weniger Spaß. Das kotzt einen spätestens
an, wenn man aus Vorschriftswut kein wirkliches Äquivalent
zu printf() mit variabler Parameterzahl bekommt.

Die Vektor-Breiten ergeben sich automatisch daraus, was du
"von oberhalb" anschliesst. Da ist nix zu tun. Du musst es
nur im Context compilieren.

Wenn Du einen Bus mit 20 Bit Breite an den Ausgang anschliesst,
dann liefert die Tabelle eben 20 Bit. Du brauchst nicht sagen,
übrigens, wir brauchen 20 Bit. Das kann man schon an den
Attributen des Ausgangsbusses sehen. Es wird einfach das 'length
oder 'high-Attribut der angeschlossenen Busse benutzt.
Das passt dann von selbst.

Aaargh, ich hatte > 8 Jahre keinen Grund mehr, mir das anzuschauen.
Ich bemühe mich, mehr in analoge Raumfahrtelektronik abzudriften.
Aber auch da poppt schon mal ein Steinzeit-Virtex hoch, das
nach einer triple module redundancy library fragt.

Gute Nacht für heute!

Gerhard

: Bearbeitet durch User
von Markus W. (elektrowagi78) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Ausführungen. Ist plausibel. Allerdings kriege ich es 
nicht ins Laufen:

Alles importiert, ein Untermodul wurde nicht gefunden.

Verweise intern von work (obsolet) auf xil_defaultlib umgestellt (was 
normal klappt), nichts geht mehr:

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.