Ich habe eine 16-Bit-Zahl, die ich durch 100 teilen möchte. Sagen wir, es ist 50000. Das Ziel ist es, 500 zu erhalten. Ich versuche jedoch, abgeleitete Teiler auf meinem FPGA zu vermeiden, weil sie Timing-Anforderungen brechen. Das Ergebnis muss nicht genau sein; eine Annäherung wird tun.
Ich habe die Hardware-Multiplikation mit 0,01 versucht, aber echte Zahlen werden nicht unterstützt. Ich schaue jetzt auf Pipeline-Teiler, aber ich hoffe, dass es dazu nicht kommt.
Konzeptionell: Mit 655 (= 65536/100) multiplizieren und dann um 16 Bits nach rechts verschieben. Natürlich ist in der Hardware das Shift-Recht frei.
Wenn Sie es noch schneller brauchen, können Sie die Teilung als eine Summe von Teilungen durch Zweierpotenzen (Verschiebungen) fest verdrahten. Zum Beispiel,
%Vor%Im C-Code wäre das letzte Beispiel oben:
%Vor%Angenommen, dass
Dann können Sie genaue Werte erhalten, indem Sie einen 16x16-Multiplikator ohne Vorzeichen implementieren, wobei ein Eingang 0xA3D7 und der andere Eingang Ihre 16-Bit-Zahl ist. Fügen Sie 0x8000 zu dem 32-Bit-Produkt hinzu, und Ihr Ergebnis befindet sich in den oberen 10 Bit.
Im C-Code sieht der Algorithmus so aus
%Vor% Im Allgemeinen können Sie mit der Umkehrung und Verschiebung multiplizieren. Compiler machen das ständig, auch für Software.
Hier ist eine Seite, die das für Sie erledigt: Ссылка
In Ihrem Fall scheint das eine Multiplikation mit 0x431BDE83 zu sein, gefolgt von einer Rechtsverschiebung von 17.
Und hier ist eine Erklärung: Berechnung des Multiplikativen Inverse zur Optimierung der Ganzzahligen Division
Die Multiplikation mit dem Reziproken ist oft ein guter Ansatz, wie Sie festgestellt haben, obwohl reelle Zahlen nicht unterstützt werden. Sie müssen mit Festkommazahlen statt Gleitkommazahlen arbeiten.
Verilog hat keine Definition von Fixpunkt, aber es verwendet nur eine Wortlänge und Sie entscheiden, wie viele Bits ganzzahlig und wie viele Bruchzahlen sind.
0,01 (0,0098876953125) binär wäre 0_0000001010001
. Je größer diese Wortlänge ist, desto größer ist die Präzision.
Real-zu-Binär-Konvertierung mit dem Ruby-Juwel Fixed_point.
Eine Ruby-IRB-Sitzung (mit fixed_point installiert über gem install fixed_point
):
Tags und Links algorithm division system-verilog