Necesito dividir un número entero por otro número entero en un ciclo de reloj.
¿Cómo debo hacer esto?
Tengo una función para ello que encontré en internet pero siempre devuelve uno.
function divide (a : unsigned; b : unsigned) return integer is variable a1 : unsigned(15 downto 0):=a; variable b1 : unsigned(15 downto 0):=a; variable p1 : unsigned(16 downto 0):= (otros => '0'); variable i : integer:=0; begin for i in 0 to b'longitud-1 loop p1(b'longitud-1 downto 1) := p1(b'longitud-2 downto 0); p1(0) := a1(a'longitud-1); a1(a'longitud-1 downto 1) := a1(a'longitud-2 downto 0); p1 := p1-b1; if(p1(b'longitud-1) ='1') then a1(0) :='0'; p1 := p1+b1; else a1(0) :='1'; end if; end loop; return to_integer(a1); end divide;
0 votos
La división siempre es un poco más difícil que la multiplicación. Piensa en multiplicar por el recíproco y obtener el recíproco del divisor de una tabla de búsqueda.
3 votos
Quizás "variable b1 : unsigned(15 downto 0):=b;" en lugar de ...":=a"
1 votos
¿Son tus entradas (dividendo y divisor) ambas variables? Hacer un divisor de 1 ciclo es posible, pero funcionará a baja frecuencia y ocupará mucha área (bueno, por supuesto, depende de la anchura de los operandos...).
0 votos
¿Latencia de un ciclo, o rendimiento de un ciclo?
0 votos
Una latencia de un ciclo. Arreglé mi código con la sugerencia que hizo @TEMLIB, pero ahora estoy usando más recursos de los que mi FPGA puede manejar. ¿Cómo podría usar menos recursos en mi código?
2 votos
Un ciclo de latencia de división de 16 bits es realmente una mala idea. Requiere 16 sumadores consecutivos, lo que significa una gran cantidad de área y un camino crítico muy largo. Si puedes vivir con una aproximación, multiplicar por el inverso sería mejor, pero para 16 bits se requiere mucha ROM... Algoritmo de división algún debería producir un circuito más pequeño (como SRT-4) y una división más rápida, pero requiere que el bit más significativo del dividendo siempre sea '1'.
0 votos
Cuando dices aproximación, ¿a qué te refieres? No voy a recibir un flotante, por lo que redondear hacia arriba está bien. ¿Multiplicar por el inverso sería invertir el entero y multiplicar, verdad? @JonathanDrolet
0 votos
Por aproximación, quiero decir que no obtendrás el valor exacto pero bastante cercano a él. Esto se debe a que muchas inversiones no pueden representarse exactamente en binario. La precisión general depende de tu precisión en la representación de la inversa (por lo tanto, el tamaño de la ROM y el multiplicador). Por ejemplo, si deseas hacer 12345/45 (debería dar 274) y das 16 bits para representar 1/45 (1456), el resultado de la multiplicación por la inversa es 278. Obtendrías un error más pequeño al usar una ROM de más de 16 bits.
0 votos
¿Qué tan grande debería ser un multiplicador para obtener 274 en lugar de 278 para tu ejemplo? Estoy diseñando un procesador en VHDL y la precisión es importante hasta cierto punto. @JonathanDrolet
0 votos
Tendrías que hacer ese análisis por ti mismo, pero para no tener ningún error para un divisor de 16 por 16 bits: muy grande. Todos los procesadores realizan divisiones en múltiples ciclos, en el orden de 1 ciclo de reloj por bit. Los procesadores más pequeños no tienen un divisor de hardware, dependen de una implementación de software (mucho más lenta). Por lo general, el compilador y un buen programador evitan la división a toda costa, ya que es inherentemente lenta. Si deseas agregar un divisor de latencia única a tu procesador, todas las demás operaciones serían más lentas como resultado del camino crítico más grande.
0 votos
No tan aplicable a esta pregunta, pero para beneficio de los usuarios de Google: la división por una potencia de dos es muy económica en hardware, simplemente implica desplazar los bits hacia la derecha.
0 votos
Entonces, ¿cuáles son los pasos lógicos para no tener errores, una latencia de un ciclo en la división de 16 bits? Voy a estar dividiendo por números algo aleatorios, desde 0 hasta 65535.
0 votos
@JonathanDrolet Lo logré hacer funcionar, me refiero al código de arriba. ¡Ahora la división me da un resultado diferente cada vez! ¿Por qué?