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
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
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
> (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
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
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
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
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.
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.
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
@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
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).
> 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 ...
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.
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
@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
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.
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.
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/
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.
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.
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.
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 ...
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.