2012-07-30 26 views
9

Me enseño a mí mismo verilog. El libro que estoy siguiendo declaró en los capítulos de introducción que para realizar la división usamos el operador '/' o el operador '%'. En capítulos posteriores, se dice que la división es demasiado compleja para verilog y no se puede sintetizar, por lo que para realizar la división se introduce un algoritmo largo.División en verilog

Por lo tanto, estoy confundido, no puedo verilog manejar división simple? es el/el operador inútil?

+1

Para un RTL eficiente si el denominador es fijo, solo use 1/denominador, en lugar de a/3 use un * 0.33. para a/2 use a >> 1. La longitud de palabra del punto fijo determinará la precisión de los coeficientes y las respuestas. – Morgan

+1

Las herramientas de síntesis son bastante buenas en estos días y, a menudo, el múltiplo de un solo coeficiente será tan pequeño como una operación artesanal. En igualdad de condiciones, elegiría la versión más fácil de leer, para una mejor calidad de código. – Morgan

Respuesta

23

Todo depende del tipo de código que está escribiendo.

Si está escribiendo código que pretende sintetizar, que tiene la intención de entrar en un FPGA o ASIC, entonces probablemente no desee utilizar los operadores de división o módulo. Cuando coloca cualquier operador aritmético en RTL, el sintetizador crea un circuito para hacer el trabajo; Un sumador para + & -; Un multiplicador para *. Cuando escribe /, está pidiendo un circuito divisor, pero un circuito divisor es algo muy complejo. A menudo lleva varios ciclos de reloj y puede usar tablas de búsqueda. Pedir una gran cantidad de una herramienta de síntesis para inferir lo que quieres cuando escribes a/b.

(Obviamente dividir por potencias de 2 es sencilla, pero normalmente tendrá que utilizar los operadores de desplazamiento)

Si estás escribiendo código que usted no desea ser sintetizado, es parte de una prueba Banco por ejemplo, entonces puedes usar la división todo lo que quieras.

Para responder a su pregunta, el operador / no es inútil, pero debe saber dónde y por qué lo está utilizando. Lo mismo ocurre con *, pero en menor grado. Los multiplicadores son bastante caros, pero la mayoría de los sintetizadores pueden inferirlos.

+0

No sabía que había una relación entre el cambio y la división ... Lo investigaré, gracias – StuckInPhD

+1

+1 recuerdas que estás fabricando hardware , no escribiendo un programa – Balthamos

+1

@FarazKhan La relación es bastante obvia, Al desplazarnos a la derecha estamos dividiendo por 2 y al desplazarnos a la derecha estamos multiplicando por 2. ej. Piensa en términos de binario. Tome un número digamos 4'd12, en binario es 4'b1100. Ahora si lo cambiamos a la derecha una vez que obtenemos 4'b0110 que es 6 en decimal, en otras palabras, hemos dividido el valor entre 2 y solo usó un reloj. – Osaid

5

La división y el módulo nunca son "simples". Evítelos si puede hacerlo, p. a través de máscaras de bits u operaciones de cambio. Especialmente un divisor variable es realmente complicado de implementar en hardware.

+0

No sabía que había una relación entre el cambio y la división ... Lo investigaré, gracias – StuckInPhD

5

So im confused. ¿Puede verilog manejar la división simple? ¿Es/el operador inútil?

La especificación de síntesis verilog (IEEE 1364.1) en realidad indica que todos los operadores aritméticos con operandos enteros deben ser compatibles pero nadie sigue esta especificación. Algunas herramientas de síntesis pueden dividir los números enteros, pero otros lo rechazarán (creo que XST aún lo hace) porque la división combinacional suele ser muy ineficiente en el área. Las implementaciones de multiciclo son la norma, pero no se pueden sintetizar desde '/'.

3

"Verilog the language" maneja la división y el módulo muy bien: cuando está usando una computadora para simular su código, tiene acceso completo a todas sus capacidades.

Cuando está sintetizando su código para un chip en particular, existen limitaciones. Las limitaciones tienden a basarse en lo que el vendedor de la herramienta considera "sensato" en lugar de lo que es factible.

En los viejos tiempos, la división por cualquier cosa que no fuera una potencia de dos se consideraba no sensible para el silicio, ya que ocupaba mucho espacio y funcionaba muy lentamente. Por el momento, algunos sintetizadores crean circuitos para "dividir por una constante".

En el futuro, no veo ninguna razón por la cual el sintetizador no deba crearle un divisor (o utilizar uno que esté en los bloques DSP de una futura arquitectura potencial).Queda o no por ver, pero atestigua la progresión de multiplicadores (de "solo potencias de dos" a "una constante de entrada" a "implementación completa" en unos pocos años)

+0

Gracias. Pensé simplemente en usar el módulo generado por el generador de núcleo para la división, en lugar de entrar en el algoritmo si fuera así. – StuckInPhD

-7

usando result <= a/b y funciona perfectamente .

Recuerde al utilizar el operador <=, la respuesta se calcula inmediatamente, pero la respuesta se ingresa dentro del registro "resultado" en el borde positivo del próximo reloj.

Si no desea esperar hasta el próximo uso del reloj flanco positivo result = a/b.

Recuerde, cualquier circuito operación aritmética necesita un poco de tiempo para terminar la operación, y durante este tiempo el circuito genera números aleatorios (bits).

Es como cuando un avión de ataque con warthog A-10 ataca un tanque dispara muchas balas. Así es como el circuito divisor actúa mientras se divide, escupe bits aleatorios. Después de un par de nanosegundos, terminará de dividirse y devolverá un buen resultado estable.

Es por eso que esperamos hasta el próximo ciclo de reloj para el registro "resultado". Intentamos protegerlo de los números aleatorios de basura.

La división es la operación más compleja, por lo que tendrá un retraso en el cálculo. Para la división de 16 bits, el resultado se calculará en aproximadamente 6 nanosegundos.

+3

6 nano segundos en el módulo funcionando a qué reloj y qué tipo de algoritmo de división está usando? – Osaid

+0

Creo que esta publicación causa muchos más problemas de los que resuelve. – travisbartley

1
  1. circuitos incluyendo sólo la división por 2, es suficiente cambiar el bit :)
  2. distinto de 2 .... ve siempre se debe pensar en Verilog nivel de circuito no es C o C++
  3. /y% es no se puede sintetizar o si se convierte (en nuevas versiones), creo que deberías mantener tu propio circuito de división, esto es porque la IP que proporcionan será general (lo más probable es que hagan flotación no sea fija)
  4. apuesto a que has pasado por libro de arquitectos de computadora morris mano, allí en algunos capítulos finales todo el flujo se da junto con algo, seguirlo seguirlo y hacer su propio
  5. vea ahora si sus trabajos solo requieren verificación lógica y no se necesita ningún circuito real, seguro vaya para/y%. no hay problema, funcionará para la simulación
5

Debes pensar en el hardware.

Cuando escribe un < = b/c, está diciendo a la herramienta de síntesis "Quiero un divisor que pueda proporcionar un resultado en cada ciclo de reloj y no tenga registros intermedios de pipline".

Si resuelve el circuito lógico requerido para crearlo, es muy complejo, especialmente para conteos de bits más altos. En general, los FPGA no tendrán bloques de hardware especializados para la división, por lo que deberían implementarse a partir de recursos de lógica genérica. Es probable que sea a la vez grande (mucho luts) y lenta (fmax baja).

Algunos sintetizadores pueden implementarlo de todos modos (a partir de una búsqueda rápida parece que Quartus lo hará), otros no se molestarán porque no creen que sea muy útil en la práctica.

Si se divide por una constante y puede vivir con un resultado aproximado, entonces puede hacer trucos con multiplicadores. Tome el recíproco de lo que quería dividir, multiplíquelo por una potencia de dos y redondee al número entero más cercano.

Luego en su verilog puede implementar su división aproximada por multiplicación (que no es demasiado cara en FPGAS moderno) seguida de desplazamiento (el desplazamiento por un número fijo de bits es esencialmente gratuito en hardware). Asegúrese de permitir suficientes bits para el resultado intermedio.

Si necesita una respuesta exacta o si necesita dividir por algo que no es una constante predefinida, tendrá que decidir qué tipo de divisor desea. Si su rendimiento es bajo, entonces puede usar un enfoque basado en la máquina de estado que hace una división cada n ciclos de reloj. Si su producción es alta y puede permitirse el área del dispositivo, entonces puede ser más apropiado un enfoque en línea que haga una división por ciclo de reloj (pero requiere múltiples ciclos para que el resultado fluya).

A menudo, los vendedores de herramientas proporcionarán bloques prefabricados (altera les llama megafunciones) para este tipo de cosas. La ventaja de esto es que el proveedor de la herramienta probablemente los habrá optimizado cuidadosamente para el dispositivo. La desventaja es que pueden traer bloqueo de proveedor, si desea cambiarse a un proveedor de dispositivo diferente, lo más probable es que tenga que cambiar el bloque y el bloque con el que lo intercambie puede tener diferentes características.

0

La división con '/' es posible en verilog. Pero no es un operador sintetizable. Lo mismo es el caso de la multiplicación usando '*'. Existen ciertos algoritmos para realizar estas operaciones en versión, y se usan si el código necesita ser sintetizable. es decir. si requiere un hardware equivalente para ello.

No conozco ningún algoritmo para la división, pero para la multiplicación, he usado el algoritmo de Booth.