Guten Morgen liebes Forum, da ich eine Division auf einem FPGA durchführen möchte und den Quotienten anschließend stark verstärken muss komme ich an die Grenzen der Quantisierung. Als Eingänge für die Division sind mir derzeit 2 Binärvektoren (A und B) mit dem Format signed(14 downto 0) gegeben. Meine Idee war es nun, die von Altera Quartus bereitgestellte IP-Core zur FloatingPoint Division zu nutzen. Anschließend kann ich das Ergebnis der Division (C) wieder normalisieren und entsprechend verstärken ohne auf die Genauigkeit der Division verzichten zu müssen.. bzw. erhoffe ich mir so ein wesentlich besseres Ergebnis, da FP.. Ist der Gedankengang soweit korrekt und nachvollziehbar? Nun stellt sich mir folgende Frage: Wie bekomme ich meie derzeitigen Vektoren A und B in eine normalisierte FP-Darstellung mit 32 Bit (Single-precision)? Und wie gehe ich mit dem Ergebnis C richtig um? Dieses soll ja schließlich wieder auf die vollen 15 Bit skalliert werden. Sehe ich das richtig, dass ich den Exponenten der FP-Darstellung entsprechend anpasse (auf e=-14 -> "01110001") und anschließend meine die Mantisse m (in der Länge angepasst) durch meine Vektoren A und B ersetze? Bei einem vollskallierten signed(14 downto 0) also m -> "0...0111111111111111"? Wie skalliere ich dann den Ausgangsvektor C? Besten Gruß und einen guten Start ins Wochenende!
Warum verstärkst du nicht erst, und dividierst dann? So brauchst du zwar viele Bits, aber kein Floating Point.
Gute Frage! Geht nat. auch. bis 64 Bit kann der Quartus LPM_Divider und sp viele werd ich sicher nicht brauchen. Danke für den Tipp!! Mein Problem wäre so dann doch recht elegant gelöst und sogar noch mit weniger Ressorucen, da kleinere Wortbreiten. Wirklich vielen Dank! In der Annahme ich verstärke um 1024 ergäbe mein ausgangsvektor für den Quotienten 26 Bit. Meine Information steckt nun wieder in den MSB's, korrekt?
Ich schiebe (nicht FPGA, bin nur durch Zufall hier gelandet) vor einer Division immer weitestmöglich nach links, wenn ich maximale Genauigkeit brauche.
Das würde die Verstärkung im Vorfeld auch machen, nur dynamisch (anhand des extern eingestellten Wertes) und mit mehr Hardware. Beschränkt eben durch die Größe des Binärvektors der Verstärkung. Diesen Weg müssen wir gehen, da die Verstärkunung von äußeren Randbedningungen abhängt. Wäre die Verstärkung bekannt ist das nach links schieben oder anhängen von Bits, rechtsseitig des Binärvektors, die sinvollere Lösung. Da stimme ich zu.
Was heisst denn hier bitte "Verstärken"? Wir reden jetzt nicht von einem simplen Skalieren des Wertes, oder? Das sollte auf der Hand liegen. Außerdem gibt der Core genau für diese Zwecke einen remainder ab, der wieder weiterprozessiert werden darf und das sogar beliebig. Somit entfallen alle Bitgrenzen, welche die Division scheinbar aufwirft. Vom Aufwand ist es letzlich egal, mit der konventionellen, unverstärkten Methode, hast Du nur schon vorab ein Zwischenergebnis, das sich weiterberarbeiten ließe. Stephan K. schrieb: > Meine Idee war es nun, die von Altera Quartus bereitgestellte IP-Core > zur FloatingPoint Division zu nutzen. Anschließend kann ich das Ergebnis > der Division (C) wieder normalisieren und entsprechend verstärken ohne > auf die Genauigkeit der Division verzichten zu müssen. Ich möchte Dir keinesfalls zu nahe treten, lieber Stephan, aber Ich frage mich schon ein wenig, was ihr Jungens heute so in der Schule lernt. Wir hatten noch das schriftliche Dividieren, das man ganz ohne Core oder Libraries direkt auswendig aus dem Kopf auf alles anwenden konnte, was der Lehrer an die Tafel gekritzelt hat. Sieh Dir mal die Seite vom Kollegen Brünner an: http://www.arndt-bruenner.de/mathe/scripts/polynomdivision.htm Wenn Du jetzt hergehst und die darin inbegriffene Rückmultiplikation weglässt, wie es bei Dualzahlen ja einfach möglich ist, dann hast Du direkt was noch Einfacheres, nämlich die Binärdivision. Das ist Mathe aus der Mittelstufe und erfordert kein Studium an einer Erlanger Hochschule, wobei Ich das Level in Erlangen nicht so kenne :-) In Kenntnis dieser Zusammenhänge, sollte man direkt verstehen, daß man den Eingang einfach beliebig schieben- und/oder den Rest beliebig weiterverarbeiten kann und dass das keinen Unterschied macht sondern genau Dasselbe ist. Auf die Idee, eine binäre Rechnung in FP zu verwandeln, um dann "besser" rechnen zu können, kommen nur die, die Softcores in FPGAs stecken, damit die dann besser rechnen. Hier kommt mein Vorschlag: Packt doch einfach einen kompletten Intel-7-Multi-Kern auf eine Multi-Chip-FPGA-Plattform wie sie fürs ASIC-Prototyping verwendet wird, dann installiert Windows drauf und ladet MATLAB obenauf. Dann rechnet das MATLAB alles durch, was es so gibt. Auch das kleine Einmaleins. Fertisch. Die anderen, die keine Resourcen verschwenden möchten, empfehle Ich ein Grundlagenstudium hier: https://www.thm.de/site Dort bekommt man praktiche Lösungen beigebracht. :-)
Stephan K. schrieb: > In der Annahme ich verstärke um 1024 > ergäbe mein ausgangsvektor für den Quotienten 26 Bit. Meine Information > steckt nun wieder in den MSB's, korrekt? Logisch, weil deine "Verstärkung" ja nur eine Verbreiterung des Vektors um 10 LSB ist. Da wird dann auch in der realen Hardware gar nichts multipliziert, sondern einfach 10 Bits dazuverdrahtet... > erhoffe ich mir so ein wesentlich besseres Ergebnis, da FP.. Nur geht die Rechnung "mehr Aufwand = besseres Ergebnis" hier nicht auf, weil Float trotz der 32 Bit Breite leider nur 6 signifikante Stellen hat. Es kann dir also passieren, dass du rechnest 1234567.8 + 1.0 und hinterher kommt wieder 1234567.8 heraus... :-o
:
Bearbeitet durch Moderator
Weltbester FPGA-Pongo schrieb im Beitrag #5196400: > simplen Skalieren des Wertes, oder? Nur werden Vektorbreiten fest synthetisiert, sodass im Nachgang selten um n belibige Stellen geshiftet werden kann.. > remainderder weiterprozessiert werden darf und das sogar beliebig. Und genau das lernt man in der Schule nicht. Dort wird dann einfach hingenommen, dass es einen Rest gibt, wie groß der ist und das war es dann auch... > Ich möchte Dir keinesfalls zu nahe treten, lieber Stephan, aber... aber den Spruch kann man sich sparen? Überragender Vorschlag übrigens.. ;) Lothar M. schrieb: > Da wird dann auch in der realen Hardware gar nichts > multipliziert, sondern einfach 10 Bits dazuverdrahtet... Ein Bit dazu bedeutet aber ja immer ich verdopple den Wert. Was ist nun, wenn ich den Wert nicht verdoppeln mag sondern nur um 1,5(dezimal) anheben möchte? Verstärke halt momentan mit einem 7 Bit-Vektor und shifte gleichzeitig das Ergebnis um 3 Bits nach rechts, was wiederum einer Division mit 2^3 gleich kommt. So kann ich das Ergebnis mit einer Stufung von 0,125(dezimal) verstärken.. und zwar abhänig von aktuellen Randbedingungen. Diese ändern sich. > Nur geht die Rechnung "mehr Aufwand = besseres Ergebnis" hier nicht auf, > weil Float trotz der 32 Bit Breite leider nur 6 signifikante Stellen > hat. Es kann dir also passieren, dass du rechnest 1234567.8 + 1.0 und > hinterher kommt wieder 1234567.8 heraus... :-o Ist mir mittlerweile auch schon klar geworden.
:
Bearbeitet durch User
Stephan K. schrieb: > Was ist nun, wenn ich den Wert nicht verdoppeln mag sondern nur um > 1,5(dezimal) anheben möchte? Dann würde ich das Ganze auf eine Addition des Ausgangswertes mit seiner Hälfte reduzieren und bräuchte wieder keine Multiplikation... > Verstärke halt momentan mit einem 7 Bit-Vektor und shifte gleichzeitig > das Ergebnis um 3 Bits nach rechts, was wiederum einer Division mit 2^3 > gleich kommt. Dabei wird bei signed Werten aber in die falsche Richtung "gerundet".
Lothar M. schrieb: > Stephan K. schrieb: >> Was ist nun, wenn ich den Wert nicht verdoppeln mag sondern nur um >> 1,5(dezimal) anheben möchte? > Dann würde ich das Ganze auf eine Addition des Ausgangswertes mit seiner > Hälfte reduzieren und bräuchte wieder keine Multiplikation... Schon, wenn ich vorher weiß, dass es immer die hälfte ist, wie in diesem Beispiel eben. Es war allerdings auch nur ein Beispiel, nichts weiter. Wir haben es leider nicht mit fest vorhersagbaren "skalierungen" zu tun. Wie startk skaliert werden muss ist abhängig von externen Modulen.. verschiedene Sensoren z.B. >> Verstärke halt momentan mit einem 7 Bit-Vektor und shifte gleichzeitig >> das Ergebnis um 3 Bits nach rechts, was wiederum einer Division mit 2^3 >> gleich kommt. > Dabei wird bei signed Werten aber in die falsche Richtung "gerundet". Hmm das kann ich nicht gleich nachvollziehen. Kannst du mir vllt. einen Denkhinweis geben? Stelle mir den Vektor grad vor, ich gehe nur soweit mit der "Verstärkung", bis mein Ausgangsvektor voll skalliert ist. Die MSB's bleiben allso stets unbesetzt. Sollten sie doch einen Wert annehmen.. Dann wird das Ausgangssignal auf den maximalen wert, bzw. auf den minimalen Wert gesetzt. Ich schneide also MSB ab, welches meinen Wert repräsentiert. Wie wird dann da falsch gerundet?
Stephan K. schrieb: > Wie wird dann da falsch gerundet? Zeichne mal ein paar Bitmuster von negativen Zahlen auf und schneide die MSB ab. Rechne das selbe mit dem Taschenrechner... ?
Si claro, meinst sowas hier? 3d*3d = [011]b*[011]b = [001001]b = 9d linksshift (/2) = [00100]b = 4d Also doch lieber meine Ausgangsvektoren mit einem variablen Wert aufaddieren?! Macht man das bei der Skallierung dann immer so? Ich gebe dem Wert ja damit einen Offset.
:
Bearbeitet durch User
Stephan K. schrieb: > Nur werden Vektorbreiten fest synthetisiert, sodass im Nachgang selten > um n belibige Stellen geshiftet werden kann. Erstens geht das sehr wohl und zweitens ist das das hier unerheblich. Alles, was zur Laufzeit passiert, müsste mit FP auch getan werden und das Umskalieren ist in VHDL nun wirklich kein Problem. >> remainder der weiterprozessiert werden darf und das sogar beliebig. > Und genau das lernt man in der Schule nicht. Dort wird dann einfach > hingenommen, dass es einen Rest gibt Du solltest aber in der Lage sein, anhand der Vorgehensweise des schriftlichen Dividierens diese Schlussfolgerungen zu ziehen. Das ist doch anschaulich. Ich konnte sie ja auch ziehen und hatte nie etwas von FPGAs in der Schule gehabt. Es geht doch nur ums Gucken, Nehmen, Hinschreiben, Entscheiden obs reinpasst und dann so oder so weiterrechnen. Dann schiebt man die Guckebrille eins nach rechts und macht wieder dasselbe. Genau so schreibt man das beim FPGA hin. Auswählen, wie man weitermacht, ist halt ein Multiplexer. Man kann das Ganze Gedöhns sogar mit Generate-Anweisungen dynamisch hinschreiben, von der Auflösung und Tiefe abhängig machen. Macht aber keiner, sondern verdrahtet brute force aufs Maximum, lässt untern die Bits weg und die Synthese darf dann entscheiden, was sie davon einbauen möchte. > Lothar M. schrieb: >> Da wird dann auch in der realen Hardware gar nichts >> multipliziert, sondern einfach 10 Bits dazuverdrahtet... > Ein Bit dazu bedeutet aber ja immer ich verdopple den Wert. > Was ist nun, wenn ich den Wert nicht verdoppeln mag sondern nur um > 1,5(dezimal) anheben möchte? Dann nimmts Du eben das Einfache + die Hälfte. Das sind 50% mehr. Auch das sollte man direkt ersehen. Du hast aber ein anderes Problem: Dir ist nicht klar, was Du wann tun musst. Wenn Du etwas zur Laufzeit ändern willst, dann musst Du das Umrechnen ins FPGA einbauen. D.h. die Skalierung mit einer Multiplikation lösen. Also wird es einen Skalierfaktor geben, denn man in einem Register wo einstellt und der dann die Rechnung zurechtbiegt. Dies bitte so, das keine Divisionen durch X entstehen sondern nur solche durch n hoch 2. Das kriegst Du hin. Wenn nicht, dann kriegst Du es auch mit FP nicht hin. > Verstärke halt momentan mit einem 7 Bit-Vektor und shifte gleichzeitig > das Ergebnis um 3 Bits nach rechts Vergiss mal die Begriffe "verstärken" etc, Du verhaspelst Dich. Ich denke, in Deinem Fall ist es wirklich besser, Du baust eine variable Division ein und verzichtest auf Bit-Operationen.
Markus F. schrieb: > Rechts ist da, wo der Daumen links ist. .. oder innen. Weltbester FPGA-Pongo schrieb im Beitrag #5196637: > das Umskalieren ist in VHDL nun wirklich kein Problem. Nattürlich nicht.^^ Weltbester FPGA-Pongo schrieb im Beitrag #5196637: > Du solltest aber in der Lage sein, anhand der Vorgehensweise des > schriftlichen Dividierens diese Schlussfolgerungen zu ziehen. Bin ich, nur bin ich auf den Gedanken, mit dem Rest einfach weiter zu arbeiten nicht gekommen.. Weltbester FPGA-Pongo schrieb im Beitrag #5196637: > Wenn Du etwas zur Laufzeit > ändern willst, dann musst Du das Umrechnen ins FPGA einbauen. D.h. die > Skalierung mit einer Multiplikation lösen. Also wird es einen > Skalierfaktor geben, denn man in einem Register wo einstellt und der > dann die Rechnung zurechtbiegt. Dies bitte so, das keine Divisionen > durch X entstehen sondern nur solche durch n hoch 2. Genau das mache ich doch z.Z. Ich skaliere mit einem 7 Bit Vektor und teile gleichzeitig durch 8... (um 3 Bits geshiftet) Das ergbit mir einen Skalierungsfaktor, den ich über register beliebig von außen einstellen kann.. und zwar mit der Genauigkeit von 1/8 in den Bereichen von 0,125 bis 16.
Stephan K. schrieb: > Genau das mache ich doch z.Z. Ich skaliere mit einem 7 Bit Vektor und > teile gleichzeitig durch 8... (um 3 Bits geshiftet) Das ergbit mir einen > Skalierungsfaktor, den ich über register beliebig von außen einstellen > kann.. und zwar mit der Genauigkeit von 1/8 in den Bereichen von 0,125 > bis 16. Dann verstehe Ich das Problem nicht. Willst du diese Funktion irgendwie wegsparen?
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.