Dividir números en un FPGA

Escribí un programa para un FPGA Cyclone II que divide 2 números de 64 bits y devuelve si el resto es 0 usando la operación de módulo (%).

Cuando compilé el programa con números de 64 bits para el divisor y el dividendo, usó casi todas las celdas lógicas del dispositivo.

¿Hay alguna manera de hacer la división, o el módulo, o [si el módulo == 0] de una manera que use menos celdas lógicas?

Haga una copia de seguridad y hable sobre el problema real que está tratando de resolver: ¡es probable que esta no sea la forma más eficiente de hacerlo!
Es más una pregunta general. Estaba pensando en usar un FPGA como acelerador matemático para hacer operaciones complejas.
La división no es una buena operación para tratar de realizar en un solo ciclo de reloj. Estoy un poco sorprendido de que realmente hayas logrado eso para sintetizar, no todos los sintetizadores incluso admiten la división para síntesis.
¿Hay alguna manera de dividirlo en varios ciclos de reloj para obtener un aumento neto en la cantidad de divisiones que puedo hacer? Lo que quiero decir es que si lo divido en 4 ciclos de reloj, podría hacer más de 4 divisiones simultáneamente.
ChrisStratton, el proyecto que estoy haciendo actualmente es determinar si un número de 64 bits es primo pero quiere respuestas generales para la división.
En la práctica, para este tipo de cosas, le resultará sorprendentemente difícil superar la unidad de división de enteros de una CPU a menos que aplique algún tipo de técnica inteligente no general. O encuentre un bloque de IP adecuado. El dispositivo tiene muchos multiplicadores incorporados , por lo que es posible que pueda usar algún tipo de técnica de Newton-Raphson para encontrar la respuesta.

Respuestas (2)

Nuestra biblioteca PoC de código abierto tiene un núcleo IP de división de ciclo múltiple, que se puede sintetizar como una canalización. El recuento de bits del dividendo y el divisor, así como la base, se pueden configurar según las necesidades de los usuarios. Este módulo devuelve tanto el cociente como el resto.

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;

Consulte la fuente de PoC.arith.div para ver la implementación completa (es demasiado largo para publicarlo aquí).

¿Sabes algo sobre el divisor? Si lo hace, entonces hay varias cosas que se pueden hacer.

La clave para resolver la división, en general, es la División Euclidiana. Lea https://en.wikipedia.org/wiki/Euclidean_division para comprender por qué es necesario canalizar este algoritmo. Básicamente se reduce al mismo algoritmo que usarías para resolver divisiones a mano.