Verilog for-loops se puede sintetizar perfectamente bajo ciertas condiciones:
- Puede usar cualquier declaració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 de bucle y una constante o un parámetro.
- La asignación de pasos debe aumentar el valor del bucle en una cantidad constante.
- Puede asignar un valor diferente a la misma variable en cada bucle (por ejemplo, calcular un índice a partir de la variable de bucle).
- Para fines de síntesis, el bucle se evalúa en tiempo cero, es decir, si intenta hacer un contador, solo verá el valor final.
Esas mismas reglas se aplican tanto si utiliza un bucle for en un bloque de procedimiento como en un bloque de generación.
Cuando se realiza en un bloque de procedimiento, initial
y always
, puede usar un bucle for 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, que suma los valores de cuatro índices de matriz.
La clave es que no se pueden crear nuevas variables o módulos en un procedimiento para bucle. Esta regla se aplica a los bloques de procedimientos en general, no solo a los bucles (es decir, no se puede declarar una variable en un bloque de procedimientos).
Los bloques de generación, por otro lado, permiten 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 de generación de for para inferir módulos. Esa es prácticamente la única diferencia.
Para generar bucles, debe usar genvar
como variable de bucle (es decir, el valor que usa para contar a través de cada bucle). También debes darle un nombre al bucle for:
for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName
Este nombre se añade a cualquier pieza de hardware que cree en el bucle. Entonces, si creas una instancia llamada bob
, el bucle 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 la generación como el procedimiento de los bucles realizarán el desenrollado del bucle, como usted dice. La diferencia es simplemente cómo puedes usarlos. El procedimiento puede utilizarse en bloques de procedimiento (por ejemplo, para inicializar una memoria). Generar solo se puede utilizar en generar bloques.
Ambos son útiles y preferidos. Uno no puede reemplazar al otro.