Forum: FPGA, VHDL & Co. Rest Bestimmen in Float


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 Jens W. (jensw)


Lesenswert?

Hallo zusammen,

ich beschäftige mich gerade wieder mit meinem LCR-Meter.
Da hatte ich auch schon in der Vergangenheit was drüber geschrieben:
Beitrag "LCR-Meter mit Audio ADC/DAC"

Jetzt bräuchte ich mal wieder einen Gedankenanstoß.
Um was geht es:
Ich möchte bei dem LCR-Meter einen Audio-ADC verwenden. Bei dem ist die 
Wandlungsrate konstant.
Wenn ich nun über einige 10kPts messe und dann die Berechnungen 
durchführe, dann kann es passieren, dass ich nicht über eine Periode des 
Messignals messe, sondern über mehrere, oder eben nicht mal eine 
Periode.
Und da fängt das Problem an.
Wenn man sich bei den Berechnungen den Term (2*Pi*i/N) anschaut, dann 
muss man hier berücksichtigen, dass es über mehrere Perioden geht.
Ich hab das in Excel mal getestet und runde auf (2*Pi). Somit kann der 
Wert in der Klammer nie größer werden als (2*Pi). Das funktioniert auch.

Würde ich in Integer rechnen dann macht mir das eine Modulo-Division.
Aber wie kann ich das in float machen?
Modulo gibt es bei float nicht. Und über eine Schleife so oft (2*Pi) 
abziehen bis der Wert kleiner als (2*Pi) ist, das finde ich nicht so 
schön. Vor allem wenn die Messung mal über 10000 Perioden sein kann.

Wie könnte man das elegant rechnen?

Viele Grüße, Jens

von Markus F. (mfro)


Lesenswert?

Jens W. schrieb:
> Modulo gibt es bei float nicht.

man fmod

von Jens W. (jensw)


Lesenswert?

Hallo Markus,

ich verwende für die float division einen IP Core von Xilinx. Der gibt 
das nicht her.

Oder was hast du genau gemeint?

Grüße, Jens

von Gunther (Gast)


Lesenswert?

Falls ich die Anforderung richtig verstanden habe, dann sollte das nicht
so schwierig sein. Du solltest Dir mal das Float-Format angucken und
auf der Webseite
https://www.h-schmidt.net/FloatConverter/IEEE754.html
mal ausprobieren.
Der Exponent zeigt die Anzahl der Vorkommabits an. Der Rest sind die 
Nachkommastellen. Du musst nur einmal schieben.

Gruß
Gunther

von foobar (Gast)


Lesenswert?

> (2*Pi*i/N)
>
> Würde ich in Integer rechnen dann macht mir das eine Modulo-Division.
> Aber wie kann ich das in float machen?

Den Modulo auf i anwenden: 2*Pi*mod(i,N)/N

von Jens W. (jensw)


Lesenswert?

Hallo Günter,

bist du dir da sicher? Der Wert erscheint ja nach der Division in einem 
32bit vector. Man kann doch float Werte nicht einfach schieben. Bei 
Fixed Point gebe ich dir Recht aber bei float? Das ist mir neu.
Aber ich schaue mir das mal an. Danke dir!

@foobar:
Das schau ich mir auch mal an. Aber ich denke das ist nicht das was ich 
brauche.
Ich muss eigentlich rechnen: mod(2*Pi*i/N, 2*Pi)
Damit bekomme ich den Sägezahn über mehrere Perioden. Und ich brauche 
das für float Zahlen, da 2*Pi eben nicht so ohne weiter Umwege als 
Integer darstellbar ist.
Bei dem was du oben geschrieben hast ist der Teiler anders.

Danke euch für die Gedankenanstöße!

Grüße, Jens

von Samuel C. (neoexacun)


Lesenswert?

Jens W. schrieb:
> Man kann doch float Werte nicht einfach schieben.
Nicht den ganzen Float, aber die Mantisse schon. Schau dir an, wie ein 
Float funktioniert.

