Hallo,
ich habe gerade versucht, mit der DDFS von Lothar Miller, einen Sinus zu
generieren.
http://www.lothar-miller.de/s9y/categories/31-DDFS
Dazu wollte ich den gegebenen VHDL Code etwas umschreiben, damit es für
mich übersichtlicher wird. (siehe Anhang)
Ich wollte die sign und quadrant Abfrage mit einer case gestalten.
Eigentlich dachte ich, dass
das gleiche ist. Die Simulationsergebnisse haben aber einen kleinen
Unterschied.
Bei der case-Variante bekomme ich, sobald die Adresse 1 wird, immer
komische peaks in die Sinuswelle hinein und ich kann mir nicht wirklich
erklären, wieso das so ist.
Anscheinend springt das Result_sin2 Register einmal mehr um, als es bei
der originalen If Anweisung der Fall ist.
Kann mir das jemand erklären und mir meinen Fehler zeigen?
Vielen Dank!
Michael
Hi!
ohne Gewähr:
Dein Signal "Sign_Quadrant" wird immer erst am Ende des Prozesses
zugewiesen, d.h. bei einer neuen Adresse hängst du im ersten Taktzyklus
hinterher.
Wenn Du es direkt so verwenden willst, musst Du "Sign_Quadrant" als
Variable anlegen.
Gruß
Obstmann schrieb:> d.h. bei einer neuen Adresse hängst du im ersten Taktzyklus hinterher.
Weil da gar kein Takt beteiligt ist, kann das keine Latency sein und der
Fehler muss woanders herkommen...
> Wenn Du es direkt so verwenden willst, musst Du "Sign_Quadrant" als> Variable anlegen.
Möglich, ist aber ein übler Workaround für einen ganz (all-)gemeinen
Fehler. Und da haben wir den Klassiker aller Musterbeispiele für
fehlerhafte Simulationen:
J. S. schrieb:> Die Tabellenwerte für den Sinus sehen mir ein wenig verdächtig aus - wie> sind die erzeugt worden?
Per Kopie, von einem Franzosen, dessen Name mir nicht mehr einfällt.
Allerdings bin ich dann auf die Variante mit den berechneten Sinusweten
umgestiegen... ;-)
Kennst du die Quelle? Moment, die Welt ist doch klein, ich habs, da
isses: http://www.alse-fr.com/archive/CplxFPGA_us.pdf
Lothar Miller schrieb:> Per Kopie, von einem Franzosen, dessen Name mir nicht mehr einfällt.
Lothar, man kopiert grundsätzlich nichts von Franzosen! - Wenigstens
nicht, ohne es vorher zu prüfen :-)
Was der gute Bert Cuzeau da mit seinem Dokument so vollmundig betreibt,
ist typisch französisch: "Wir haben den Längsten und wissen alles
besser".Lies Dir mal den Satz zu den Studenten auf der IP-Core Webseite
an. Da legst Du Dich nieder. Besonders belustigend finde ich den Satz:
"Sound Digital Design principles must be understood & enforced !"
Recht hat er, der Bert, nur warum macht er es dann nicht? Sein Code ist
längst nicht optimal. Zwar bezieht er die 0...63 Stützstellen des Sinus
richtigerweise auf 64 und nicht etwa auf 63, was manche nicht kapieren,
aber er rundet nicht richtig und hat damit doppltes Rauschen in seinem
tollen Audio-Sinus.
Wenn man es richtig schlau macht, dann schiebt man die Stützstellen auch
um einen halben Stützpunkt nach rechts und gelangt zu dem, was ich hier
im Forum in meinem Artikel zur DDS und Sinuerzeugung beschreibe.
http://www.mikrocontroller.net/articles/Digitale_Sinusfunktion
Das spart einen Berechnungsschritt und auch noch ein bit in der
Phasenvektorbreite und ist streng genommen mathematisch auch richtiger,
weil die Punkte nummer dann die Mitte des Phasenbereiches definiert und
nicht deren linken Rand.
Wenn man es so macht, wie Bertrand Cuzeau, bekommt man ein Problem mit
dem neuen Punkt im neuen Bogen! Der muss gesondert berechnet werden und
wer genau hinsieht, erkennt in der Grafik des TO genau diesen Effekt:
Wenn man die Phase an 128 spiegelt kommt man wieder zum Punkt 127, der
jedoch entspricht dem Wert, den eigentlich Punkt 129 haben müsste.
Man muss also den 128er künstlich erzeugen / Abfangen und den zweiten
Ast schieben. Nur die Spiegelung an der X-Achse gelingt korrekt.
Der nächste Punkt ist die Skalierung: 127 als Multiplikator ist nur dann
richtig, wenn man den 90 Grad Punkt benutzt und auch dann müssten es
"127.5-epsilon sein". Bei geringen Punktezahlen geschieht dies bei
meiner Kurve nicht und ich kann BEIDE Punkte um die 90 Grad Achse auf
das Maximum schieben, in dem ich mit mehr als 127 skaliere und so runde,
dass gerade wieder 127 entstehen. Das bringt - gerade für low cost apps
- kostenlos mehr Auflösung! Wenn Bert sich und seine Firma ALSE als die
Audio Experten ansieht, müsste er da mehr bringen :-)
Aber wie Bertrand Cuzeau selbst richtig schreibt: "Not all Books &
Training Courses are good …"
Ich habe das in der angehängten Grafik nochmal mit nur 4x8 Werten (statt
4x64 wie bei Cuzeau) deutlich gemacht. Dargestellt sind die Winkel in
Punkten und Prozent, sowie Winkelgrade und der skalierte Sinuswert,
teilweis ungerundet. Man erkennt, dass nur bei der grünen Kurve, die
Nummer des Punktes tatsächlich die Mitte der Bereiches markiert und den
zugehörigen Sinuswert repräsentiert. Man tastet einfach von 0..7 ab und
denkt sich die +0,5 in die Tabelle hinein. Der negierte
PhasenVektor/SinusWert für die anderen Quadranten werden dann einfach
per Negation gebildet. Das ist kleiner, genauer und in der maximalen
Taktfrequenz potenziell schneller.
> Allerdings bin ich dann auf die Variante mit den berechneten Sinusweten> umgestiegen... ;-)
Das hier wären meine Werte:
002 005 008 011 014 017 020 023
026 029 032 035 038 041 044 047
050 053 056 059 061 064 067 070
072 075 077 080 082 084 087 089
091 093 095 098 100 101 103 105
107 109 110 112 113 115 116 117
118 119 121 121 122 123 124 125
125 126 126 127 127 127 127 127
Wenn es als DDS benutzt wird, sollte man die jeweils abgetasteten Werte
noch mit einem IIR filtern. Dabei lässt sich die Auflösung nochmal etwas
erhöhen.
J. S. schrieb:> Lothar, man kopiert grundsätzlich nichts von Franzosen! -> Wenigstens nicht, ohne es vorher zu prüfen :-)
Richtig, diese doppelte 0 ist arg unschön... :-/
Ich werde mit deiner freundlichen Genehmigung und mit einem Verweis auf
deinen Artikel diese Tabelle übernehmen... ;-)
> in seinem tollen Audio-Sinus.
Ich bin nicht sicher, ob er wirklich einen Audio-Sinus gemeint hat, denn
"Sound Digital Design" /= "Digital Sound Design" :-)
Uwe Bonnes schrieb:> Habt Ihr auch mal an einen Cordic zur Sinusumsetzung gedacht?
Wieviele Resourcen braucht der?
Thomas schrieb:> ob er wirklich einen Audio-Sinus gemeint hat
Du hast wohl Recht! Mit "sound" war wahrscheinlich "gesund" = "gut"
gemeint, ist aber egal, denn der Sinus ist weder für Messtechnik noch
Consumeranwendungen optimal - ich verweise nach wie vor auf meine DDS
und meine Art, den Sinus in die Tabelle zu definieren.
Wie ich sehe, arbeiten eure DFFs mit vergleichweise kleinen Tabellen.
Gibt es eine Möglichkeit, im Vorhinein abzuschätzen, wie gross eine
solche Tabelle sein muss, um einen definierte SNr heraus zu bekommen,
OHNE es zu bauen und durchzumessen?
Solange die Tabelle komplett durchlaufen wird, ist das relativ einfach:
pro Bit Wortbreite und entsprechend angepasster Tabellenlänge sind es 6
dB. Wenn aber der Akku zu kurz ist und die Frequenz zu hoch, dann werden
einzelne Tabellenwerte ausgelassen und die SNR nimmt zu. Aber un jedem
Fall kann die SNR nicht nur abgeschätzt, sondern genau ausgerechnet
werden...
Man könnte es diskret machen, indem man die Werte aus den Tabellen,
genauer deren in den Datenstrom eingeprägten Fehler für die gewünschte
Situation bewertet, z.B. in Excel. Allerdings ist das von der Frequenz,
der Startphase und auch von dem Betrachtungszeitpunkt abhängig.
Denkbar wäre, es in Modelsim in INT und REAL gleichzeitig zu simulieren
und das Rauschen permanent zu bilden und formell aufzuintegrieren. Dann
bekommt man für jeden Zeitpunkt einen Wert (der sich permanent leicht
ändert). Der Mittelwert (oder der Maxert?) wäre dann der SNR-Wert.
Rudi Ratlos schrieb:> Wie ich sehe, arbeiten eure DFFs mit vergleichweise kleinen Tabellen.> Gibt es eine Möglichkeit, im Vorhinein abzuschätzen, wie gross eine> solche Tabelle sein muss, um einen definierte SNr heraus zu bekommen,> OHNE es zu bauen und durchzumessen?
Mein sin/cos core auf opencores.org
< http://opencores.org/project,sincos >
hat einen DDS als Testbett, der die erzeugten sin-Werte in files
schreibt. Man kann dann per FFT in Matlab o.ä. gleich sehen, was man
mit den gewählten Parametern bekommt.
Die Tabellentiefe / Breite wird automatisch gleich
passend zu den Dimensionen den angeschlossenen Busse gemacht.
Pipelining ist wählbar von kombinatorisch bis 10 Stufen,
gleich sinnvoll verteilt, damit der Register-Balancer nicht so
viel zu tun hat.
Ich habe ziemlich viel Aufwand in die Symmetrie der Faltung der
Tabelle und die Rundung zum nächsten LSB reingesteckt.
Reines VHDL, für's Testbett braucht man den Modelsim o.ä.
Gruß, Gerhard
Die 80% des Codes, die nicht zu Hardware compiliert werden
und nur dazu dienen, die Benutzung der eigentlichen entity
zu demonstrieren und zu prüfen, ob sie tut was von ihr
erwartet wird.
Testbett ist hier nichts anderes, als Testbench. Der Name ist auch
ziemlich Wurscht.
>Pipelining ist wählbar von kombinatorisch bis 10 Stufen,>gleich sinnvoll verteilt, damit der Register-Balancer nicht so>viel zu tun hat.
Bist Du Dir da ganz sicher, dass das was bringt?
>Lothar, man kopiert grundsätzlich nichts von Franzosen
Da stimme ich uneingeschränkt zu, beim folgenden aber nicht:
>Das spart einen Berechnungsschritt und auch noch ein bit in der>Phasenvektorbreite und ist streng genommen mathematisch auch richtiger,
Warum soll das "richtiger" sein?
Dann:
Du hast zwar Recht, mit Deiner Methode wird ein bit weniger gebraucht,
aber wen kümmert bitte ein lumpiges bit mehr bei der Vektorbeschreibung?
>weil die Punkte nummer dann die Mitte des Phasenbereiches definiert und>nicht deren linken Rand.
FPGA-Vollprofi schrieb im Beitrag #3390116:
>>Pipelining ist wählbar von kombinatorisch bis 10 Stufen,>>gleich sinnvoll verteilt, damit der Register-Balancer nicht so>>viel zu tun hat.> Bist Du Dir da ganz sicher, dass das was bringt?
Zumindest vor knapp 3 Jahren, als ich das veröffentlicht habe,
war die ISE nicht in der Lage, ein Blockram zu inferieren wenn
das nicht in einem getakteten Prozess war. Ein D-FF direkt
dahinter war nicht deutlich genug.
(Block Rams gibt's nur synchron)
Das spricht nicht dafür, dass da große Anstrengungen gemacht
werden, asynchrone Logik sauber in den Pipelinestufen zu
verteilen, so dass fmax möglichst groß wird.
Da macht man besser von Hand sinnvolle Vorgaben und hofft,
dass sie nicht verschlimmbessert werden.
Mit Mentor Precision oder sowas mag das besser gehen.
gerhard schrieb:> war die ISE nicht in der Lage, ein Blockram zu inferieren wenn> das nicht in einem getakteten Prozess war. Ein D-FF direkt> dahinter war nicht deutlich genug.
Ein BRAM wird nicht dadurch erzeugt, dass die zu lesenden Daten
zwischengespeichert werden, sondern dadurch, dass die Leseadresse
registriert wird:
http://www.lothar-miller.de/s9y/archives/20-RAM.html#extended
FPGA-Vollprofi schrieb im Beitrag #3390116:
> Testbett ist hier nichts anderes, als Testbench. Der Name ist auch> ziemlich Wurscht.
Da bin ich etwas anderer Meinung:
gerhard schrieb
> Die 80% des Codes, die nicht zu Hardware compiliert werden
Eigentlich bezeichnet man damit durchaus eine Hardware- und zwar eine
nicht ganz unbedeutended Grosse. Was hier aber besprochen wurde ist die
klassische Testbench, also die virtuelle Umgebung im Simulator.
>>Pipelining ist wählbar von kombinatorisch bis 10 Stufen,>>gleich sinnvoll verteilt, damit der Register-Balancer nicht so>>viel zu tun hat.> Bist Du Dir da ganz sicher, dass das was bringt?
Wäre mal zu untersuchen. Ich z.B. meine, ja, es bringt was - allerdings
lasse ich mich auch vom Gegenteil überzeugen, dass es mit einer Zahl
zusätzlicher Register und "register balancing" genausso rasch geht.
>>man kopiert grundsätzlich nichts von Franzosen> Da stimme ich uneingeschränkt zu,
Das war als gag gedacht und bezog sich auf das o.g. Beispiel. Ich war
ein wenig über deren Webseite erstaunt, die sich las, als seien es die
Gurus im FPGA-Design schlechthin. Fand ich etwas übertrieben, angesichts
der in diesem Beispiel präsentierten Standardlösung. Vor allem las ich
dort einen Aufruf an die Studenten, nicht einfach alles zu kopieren,
sondern selber nachzudenken. Das unterstreiche ich in diesem Fall
ausdrücklich :-)
>>Das spart einen Berechnungsschritt und auch noch ein bit in der>>Phasenvektorbreite und ist streng genommen mathematisch auch richtiger,> Warum soll das "richtiger" sein?
Weil es bei meiner Definition egal ist, mit vielen Stützstellen man
arbeitet- die resultierende Kurve ist nach einer idealen Filterung exakt
wieder dieselbe und hat keinen anderen Offset. Bei der herkömmlichen
Definition gibt es einen leicht veränderten Phasenversatz. Erst wenn die
Zahl der Stützstellen gegen unendlich geht, läuft sie auf meine Lösung
zu.
> Du hast zwar Recht, mit Deiner Methode wird ein bit weniger gebraucht,> aber wen kümmert bitte ein lumpiges bit mehr bei der Vektorbeschreibung?
Hatte ich glaube ich schon mal geschrieben. Es gibt langsame
Technologien, mit denen man beim speed etwas genauer hinsehen muss. Mit
meiner Definition ist esmöglich, die Negation der Viertelkurven allein
mit Invertern zu generieren. Ansonsten muss ein Sub her.
gerhard schrieb:> Das spricht nicht dafür, dass da große Anstrengungen gemacht> werden, asynchrone Logik sauber in den Pipelinestufen zu> verteilen, so dass fmax möglichst groß wird.
Die BRAMs bestehen nicht aus verschiebbaren Zellen. Auch die internen
FFs vor und nach den RAMs sind ortsfest. Nur die zusätzlichen Register
FFswerden u.u. als fabric erzeugt und wären damit rein funktionelle FFs,
die irgendwo sitzen können.