Images

Simulación del Proyecto LEDA_blog

Con este software hay diferentes formas de simular, aquí vamos a usar la más fácil para este caso. 


Lo que obtendremos de esta simulación es un cronograma, si eso de cronograma te suena a crucigrama y no tienes ni idea que es, no te preocupes que lo verás. De hecho si echas un ojo a la última entrada, ahí encontrarás que uso cronogramas como este:


También subrayo lo dicho, que hay distintas formas de simular con XILINX, (e incluso con XILINX en colaboración con SIMULINK o Labview), esta forma de simular es sólo una más.

En VHDL, como en prácticamente todos los lenguajes de programación, hay muchas formas de hacer código para obtener un mismo resultado, pero es que además en el caso concreto de VHDL depende mucho de cómo describas el sistema.

En VHDL la descripción de un sistema digital puede ser de res tipos: flujo de datos, funcional (también llamada algorítmica) o estructural.

En este caso tenemos una descripción funcional (o algorítmica), y eso hace que la forma de simular que veremos sea probablemente la más fácil.

Sobre estos conceptos (formas de describir un sistema digital en VHDL) hay abundante documentación en Internet, y de todas formas si no los conoces me conformo de momento con que sepas que un sistema digital se puede abordar de diferente maneras. Con eso por ahora basta.

Ahora “vayamos al grano”.

En el código que tenemos, justo dónde señalo en la siguiente imagen:

Lo que vamos ha hacer es hacer la siguiente modificación de lo que está en verde:



Aquí dejo el código modificado para copiar y pegar:

--???21EDA?? --?????:A-C8V4 --www.21eda.com --??LED???LED??????0??????1??? --????????21EDA???????? LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY LEDA_blog is PORT( clk:in STD_LOGIC; --System Clk --???? led1:out STD_LOGIC_VECTOR(3 DOWNTO 0); LCD_N : out std_logic; --?????? LCD_P : out std_logic ); --LED output???8? END LEDA_blog ; ARCHITECTURE light_blog OF LEDA_blog IS SIGNAL clk1:std_logic := ‘0’; SIGNAL CLK2:std_logic := ‘0’; BEGIN LCD_N<='0'; LCD_P<='0'; P1:PROCESS (clk) VARIABLE count:INTEGER RANGE 0 TO 9999999; BEGIN IF clk'EVENT AND clk='1' THEN --????????????????? IF count<=4999999 THEN clk1<='0'; --?count<=499999?divls=0??count?1 count:=count+1; ELSIF count>=4999999 AND count<=9999999 THEN --?ount>=499999 ?count<=999998 clk1<='1'; -- count:=count+1; --clk1=1??count?1 ELSE count:=0; --?count>=499999???count1 END IF; END IF; END PROCESS ; P3:PROCESS(CLK1) Begin IF clk1'event AND clk1='1'THEN clk2<=not clk2; END IF; END PROCESS P3; --------------------------------------------------------- P2:PROCESS(clk2) variable count1:INTEGER RANGE 0 TO 16; --???????????? BEGIN -- IF clk2'event AND clk2='1'THEN --????????????????? if count1<=4 then --?COUNT1<=9??????? if count1=4 then --?COUNT1=8??COUNT1?? count1:=0; -- end if; -- CASE count1 IS --CASE?????LED1?? WHEN 0=>led1<="1110"; --????????? WHEN 1=>led1<="1101"; -- WHEN 2=>led1<="1011"; -- WHEN 3=>led1<="0111"; -- WHEN OTHERS=>led1<="1111"; END CASE; count1:=count1+1; end if; end if; end process; END light_blog;

Estas modificaciones no afectan de forma sustancial el comportamiento del sistema. De hecho, si volvemos a implementar este código modificado en el hardware que expliqué en las doce primeras entradas (el kit Open3S250E) veremos que
funciona exactamente igual.

No es raro que no se haya cambiado esencialmente el algoritmo a implementar, porque lo único que hemos hecho es inicializar las señales clk1 y clk2 a ‘0’. También las podíamos haber inicializado a ‘1’ sin ningún problema. La cuestión es inicializar esas señales a un valor cero o uno (son de tipo std_logic que ya vimos es un tipo de dato para bits 0 o 1).