> @foobar:
> Das schau ich mir auch mal an. Aber ich denke das ist nicht das was ich
> brauche.
> Ich muss eigentlich rechnen: mod(2*Pi*i/N, 2*Pi)
https://www.wolframalpha.com/input?i=2*Pi*mod%28x%2CN%29%2FN+%3D%3D+mod%282*Pi*x%2FN%2C+2*Pi%29

von Achim M. (minifloat)


Lesenswert?

Jens W. schrieb:
> dann kann es passieren, dass ich nicht über eine Periode des Messignals
> messe, sondern über mehrere, oder eben nicht mal eine Periode.

Wer erzeugt denn den Stimulus des LCR-Meters?

1 Wenn der von demselben Rechner erzeugt wird, der auch die Samples 
puffert und für spätere Rechnung aufhebt, "weiß" der doch wo eine 
Periode anfängt und aufhört. Den so bestimmten Bereich des Messpuffers 
dann als zyklischen Puffer behandeln.
Geht es um geringere Frequenzen, sodass eine Periode nicht in den Puffer 
passen würde, wird eben nur jedes zweite oder dritte usw. Sample im 
Puffer abgelegt.

2 Für den umständlichen Fall, dass eine Analogschaltung den Stimulus 
erzeugt, stellst du dem Rechenknecht eben zwei Wandler zur Verfügung: 
einer um den Stimulus zu vermessen und einen um die Messgröße zu 
erfassen. Man kann sich da auf den Stimulus aufsynchronisieren oder die 
Periodizität on-the-fly oder mit Puffern und Nachanalyse aus dem Puffer 
errechnen.
Oder eben beides Puffern und im Fall dass der Stimulus nicht mehr in den 
Puffer passte, Samplerate verringern und nochmal sampeln.

mfg mf

: Bearbeitet durch User
von Achim S. (Gast)


Lesenswert?

Jens W. schrieb:
> ich verwende für die float division einen IP Core von Xilinx.

Du berechnest das also auf einem FPGA? Und dort willst du die Sinus- und 
Cosinusterme selbst ausrechnen?

Würde ich an deiner Stelle nicht machen. Setze auf dem FPGA einen 
DDS-Core ein, der dir die Sinus-Werte für den DAC erzeugt. Lass dir 
parallel dazu auch einen Cos-Wert erzeugen. Und jedesmal, wenn der ADC 
einen neuen Wert der Messspannung abtastet, multiplizierst du ihn mit 
dem Sin- bzw. Cos-Wert, den dein DDS-Kern grade ausgibt.

Damit kannst du dir die eigene Berechnung von Sinus und Cosinus sparen 
(macht der DDS-Kern über eine Look-Up Table). Und du kannst dir den 
Überlauf bei 2 pi sparen, weil der Phasenakkumulator des DDS-Kerns "ganz 
von selbst" den Überlauf macht. Er bildet den Phasenbereich von 0 bis 2 
pi auf eine n-Bit Zahl ab. Sobald der momentane Phasenwert größer als 2 
pi wäre (größer als (2^n)-1), springt die Phase um 2 pi (um 2^n) nach 
unten - einfach indem die Überlaufbits ignoriert werden.

An Berechnungen für deine Auswertung im FPGA bleibt nur noch wenig 
Aufwand übrig, weil Sinus- und Cosinus zum aktuellen Phasenwinkel schon 
bekannt sind. Das FPGA muss nur noch
- den aktuellen ADC-Wert mit den bekannten Sin- und Cos-Werten 
multiplizeren
- die einzelnen Produkt aufzusummieren bzw. über einen digitalen 
Tiefpassfilter zu schicken.

Beides machen die dsp-Kerne im FPGA problemlos in Ganzzahlenarithmetik. 
Die typisch 18 Bit Auflösung eines einzelnen dsp-Kerns reichen zwar 
nicht für Multiplikation und Filterung. Aber ein paar dsp-Kerne 
nebeneinander kommen z.B. leicht auf 48 oder 72 Bit, mit denen dein 
Filterergebnis auch bei langen Summationszeiten nicht überläuft.

