Pregunta sobre el bucle For Synthesizable y Generate

Estoy usando el lenguaje Verilog y Zedboard como placa de destino.

Hasta donde yo sé , el bucle for se puede sintetizar y la herramienta de síntesis traduce el bucle for como una secuencia de instrucciones duplicadas, como el desenrollado del bucle.

Por ejemplo,

for ( i = 0; i < 4; i=i+1) begin mem[i] = i; end will be translated to mem[0] = 0; mem[1] = 1; mem[2] = 2; mem[3] = 3; 

Por lo tanto, hasta donde yo sé, el bucle for se puede usar si el recurso está disponible para inferir las puertas múltiples pero con el mismo propósito.

Sin embargo, parece que generar en Verilog se puede usar para, no solo implicar las instancias múltiples, sino también las instrucciones múltiples iguales que el bucle for.

Entiendo que la generación solo puede implicar las instancias múltiples del módulo y el bucle for no se puede usar para ese propósito.

Entonces, ¿cuál es la diferencia entre el ciclo generate + for y solo el ciclo for? Sin embargo, creo que ambos funcionan como el ciclo desenrollado. ¿Hay alguna diferencia notable? Si no hay diferencia, ¿cuál es el estilo de codificación preferible para inducir el desenrollado de bucles?

Comentarios

  • Solo para mayor claridad, ' s: insinúo, infieres. p.ej. implica una RAM en Verilog / VHDL, el software de síntesis infiere esa RAM de su Verilog / VHDL. Error muy común, vale la pena aprender.

Respuesta

Los bucles for de Verilog se sintetizan perfectamente bajo ciertas condiciones:

  • Puede usar cualquier instrucción de procedimiento dentro de un bucle (por ejemplo, if-else).
  • El número de bucles debe estar predeterminado .
    • La expresión limitante debe ser una comparación entre la variable del ciclo y una constante o un parámetro.
    • La asignación de pasos debe incrementar el valor del ciclo en una cantidad constante.
  • Puede asignar un valor diferente a la misma variable en cada ciclo (por ejemplo, calcular un índice a partir de la variable del ciclo).
  • Para propósitos de síntesis, el ciclo se evalúa en tiempo cero, es decir, si intenta hacer un contador, solo verá el valor final.

Esas mismas reglas se aplican ya sea que use un bucle for en un bloque de procedimiento, o en un bloque de generación.

Cuando se hace en un bloque de procedimiento, initial y always, puede utilizar un for bucle para cambiar elementos en una matriz (exactamente como su ejemplo), o puede cambiar el mismo valor varias veces, por ejemplo:

for (idx = 0; idx < 4; idx=idx+1) begin a = a + b[idx]; c = c + 2; //You can change more than one variable in a for loop end 

En ese ejemplo, el hardware resultante será una cadena de sumadores, sumando los valores de cuatro índices de matriz.

La clave es que no puede crear nuevas variables o módulos en un bucle for de procedimiento. Esta regla se aplica a los bloques de procedimiento en general, no solo a los bucles (es decir, no se puede declarar una variable en un bloque de procedimiento).

 

Generar bloques, por otro lado, permite la creación de variables y la creación de instancias de módulos. Eso significa que en un bloque de generación, puede usar un ciclo generate for para inferir módulos. Esa es prácticamente la única diferencia.

Para generar bucles for, debe usar un genvar como variable de bucle (es decir, el valor que usa para contar cada bucle). También debe darle un nombre al bucle for:

for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName 

Este nombre se antepone a cualquier pieza de hardware que cree una instancia en el bucle. Entonces, si crea una instancia llamada bob, el ciclo anterior crearía instancias:

loopName[0]|bob loopName[1]|bob loopName[2]|bob loopName[3]|bob 

Esto da como resultado múltiples instancias con nombres únicos.

 

Tanto los bucles de generación como los de procedimiento realizarán el desenrollado de bucles como usted dice. La diferencia es simplemente cómo puedes usarlos. El procedimiento se puede utilizar en bloques de procedimiento (por ejemplo, para inicializar una memoria). Generate solo se puede usar en bloques generate.

Ambos son útiles y preferidos. Uno no puede reemplazar al otro.

Comentarios

  • otra forma de pensar en generate es como una especie de preprocesador, su compilador verilog ' ejecuta ' elementos en generar bloques en el punto en el que ' s instancia el bloque que contiene las genera – no ' t suceden en tiempo de ejecución (a diferencia de los bucles de procedimiento)
  • @Taniwha bucles de procedimiento don ' t tampoco se ejecutan en tiempo de ejecución. El compilador las desenrolla. Al final, todo se reduce al hardware. Tampoco ' confunda el preprocesador con las declaraciones generate, no son el mismo concepto – Verilog tiene un preprocesador que incluye declaraciones de tipo if-else.
  • @TomCarpenter Agradezco una gran respuesta. Podría entender todos sus puntos excepto el bucle generate for.Parece que comenzar: algo debería agregarse justo antes del ciclo for, pero no puedo entender cómo funciona al crear instancias de módulos. ¿Es el loopName una variable o simplemente una cadena? Y cómo se pueden indexar de [1] a [4].
  • @JaeHyukLee loopName es solo texto, como un nombre de instancia o un nombre de señal. Puede ser cualquier cosa que desee.
  • @TomCarpenter – depende del compilador – si ' está compilando puertas, sí, se desenrollan, si ' volver a compilar código para simulación es más probable que no (descargo de responsabilidad, ' he escrito un compilador de Verilog)

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *