viernes, 19 de agosto de 2016

6. Programando un FPGA de Altera

Hasta el momento, solo hemos visto simulaciones de los diseños que estamos realizando. Antes de proseguir con otros sistemas digitales, es necesario aprender a llevar nuestros diseños a un CPLD o FPGA real. Es decir, ha llegado el momento de jugar...

Para la presente entrada, y para las siguientes, a menos que indique otra cosa, los diseños se probarán sobre la tarjeta de desarrollo de Altera Modelo DE1-SoC. Esta tarjeta cuenta como core a un FPGA de la Familia Cyclone V, y además, como si ya no fuera suficiente, cuenta con un Procesador ARM Cortex A9.
Tarjeta de Desarrollo DE1-SoC. (Fuente:Terasic)
Y cómo hago para programar un FPGA? Bueno, el procedimiento es muy sencillo, y si no me creen, esperan a verlo a continuación.

Programando nuestro primer FPGA

La tarjeta de desarrollo DE1-SoC viene con un set de 10 switches (SW), y un set de 10 Leds (LEDR).

La idea del primer programa que elaboraremos será mapear es estado de los 10 switches en los 10 Leds.

Empecemos por el código VHDL para este sencillo ejemplo.
library ieee;

use ieee.std_logic_1164.all;

entity puertos is
port(
sws :in std_logic_vector(9 downto 0);
leds :out std_logic_vector(9 downto 0));
end puertos;

architecture arch of puertos is
begin
leds<=sws;
end;

Como se puede apreciar, el código consiste en asignar al vector leds el estado del vector sws. Al guardar el fichero creado, Quartus II nos consultará si deseamos crear un proyecto con este fichero. En este caso, le diremos que Sí (este es otro modo de iniciar un proyecto en Quartus II).

Esto arrancará el asistente para la creación de un proyecto, que es el mismo que vimos en entradas anteriores. Definimos una ruta donde se guardarán los archivos del proyecto, el Nombre del proyecto y el fichero .vhd de mayor jerarquía. Para nuestro caso, el nombre del proyecto será Test1 y el fichero .vhd de mayor jerarquía el que acabamos de crear, es decir, puertos.vhd.

Iniciando la creación de nuestro proyecto.
Damos click a Next, y seleccionamos Add All, para añadir el fichero que hemos creado al proyecto.

Incorporando nuestro fichero de diseño.
Damos click en Next, para llegar a un punto importante: Family & Device Settings [page 3 of 5]. En esta ventana seleccionaremos a la tarjeta de desarrollo en la que grabaremos nuestro diseño. Para el caso de la tarjeta de desarrollo, el FPGA es un Cyclone V, con Nombre 5CSEMA5F31C6. Este nombre se puede encontrar sobre la superficie del FPGA, justo debajo del logo de Cyclone.

Ubicación del nombre del FPGA.
Aplicando el filtro, seleccionamos del dispositivo disponible.

Seleccionando nuestro FPGA.
Hecho ello, hacemos click en Finish.

Bueno, si bien el paso anterior es importante, en caso de que no se disponga del nombre del FPGA y se defina luego de diseñado y testeado el sistema, siempre es posible realizar la selección del FPGA, acudiendo para ello a la Opción Device del Menú de Assignments, ubicado en la barra de herramientas de Quartus II. Esto es aplicable si se desea grabar un sistema en distintos FPGAs o CPLDs.

Device, para seleccionar el dispositivo embebido que se empleará.

Bueno, al momento ya estamos a mitad de camino. A continuación procederemos a verificar nuestro diseño. Para ello, hacemos click en Start Analysis & Synthesis. Esta opción permitirá verificar si hay algún error en nuestor código. Bueno, en nuestro caso, al final del proceso, obtenemos que no hay ni errores ni advertencias (eso es bueno).

0 errors, 0 warnings. La idea es ver este mensaje cada que acabemos un diseño.

Para esta entrada, nos saltearemos la simulación, pero ustedes son libres de realizarla siguiendo los pasos descritos en la entrada 4. Primer Ejemplo y Simulación empleando archivos .VWF.

El siguiente paso es realizar la asignación de pines. Es decir, decirle a Quartus II qué pines se corresponderán con el vector leds y que otros con el vector sws.

Para ello, ingresaremos a la opción Pin Planner del Menu Assignments de la barra de herramientas.

Seleccionando Pin Planner.
Se abrirá una ventana en la que veremos, en la parte inferior, los puertos definidos por nuestro diseño, es decir, los puertos del vector sws y los puertos del vector leds.

A mapear se ha dicho.
La idea es hacer click sobre la columan Location, e ir definiendo qué pines del FPGA se asignarán a los puertos de nuestro diseño. Sin embargo, puede resultar tedioso realizar esta asignación de manera manual, además de que la posibilidad de cometer un error es alta (se tendría que buscar el datasheet de la tarjeta DE1-SoC, y ver que puertos del FPGA están conectados con los switches SW y qué puertos están conectados con los leds LEDR, e ir asignando uno a uno).

