Dividieren von Zahlen auf einem FPGA

Ich habe ein Programm für einen Cyclone II FPGA geschrieben, das 2 64-Bit-Zahlen dividiert und zurückgibt, wenn der Rest 0 ist, indem die Modulo-Operation (%) verwendet wird.

Als ich das Programm mit 64-Bit-Zahlen für den Divisor und den Dividenden kompilierte, verwendete es fast alle Logikzellen im Gerät.

Gibt es eine Möglichkeit, Division oder Modulus oder [if Modulus==0] auf eine Weise durchzuführen, die weniger Logikzellen verwendet?

Sichern Sie sich und sprechen Sie über das eigentliche Problem, das Sie zu lösen versuchen - wahrscheinlich ist dies nicht der effizienteste Weg, dies zu tun!
Es ist eher eine allgemeine Frage. Ich habe darüber nachgedacht, ein FPGA als mathematischen Beschleuniger für komplexe Operationen zu verwenden.
Die Division ist keine schöne Operation, die man in einem einzigen Taktzyklus ausführen möchte. Ich bin ein bisschen überrascht, dass Sie das tatsächlich zum Synthetisieren bekommen haben, nicht alle Synthesizer unterstützen sogar die Division für die Synthese.
Gibt es eine Möglichkeit, es in mehrere Taktzyklen aufzuteilen, so dass ich eine Nettoerhöhung der Anzahl der möglichen Divisionen erhalte? Was ich meine ist, dass, wenn ich es in 4 Taktzyklen aufteile, es mehr als 4 Divisionen gleichzeitig machen könnte.
ChrisStratton, das Projekt, das ich gerade durchführe, bestimmt, ob eine 64-Bit-Zahl eine Primzahl ist, möchte aber allgemeine Antworten für die Division.
In der Praxis werden Sie es für solche Dinge überraschend schwer finden, die ganzzahlige Divisionseinheit einer CPU zu schlagen, es sei denn, Sie wenden eine Art clevere, nicht allgemeine Technik an. Oder finden Sie einen passenden IP-Block. Das Gerät verfügt über viele eingebettete Multiplikatoren , sodass Sie möglicherweise eine Art Newton-Raphson-Technik verwenden können, um die Antwort zu finden.

Antworten (2)

Unsere Open-Source PoC-Library verfügt über einen Multi-Cycle-Division-IP-Core, der als Pipeline synthetisiert werden kann. Die Bitanzahl des Dividenden und Divisors sowie der Basis kann nach den Bedürfnissen des Benutzers konfiguriert werden. Dieses Modul gibt sowohl den Quotienten als auch den Rest zurück.

entity arith_div is
  generic (
    A_BITS             : positive;          -- Dividend Width
    D_BITS             : positive;          -- Divisor Width
    RAPOW              : positive := 1;     -- Power of Compute Radix (2**RAPOW)
    PIPELINED          : boolean  := false  -- Computation Pipeline
  );
  port (
    -- Global Reset/Clock
    clk : in std_logic;
    rst : in std_logic;

    -- Ready / Start
    start : in  std_logic;
    ready : out std_logic;

    -- Arguments / Result (2's complement)
    A : in  std_logic_vector(A_BITS-1 downto 0);  -- Dividend
    D : in  std_logic_vector(D_BITS-1 downto 0);  -- Divisor
    Q : out std_logic_vector(A_BITS-1 downto 0);  -- Quotient
    R : out std_logic_vector(D_BITS-1 downto 0);  -- Remainder
    Z : out std_logic  -- Division by Zero
  );
end arith_div;

Sehen Sie sich die Quelle von PoC.arith.div für die vollständige Implementierung an (es ist zu lang, um sie hier zu posten).

Weißt du etwas über den Divisor? Wenn ja, dann gibt es mehrere Dinge, die getan werden können.

Der Schlüssel zum Lösen der Division ist im Allgemeinen die euklidische Division. Lesen Sie https://en.wikipedia.org/wiki/Euclidean_division , um zu verstehen, warum das Pipelining dieses Algorithmus notwendig ist. Es läuft im Grunde auf den gleichen Algorithmus hinaus, den Sie verwenden würden, um die Division von Hand zu lösen.