viernes, 29 de agosto de 2014

Tutorial FPGA en VHDL: Parte 3, Encoder de prioridad

Saludos. Continuando con el tutorial de VHDL vamos a implementar encoder de prioridad, con el objetivo de utilizar la condición "when-else".

Programa a realizar

El encoder de prioridad a implementar debe cumplir con la siguiente tabla de verdad:


Por lo tanto tenemos un vector "r" de ingreso con 4 bits, y un vector "pcode" de salida con 3 bits.


Plataforma de desarrollo

En este caso utilizaremos el Spartan-3E de Digilent

Figura 1.  Spartan 3E Starter Board

A diferencia del Elbert y la Basys2, la Spartan-3E es una placa muy potente, y con varios periféricos disponibles como:

  • Puerto VGA
  • Puerto PS2
  • 2 puertos RS-232
  • Puerto Ethernet
  • LDC alfanumérico
  • Pulsantes, switches, y encoder
  • Y quizá la mejor ventaja: Es programable desde LabView (sólo la versión de 500k)
Las desventajas de esta placa son las siguientes:

  • Precio elevado ($299 sin envío)
  • El código del microcontrolador no es abierto
  • El diseño es de una complejidad elevada.  Con esto hago referencia al diseño de la placa en si, es decir, utiliza memorias, circuitos integrados, y conversores CD-CD que no son de fácil adquisición para el aficionado común.  Lo contrario ocurre con la placa Elbert, pues los dispositivos utilizados se pueden comprar con facilidad en internet.
  • Aunque la programación en LabView sea una ventaja significativa, esto implica costos elevados pues la licencia de LabView FPGA no es gratuita.
Al realizar la programación en ISE debemos seleccionar el IC XC3S500E con empaquetado FG320, o directamente la placa de desarrollo Spartan-3E Starter Board (fig.2).

Figura 2. Selección de la Spartan-3E Starter Board

Programación en VHDL

La programación se basará en la utilización de "when-else", es decir, "cuando" se tenga un valor se realiza una actividad, "caso contrario" se realiza otra actividad.  El código en VHDL es el siguiente:
Analizando el código por partes:


  1. De igual manera que en los casos anteriores se utiliza la librería ieee por defecto, se declaran los puertos de entrada ("r" como vector de ingreso de 4 bits y "pcode" como vector de salida de 3 bits).
  2. Se inicia la arquitectura y se realiza la programación requerida para actualizar el vector de salida.  Como se observa (al utilizar pcode<="100" when (r(4)='1') else...) se le da el valor requerido de la tabla de verdad cuando se da la condición asignada, en este caso, al ser un decodificador de prioridad, actualizará sus salidas únicamente cuando el bit más significativo del vector de ingreso así lo indique.  Si observamos con detalle la tabla de verdad, nos daremos cuenta que los bits más significativos son los que dictan el funcionamiento del encoder, los otros bits son "condiciones no importa".
Simulación

Al igual que en la entrada anterior, debemos crear un archivo "test bench" para hacer la simulación.  El código para dicha simulación es el siguiente:


Como podemos observar, se crea la entidad de simulación, y se le da valores al vector de entrada "r".  Si todo se compila adecuadamente, la simulación será la mostrada en la figura 3.


Figura 3. Simulación del encoder de prioridad

Conexión del hardware

En el caso de la Spartan-3E Starter Board, se tiene soporte directo en el software de Xilinx, es decir, que al contrario de la Basys2 y del Elbert, no se requiere un software de otro propietario.  Así, después de compilar el programa y generar el archivo de programación (como se vió en el tutorial anterior) hacemos doble click en "Configure Target Device" (fig. 4).

Figura 4.  Configuración de dispositivo

Se abrirá la ventana del "ISE iMPACT".  iMPACT nos permite programar un FPGA de Xilinx si disponemos del cable de programación del fabricante, el cual puede ser un cable JTAG o el programador incluido en las placas del desarrollo (el microcontrolador).  Para esto primero tenemos que hacer que el software reconozca la placa de desarrollo haciendo doble click en "Boundary Scan", luego hacemos click derecho en la parte derecha de la pantalla donde dice "Right click to Add..." y seleccionamos "Initialize Chain" (fig. 5).

Figura 5.  Inicialización de la cadena JTAG

Si todo sale bien, el programa nos pedirá cargar el archivo de configuración, para lo cual podemos seleccionar "No" si queremos hacerlo independientemente en cada dispositivo en la cadena JTAG, o "Si" si queremos cargar los archivos con ayuda del asistente.  En todo caso, la cadena JTAG debe mostrarse como en la figura 6.

Figura 6.  Cadena JTAG de la placa de desarrollo utilizada

Podemos hacer click derecho en cada uno de los dispositivos y cargar el archivo de configuración requerido.  Debemos tener en cuenta que si cargamos la configuración en el FPGA, el programa funcionará hasta que apaguemos la fuente de poder de la placa (memoria volátil), y en el caso de cargar la configuración en la memoria PROM (xcf04s) el programa se mantendrá luego de quitar la alimentación.  En el caso de esta placa en particular, se pueden cargar archivos de configuración en una memoria SPI/BPI, la memoria PROM y en un CPLD (xc2c64a), pero esto lo analizaremos en otra ocasión.  Además, como esta placa la tengo desde hace años, y he hecho varias pruebas con ella, no puedo asegurar la posición original de los jumpers de configuración, los cuales están ubicados en la parte superior derecha de la placa (fig. 7).
 Figura 7.  Ubicación de los jumpers de configuración

Para este tutorial, he cargado la configuración en el FPGA con el objetivo de mantener el programa de fábrica funcionando, y además tengo los jumpers configurados de la siguiente manera:

Figura 8.  Configuración de jumpers para el tutorial

Con esto podremos ver los leds de la placa de desarrollo cumplir con la tabla de verdad (fig. 9).

Figura 9.  Leds y pulsantes de la placa

Es todo por esta entrega, espero que la información les sea de utilidad.  Hasta la próxima.