LABORATORIO DE ESTRUCTURA DE COMPUTADORES PRÁCTICA 0: Utilización de la herramienta ModelSim Los objetivos de esta práctica son que el alumno conozca la estructura básica de un programa escrito en un lenguaje de descripción de hardware, en concreto VHDL, y se familiarice con el entorno de trabajo que se va a utilizar durante el primer cuatrimestre de la asignatura, la herramienta ModelSim. Un circuito escrito en VHDL consta básicamente de una entidad y de una o más arquitecturas. La entidad indica el número, nombre y anchura de cada uno de los puertos de entrada y de salida del circuito. Y la arquitectura recoge el funcionamiento del circuito, es decir, cómo se propagan los valores de las entradas del sistema para generar las salidas del mismo. Como ejemplo vamos a considerar el sumador completo de 1 bit, que consta de 3 puertos de entrada: los 2 valores que se desean sumar (llamados en la figura a y b) y al acarreo de entrada (cin), y 2 puertos de salida: el resultado de la suma (sum) y el acarreo de salida (cout). La Figura 1 muestra la entidad correspondiente al sumador de 1 bit. Como puede observarse todas las señales son del tipo de datos std_logic, lo que significa que únicamente pueden tomar los valores 0 ó 1. a cout entity adder is port (a : b : cin : sum : cout : end adder; b +1 cin sum in std_logic; in std_logic; in std_logic; out std_logic; out std_logic); Figura 1. Sumador completo de 1 bit y su entidad correspondiente en lenguaje VHDL. La figura 2 muestra un posible diseño del sumador de 1 bit compuesto de 1 puerta or, 2 puertas and y 2 puertas xor, y su correspondiente arquitectura. a b cout cin architecture rtl of adder is begin sum <= (a xor b) xor cin; cout <= (a and b) or ((a xor b) and cin); end rtl; sum Figura 2. Diseño del sumador de 1 bit y su arquitectura correspondiente en lenguaje VHDL. Comprobaremos ahora que el diseño realizado es correcto, para ello vamos a simularlo utilizando la herramienta ModelSim (dentro de electrónica). Al abrir la herramienta nos encontraremos con la siguiente pantalla: El siguiente paso será crea el proyecto sobre el cual vamos a añadir un fichero VHDL en el cual escribiremos el código a simular: Al pulsar sobre Project aparece la pantalla superior. Indicar el nombre del proyecto (p0 por ejemplo); la carpeta donde se guarda el proyecto (C:/local) y la biblioteca donde guardaremos los componentes (work). Una vez creado el proyecto podemos crear al archivo VHDL pulsando sobre “Create New File”. Llamaremos al archivo VHDL sumador, debemos asegurarnos que el tipo del archivo es VHDL. A continuación escribimos el código correspondiente al sumador de 1 bit, utilizando el editor de textos que ha aparecido. El código completo que debe figurar en dicho fichero es el siguiente: ------------------------------------------------------------------ sumador de 1 bit ----------------------------------------------------------------library IEEE; use IEEE.std_logic_1164.all; entity adder is port (a : in std_logic; b : in std_logic; cin : in std_logic; sum : out std_logic; cout : out std_logic); end adder; -- descripcion del sumador mediante sentencias concurrentes architecture rtl of adder is begin sum <= (a xor b) xor cin; cout <= (a and b) or ((a xor b) and cin); end rtl; Una vez guardado realizaremos la compilación (Compile -> Compile Selected) y comprobaremos que no tiene ningún error. A continuación realizaremos la simulación pulsando Simulate Una vez compilada la práctica y comprobado que no tienen errores podemos simular el sumador de 1 bit que hemos diseñado. Pulsamos el botón SIMULATE (situado junto a COMPILE) y seleccionamos la entidad y arquitectura a simular (en nuestro ejemplo son adder y rtl) y pulsamos OK. Tras esta orden han aparecido las siguientes ventanas: Primero nos tenemos que asegurar que las señales de nuestro diseño se encuentran en la ventana wave, para eso colocamos el cursor sobre la ventana instance encima de “adder” y pulsamos al botón derecho. Add -> Add to Wave: Para poder simular nuestro diseño hay que aplicar estímulos a las señales de entrada. Esto se puede hacer si se ha creado un banco de pruebas o mediante la orden force. Por ejemplo daremos a la señal a el valor 0 en el instante inicial (0 ns) y el 1 en el instante 50 ns, escribimos para ello la siguiente orden en la pantalla Transcript: force a 0 0, 1 50 Si queremos que además se repita esta orden cada 100 ns utilizaremos la orden: force a 0 0, 1 50 –repeat 100 Para probar nuestro diseño con todos los casos posibles podemos utilizar el reloj por defecto pero con distintas frecuencias que crea automáticamente ModelSim. Para eso hay que colocar el cursor sobre cada una de las señales de entrada dentro de la ventana wave. Para realizar la simulación Simulate -> Run all Banco de pruebas Los bancos de pruebas se utilizan para comprobar el funcionamiento de un diseño, por tanto son una alternativa a los comandos force y run. Constan de una entidad vacía y una arquitectura en la que se dan valores a las señales de entrada del circuito que se desea probar. A continuación se presenta un banco de pruebas para el sumador de 1 bit. entity prueba is end prueba; architecture pru1 of prueba is component adder port (a : in std_logic; b : in std_logic; cin : in std_logic; sum : out std_logic; cout : out std_logic); end component; signal x,y,ci,z,co: std_logic; begin a1: adder port map(x, y, ci, z, co); x<='0', '1' after y<='0', '1' after '0' after '1' after ci <= '0'; 100 ns; 50ns, 100ns, 150ns; end pru1; Para utilizar este banco de pruebas éste debe compilarse primero, y a continuación simular la arquitectura pru1 de la entidad prueba. Realizando todos los pasos anteriores, aunque se puede añadir directamente al proyecto desde el botón File. Una vez compilado el banco de pruebas, se puede simular directamente añadiendo las señales a wave y pulsando run all Diseño de sumador de N bits El siguiente código corresponde al diseño de un sumador de 4 bits. Comprueba su funcionamiento simulándolo utilizando las órdenes force y run, y mediante un banco de pruebas. entity adder4 is port (a : b : cin : sum : cout : end adder4; in std_logic_vector(4 downto 1); in std_logic_vector(4 downto 1); in std_logic; out std_logic_vector(4 downto 1); out std_logic); -- implementación de comportamiendo del sumador de 4 bits architecture behavioral of adder4 is begin p1: process(a, b, cin) variable vsum : std_logic_vector(4 downto 1); variable carry : std_logic; begin carry := cin; for i in 1 to 4 loop vsum(i) := (a(i) xor b(i)) xor carry; carry := (a(i) and b(i)) or (carry and (a(i) or b(i))); end loop; sum <= vsum; cout <= carry; end process p1; end behavioral; Diseño de un sumador de N bits concurrente El diseño anterior sólo utiliza variables, sin embargo, un diseño mas real debería utilizar sólo cables (señales (signal)). Variar el código VHDL para conseguir un sumador. Nota: el loop con señales se escribe: for i in 1 to 4 generate … end generate;