Ahora activamos el casillero de Simulation (configurado para simular con “isim”), justo dónde señala la flecha roja en la siguiente imagen:



A continuación nos queda:




En la anterior interfaz surgido de activar el casillero Simulation (con Isin), se hace doble clic en dónde señalo en la figura siguiente:



Nos surge una nueva ventana llamada Isim, que forma parte del paquete software de XILINX, con la siguiente apariencia. 



A continuación ponemos el cursor dónde señalo a continuación:



Con el cursor en clk, hacemos clic derecho en el ratón:


Ya vemos que surge un desplegable, en dicho desplegable hacemos clic en “Force Clock...”.



Aparece una ventana emergente con el nombre “Define Clock”.



Esta ventana emergente rellenamos tres campos como explicaré a continuación (los demás se dejan igual o en blanco):


Para explicar el porque de estos valores que damos a estos parámetros usare la siguiente figura (una imagen vale más que mil palabras).

Leading Edge Value: 0

Trailing Edge Value: 1

Period: 20ns

Es decir, es así como se inicia el periodo de reloj.

Una vez iniciado el reloj, sigue el tren de pulsos que suelen ser las señales de reloj:


El periodo lo hemos puesto a 20ns porque (como ya vimos) la señal de reloj de clk tiene una frecuencia de 50 MHz, o sea  fclk = 50 MHz. Por tanto:


Periodo = Tclk = 1/ fclk = 20 ns


Sin embargo si lo hubiéramos iniciado como sigue:

Leading Edge Value: 1

Trailing Edge Value: 0

Period: 20ns

Tendríamos: 



y por tanto la señal de reloj:


Ahora clic en OK.


Y tenemos:


---------------------------------------------------------------------------------

Inciso:

Antes de seguir con el proceso de simulación tengamos en cuenta como realiza el proceso de simulación (pre-síntesis) el software.

Si no lo viste en su momento, ahora sería bueno que vieses los conceptos de sentencias concurrentes y las diferencias entre señal y variable (que más adelante nos vendrá bien conocer) que describí en esta entrada:


Si por cuestiones de tiempo o lo que sea, estás más interesado en el “como simular” que en el “ como el software simula”, puedes saltarte estas explicaciones.

Tenemos que tener en cuenta que un PC – en principio- trabaja con las instrucciones o sentencias de forma secuencial y no concurrente, y en cualquier caso el procesador de un PC no trabaja como un sistema digital.

Sin embargo la simulación se hace en el PC, es por ello que básicamente lo que hace el software de XILINX es convertir cada sentencia concurrente a su proceso secuencial equivalente. Luego se simula todos esos procesos concurrentes entre sí.

Como el algoritmo se diseñó con procesos, en este caso la simulación se facilita. 

--------------------------------------------------------------------------------------------------------------------------

Una vez hecho este inciso, seguimos con el tutorial.

Para que podamos ver el resultado de la simulación en forma de cronograma mejor hacer lo que voy a explicar:

Clic derecho del ratón en la pestaña que señalo a continuación:


Clic en float:




Ahora tenemos el visor de cronogramas a pantalla completa:


Si quisiéramos colocar el cronograma en su situación original, bastaría con hacer clic derecho en la pestaña ya mencionada y hacer clic en “Dock”.



Como vimos que no vamos a considerar ni LCD_N ni LCD_P, podemos eliminarlos del cronograma como sigue:

Clic en LCD_N clic en botón derecho del ratón:


Clic en “Delete”.


Lo mismo con LCD_P  y ya tenemos:


 

Dónde aparece como valor (Value) la letra ‘U’ (y los cronogramas aún no simulados en naranja) significa “Undefined” o indefinido en inglés. Lo que está en verde, si está definido, pues lo inicializamos a cero.

Aun nos aparece como “U” (indefinido) la señal clk, calm-down, en cuanto simulemos eso se arregla.

