Hay una serie de problemas de estilo aquí y un problema importante.
Fru1tbat ha señalado que nunca inicializa MainCounter: una forma de hacerlo sería controlar la entrada de reinicio con una forma de onda simple:
RESET <= '0', '1' after 100 ns, '0' after 200 ns;
en la región de ejecución paralela (después de que la arquitectura "comience") lo haría. Tenga en cuenta que esto es solo para simulación, y sería MUCHO mejor hacer que RESET se convierta en un puerto de entrada y lo conduzca desde su banco de pruebas de simulación.
En segundo lugar (y este es el principal problema, a la espera de morderte aleatoriamente en el hardware real), la cláusula RESET en el proceso COUNT debería simplificarse para SOLAMENTE borrar MainCounter
en el reinicio. Luego, la compensación de la envolvente se debe mover a la parte cronometrada del proceso:
if Reset = '1' then
MainCounter <= (others => '0');
elsif rising_edge(Clk) then
if MainCounter >= 12345 then
MainCounter <= (others => '0');
else
MainCounter <= MainCounter + 1;
end if;
end if;
La razón de esto es sutil si no está acostumbrado al diseño de hardware: como se expresó, tiene un montón de lógica asíncrona esperando para borrar el contador si este pasa momentáneamente a un número alto mientras cuenta. Entonces, contando de X "7FFF" a X "8000", probablemente pasará momentáneamente a través de X "FFFF" ... y se reiniciará.
Al mover esa lógica a la parte cronometrada, solo se restablecerá si el estado temporal persiste hasta el próximo límite del reloj: y las herramientas de análisis de tiempo informarán un error de sincronización si es posible.
Ahora las advertencias: Metavalues en 0 ns son básicamente inofensivos. Los metavalues que persisten DESPUÉS de que se haya completado el restablecimiento son un asunto diferente ...
Y los problemas de estilo:
Puede comparar los literales enteros no firmados con números enteros simples (porque numeric_std sobrecarga a los operadores de comparación con tipos de operandos mixtos) y eso haría que el código sea MUCHO más legible. Mejor: usa declaraciones constantes en lugar de números mágicos. (Como descubrió, no puede asignar un literal entero a un sin signo; porque la asignación no es un operador . Hay funciones de conversión to_unsigned y to_integer para ese fin)
No hay necesidad de paréntesis alrededor de las expresiones booleanas, p. ej. en si-declaraciones. Algunos programadores de C los utilizan por costumbre, pero a mi me parece innecesariamente desordenado.
Su proceso LENTO se desbloquea, a pesar del reloj en su lista de sensibilidad ... Prefiero los procesos cronometrados simples; evitan los problemas que afectan a los procesos de combinación como SLOW, que no funcionarán correctamente a menos que agregue todas las señales RHS (aquí, solo Maincounter) a la lista de sensibilidad.