Was ist der schnellste Weg, um die Hardware-Division einer ganzen Zahl durch eine feste Konstante durchzuführen?

8

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.

    
geft 16.07.2014, 16:19
quelle

4 Antworten

10

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%     
Doug Currie 16.07.2014, 16:43
quelle
3

Angenommen, dass

  • die Ganzzahl-Division soll abschneiden, nicht runden (z. B. 599 / 100 = 5)
  • ist es in Ordnung, einen 16x16 Multiplikator im FPGA zu haben (mit einem festen Wert auf eine Eingabe)

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%     
user3386109 16.07.2014 18:24
quelle
1

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

    
Mehrdad 16.07.2014 18:37
quelle
0

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.

%Vor%

Real-zu-Binär-Konvertierung mit dem Ruby-Juwel Fixed_point.

Eine Ruby-IRB-Sitzung (mit fixed_point installiert über gem install fixed_point ):

%Vor%     
Morgan 16.07.2014 18:55
quelle