La simulación VHDL no funciona

0

Sin experiencia en VHDL, estoy intentando convertir un código C ++ para conducir un CCD a un código basado en VHDL. Es muy probable que esta no sea la mejor manera de implementarla, pero es intuitiva para mí. Entonces, mi contador cuenta los ciclos de reloj y, según el número de ciclo de reloj, asigno el estado específico a la salida. Soy capaz de implementar el diseño con éxito:

Sinembargo,cuandoejecutolasimulación,ALLOUTnocambia,dehechopermaneceenestadoST3.Lasadvertenciasdesdelaconsoladelbancodepruebas:

Se repiten cada 25 ns hasta el final de la simulación. ¿Alguna sugerencia sobre dónde cometí el error?

    
pregunta Nazar

2 respuestas

3

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.

    
respondido por el Brian Drummond
2

MainCounter no se inicializa, y nunca se configura en ningún otro lugar (no se maneja RESET a '1' en ninguna parte). El mensaje "metavalue" indica que tienes 'U' , 'X' , etc. en tus entradas para la comparación (una búsqueda en la web debería haberte dicho mucho, por cierto).

Es posible que desee considerar el uso de literales enteros, por cierto. numeric_std y unsigned le permiten hacer eso, y es mucho más fácil de leer. Por ejemplo:

if (RESET = '1' or MainCounter >= 110000) then
    
respondido por el fru1tbat

Lea otras preguntas en las etiquetas