von foobar (Gast)


Lesenswert?

Ich schrieb:
> Den Modulo auf i anwenden: 2*Pi*mod(i,N)/N

Jens meint:
> Das schau ich mir auch mal an. Aber ich denke das ist nicht das was ich
> brauche.

Es tut das, was du brauchst.

> Ich muss eigentlich rechnen: mod(2*Pi*i/N, 2*Pi)

mod(2*Pi*i/N,2*Pi) = 2*Pi*mod(i/N,1) = 2*Pi*mod(i,N)/N

also genau das, was ich oben schrieb. Und wenn i und N Integer sind, ist 
mod(i,N) ein Integer-Modulo.

von Jens W. (jensw)


Lesenswert?

Hallo zusammen,

@Samuel:
vielen Dank für den Link. Somit könnte das von foobar funktionieren.
Das ist also eine echte Alternative.
Vielen Dank!

@Achim M:
Der Stimulus wird vom gleichen FPGA erzeugt. Das mache ich mit einem DDS 
Core.
Und du hast Recht, für den Stimulus habe ich den Term (sogar gleich mit 
Sinus-Berechnung) schon zur Verfügung. Das werde ich wohl nehmen. Dann 
hebt sich sogar die Sinus- und Cosinus-Berechnung auf. Das spart unter 
dem Strich einen riesigen Aufwand!
Die Werte, die ich hier brauche liegen schon vorberechnet in der Look-Up 
Table. Da muss ich nur die Architektur ein bisschen abändern.

Vielen Dank an alle!

Grüße, Jens

von Jens W. (jensw)


Lesenswert?

@Achim S:
Den DDS Core habe ich schon drin.
Die Werte für die Berechnung nochmal her zu nehmen, das war der Hinweis.
Die Architektur dahingehend zu änder ist nur ein minimaler Aufwand.
So werde ich es machen! Da komme ich vielleicht um die gesamte float 
Geschichte rum.

Grüße, Jens

von Achim S. (Gast)


Lesenswert?

Jens W. schrieb:
> Da komme ich vielleicht um die gesamte float

Das würde ich dir dringend empfehlen. Bringt dir nichts, und die 
Festkommaumsetzung im FPGA ist wesentlich einfacher (braucht ggf. nur 
ein bisschen "Reserve" bei der Bitbreite, falls du die Aufsummierzeit 
einstellbar machen willst).

von foobar (Gast)


Lesenswert?

> die Festkommaumsetzung im FPGA ist wesentlich einfacher

FPGA (insb eins, das für FP dick genug ist) klingt mir hier eh nach 
Perlen vor die Säue ...

von Mastermind (Gast)


Lesenswert?

Jens W. schrieb:
> Ich hab das in Excel mal getestet und runde auf (2*Pi).
Ganz nebenbei: Damit muss man aufpassen. Excel rundet auch nur in etwa, 
was dazu führt, dass es bei Vielfachen von PI zunehmend ungenau wird.

von Achim M. (minifloat)


Lesenswert?

Jens W. schrieb:
> Das werde ich wohl nehmen. Dann hebt sich sogar die Sinus- und
> Cosinus-Berechnung auf.

Ich könnte mir an der Stelle sequentiell erst Sin und dann Cos zu 
rechnen vorstellen. Sind dieselben Rechenschritte, nur eben einmal mit 
Sin(x) und einmal mit Sin(x+(π/2))...

Wäre sonst Mutmaßung, dass es sich um eine reine Kapazität oder 
Induktivität oder reinen Widerstand dreht.

Will sagen du brauchst zwingend Information über die Phasenlage, wenn du 
z.B. "R und C in Serie" errechnen willst.

mfg mf

von Jens W. (jensw)


Lesenswert?

@Mastermind:
Danke für den Hinweis. Bei den Rechnungen, die ich bisher in Excel 
gemacht hatte, ist mir da nichts aufgefallen. Bei mir wird so gerundet 
wie es sein soll und ich erhalte einen schönen Sägezahn.

@Achim M:
Ich verwende für die Signalerzeugung einen DDS Core. Der ist nun 
erweitert und gibt mir Sinuns und Cosinus aus (einfach eine zweite 
Tabelle dazu). Den Sinus verwende ich tatsächlich für das Signal und den 
Cosinus nur für die Berechnungen.
Jetzt muss ich den Sinus und Cosinus gar nicht mehr berechnen! Da fällt 
so viel an Rechnerei weg, dass das FPGA vermutlich Langeweile hat.

Die Phasenlage kommt automatisch zustande. Ich sample die Kanäle für 
Spannung und Strom simultan. Ich verwende ja Audio ADCs und DACs. Die 
kommen ja praktischerweise mit zwei Kanälen. Die sampeln synchron, das 
hab ich schon sicher gestellt.

In meiner Excel Tapete habe ich das alles mal ausprobiert und da schaut 
es tatsächlich vielversprechend aus.
Das einzige was man machen muss ist, den Gain der ADCs bestimmen und in 
die Rechnung einfließen lassen. Dazu verwende ich einen 
Präzisions-Spitzengleichrichter für die Signale (der macht DC draus) und 
einen extra ADC mit genauer Referenz.
Im FPGA speicher ich mir den maximal gesampelten ADC Wert ab und aus den 
beiden Werten kann ich das Gain bestimmen. Dann geht der Audio ADC auch 
genau.

Was ein Problem werden kann ist, wenn die beiden analogen Kanäle für 
Spannung und Strom eine Phasendifferenz aufweisen würden. Das ist dann 
nicht mehr so leicht herauszurechnen, da ich den Sinus und Cosinus ohne 
Phasenversatz aus der Tabelle entnehme. Da müsste ich dann vermutlich 
nochmal an den DDS Core ran.

Grüße, Jens

von Achim S. (Gast)


Lesenswert?

Jens W. schrieb:
> Was ein Problem werden kann ist, wenn die beiden analogen Kanäle für
> Spannung und Strom eine Phasendifferenz aufweisen würden. Das ist dann
> nicht mehr so leicht herauszurechnen, da ich den Sinus und Cosinus ohne
> Phasenversatz aus der Tabelle entnehme. Da müsste ich dann vermutlich
> nochmal an den DDS Core ran.

Wenn Strom- und Spannungspfad unterschiedliche Phasenverschiebungen 
haben (z.B. weil du die beiden Signale unterschiedlich stark verstärken 
musst), kannst du trotzdem beide mit den identischen SIN und COS 
Momentanwerten in Real- und Imaginärteile zerlegen. Du brauchst als 
keine geänderten Werte aus dem DDS-Kern.

Am Ende hat dann dein berechnetes komplexes Z einen Phasenfehler 
delta_phi. Aber den kannst du einfach rauskorrigieren, indem du dein 
Endergebnis mit e^(-j*delta_phi) multiplizierst.

von Audiomann (Gast)


Lesenswert?

Achim S. schrieb:
> mit e^(-j*delta_phi)
... was im FGPA spannend wird :-)

von Achim S. (Gast)


Lesenswert?

Audiomann schrieb:
> was im FGPA spannend wird :-)

spätestens wenn es um die Ausgabe des Ergebnisses in verschiedenen 
Ersatzschalterbildern geht, kommt man um ein wenig komplexe Rechnung 
nicht herum. ebenso beim einrechnen der Korrekturen, die sich aus 
Kalibriermessungen ergeben.

aber oft findet sich in der Nähe des FPGAs noch irgendein 
Controller/CPU, mit dem sich dieser Teil der Signalverarbeitung 
einfacher umsetzen lässt. und diese Rechnungen fallen nur einmal pro 
gemessenem Z an (also vielleicht einmal pro 100ms an) nicht bei jeder 
einzelnen Abtastung des ADCs.

von Hawthorne Abendsen (Gast)


Lesenswert?

wenn man nicht alles selbst machen will (was an sich keine schlechte 
Idee ist, außer es fehlt einem an intellektuellem Inventar) dann bedient 
man sich bei Standards. Bei float wäre das der IEEE-754 und der hat auch 
eine Operation namnes "Floating point remainder" die weitgehend, bis auf 
Vorzeichen, dem modulo entspricht.

https://www.xilinx.com/products/intellectual-property/floating_pt.html#documentation

https://core.ac.uk/download/pdf/148661177.pdf
https://www.eetimes.com/the-basics-of-fpga-mathematics/

von FPGA-Experte (Gast)


Lesenswert?

Die Benutzung von floating point ist etwas für Mädchen. Wir richtigen 
Männer setzen alles auf fixed point um. Da entfallen dann ein ganzer 
Haufen an umständlichen Konversionen. Ich meine, es ist doch ein 
Einfaches, seine gesamte float Rechnung einmal um einen Faktor X 
hochzuskalieren, der eine ausreichende Auflösung garantiert.

von Jens W. (jensw)


Lesenswert?

Na dass ist doch mal ne Aussage! Endlich richtige Männer am Start!

Aber die Aussage ist sehr pauschal.
Mir scheint du hast den Vorteil von float nicht so richtig verstanden.

Das ist so pauschal wie:
"Ich programmiere nur in Assembler, dann hab ich alles selbst im Griff."
Kann man machen, aber man erreicht damit sein Ziel nicht unbedingt 
effizient.

von FPGA-Experte (Gast)


Lesenswert?

Der Vergleich hinkt aber gewaltig. C hat gegenüber Assembler mehrere 
Vorteile:

- mehr vordefinierte Strukturen und damit Kompatibilität zu anderen 
Entwicklern
- das Programmieren der Funktion ist meistens schneller, von low level 
Zugriffen mal abgesehen
- viele Funktionen sind einfach nötig und müssten in ASM erst 
geschrieben werden, das aber jeden 2. Tag
- das C ist leicht übertragbar

Real bringt aber keine neuen Strukturen sondern nur einen einzigen neuen 
Datentyp mit Handhabungsfunktionen drum herum. Aufgrund der nun 
versteckten Rundungen ist es undurchsichtiger und es wird nahezu 
unmöglich, aufs Bit genau zuarbeiten. Man braucht immer einen overhead 
und zwar einen, der nicht immer genau zu determinieren ist und wenn, 
dann nicht eben einfach.

Das ist dasselbe wie in C: Real schafft erst mal mehr Ungenauigkeit, die 
nur bei überhöhter Auflösung und Resourcennutzung kompensiert wird. Wir 
haben nicht umsonst in vielen DSP-Applikationen in Ganzzahl gerechnet 
weil am Ende 24/48Bit Genauigkeit in den Akkus besser war, als 32er 
float.

Das hat sich erst mit 64er float geändert. Zugegeben ist seither das 
Programmieren einfacher, weil man keine Rücksicht nehmen muss, sondern 
mit irrsinniger Auflösung rechnet, die Affen nutzen könnten. (Es gibt 
Versuche am MIT, Affen das Programmieren beizubringen).

Es bleibt aber das Resourcenproblem: In einer Intel-CPU rechnet die neue 
64er-Einheit nicht langsamer, als die alte 32er. Es braucht aber mehr 
Daten, die ins RAM müssen. Durchschnittlich würden Auflösungen von 20/40 
bis 25/50 Bit benötigt, um Echtzeitdaten in kritischen Anwendungen zu 
berechnen. Float braucht im Schnitt 4-6 Bit mehr. Passt also in der 
Intel-CPU ohne Mehraufwand. Für den Datenverkehr in die DDR-RAMs sind es 
aber schon im Schnitt 30%-50% mehr, wegen nutzlosem Overhead.

Bei FPGAs kommt hinzu, dass sie keine float-CPU haben sondern alles per 
Ersatz in Ganzzahl-DSPs machen müssen. D.j. die Library muss wie früher 
bei den alten SX-Prozessoren, alles in Software übersetzen, damit das 
float in Ganzzahl gerechnet werden kann, was ansonsten der DX gemacht 
hat.

Solange FPGAs keine FPU-Einheiten besitzen, die genau so schnell 
rechnen, wie die INT-Einheiten, erzeugt das einen riesigen oberhead und 
Code und Aufrufen. Das macht es funktioniell langsamer, weil mehr zu 
rechnen ist, als direkt über INT. Hinzu kommt dass der oberhead beim 
float alle Vektoren breiter macht und Additionen, Multiplikationen und 
Vergleiche breiter werden lässt.

Das führt sofort zu verschlechterem timing.

Kannst ja mal einen float MUL 32x32 bauen und einen INT 32x32. Praktisch 
ist der real rund 30% größer und entsprechend langsamer zu takten. 
Obendrein ist die Rechnung, wenn man sie richtig formuliert auch mit 
einem 25x25 zu machen, was die INT-Variante shrinkt und noch schneller 
werden lässt.

von Xilinx-Nutzer (Gast)


Lesenswert?

Jens W. schrieb:
> Jetzt muss ich den Sinus und Cosinus gar nicht mehr berechnen! Da fällt
> so viel an Rechnerei weg, dass das FPGA vermutlich Langeweile hat.
Dir ist schon klar, dass der FPGA auch nichts rechnet, sondern

- die Werte bei DDS aus einer Tabelle nimmt?
- dass das für SIN und COS dieselbe ist, die nur an zwei Punkten gelesen 
wird?
- es genau genommen nur ein Halbbogen ist?
- es nur bis 16 bit Phasenauflösung geht?

Hawthorne Abendsen schrieb:
> dann bedient man sich bei Standards.

Was mich an den IPs stört, ist der Sachverhalt, dass diese immer mehr 
auf den Hersteller zugeschnitten sind. Bei Xilinx sind sie 
ausschließlich in AXI und der Nutzung als Prozessorbus ausgelegt. Den 
oftmals besseren wishbone findet man gar nicht. Wäre ja auch z einfach.

Das scheint mir auch bei diesen IPs für Real-Verarbeitung der Fall zu 
sein. Alles für den Anschluss an AXI ausgelegt.

Weil es aber bei AXI unterschiedliche Methoden der Nutzung und 
Möglichkeiten des Zugriffs gibt, entstehen unterschiedliche Kombination 
von Zeitverhalten, die gemanaged werden müssen und zwar sowohl vom Core, 
als auch vom Nutzer; z.B. FIFOs. Da diese IPs auch immer eine Latte an 
Funktionen abdecken müssen, sind auch "innendrin" noch Funktionen 
vorzusehen, um diese Optionen abzudecken. Wenn man sich allein das 
Abfangen möglicher Fehler bei Wurzel- und Divisionsfunktionen ansieht, 
dann ist das generell überall drin, auch wenn es real bei der konkreten 
Funktion, die man selber hat, nicht auftaucht und in nativem VHDL auch 
nicht implementiert worden wäre.
Deshalb ist dort immer eine Reihe von Zusatzlogik implementiert, die 
sich nicht beliebig verschlanken lässt. So ziehst du dir kontinuierlich 
mehr Funktionalität in die Schaltung, als eigentlich benötigt wird.
Diese liegt dann zwar brach und kommt nicht zum Einsatz, frisst aber 
resourcen weg.