Ahora podemos dar un rango de tiempo a la simulación (de tiempo del proceso a implementar, no el tiempo de la simulación ojo).


Para ello vamos a el campo que señalo y escribimos 2 segundos por ejemplo (por defecto está puesto a 1.00us, muy poco en este caso).





A continuación se pulsa el icono “Run for the specified on toolbar”:


--------------------------------------------------------------------------------------------------------------------------

Nota:

Existe otra opción para simular.

También se podría haber hecho pulsando el icono “Run All”, para simular sin rango de tiempo establecido.


--------------------------------------------------------------------------------------------------------------------------

 Pero lo haremos con “Run for the specified on toolbar”  para que podamos sacar más partido a las potencialidades del ISim.

Una vez que hemos empezado la simulación puedes observar que el cronograma aparece intermitente. Esto es porque la pantalla avanza en el tiempo más rápido que la simulación. De manera que en muchos momentos no vemos los cronogramas (esto no sucede con la opción “Run All”).


Para resolver esto, sin ni siquiera parando la simulación, hacemos como sigue:














Con lo que tenemos ahora:


Si queremos parar la simulación basta con dar al icono:

Y si queremos reanudar:



Además, podemos mejorar la visualización alejando (Zoom Out) o acercando (Zoom In) la imagen de los cronogramas, tanto en simulación como en pausa. 

Para ello tenemos dos iconos justo a la izquierda de la ventana de cronogramas y encima del icono “Zoom to full view”:















Así pues, si partimos de:



Pulsando varias veces el icono de “Zoom out”  se tiene:



Resultado que por cierto encaja bastante bien con lo que habíamos descifrado del código VHDL en la entrada anterior.

Hay, sin embargo un par de detalles que destacan de la última figura y que aún no hemos abordado.

El primero es que hasta los 100 ms (una décima de segundo), la señal de los LEDs aparece como indefinida. Esto no es tan extraño si consideramos que led1 es una señal, y tal y como abordamos en la segunda parte de la entrada:


(que trataba de la diferencia entre variables y señales y abordaba especialmente la cuestión de las señales), cuando hacemos una asignación a señal realmente estamos dándole un valor futuro (para el siguiente instante de tiempo en que vuelva a ejecutarse), tomando la señal el valor actual (anteriormente asignado).

Como el vector de bits led1 no se inicializa, por defecto empieza con el “valor” indefinido (o Undefined, de ahí la U y el correspondiente color anaranjado), hasta que pasados los 100 ms se hace vigente el valor anteriormente asignado.

La segundo cuestión es el cursor en forma de línea vertical amarilla.


Si mantenemos pulsado dicho cursor no sólo podemos ir desplazándonos por la señal simulada, además nos marcará el valor de las señales dónde este situado en cada momento, así como el instante de tiempo dónde está situado en los cronogramas.

Vamos a hacer una prueba de su utilidad, en el anterior post a este (el que explicaba el algoritmo VHDL del código LEDA_blog), calculamos que el periodo de la señal clk2 era 0,4 segundos o 400 milisegundos. Veamos si el calculo era correcto.




Al principio de periodo (en el primer flanco de subida), tenemos el tiempo de 100 ms.

Al final del periodo (en el segundo flanco de subida), tenemos el tiempo de 500 ms.
Luego:

Tclk2 = 500 ms – 100 ms = 400 ms = 0,4 ms.

Luego el resultado del periodo que predijimos para Tclk2, Tclk2 = 0,4 ms, era correcto.

Además en el la siguiente figura del cronograma resultante de la simulación se oserva que se cumple la secuencia esperada de 0s y 1s del vector de bits led1.



Como ya comentamos al principio de esta entrada del blog, hay otras formas de simular, incluso en colaboración con otras aplicaciones como el SIMULINK de MATLAB por ejemplo.

Lo abordaremos en próximas entradas.

Nota final: si queremos volver a iniciar todo el proceso, en la ventana de cronogramas pulsamos en el icono: 



Tras lo cual volveríamos con el proceso de "Force Clock..." etc.

0 comentarios: