-
Crear un "Block Design" de Vivado.
-
Importar Constraints, si se desea agregar RTL (Prefiera activar copiar el .xdc dentro del proyecto.
-
Configurar el CPU principal.
-
Conectar
FCLK_CLK0
conM_AXI_GP0_ACLK
. Este reloj tambien sera el reloj principal del bus AXI. . (Los Warnings no generan mayores problemas). -
Agregar y Configurar IP's
-
Configurar bloque Concat: Dado que el tipo de
IRQ_F2P
no es compatible con las lineas de interrupcion, deben concatenarse las lineas en un solo vector lógico. Este bloque puede juntar las lineas de interrupción. Debe agregarse una entrada por cada interrupción -
Configurar AXI GPIO: Doble clic en el bloque
-
Los otros bloques usan en este caso la configuración predeterminada.
-
Conectar los bloques de IP: Puede autoconectarse los bloques IP AXI. Nótese que la conexión automática no conecta las interrupciones y solo puede autoconectar un reloj.
- Hacer clic en el pop-up *Run Connection Automation
- Seleccionar todos los bloques en las casillas. Esto hará que se genere automáticamente un bloque de interconexión y arbitraje AXI y las líneas de dirección y datos del bus.
- Conectar Lineas de Interrupción
- Agregar BRAM
- Agregar el bloque BRAM Controller.
- Agregar el bloque Block Memory Generator. Pueden configurarse las caracteristicas de la BRAM, como la cantidad de puertos, el ancho y la capacidad máxima.
- Agregar Interfaz de gestion del Ethernet PHY (Sólo Zybo).
- Descomentar las lineas 49 y 50
set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports eth_int_b]; #IO_L6P_T0_35 Sch=ETH_INT_B set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports eth_rst_b]; #IO_L3P_T0_DQS_AD1P_35 Sch=ETH_RST_B
- Crear puertos con los nombres
eth_int_b
yeth_rst_b
. - Conectar
eth_int_b
a concat yeth_rst_b
, aperipheral_aresetn
- Crear Wrapper de HDL(botón derecho sobre el diseño de bloques (el archivo .bd, en la pestaña Sources). (Esto encapsula el diseño y lo hace referenciable por el simulador y el sintetizador).
Después de exportar el hardware, Abrir Xilinx Vitis. Al ser similar a Eclipse creará un Workspace. Los archivos de código fuente y del proyecto quedarán guardados en este entorno protegido, mientras se desarrolla la aplicación.
- Crear una aplicación Baremetal
- Ir a "File"->"Project"->"Application"
- Darle un nombre al proyecto. No ponerle espacios al nombre.
- Selecionar la plataforma del proyecto. Puede seleccionarse una plataforma existente (Lamentablemente está buggy no ocupar) o crear una nueva.
- Al presionar Next, debe seleccionarse que método será usado para generar la plataforma. Seleccionar "Create new platform from Hardware (XSA)". La ventana tiene un campo donde se listan plataformas recientes disponibles en los ejemplos o bien dentro del Workspace. Seleccionar "Create new platform from Hardware (XSA)".Si se necesita importar una plataforma de elaboración propia (el presente caso), debe hacer clic en "+" y seleccionar la carpeta donde se encuentra el archivo
.xsa
que se generó al exportar hardware con Vivado. Presionar Next, después de seleccionar la plataforma recién agregada. - Ahora debe seleccionarse el Domain de la plataforma. En este caso, en cada campo debe seleccionarse "ps7_cortexa9_0"(Podría haber más de un procesador independiente dentro del sistema que se ha importado), "Standalone" y "C". También debe seleccionarse "Generate Boot components"
- Al presionar Next, debe seleccionarse un Template para este caso, se seleccionará "Hello World".
- Al presionar Next quedará disponible el entorno de vitis
En el arbol o Explorer, pueden verse los directorios del proyecto.
- Release y Debug son los objetivos convencionales de construcción. Release por lo general optimizará el ejecutable y no incluirá ni símbolos ni información de depuración. Debug incluirá información de depuración y omitirá algunas optimizaciones. Pueden personalizarse los objetivos si se edita el archivo "Makefile" dentro de los directorios.
- src Contiene el codigo fuente del ejecutable que se va a construir. Un proyecto Baremetal mínimo necesita de la inicialización de plataforma "platform.c" y de un codigo fuente .c que tenga el procedimiento
main
. Si desea aceder a un código fuente referenciado (por ejemplo#include <algunarchivo.h>
), puede seguir como si fuera un enlace, el nombre del archivo presionando Ctrl. El script de enlazado "ldscript.ld" contiene la configuración de la estructura del ejecutable .elf. Vitis tiene un parser que permite editarlo de manera gráfica.
Como el proyecto solo tiene referenciado el terminal, solo habrá como parámetro configurable, la velocidad de transferencia del UART. En "platform.c", debe especirficarse en la la velocidad deseada. Esta es la velocidad que se deberá configurar en el terminal más tarde.
Al seleccionar "ldscript.ld" del árbol aparecerá en la sección principal la configuración del ejecutable .
- "Available Memory Regions": Lista las regiones de memoria disponibles. En este caso se habían creado 2 regiones de memoria, la memoria local y la memoria "Empotrada" en el FPGA.
- "Stack and Heap Sizes": Controla el tamaño de tales regiones. El "Stack" almacena las direcciones y las Flags de retorno de las llamadas, por lo tanto, un programa más complejo, requerirá mas "Stack". "Heap" es una estructura de datos tipo montículo que se usa para asignar memoria dinámicamente. Un programa que genere estructuras de datos que crecen con el paso de la ejecución requerirá más "Heap". Los campos permiten establecer el tamaño de ambas secciones. Si es que no se compartirá la memoria con nada más, se recomienda ocuparla completamente. Una buena medida es darle al Stack el 25% o el 50% del total y el resto para el montículo.
- "Section to Memory Region Mapping": Muestra la asociación entre las secciones del ejecutable y las regiones de memoria
En este caso "helloworld.c" es el archivo con el procedimiento main
. Todo lo que se desea que el programa haga en su cuerpo principal debería ser agregado aquí. Para propósitos de prueba, modificar el programa en la linea
print("Hello World\n\r");
por
unsigned long count=0;
while(1)
{
printf("Hello World\n\r");
printf("%lu", count);
count++;
}
Nótese que al final hay una llamada a cleanup_platform()
definida en "platform.c". Si se desean agregar más acciones, deben editarse ahí.
Al presionar "build" (el martillo) se construye la aplicación y el entorno, completos, según el objetivo que se haya establecido. Al lado del ícono, aparece una flecha, donde se puede seleccionar el objetivo de compilación ("Debug", "Release" u otro que se haya creado).
En el arbol, botón derecho en holamundo_pynq_system..
Aparece la ventana de generación de imagen de arranque. Si se contruyó la imagen correctamente, debería aparecer, si se seleccionar "Import from existing BIF file", las sigueintes particiones de Flash
Si no se desean agregar más particiones, presionar Create Image.
En el arbol, botón derecho en holamundo_pynq_system. Aparece la ventana de Flasheo. Presionar Program. Esto tardará bastante tiempo. Asegurarse de que no se interrumpirá el suministro de energía de la placa. De interrumpirse, podría "Regrabarse" la memoria cambiando la configuración de los jumpers a otra que no haga al FPGA arrancar con la memoria SPI (Por ejemplo JTAG).
- La "actualización" de plataformas no es capaz de encontrar el bitstream exportado por Vivado, asi que cada vez que se altere la plataforma, debe recrearse nuevamente. Esto rompe parte de la característica de portabilidad Automática.
- Cuando se crea primero una plataforma y después la aplicación, con el Workspace vacío, el mago generador de aplicaciones no puede encontrar la definición de plataforma ya creada y queda incompleta y no puede terminarse, o bien, debe seleccionarse una de las incluidas en Vitis y luego reasignar la plataforma manualmente (Cuidado con las inicializaciones, porque si fueron modificadas por el programador, serán totalmente incompatibles).
- Pese a que los archivos de Digilent incluyen información sobre los dispositivos de la placa, hay que especificar la Flash SPI a mano.
- Las opciones de los menús contextuales no tienen resultados consistentes. Asegurarse de no seleccionar una opción incorrecta, ya que parecerá que hay un problema o que la imagen se generó incorrectamente.
- La "actualización" de plataformas no es capaz de encontrar el bitstream exportado por Vivado, asi que cada vez que se altere la plataforma, debe recrearse nuevamente. Esto rompe parte de la característica de portabilidad Automática.
- Cuando se crea primero una plataforma y después la aplicación, con el Workspace vacío, el mago generador de aplicaciones no puede encontrar la definición de plataforma ya creada y queda incompleta y no puede terminarse, o bien, debe seleccionarse una de las incluidas en Vitis y luego reasignar la plataforma manualmente (Cuidado con las inicializaciones, porque si fueron modificadas por el programador, serán totalmente incompatibles).
- Pese a que los archivos de Digilent incluyen información sobre los dispositivos de la placa, hay que especificar la Flash SPI a mano.
# mkdir /opt/pkg/petalinux/2019.2/
# chown <su_usuario> /opt/pkg/petalinux/2019.2/
$ ./petalinux-v2019.2-final-installer.run /opt/pkg/petalinux/2019.2
$ source <path-to-installed-PetaLinux>/settings.sh
$ source <path-to-installed-PetaLinux>/settings.sh
$ petalinux-create -t project -s <ruta_al_bsp>
Deben ser de la misma versión.
$ source <path-to-installed-PetaLinux>/settings.sh
petalinux-create --type project --template zynq --name <nombre_del_proyecto>
Esto creará una carpeta con el nombre del proyecto, luego debe configurarse el proyecto con la definición de hardware creada con Vivado
$ cd <carpeta_con_nombre_del_proyecto>
$ petalinux-config --get-hw-description=<carpeta_del_proyecto_de_Vivado>
Esto Iniciará un configurador Kconfig
de la imagen. En muchos casos la configuración predeterminada es satisfactoria, por lo que bastará con seleccionar Save.
Para construir el sistema completo predeterminado
$ cd <carpeta_con_nombre_del_proyecto>
$ petalinux-build
Esto podría tardar hasta 15 minutos
Las imágenes construidas van a estar en <carpeta_con_nombre_del_proyecto>/images/linux
.
$ petalinux-package --boot --fsbl <Imagen FSBL> --fpga <bitstream> --u-boot
o bien, si solo hay una configuración
$ petalinux-package
los archivos BOOT.BIN
e image.ub
en <carpeta_con_nombre_del_proyecto>/images/linux
deben ser copiados a una sd con formato FAT32. Esto es suficiente para que el Zynq logre arrancar Petalinux
Las imágenes construidas van a estar en <carpeta_con_nombre_del_proyecto>/images/linux
.
$ petalinux-package --boot --fsbl <Imagen FSBL> --fpga <bitstream> --u-boot
o bien, si solo hay una configuración
$ petalinux-package
Sin embargo debe notarse que la imagen predeterminada podría exceder ampliamente el tamaño de la memoria. Debe configurarse el Núcleo (Kernel) y el RootFS para descartar cualquier componente que se considere innecesario, entre ellos, controladores de dispositivos que no va a estar conectados, aplicaciones y daemons que no se van a usar.
$ cd <carpeta_con_nombre_del_proyecto>
$ petalinux-config -c kernel
$ petalinux-config -c rootfs
Al hacer cualquiera de estos cambios, la imagen debe reconstruirse. Luego con la tarjeta conectada y con Xilinx Vitis, debe crearse una aplicación del mismo modo que una aplicación baremetal. Asegurarse que se está referenciando la plataforma correcta.