La alternativa que personalmente empleo para estos casos es realizar la importación de una asignación de pines preestablecida para la tarjeta DE1-SoC. Estos archivos suelen encontrarse en las páginas de recursos de cada tarjeta de desarrollo de Altera. Para nuestro caso, este fichero puede descargarse desde el siguiente link: https://www.altera.com/support/training/university/boards.html#de1-soc (Buscar en Resources la opción Quartus Setting File with Pin Assignments, y descargar el fichero QSF).


Este fichero contiene mapeado todos los pines del FPGA en función de los periféricos conectados a ellos en la tarjeta de desarrollo. Para importar el archivo descargado, nuevamente ingresamos a la opción Assignments, pero esta vez elegiremos Import Assignments.

Importar asignaciones de pines.
En la ventana siguiente seleccionaremos el fichero descargado, e ingresamos Ok.

Seleccionando el fichero qsf.
Si vemos ahora el Pin Planner, encontraremos que casi todos los pines del FPGA están mapeados a un nombre de puerto específico, pero si observamos la columna Direccion, veremos que estos tienen el valor de Unknown, desconocido. Esto, debido a que no existe ninguna entidad en nuestro diseño que emplee puertos con esos nombres.

¿Varios desconocidos?... no se preocupen. Aun vamos por buen camino.
Observando los puertos importados del fichero .qsf descargando, podemos ver que existe un conjunto de rótulos con el nombre de SW[0], SW[1], ... SW[9]. Estos rótulos mapean a los pines del FPGA conectados a los switches SW. Del mismo modo, los rótulos LEDR[0], LEDR[1], ... LEDR[9] mapean los pines del FPGA conectados a los diodos led LEDR. El siguiente paso es modificar nuestro diseño para que los puertos de entrada tengan la etiqueta de vector SW, y el puerto de salida la etiqueda de vector LEDR.

library ieee;

use ieee.std_logic_1164.all;

entity puertos is
port(
SW :in std_logic_vector(9 downto 0);
LEDR :out std_logic_vector(9 downto 0));
end puertos;

architecture arch of puertos is
begin
LEDR<=SW;
end;

Ejecutamos Start Analysis & Synthesis para verificar si el diseño funciona. Hecho esto, volvemos al Pin Planner, pero esta vez veremos que los puertos SW y LEDR ya tienen direcciones. Esto nos indica de que la asignación de los pines del FPGA con los puertos de nuestro diseño se realizó de manera exitosa.

Asignación exitosa.
A continuación, ejecutamos la compilación del proyecto.Al final, Quartus II nos proporcionará el reporte de compilación. Un aspecto importante es verificar el campo Logic Utilization (in ALMs), puesto que este indicador nos dirá cuantos recursos del FPGA requiere nuestro sistema. En este caso, podemos ver que no llega ni a un 1%.

Ni siquiera el 1% de los recursos del FPGA son empleados.

El siguiente paso es programar el FPGA. Para ello, conectamos nuestra tarjeta de desarrollo a un puerto USB de nuestro equipo PC. Si es la primera vez que se conecta una tarjeta de Altera a la PC, necesitaremos instalar los drivers del USB-Blaster. Estos se encuentran en la carpeta de instalación de Quartus II, en la siguiente dirección (que aplica en mi equipo, en la de ustedes puede variar): C:\altera\13.1\quartus\drivers

Una vez cargado los drivers, procederamos a ir al Menú Tools, y elegiremos la opción Programmer.

Arrancando el programador.
En la ventana del programador hacemos click en Hardware Setup. Ello con el objetivo de definir a la Tarjeta DE1-SoC como objetivo para grabar el diseño compilado.

Seleccionando al DE-SoC como hardware.
Nota: Si en este apartado no llegaran a detectar a la tarjeta de desarrollo, deberá revisarse si los drivers del USB-Blaster se instalaron correctamente.

Una vez hecho todo ello, se debe obtener una ventana similar a la mostrada a continuación.

Ya casi está...
Para evitar errores, eliminaremos la cadena de programación. Hacemos click sobre el simbolo de chip que representa nuestro FPGA y hacemos click en Delete. Luego, hacemos click en Auto-Detect, y elegimos, en nuestro caso, la opción 5CSEMA5 (las primeras letras del nombre de nuestro FPGA).


Hacemos click en Ok. Ahora, la cadena de programación se mostrará como en la siguiente figura.

Cadena de programación lista.
Vemos que ahora aparecen dos chips en la cadena de programación. No hay por qué alarmarse. Esto es correcto porque nuestra tarjeta de desarrollo tiene un procesador ARM Cortex A9 además del FPGA. En este caso, el procesador es el chip de nombre SOCVHPS y el FPGA es el chip de nombre 5CSEMA5.

Hacemos click sobre el FPGA, luego hacemos click en Change File. A continuación, buscamos en la carpeta output_files, y cargamos el fichero puertos.sof.

Cargando el fichero para la programación.
Finalmente, marcamos con check la casilla Program/Configure, y finalmente hacemos Click en Start. Al cabo de unos segundos nuestro diseño se habrá cargado en el FPGA de manera exitosa.

A un paso de terminar.


Exito!

En unos días colgaré un link de youtube mostrando al FPGA funcionando con el sistema diseñado.

Bueno, ¿qué opinan? No fue complicado, cierto... El truco es intentarlo... Hasta la siguiente entrada.