El objetivo de este capítulo es que el lector conozca algunos detalles básicos del funcionamiento del simulador. Dicho conocimiento permitirá entender algunas limitaciones o consecuencias. No se trata de una explicación exhaustiva de como debería funcionar un simulador VHDL, sino de exponer el mecanismo básico.
Como ya se comentó en Capítulo 1 lo más frecuente es que la herramienta genere un ejecutable. Al ejecutar este programa lo primero que realizará es la inicialización de todas nuestras señales y variables. Para esto utilizará los valores por defecto que hayamos definido. En el caso en que no haya ningún valor por defecto usará el menor valor posible. Esto es cero para valores numéricos, el primer valor posible para enumeraciones, etc. En el caso del tipo std_logic, que se encuentra definido como una enumeración, el primer valor posible es justamente 'U' (indefinido).
Una vez establecidos los valores iniciales el simulador comienza a evaluar todas las expresiones buscando llegar a valores estables. Para esto se evalúan todas las expresiones del lado derecho de las asignaciones temporales (<=). Una vez determinados sus resultados el simulador avanza un delta de tiempo infinitesimal. A los fines prácticos este avance de tiempo no es observable, sin embargo tiene una gran importancia en el comportamiento del simulador. Luego de avanzar un delta t los valores computados se transportan al lado izquierdo de las asignaciones. Con los nuevos valores se inicia una nueva secuencia de evaluación. Cuando el simulador detecta que al avanzar un delta t los nuevos valores son los mismos que los anteriores, se da por concluida la secuencia. Cabe destacar que las conexiones realizadas en la instanciación de un componente (operador =>) no implican un transporte temporal, y por lo tanto no introducen un delta de tiempo.
Una vez determinado el valor estable, el simulador procede a avanzar un monto de tiempo no infinitesimal. Para esto evalúa todas las sentencias wait buscando cual es la más cercana en el tiempo. De no ser posible avanzar en el tiempo termina la simulación. Esto último sucede cuando todos los procesos se encuentran, o bien esperando a cambie una señal que ya no cambia, o bien esperando por siempre.
Como consecuencia de este comportamiento se derivan varias consecuencias. Una de ellas es que si nuestro circuito tiene un lazo de realimentación que lo vuelve inestable, el simulador jamás podrá encontrar un valor estable para las señales y no podrá avanzar en el tiempo.
Otra de las consecuencias interesantes es un tanto más sutil. La misma se puede enunciar de la siguiente manera: Una señal de reloj jamás debe ser asignada utilizando el operador <= a otra señal que pretendamos que sea sincrónica con la primera. Esto se debe a que al hacerlo la segunda señal tendrá una demora de un delta t extra. Esto podría generar problemas serios, ya que una señal muestreada por el primer reloj podría diferir del resultado muestreado con la segunda. Es por esta razón que las señales de reloj sólo pueden conectarse a través de los puertos de entrada y salida. Cabe destacar que esto no afecta a la síntesis, donde el concepto de delta t carece de sentido.
Usualmente es posible indicarle al simulador que sólo simule una cantidad de tiempo prefijada. Esto es útil para correr un test bench incompleto, pero no debe tomarse como mecanismo natural.