- El objetivo de esta práctica es mostrar los pasos para crear nuestro propio IP core y enlazarlo con nuestro sistema PS por medio de AXI.
- Para ejemplificar el proceso pongamos el siguiente requerimiento:
Mandar 3 datos de 32 bits llamados output_1, output _2 y output
_3 desde la terminal SDK hacia el display OLED y visualizar su incremento cada
segundo.
·
De la misma forma recibir 3 datos de 32 bits desde el
sistema PL (input_1, input _2, input _3)
hasta el SDK e imprimirlos vía UART.
·
Crear nuestro MY_IP (IP CORE con AXI) para interconectar
PS y PL.
- La siguiente imagen muestra el flujo de diseño que llevaremos a cabo:
El sistema base consiste en crear el diagrama de bloques
con Zynq, generar nuestro IP CORE con AXI, obtener el archivo de sintesis MY_IP_CORE_wrapper.dcp
y por ultimo exportar el proyecto a SDK de Xilinx.
·
Creando un nuevo proyecto:
·
Crear un diagrama de bloques:
·
Crear un paquete IP como se muestra en las siguientes
figuras:
·
Escoger la opción de crear un periférico AXI:
·
Establecer 6 registros (3 para las entradas y 3 para las
salidas):
·
Seleccionar la opción de editar el IP:
·
Agregar las lineas de la 19 a la 24, que corresponden a las
entradas y salidas respectivamente.
·
Mapear los registros en el proceso de la linea 370, 377, 379
y 381.
·
Agregar las salidas en la linea 413 a 415.
·
Ahora en el archivo TOP declarar nuevamente la entradas y
salidas. Lineas 19 a 24.
·
Declarar nuevamente en la arquitectura. Linea 64 a 69.
·
En la instanciacion mapear las entradas y salidas. Linea 105
a 110.
·
Configurar el paquete IP como las siguientes imágenes:
·
Crear el diagrama de bloques con Zynq y MY_IP_CORE:
·
Crear puertos para las entradas y salidas de MY_IP_CORE_0:
- Diagrama de bloques completo:
·
Crear el HDL Wrapper y generar los products:
·
Como se observa en el diseno TOP. Las entradas y salidas ya
están declaradas y nos servirá de enlace con el código generado por DK Design Suite
de Handel-c. Como lo veremos mas adelante.
·
Creamos la interfaz MY_IP_CORE_wrapper en DK Design con sus
entradas y salidas:
·
La dirección de memoria de nuestro IP CORE es:
·
Realizamos la
síntesis:
·
Identificamos el archivo generado por la síntesis MY_IP_CORE_wrapper.dcp
ya que lo utilizaremos en la segunda parte para unificarlo con los archivos
generados por DK Design Suite.
·
Se correrá la implementacion con el objetivo de poder
exportar el hardware a SDK:
·
Abrimos la
implementacion:
·
Exportamos el
Hardware:
·
No incluimos el
bitstream:
·
Por ultimo lanzamos SDK y Cerramos proyecto:
PASO # 2. Fusionar sistema base y
archivos de DK Design Suite
·
Crear un nuevo proyecto:
·
Agregar todos los archivos generados por DK, incluyendo la librería
agility y el MY_IP_CORE_wrapper.dcp:
·
Eliminamos la declaración de componente externo duplicada:
·
Generamos
el bistream para programar el Zynq:
·
Programamos el
Zynq:
·
Abrimos el
proyecto SDK que en el paso #1 generamos. Y hacemos una aplicación:
·
Vamos anuestra carpeta de proyecto donde se genero nuestro
ip_repo:
C:\
MY_IP_CORE_AXI\ip_repo\MY_IP_CORE_1.0\drivers\MY_IP_CORE_v1_0\src
Copiamos ambos archivos MY_IP_CORE al proyecto:
·
El software para el proyecto es:
#include <stdio.h>
#include
"platform.h"
#include
"xparameters.h"
#include
"MY_IP_CORE.h"
#define TEST_BASE
XPAR_MY_IP_CORE_0_S00_AXI_BASEADDR
int main()
{
long int delay, ust_limit = 83333323;
int i, in_1, in_2, in_3;
init_platform();
printf("My IP CORE test begin.\r\n");
printf("--------------------------------------------\r\n\n");
while(1)
{
for(i=0;i<255;i++)
{
MY_IP_CORE_mWriteReg(TEST_BASE,
MY_IP_CORE_S00_AXI_SLV_REG3_OFFSET, i);
MY_IP_CORE_mWriteReg(TEST_BASE,
MY_IP_CORE_S00_AXI_SLV_REG4_OFFSET, i+1);
MY_IP_CORE_mWriteReg(TEST_BASE,
MY_IP_CORE_S00_AXI_SLV_REG5_OFFSET, i+2);
in_1
= MY_IP_CORE_mReadReg(TEST_BASE, MY_IP_CORE_S00_AXI_SLV_REG0_OFFSET);
in_2
= MY_IP_CORE_mReadReg(TEST_BASE, MY_IP_CORE_S00_AXI_SLV_REG1_OFFSET);
in_3
= MY_IP_CORE_mReadReg(TEST_BASE, MY_IP_CORE_S00_AXI_SLV_REG2_OFFSET);
printf("
Input_1 = %i \n",in_1);
printf("
Input_2 = %i \n",in_2);
printf("
Input_3 = %i \n\n",in_3);
for(delay=0;delay<ust_limit;delay++){};
}
}
return 0;
}
·
Construcción del proyecto:
·
Generamos el GDB para programar el ARM del Zynq:
·
Corremos el debugger y vemos satisfactoriamente la implementación
en SDK:
·
Se observa en la tarjeta ZedBoard la salidas secuenciales
funcionando correctamente!
Muy útil esta entrada y el blog en general! Muchas gracias!
ResponderBorrar