Und: All das Gedöhns drum herum, inklusive Bussmanagement, Abschätzung 
möglicher Fälle, das Constraining der Cores und deren Parametrierung 
erfordert auch Aufwand und nicht selten sogar Einarbeitung. In einigen 
Fällen muss man regelrecht nachdenken, was der Core-Entwickler sich 
gedacht haben könnte und wie man das am Besten nutzt. Auch ein 
Lernbedarf besteht darin, nicht benötigte Funktionen abzuschalten und 
Eingänge zu nullen.

Bei der Synthese poppen dann massenweise Meldungen über nicht belegte 
Funktionen, Ein- und Ausgänge auf, die man auch erst einmal sortieren 
muss, um zu sehen, ob das so ok ist oder nicht.

Das Arbeiten mit IPs ist deshalb nicht pauschal eine Vereinfachung.

Was jetzt die Real-IP anbelangt: Ich finde in den Dokumenten keine 
verwertbaren Angaben über Zeitverhalten und Resourcenbedarf. Macht mich 
nachdenklich ...

von jensw (Gast)


Lesenswert?

Hallo,

Xilinx-Nutzer schrieb:
> Jens W. schrieb:
>> Jetzt muss ich den Sinus und Cosinus gar nicht mehr berechnen! Da fällt
>> so viel an Rechnerei weg, dass das FPGA vermutlich Langeweile hat.
> Dir ist schon klar, dass der FPGA auch nichts rechnet, sondern
>
> - die Werte bei DDS aus einer Tabelle nimmt?
> - dass das für SIN und COS dieselbe ist, die nur an zwei Punkten gelesen
> wird?
> - es genau genommen nur ein Halbbogen ist?
> - es nur bis 16 bit Phasenauflösung geht?

Das stimmt nicht so ganz wie du das schreibt.
Die DDS habe ich "zu Fuß" implementiert. Da verwende ich keinen fertigen 
IP-Core.
Die Werte kommen aus der Tabelle, das ist richtig. Da wird nichts mehr 
gerechnet. So wie ich schrieb, die Rechnerei fällt weg.
Aber ich habe nicht nur einen Viertelbogen abgelegt. Ich verwende den 
vollen Sinus mit einer Auflösung von 24bit und eine extra Tabelle für 
Cosinus.
Ich habe das so gelöst, da ich keinen zusätzlichen Aufwand 
(Adressberechnung) für die Werte haben wollte. Ich greife in die 
Tabellen zu und das ist es.
Das ist sicher nicht die sparsamste Lösung, aber ich hab die Ressourcen 
ja frei. Es macht keinen Sinn zu knausern. Wenn ich was frei habe gibt 
es kein Geld zurück. Als nutze ich alles, was ich zur Verfügung habe.

Was ich noch mache ist, dass ich zwischen den Werten linear 
interpoliere, da ich natürlich nicht für 24bit Auflösung und  18bit 
Länge und Sinus und Cosinus alle Werte ablegen kann. Das wäre zu viel.

Ich teste gerade. Die Werte aus der DDS führe ich für die Berechnungen 
für das LCR-Meter zurück. Es schaut gut aus, aber ich bin noch nicht 
fertig.

Grüße, Jens

von Duke Scarring (Gast)


Lesenswert?

Xilinx-Nutzer schrieb:
> Was mich an den IPs stört, ist der Sachverhalt, dass diese immer mehr
> auf den Hersteller zugeschnitten sind. Bei Xilinx sind sie
> ausschließlich in AXI und der Nutzung als Prozessorbus ausgelegt. Den
> oftmals besseren wishbone findet man gar nicht. Wäre ja auch z einfach.
Mit Vivado darfst Du auch Deine eigene IP in ein Repo packen und als 
Blöcke in einem Blockdesign einsetzen. Das AMD/Xilinx kein echtes 
Interesse an Wishbone hat, sollte klar sein: AXI passt im Zynq viel 
besser an das Processing System. (Und größere FPGAs kann man mit AXI 
vielleicht auch verkaufen...)

Duke

von -gb- (Gast)


Lesenswert?

jensw schrieb:
> Das ist sicher nicht die sparsamste Lösung, aber ich hab die Ressourcen
> ja frei.

