Este es un buen ejemplo de desajuste en los resultados entre simulación y síntesis.
Si sintetizará este código y ejecutará una prueba en FPGA, funcionará (al menos no verá un valor hash constante). Sin embargo, en la simulación se comporta de manera diferente:
-
always @(*)
construct significa "evaluar el siguiente bloque de código en cualquier momento en cualquiera de las señales utilizadas en el lado derecho del cambio de asignación". En su código, estas señales son: data_in
, poly
y hashValue
.
- Si ninguna de las señales anteriores cambia (¿cuál es el caso que está describiendo, verdad?) - el simulador no evaluará el bloque y no se harán las asignaciones.
Una vez más, la herramienta de síntesis producirá la lógica correcta para este código, por lo tanto, este tipo de errores son muy peligrosos .
Hay una forma correcta de manejar esto es definir una señal de reloj y usar una construcción secuencial always @(posedge clk)
.
Además, parece que tienes al menos dos bucles combinatorios en tu código. Incluso si están destinados, esta es una muy mala práctica. Desea evitar el uso de cualquier bucle comb de sintetizable.
Sin embargo, al inspeccionar su código, parece que la referencia circular aquí es solo por conveniencia, tal vez no se sintetice en un bucle de peine. En este caso tienes dos opciones:
- Encuentre un formulario equivalente que no use una referencia circular
- Use Verilog
function
construct.
El primer enfoque es el correcto. Verilog no es un lenguaje de programación, y las declaraciones que está utilizando para describir la lógica deben ser lo más similares a la lógica inferida. Sin embargo, este enfoque puede ser complicado, ya que muchos algoritmos están escritos en formularios de software. Por lo tanto, puede utilizar el segundo enfoque, en cuyo caso el código se verá así (no probado):
always @(posedge clk)
begin
hashValue[15:0] <= calcNewHashValue(hashValue[15:0], poly[15:0], data_in[3:0]);
end
Donde calcNewHashValue
es la función que encapsula el bucle for
de tu código.
Una vez más: si la herramienta de síntesis le advierte sobre los bucles de peine, no debe usar este diseño. En este caso, piense en otra implementación algorítmica o distribuya el cálculo en varios ciclos de reloj.
También puede leer este documento para obtener una comprensión más profunda del comportamiento de los simuladores Verilog.
Excepto por eso, su estilo de codificación es muy propenso a errores. Como guía, sugiero que defina un bloque always
separado para cada señal. En otras palabras, solo se asigna una señal en el bloque always
. Haga excepciones solo cuando no pueda manejarlo de otra manera, y piense detenidamente antes de cada decisión.