Placa de ejemplo
Como placa de ejemplo he usado una placa recién adquirida por AliExpress, en concreto un clon de la QMTech XC6SLX16 SDRAM Core Board, una placa que incluye una FPGA Spartan 6 de Xilinx, un oscilador a 50 MHz, una SDRAM de 32 Mb, una flash SPI de 8 Mbit (para almacenar la configuración no volátil de la FPGA), varios leds y múltiples puestos de entrada/salida. El clon que se puede adquirir por AliExpress es exactamente igual que la placa original. Me costó unos 19¤ con los gastos de envío incluidos.
Programador de ejemplo
Como interface de programación se ha optado por usar un conversor USB a UART/SPI/I2C/JTAG basado en el chip FT232H. En concreto he usado este por ser una opción barata y de buena calidad de construcción. Costó unos 9¤ con los gastos de envío incluidos.
Prueba de concepto
Instalamos el entorno ISE WebPack de Xilinx (la última versión disponible con soporte para Spartan 6 es la 14.7. No es necesario instalar los drivers de programación), lo abrimos y creamos un nuevo proyecto para la FPGA XC6SLX16, con encapsulado FTG256 y velocidad -2.
Yo llamé al proyecto "Spartan6Blinker" y dentro de él creé un único módulo VHDL al que llamé "Spartan6Blinker.vhd" con el siguiente código:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity Spartan6Blinker is Port ( Clk : in std_logic; D1Led : out std_logic ); end entity; architecture A of Spartan6Blinker is constant COUNTER_WIDTH : integer := 23; signal CounterDBus : std_logic_vector((COUNTER_WIDTH - 1) downto 0); signal CounterQBus : std_logic_vector((COUNTER_WIDTH - 1) downto 0); begin process (Clk) begin if (Clk'event and (Clk = '1')) then CounterQBus <= CounterDBus; end if; end process; CounterDBus <= std_logic_vector(to_unsigned(to_integer(unsigned(CounterQBus)) + 1, COUNTER_WIDTH)); D1Led <= CounterQBus(COUNTER_WIDTH - 1); end architecture;
Como se puede ver es un sencillo contador incremental de 23 bits sin control de desbordamiento (se va incrementando desde 0 hasta (2^23 - 1) y vuelta a empezar) y lo único que hacemos es conectar el bit más significativo del registro contador a la salida del led D1.
A continuación añadimos un nuevo fichero fuente de tipo UCF (Implementation Constraints File) al que llamamos "QMTechSpartan6Board.ucf" (podemos ponerle el nombre que queramos) y le metemos el siguiente contenido:
NET Clk LOC = A10 | IOSTANDARD = LVCMOS33;
NET D1Led LOC = T9 | IOSTANDARD = LVCMOS33;
Lo que hemos hecho es definir en qué pines concretos está la entrada de reloj y la salida hacia el led D1. Estos datos están disponibles en el repositorio de Github de QMTech.
Hacemos doble click en "Generate Programming File" y esperamos a que termine todo el proceso de compilación y síntesis del VHDL. Este proceso generará un fichero llamado "Spartan6Blinker.bit" en la carpeta del proyecto, que es el fichero que se manda a la FGPA o se tosta en la flash SPI.
Por ultimo, nos vamos a una consola, nos descargamos el código fuente del programa xc3sprog en una carpeta aparte:
mkdir -p /opt/src
cd /opt/src
git clone https://github.com/buserror/xc3sprog.git
Y seguimos las instrucciones del fichero README para compilarlo.
Programar directamente la FPGA
Para programar la FPGA lo que hacemos es conectarle el programador basado en FT232H de la siguiente manera:
FT232H Spartan 6
AD0 --------- TCK
AD1 --------- TDI
AD2 --------- TDO
AD3 --------- TMS
GND --------- GND
Conectamos a continuación la placa Spartan 6 a la alimentación de 5 voltios, la placa FT232H al USB de nuestro ordenador y ejecutamos el xc3sprog de la siguiente manera:
cd /opt/src/xc3sprog/build
./xc3sprog -c ft232h /RUTA_CARPETA_PROYECTO/Spartan6Blinker.bit
Programar la flash SPI
Con el programador FT232H conectado de la misma forma, grabamos en la RAM de la FPGA una configuración que nos permitirá transferir datos entre JTAG y la flash SPI:
cd /opt/src/xc3sprog/build
./xc3sprog -c ft232h ../bscan_spi/xc6slx16_cs324.bit
Y a continuación transferimos nuestro fichero bit indicando que es para la flash:
./xc3sprog -c ft232h -I /RUTA_CARPETA_PROYECTO/Spartan6Blinker.bit
De esta forma la FPGA, nada más arrancar, cargará nuestro blinker (sin necesidad de que esté conectada por JTAG).
[ añadir comentario ] ( 1476 visualizaciones ) | [ 0 trackbacks ] | enlace permanente | ( 3 / 2752 )