Welche Tabellenlänge bekommst du denn auf die Art noch rein?

von Jens W. (jensw)


Lesenswert?

Hallo,

ich habe zwei Tabellen drin mit jeweils 12 Bit Adresse.
Da sind noch reichlich Ressourcen übrig.

Grüße, Jens

von Kay-Uwe R. (dfias)


Lesenswert?

Würde man für die interne Darstellung nicht sowieso auf π normieren, 
Vollkreis also auf 1 oder 4 setzen? Ansonsten ist doch das erste, was 
die Algorithmen machen, durch 2π oder π/2 zu teilen.

von Jens W. (jensw)


Lesenswert?

Hallo,

das brauchst du nicht machen.
Das fliegt automatisch komplett raus. Der Term, wo Pi drin steckt, den 
verwende ich für die DDS. Also beim Tabelle anlegen. Das bleibt 
konstant.
Und für die Berechnungen später verwendet man genau diesen Wert. Anstatt 
zu rechnen hat man folglich nur noch einen Tabellenzugriff.
Das spart im FPGA dann die meißten Ressourcen, da hier nichts mehr 
gerechnet wird.

Grüße, Jens

von Rbx (rcx)


Lesenswert?

Jens W. schrieb:
> Da komme ich vielleicht um die gesamte float
> Geschichte rum.

Da kommt auch eine ganze Menge Holz zusammen, wenn man mal schaut, wie 
es tatsächlich unterm Teppich aussieht. Nur ergänzend wieder mal (z.B.):

https://stackoverflow.com/questions/14763722/python-modulo-on-floats
(dort verlinkt:)
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
https://www.eetimes.com/tutorial-floating-point-arithmetic-on-fpgas/

Und dann noch das ganze Fehlerpotential, was dieses Format mitbringt.
(https://www2.math.uni-wuppertal.de/wrswt/xsc/pxsc.html)
(https://www2.math.uni-wuppertal.de/wrswt/xsc/cxsc/apidoc/html/index.html)
(man muss auf jeden Fall schauen, dass man z.B. bei den 
Rundungsvorlieben einigermaßen im Rahmen der eigenen zulässigen 
Parameter bleibt UND Sonderfälle notieren).

von J. S. (engineer) Benutzerseite


Lesenswert?

Die Rundungsthematik und die dadurch bedingten Probleme beim 
Interpretieren von gleich und ungleich hat man beim INT-Format natürlich 
auch, weil ja auch da eine endliche Auflösung existiert, aber es ist 
halt einfacher handhabbar. Vor allem ist es besser steuerbar, wenn man 
an den richtigen Stellen die Auflösung entsprechend gestaltet.

Float sollte man eigentlich nur an den Übergabepunkten zu 
Prozessorsystemen verwenden, so sie das Format benutzen.

Das Problem das ich sehe: Prozessoren kommen mit 32 oder 64 Bit daher 
und so sind dann auch die Gleichungen dimensioniert. 32 Bit sind aber 
oft ein wenig knapp, also wird schon in der CPU-Landschaft aufgebohrt 
und eine Scheingenauigkeit in den FPGA geschleppt.

Umgekehrt muss man mit dem FPGA in beiden Fällen keine 64 Bit 
realisieren. Oftmals reichen 40...48Bit und damit eine an jeder Stelle 
optimierte Auflösung, was sehr viele Resourcen sparen kann.

Man muss sich eben die Mühe machen und "unterwegs" beim Rechnen 
mitdenken und nicht einfach bedenkenlos MATLAB und anderes den Code 
erzeugen lassen, um dann hinterher zu stutzen. Man denke sich mal eine 
64 Bit MUL in einem FPGA, was das für einen Baum an MULs zur Folge hat, 
die am Ende nur winzige Reste etwas genauer hinbringen, als eine 
vorverkürzte 36x36, die oftmals denselben Nutzen hat.

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.