Arduino es el proyecto de hardware de código abierto más exitoso de la historia. Desde su aparición hace ya mas de 10 años, son cientos de miles los aficionados a la electrónica que han puesto en marcha proyectos basados en él.

Arduino es un sistema que basa su éxito en la simplicidad. Todo el entorno de desarrollo está pensado para que gente sin ninguna experiencia en desarrollo con microcontroladores pueda desde el principio crear programas sencillos y hacer que funcionen sin complicaciones.

El éxito de Arduino en ese aspecto es también una de sus debilidades. Cuando se necesitan ejecutar procesos que demandan cierta potencia de calculo Arduino se queda bastante corto. La solución en muchas ocasiones es adquirir sistemas Arduino mas complejos como Arduino Mega o incluso una Rapsberry Pi. 

En este tutorial os demostraremos como añadir una potencia de computo mayor a Arduino Uno utilizando para ello una FPGA conectada a través del bus I2C. Nosotros hemos utilizado una FPGA de muy bajo coste de la familia Cyclone II de Altera, pero esto es válido para cualquier otra FPGA de cualquier fabricante.

Con este esquema de conexión podemos utilizar la FPGA para realizar tareas complejas que Arduino no puede ejecutar. Ejemplos de ello pueden ser procesado de video (podemos conectar memorias externas a la FPGA), tareas criptográficas, etc..

En este primer ejemplo utilizaremos una función muy sencilla, ya que el objetivo es simplemente entender el esquema de conexión. La función es tomar la entrada enviada por el bus I2C, sumarle 5 y devolver el resultado para que Arduino lo muestre por el puerto serie.

Diseños más complejos donde se enviar ráfagas de bytes requieren el uso de una infraestructura basada en FIFOs (memorias con estructura de cola de datos), que veremos en próximos tutoriales. En este diseño simplemente almacenaremos el dato enviado en un registro.

Os dejamos el video tutorial donde podéis ver los pasos seguidos y una demostración del sistema funcionando.

El código esclavo del bus I2C que hemos utilizado está tomado de github en el siguiente enlace:

https://github.com/oetr/FPGA-I2C-Slave

El código VHDL que hemos utilizado para conectar el esclavo I2C a los leds de salida y realizar la función deseada (sumar 5 a la entrada) es este que os copiamos a continuación.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;


entity i2c_leds is
  port (
    scl              : inout std_logic;
    sda              : inout std_logic;
    clk              : in    std_logic;
    rst              : in    std_logic; 
    led_o            : out std_logic_vector(7 downto 0)
  );
end entity;

architecture RTL of i2c_leds is

signal read_req         : std_logic;
signal data_to_master   : std_logic_vector(7 downto 0);
signal data_valid       : std_logic;
signal data_from_master : std_logic_vector(7 downto 0);

signal data_reg : std_logic_vector(7 downto 0);

begin

  i2c_slave0 : entity work.i2cslave(arch) port map(scl,sda,clk,rst, read_req, data_to_master,data_valid,data_from_master);

  led_o          <= data_reg;
  data_to_master <= data_reg + 5;

  process(clk)
  begin
    if(clk'event and clk='1') then
      if(data_valid='1') then 
        data_reg <= data_from_master;				 
      end if;   	 
    end if;	 
  end process;

end architecture;


Este el el código que se ejecuta sobre Arduino, como se puede ver se espera a que se introduzca un número por el puerto serie, se envía por el bus I2C, se espera la respuesta y se muestra por el puerto serie. Podéis verlo en funcionamiento al final del video.

#include <Wire.h>

byte in;
byte out;

void setup(){
 Wire.begin();
 Serial.begin(9600);
}

void loop(){
    while(!Serial.available()>0){;}
    in=Serial.read()-'0';
    Serial.print("Enviando a la FPGA ");
    Serial.println(in);
    
    Wire.beginTransmission(0x3);
    Wire.write(in);
    Wire.endTransmission();
    
    delay(1);
    
    Wire.requestFrom(3,1);
    while(!Wire.available()){;}
    out=Wire.read();

    Serial.print("Recibido de la FPGA ");
    Serial.println(out,DEC);        
    
    delay(1000);
}

Por último os dejamos una captura de la asignación de los pines de la FPGA. Es muy fácil de seguir ya que en esta placa que utilizamos el número de cada pin esta serigrafiado en la placa. En el video se puede ver como están hechas las conexiones.

pines asignados en la FPGA

Esperamos que os haya gustado este tutorial, si tenéis dudas sobre el funcionamiento del sistema, podéis dejar las dudas en comentarios del blog o en el canal de Youtube.