Dic 22

Hello World. Hello FPGA – Parte I: Toma de contacto con FPGAs

Las FPGAs aparecieron a mediados de los 80 [Trimberger2015] y desde entonces desarrollan un papel relevante en la industria de los semiconductores, junto con microprocesadores, procesadores gráficos y circuitos específicos ASIC. Yo las descubrí en 1996 y no he conseguido desengancharme. Con esta entrada pretendo hacer una introducción a estos dispositivos; tan solo unas pinceladas que sirvan como primera toma de contacto con esta tecnología.

¿Qué es una FPGA?

Los dispositivos FPGA (Field-programmable gate arrays) son circuitos integrados que permiten implementar circuitos digitales. La capacidad de estos dispositivos varía desde cientos de puertas lógicas hasta millones. El diseñador puede configurar la funcionalidad de cientos/millones de bloques lógicos (por ello lo de gate array) así como su interconexión, y esta configuración se puede hacer después de haber fabricado el chip (por ello lo de field-programmable: programable in situ).

Podemos decir que la FPGA está compuesta por una red de memorias que albergan escasos bits. Estas memorias se denominan LUTs (look-up table: tabla de consulta) y permiten implementar funciones lógicas.

Veamos un ejemplo. En la figura se ve una puerta AND con la tabla de verdad que relaciona  sus entradas (a y b) con su salida (c).

Figura. Puerta AND y su tabla de verdad

Las señales a y b son las entradas a la puerta y la señal de salida es c. Se observa como c solamente está activa (‘1’) cuando ambas entradas están a ‘1’.

Otras puertas lógicas de 2 entradas necesitarían tablas similares, es decir, tablas con 4 filas y 3 columnas. De hecho, cualquier función lógica de 2 entradas podría expresarse mediante una tabla del estilo. Estas tablas de verdad son la esencia de las FPGAs, puesto que se implementan directamente como memoria RAM y pasan a ser los bloques lógicos que mencioné antes. De manera que llenando un circuito integrado de pequeñas memorias podemos implementar gran cantidad de funciones lógicas. Nótese que no estoy hablando de usar puertas lógicas, sino memorias. De hecho, y siento ponerme pesado, las puertas lógicas o la combinación de varias puertas se implementan en una FPGA con una memoria. La matriz de puertas (gate array) que forma parte del nombre de las FPGAs es en realidad una matriz de memorias (¿memory array?). De hecho el nombre que utilizaron para la primera FPGA, el dispositivo XC2064 de Xilinx era “matriz de celdas lógicas” (Logic Cell Array, en inglés), pero luego se implantó el termino FPGA introducido por Actel [Trimberger2015].

La tabla del ejemplo anterior se convertiría en la siguiente memoria de 4 bits:

Tabla: Interpretación de la tabla de verdad como una memoria

Las señales a y b concatenadas pasan a ser el bus de direcciones y la señal c es el bus de datos. Si a y b valen 1, realmente lo que ocurren es que se leería la posición de la memoria que ocpua la posición 3 (112=3 – leer entrada sobre binario). Ahora tan solo (es un decir) nos quedaría idear un método para poder escribir en muchas LUTs – para disponer de muchas funciones lógicas-, además de disponer de canales de rutado que nos permitieran interconectar dichas LUTs, y también, idear un método para configurar las conectividad de dichos canales. Ahí es ná.

En la figura aparece un esquema de la arquitectura de una FPGA. Los bloques lógicos contienen la funcionalidad y procesan señales que provienen del exterior (señales de entrada y salida (E/S)) o de otros bloques lógicos. Las señales E/S están conectadas a las patillas o pines del chip. Los bloques lógicos producen señales binarias que se conectan a otros bloques lógicos o a las señales de salida. Los canales de rutado se configuran para que se produzca la interconexión entre bloques lógicos y señales de E/S. Obviamos los detalles con la intención únicamente de introducir la tecnología.

Figura: Esquema de arquitectura interna de FPGA (modificación de https://commons.wikimedia.org/wiki/File:Fpga_structure.svg  )

Hay que destacar que el bloque lógico además de la LUT dispone de otros elementos lógicos básicos como puertas lógicas, multiplexores y de un biestable de tipo flip-flop (memoria de un bit), que ya veremos en próximas entradas en las que revisaré la arquitectura de varias FPGAs. Comentar que las FPGAs tienen LUTs con entre 4 y 6 entradas (la LUT de dos entradas era sólo un ejemplo con el que comenzar) dando lugar a funciones lógicas de entre 4 y 6 entradas. Con esto vemos que la FPGA puede implementar circuitos tanto combinacionales como secuenciales -debido a los flip-flops – y, en general, de gran capacidad.

Afortunadamente, el paso de las ecuaciones lógicas a la distribución entre bloques lógicos y su interconexión la realiza una herramienta de ayuda al diseño electrónico, o herramienta EDA (Electronic Design Automation).

Como veis, el proceso difiere bastante del desarrollo software. Para simplificar, algunos fabricantes (como Altera Inc.) utilizan el termino compilación para englobar las fases necesarias para ir de la idea (esquema lógico) a la implementación (FPGA configurada). La diferencia principal es que el tiempo de compilación puede llevar entre varios minutos y varias horas, incluso para diseños relativamente sencillos. El motivo es que hay que tomar muchas más decisiones que las que toma un compilador software.

Un tema espinoso es que la configuración de la FPGA se denomina programación y esto puede dar pie a confusión. Se utiliza programación de igual manera que a la escritura de los datos en una memoria PROM (programable read-only memory: memoria programable de sólo lectura). Esto tiene sentido en el caso de la PROM puesto que lo que se suele almacenar en estas memorias es un programa. Sin embargo, lo que almacenamos en la FPGA es la información lógica de las LUTs y los bits que configuran la interconexión. Yo prefiero decir que las FPGAs se configuran en lugar de que se programan para evitar que se asocie a sistemas software.

En la siguiente figura se ve cómo se distribuyen las LUTs en una FPGA concreta de la familia Cyclone IV de Altera. Cómo se observa, hay un gran número de memorias LUT.  Por ejemplo, dispositivos de la familia Virtex-6 de Xilinx tienen entre 46,000 y 354,000 LUTs. Con esta cantidad de LUTs se pueden hacer muchas cositas.

Figura. Esquema de la distribución de LUTs en dispositivo de la Familia Cyclone IV de Intel FPGA (Altera)

Microprocesador, ASIC y FPGA

Veamos brevemente la diferencia entre estos circuitos integrados:

  • Microprocesador: Circuito integrado que implementa una CPU y los bloques hardware necesarios para la transferencia de datos con la memoria y con los periféricos. Se diseñan para dar soporte a gran cantidad de aplicaciones, por lo que son circuitos costosos y consumen gran cantidad de potencia eléctrica. El punto fuerte del microprocesador es precisamente el hecho de que puedan ejecutar gran cantidad de aplicaciones de forma bastante eficiente. Hay que considerar que los errores en el diseño del microprocesador no se pueden corregir a posteriori al no poderse modificar la estructura del circuito integrado.

Esto último tiene su importancia (mucha). Recordemos el fallo en la división del microprocesador Pentium de Intel descubierto por el profesor Thomas Nicely en 1995 [Cipra1995]. Se “solucionaba” con un parche software que ejecutaba la operación muy lento al ser una emulación software. O más recientemente, las vulnerabilidades tipo Spectre  que afectan a microprocesadores de Intel, IBM y ARM, que de nuevo se solucionan reduciendo el rendimiento del sistema. Todo porque el fallo es hardware y no puede modificarse.

Podríamos decir que el microprocesador realiza continuamente tres tareas básicas:

  1. Lee una instrucción de una memoria (que contiene el programa)
  2. Interpreta la operación
  3. Ejecuta la operación (probablemente leyendo datos de memoria y escribiendo los resultados en memoria)

Tras ejecutar la tarea 3, vuelve a comenzar leyendo la siguiente instrucción (que suele estar en la posición siguiente con respecto a la anterior instrucción leída). El programador trabaja modifica el programa que está en la memoria para realizar cambios en la aplicación. Le es imposible modificar el hardware.

  • ASIC: Estas siglas provienen de Application-Specific Integrated Circuits, es decir, circuito integrado de aplicación específica. Es un circuito integrado que implementa un circuito que ha sido optimizado para una tarea concreta. Está en las antípodas del microprocesador. Al disponer de una arquitectura optimizada se puede optar por reducir al máximo los recursos (número de transistores y consumo de potencia eléctrica) o bien maximizar su potencia de cálculo (sin miramiento en el número de transistores). De nuevo, cualquier fallo en el diseño hardware es fatal suponiendo grandes pérdidas de dinero. Un ejemplo claro de ASIC sería circuitos que implementan procesamiento intensivo en tiempo real: Wi-fi, reconocimiento de imágenes, etc.
  • FPGA: La FPGA es similar al ASIC puesto que permite implementar circuitos optimizados para tareas específicas. La gran ventaja es que si se detectan errores una vez ha salido el producto al mercado, es posible corregirlos, de forma muy similar a como se actualiza el firmware de muchos equipos. En este caso, lo que se modifica es la secuencia de configuración de la FPGA que ésta carga siempre tras el arranque. La pega que tienen estos dispositivos es que el coste a pagar para conseguir la capacidad de reconfiguración es que se utilizan muchos recursos. La FPGA es más lenta que el ASIC y consume más que este. Para determinadas aplicaciones, es mucho más rápida que un microprocesador y consume mucho menos.

Si nos fijamos en la velocidad de los relojes que consiguen las FPGAs, hace una década rondaban los 200 MHz y en la actualidad rondan los 400 MHz (los fabricantes os dirán que es mucho más; es fácil hablar, lo difícil es diseñar sistemas). Con estas velocidades de reloj podríamos pensar que una FPGA no puede competir con una CPU que corre a varios Gigahertzios. La clave está en el paralelismo y en la posibilidad de adecuar de forma óptima (según el arte del diseñador) los diseños a una aplicación específica. Supongamos un reloj de 200 Mhz y una aplicación que debe realizar 10 multiplicaciones de enteros de 16 bits por cada dato de entrada. Si el algoritmo permite realizar las 10 multiplicaciones en paralelo, y si la FPGA permite que se implementen 10 multiplicadores, se podrán realizar 10x200e6 = 2e9 multiplicaciones por segundo. Pronto os hablaré de algún diseño propio en el que se consigue ir 10000 veces más rápido que un microprocesador i7.

Termino diciendo que cada tecnología tiene su nicho, su punto óptimo. Hay que considerar que la FPGA requiere tiempos de desarrollo altos y que no siempre es posible paralelizar.


Aquí descanso con la intención de continuar la entrada con varias partes. En la siguiente entrada veremos las etapas del flujo de diseño con FPGA a través de un sencillo ejemplo.

Mientras tanto os dejo algunos enlaces de interés:

“FPGA for Dummies”: https://plan.seek.intel.com/PSG_WW_NC_LPCD_FR_2018_FPGAforDummiesbook

Intel FPGAs: https://www.intel.com/content/www/us/en/products/programmable/fpga.html

Xilinx: https://www.xilinx.com/products/silicon-devices/fpga.html

Lattice: https://www.latticesemi.com/Products#_D5A173024E414501B36997F26E842A31

 

Referencias

[Trimberger2015] “Three Ages of FPGAs: A Retrospective on the First Thirty Years of FPGA Technology”, Proceedings of the IEEE, 2015

[Cipra1995] “How Number Theory Got the Best of the Pentium Chip “, Barry Cipra, Science, 1995 [pdf]

 

 

Deja un comentario

Your email address will not be published.

Bitnami