Está en la página 1de 21

Haciendo periféricos para microcontroladores,

¡Al estilo Xilinx!


Raul Gerardo Huertas Paiva

Ing. Electrónico

Universidad Tecnológica del Perú

rax20037 at gmail

Abril 2011

Aquí se va a describir el proceso de la creación de un periférico para el Microblaze con interfaces


AXI y su integración con la herramienta “Xilinx Platform Studio”. Elegí este tema porque ha
requerido un tiempo considerable de mi parte encontrar el modo hacerlo, he tenido que
recolectar información de una y otra parte de la Web para tener un ejemplo básico con todos los
requisitos que quería. Finalmente lo obtuve y quiero escribir eta guía para que cualquiera de
ustedes puedan hacerlo más rápidamente en sus proyectos. Cualquier duda o consulta siéntanse
en confianza de preguntarlo en los comentarios pues con gusto los ayudaré.

¡Empezemos!

Entonces, ¿Qué se va a hacer aquí?

Bueno estaba diseñando un módulo para el procesamiento de imágenes y este puede recibir los
píxeles de forma serial e igualmente expulsar los datos de forma serial. El procesamiento está
segmentado (Pipelined) y entra en la categoría de procesadores de flujo (Stream Processors).
Además de los píxeles, este módulo necesita un par de parámetros más con los cuales se controla
su funcionamiento:

Param 1 Param 2 Param 3

Procesador de Píxeles

Entrada Salida

Memoria Principal
Para su implementación se usará un kit SP605 Embedded Edition de Xilinx, con una memoria DDR3
de 128MB, la única en la tarjeta capaz de almacenar una imagen de al menos 16MP. Para la
entrada/salida de datos las únicas interfaces con una velocidad aceptable podían ser PCI
Express(2Gb/s), Ethernet (1Gb/s). Tanto la memoria como las entradas y salidas necesitan de
controladores nada triviales de diseñar e implicarían un tiempo considerable de desarrollo. ¡Pero!,
aquí comienza la historia, Xilinx provee una interfaz AXI para todos estos módulos. Adaptando mi
módulo a esta interfaz tendría más facilidad para la comunicación de datos. Y de acuerdo a Xilinx,
junto con sus herramientas, este sería un proceso simple y tendría una solución “Plug & Play” para
todos mis proyectos. Puedes encontrar información completa sobre AXI en la página de Xilinx y su
especificación completa en la página de ARM.

http://www.xilinx.com/support/documentation/white_papers/wp379_AXI4_Plug_and_Play_IP.pdf

http://www.arm.com/products/system-ip/amba/amba-open-specifications.php

Teniendo conocimiento de esto el diseño de mi módulo tendría las siguientes interfaces:

Interfaz AXI Interfaz AXI


Stream – Slave Interfaz AXI-Lite Slave Stream – Master
Param 1 Param 2 Param 3

Procesador de Píxeles

Al final de esta guía se tendrá un ejemplo funcional de un periférico con estas interfaces para con
el cual se podrá seguir implementando el periférico que se desee.

¿Qué se necesita para programar estas interfaces?


Necesitas de estos programas para seguir los pasos que voy a describir:

 ISE Design Suite 13.1, Embedded Edition .- Disponible la versión de prueba en la página de
Xilinx. Si adquieres un kit estos vienen con una licencia permanente para el programa, con
la única limitación de sólo poder usarla para un modelo de FPGAs (¡el que viene en el kit!)
 Un editor sencillo de texto, te recomiendo el Notepad++.

También necesitas descargar los siguientes archivos con plantillas para los diseños:
 ¿How to create a custom AXI IP Core? , archivos con las plantillas de las interfaces AXI de la
página de Xilinx.

Además, necesitas un proyecto en XPS listo para poder simplemente agregar nuestro módulo. Es
decir, ya debes de tener un procesador, la memoria y demás periféricos básicos (timer, uart, leds,
botones, …) para poder trabajar sólo en este periférico. Junto a este documento estaré
adjuntando el archivo .mhs con el que empecé trabajar. No te recomiendo usar el diseño que se
crea con el asistente de XPS pues, en mi experiencia, ¡no funcionan! Hay un problemita con la
interfaz a la memoria DDR, que ya está solucionado en el diseño que adjunto. Al parecer sólo se
trata de seleccionar correctamente el orden de los pines de dirección. De cualquier forma yo baso
mi diseño en el que viene junto al kit Spartan 6 Embedded Development de Xilinx, y lo he
actualizado por completo a la interfaz AXI.

Como extra, te recomiendo empezar a reproducir un poco de música relajante como el Pop , así no
te estresas ni te cansas demasiado =).

Esta es la vista de los buses del diseño:

Como se ve en la figura, para la verificación del diseño se usará un par de interfaces stream del
microblaze en modo AXI, M0_AXS y S0_AXIS.

Instalando las plantillas


Una vez que hayas descargado las plantillas tienes que guardarlas en el directorio pcores de tu
proyecto en XPS:

pcores >
axi_lite_master_v1_00_a

axi_lite_slave_v1_00_a

axi_master_v1_00_a

axi_slave_v1_00_a

axi_stream_v1_00_a

Las dos plantillas resaltadas son las que vamos a usar en este proyecto. Revisa el documento
Platform Specification Format Reference Manual para poder entender cada detalle de esos
archivos. Aquí sólo se describirá lo necesario para lograr la conexión. Una vez copiados regresa a
XPS ve al Project>Rescan user repositores para que el programa los reconozca. Deberán aparecer
en el catálogo de IPs los siguientes componentes:

CREACION DE LA PLANTILLA PARA EL MÓDULO


El siguiente paso es crear una plantilla nueva la cual se va a modificar para convertirla en nuestro
periférico. Iniciamos el asistente de Xilinx mediante el comando Hardware>Create or Import
Peripheral . Aparecerá la ventana de introducción del asistente, pulsamos en Next:

La siguiente pestaña es la Peripheral Flow. Debemos seleccionar la opción Create template for a
new peripheral para crear la plantilla. Luego has click en Next:
La siguiente pestaña será Repository or Project. Aquí seleccionamos To an XPS repository pues no
será necesario exportarlo a otros proyectos, así lo mantenemos de forma local. Click en Next.

En la pestaña Name and Version toca elegir un nombre a nuestra IP. Rellena los siguientes datos:

Click en Next.
Ahora toca elegir el tipo de bus a usar. Desafortunadamente, por ahora, este asistente sólo nos
ayudara en crear la interfaz AXi-Lite, las interfaces stream las agregaremos manualmente en un
paso posterior. Selecciona AXI4-Lite y haz click en siguiente:

Aparecerá la pestaña de IPIF Services, tenemos tres opciones:


 Software reset .- Una señal de reset que puede reiniciar el módulo por completo el
módulo. Personalmente no uso este tipo de señales en el diseño por la cantidad der
recursos necesarios que usualmente necesitan(escribiré sobre esto después) así que para
este ejemplo no lo seleccionaré.
 User logic software register.- Si la comunicación a nuestro módulo será por registros. Esto
es lo que se necesita para el módulo, una serie de registros mediante los cuales se envían
parámetros al módulo. Esta opción se activa.
 Include data phase timer.- Si se activa esta opción se va a crear un temporizador que
notificará al sistema si el módulo se está demorando mucho en responder. Por ahora se
deja esta opción sin seleccionar.

Después de marcar las opciones necesarias, hacer click en Next:


La siguiente pestaña es User S/W registers. Para este ejemplo tendremos suficiente con cuatro
registros. Luego haz click en siguiente:

En la pestaña IP InterConnect se especifican las señales del bus van a necesitarse. Dejamos las
señales por defecto. Click en siguiente:

En la pestaña Peripheral Simulation Support se decide o no crear modelos de simulación para


nuestro periférico. No se realizará la simulación en esta guía así que por ahora dejaremos esta
opción deseleccionada. Click en siguiente:
La última pestaña es la de Peripheral Implementation Support. Aquí se va a necesitar la opción
Generate ISE and XST Project Files to help you implement the peripheral using XST flow. Esto
permite la posterior uso del ISE para la organización de los archivos del proyecto.

Esta es la última pestaña en la que tenemos que seleccionar alguna opción. Luego aparecerá la
pestaña de Congratulations con un resumen de la plantilla creada. Revísala y a continuación hazle
click en siguiente.

En la carpeta pcores del proyecto XPS aparecerá el directorio my_first_ip_v1_00_a con todas las
plantillas del proyecto. En my_first_ip_v1_00_a\hdl se han creado las plantillas con el código para
el periférico, my_first_ip_v1_00_a\data contiene los archivos con que se importa este periférico al
EDK y en my_first_ip_v1_00_a\devl se encuentran los archivos del ISE para organizar el proyecto.
EXPLORANDO EL CÓDIGO DE LA PLANTILLA
En la carpeta my_first_ip_v1_00_a\devl\projnav se encuentra el proyecto de ISE my_first_ip,
ábrelo. Este no es el proyecto del diseño completo, sino sólo para editar el código de tu periférico.

Trata de sintetizarlo y encontrarás alrededor de 19 errores. No sé realmente a que se debe esto.


Para solucionarlo en la vista de diseño selecciona el archivo ‘counter_f’, botón derecho, en el
menú que aparece elige Source Properties… Activa la acción ‘Include as Global file in Compile list’ y
luego haz click en OK. Haz lo mismo con el archivo or_gate128. Cuando sintetices todo de nuevo
los errores deben de haber desparecido.

Ahora es tiempo de explorar las fuentes


Para este proyecto veras que se han creado dos archivos en VHDL:

my_first_ip.vhd
user_logic.vhd

El primero tiene referencias a librerias externas que implementan la interfaz AXI, muy bueno, así
no hay que invertir mucho tiempo lidiando con los detalles de este protocolo. Es importante la
importación de las librerías proc_common_v3_00_a y axi_lite_ipif_v1_01_a pues, aun si no las
usas, EDK no va a poder reconocer tu módulo si no están estas presentes. Como mencionamos
más arriba, sólo contiene la implementación de la interfaz AXI-Lite.

El archivo user_logic.vhd es más comprensible. Alrededor de la línea 182 vas está el código para
almacenar los datos en los registros :

case slv_reg_write_sel is
when "1000" =>
for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
if ( Bus2IP_BE(byte_index) = '1' ) then
slv_reg0(byte_index*8+7 downto byte_index*8) <=
Bus2IP_Data(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when "0100" => …

El bucle con el iterador byte_index sirve para seleccionar, hacienda usaso de la señales AXI-STRB
que bytes de tu registro deben cambiar sus datos. Te recomiendo retirar este bucle y actualizar
todo el contenido del registro, así obtienes un núcleo más ligero.
Más abajo en el código, alrededor de la línea 218, verás la sección en que se realiza la lectura de
los registros:
case slv_reg_read_sel is
when "1000" => slv_ip2bus_data <= slv_reg0;
when "0100" => slv_ip2bus_data <= slv_reg1;
when "0010" => slv_ip2bus_data <= slv_reg2;
when "0001" => slv_ip2bus_data <= slv_reg3;
when others => slv_ip2bus_data <= (others => '0');
end case;

Para este ejemplo vamos a modificar el comportamiento de esta operación. En vez de leer el
mismo dato que ha escrito, vamos a hacer que lea de regreso el complemento binario de este
dato.

Estos archivos VHDL se han agregado a la librería my_first_ip_v1_00_a del proyecto. Cualquier
otro código fuente que agreguemos a nuestro proyecto debemos agregarlo a esta librería (Source
properties>…).
MODIFICANDO LAS FUENTES
Antes de proseguir voy a hacer una observación. Al principio estaba usando la siguiente jeraquía
para agrupar las partes del periférico:

my_first_ip

stream_logic (Donde se user_logic (Donde se


implementa la lógica de los implementa la interfaz slave)
streams)

No sé cuál es el problema, pero pase un buen par de noches tratando de que esto pudiera ser
reconocido por el EDK pero no obtuve ningún resultado. Era muy frustante. El error que me
aparecía era NGDBuild604. El EDK no generaba la netlist para el stream_logic.
Finalmente modifiqué el modulo con la siguiente jerarquía:

my_first_ip

user_logic (Donde se
implementa la interfaz slave y
se exportan las señales de la
interfaz stream)

stream_logic (Donde se
implementa la lógica de los
streams)

user_logic ha de usarse como la raíz a partir de la cual se va a implementar el resto de nuestra


lógica. Para mi sorpresa, funcionó a la primera…

PERSONALIZANDO LA INTERFAZ AXI-Lite:


Ya que tenemos una plantilla funcionando vamos hacer algo más interesante con ellas. Para hacer
que se devuelva el complemento de los valores escritos en el registro, simplemente podemos
modificar el código con lo siguiente:
case slv_reg_read_sel is
when "1000" => slv_ip2bus_data <= NOT slv_reg0;
when "0100" => slv_ip2bus_data <= NOT slv_reg1;
when "0010" => slv_ip2bus_data <= NOT slv_reg2;
when "0001" => slv_ip2bus_data <= NOT slv_reg3;
when others => slv_ip2bus_data <= (others => '0');
end case;
Esto funciona, pero vamos a hacerlo instanciando un complemento declarado en otro archivo,
esto para mostrar como agregar más archivos con las fuentes para nuestro periférico. Creamos el
archivo ‘MiComplemento.vhd’ y lo agregamos al proyecto. Va a tener el siguiente código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity MiComplemento is
Port ( Entrada : in STD_LOGIC_VECTOR (31 downto 0);
Salida : out STD_LOGIC_VECTOR (31 downto 0));
end MiComplemento;

architecture Behavioral of MiComplemento is

begin
Salida <= NOT Entrada;

end Behavioral;
Este archivo debe de agregarse a la librería de nuestro periférico, asi que seleccionamos este
archivo en la vista de diseño, botón derecho>Source Proeprties y en Source Library seleccionamos
nuestra librería:

Click en OK.
En user_logic.vhd vamos a importar ese componente:
library my_first_ip_v1_00_a;
use my_first_ip_v1_00_a.MiComplemento;
Agregamos la siguiente señal y componente a su arquitectura:
signal slv_reg0_operated : std_logic_vector(C_SLV_DWIDTH-1 downto 0);

component MiComplemento is
Port (
Entrada : in STD_LOGIC_VECTOR (31 downto 0);
Salida : out STD_LOGIC_VECTOR (31 downto 0)
);
end component MiComplemento;
Y finalmente instanciamos el componente:
--Mi operador
operacion : entity my_first_ip_v1_00_a.MiComplemento
port map(
Entrada => slv_reg0,
Salida => slv_reg0_operated
);
Lo último que queda es devolver esta señal a la hora de leer los registros:
case slv_reg_read_sel is
when "1000" => slv_ip2bus_data <= slv_reg0_operated;

Sintetiza esto. No deberían haber más errores.
PERSONALIZANDO LAS INTERFACES STREAM:
Ahora solo queda agregar las interfaces stream al periférico. Al igual que en la interfaz AXI4-Lite
vamos a hacer que a la salida devuelva el complemento de los datos que ingresan. Este es el
código fuente de la lógica del stream, StreamLogic.vhd:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

library proc_common_v3_00_a;
use proc_common_v3_00_a.proc_common_pkg.all;

entity StreamLogic is
generic(
C_M_AXIS_DATA_WIDTH : integer := 32;
C_S_AXIS_DATA_WIDTH : integer := 32
);
port(
axi_aclk : in std_logic;
axi_resetn : in std_logic;
-- Master Stream Ports
m_axis_tdata : out std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0);
m_axis_tstrb : out std_logic_vector((C_M_AXIS_DATA_WIDTH/8)-1 downto 0);
m_axis_tvalid : out std_logic;
m_axis_tready : in std_logic;
m_axis_tlast : out std_logic;
-- Slave Stream Ports
s_axis_tdata : in std_logic_vector(C_S_AXIS_DATA_WIDTH-1 downto 0);
s_axis_tstrb : in std_logic_vector((C_S_AXIS_DATA_WIDTH/8)-1 downto 0);
s_axis_tvalid : in std_logic;
s_axis_tready : out std_logic;
s_axis_tlast : in std_logic
);
attribute SIGIS : string;
attribute SIGIS of axi_aclk : signal is "CLK";
end entity StreamLogic;

architecture StreamIMP of StreamLogic is


signal outputSignal: std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0);
signal registeredSignal: std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0);

begin
m_axis_tdata <= not s_axis_tdata;
m_axis_tstrb <= s_axis_tstrb;
m_axis_tvalid <= s_axis_tvalid;
s_axis_tready <= m_axis_tready;
m_axis_tlast <= s_axis_tlast;
end StreamIMP;

Coloca agrega el código de StreamLogic a la librería del periférico (Botón derecho>Source


Properties…). Este componente crea doce señales nuevas que tiene que agregarse a los archivos
my_first_ip.vhd y user_logic.vhd:

axi_aclk : in std_logic;
axi_resetn : in std_logic;
-- Master Stream Ports
m_axis_tdata : out std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0);
m_axis_tstrb : out std_logic_vector((C_M_AXIS_DATA_WIDTH/8)-1 downto 0);
m_axis_tvalid : out std_logic;
m_axis_tready : in std_logic;
m_axis_tlast : out std_logic;
-- Slave Stream Ports
s_axis_tdata : in std_logic_vector(C_S_AXIS_DATA_WIDTH-1 downto 0);
s_axis_tstrb : in std_logic_vector((C_S_AXIS_DATA_WIDTH/8)-1 downto 0);
s_axis_tvalid : in std_logic;
s_axis_tready : out std_logic;
s_axis_tlast : in std_logic
En user_logic, una vez que se han agregado las señales, se instancia este componente de la misma
forma que ‘MiComplemento.vhd’ y conecta las señales y generics de la siguiente forma:
LogicaStreaming : StreamLogic
generic map(
C_S_AXIS_DATA_WIDTH => C_S_AXIS_DATA_WIDTH,
C_M_AXIS_DATA_WIDTH => C_M_AXIS_DATA_WIDTH
)
port map(
--Interfaz axi stream
axi_aclk => axi_aclk,
axi_resetn => axi_resetn,
-- Master Stream Ports
m_axis_tdata => m_axis_tdata,
m_axis_tstrb => m_axis_tstrb,
m_axis_tvalid => m_axis_tvalid,
m_axis_tready => m_axis_tready,
m_axis_tlast => m_axis_tlast,
-- Slave Stream Ports
s_axis_tdata => s_axis_tdata,
s_axis_tstrb => s_axis_tstrb,
s_axis_tvalid => s_axis_tvalid,
s_axis_tready => s_axis_tready,
s_axis_tlast => s_axis_tlast
);

La jerarquía final ha de ser:

my_first_ip

user_logic (Donde se
implementa la interfaz slave y
se exportan las señales de la
interfaz stream)

stream_logic (Donde se
implementa la lógica de los MiComplemento
streams)

La síntesis de este proyecto ha de realizarse sin errores.


IMPORTAR EL PERIFIERICO AL EDK
Ahora que ya tienes completas las fuentes del periférico es hora de agregarlas al diseño principal
de tu sistema. Regresa al XPS y vuelve a abrir el asistente de creación/importación de periféricos.
En la pestaña Peripheral Flow esta vez selecciona Import Existing Peripheral. Luego haz click en
siguiente hasta que llegues a la pestaña Name and Version.

Usa los datos de la siguiente fugura y haz click en siguiente, Al hacerlo te va a advertir que vas a
sobre-escribir un componente anterior, haz click en OK.
En la pestaña Source File Types selecciona que solo vas a necesitar de archivos VHDL. Click en
siguiente.

En la siguiente pestaña se debe introducir el proyecto a partir del cual se va a importar el


periférico.
 En HDL languages used to implement your peripheral selecciona VHDL.
 Deja desactivado Use Data (.mpd)…, este lo editaremos de forma manual en un paso
posterior.
 En el bloque de How to locate your HDL source files and dependent library files selecciona
la opción Use XST project file. Haz click en Browse y selecciona el archivo my_first_ip.prj
en la carpeta my_first_ip_v1_00_a\devl\projnav.
Haz click en siguiente.

La siguiente pestaña es la de HDL Analisys information. Aquí te dirá si ha podido encontrar todas
las fuentes y librerías de tu proyecto. Click en Next.
En la siguiente pestaña, Bus Interfaces, se selecciona los buses a identificar en nuestro periférico.
Selecciona AXI4-Lite- Slave. Click en Next.

Pulsa siguiente hasta llegar a la pestaña S_AXI4LITE: Parameter. Activa Register Space, como
dirección base selecciona C_BASEADDR y como dirección límite selecciona C_HIGHADDR. Click en
Next:

En la pestaña Identify Interrupt signals deselecciona Select and Configure interrupts y haz click en
next.
En la pestaña Parameter Attributes ve hacia el parámetro C_FAMILY en Default escribe Spartan6(o
el nombre de tu dispositivo). Click en Next.

En la última pestaña revisa tu diseño y haz click en finish. Tu periférico apareceré en junto a las
otras plantillas.

Agrégalo al proyecto de XPS haciéndole doble click. Deja los parámetros por defecto y cuando te
aparezca el diálogo Instantiate and Connect IP selecciona User will make necessary conenctions
and settings. Una vez agregado veraz que sólo aparece con la interfaz AXI4-Lite:
Hasta aquí se acabaron los aistentes.. todo se editará de forma manual. En la vista System
Assembly View, click derecho en my_first_ip_0 y selecciona View MPD. Aquí aparecerá el archivo
que usa XPS para reconocer los puertos de tu periférico. Casi al final verás las interfaces axi stream
con la siguiente declaración:

PORT axi_aclk = "", DIR = I, SIGIS = CLK


PORT axi_resetn = "", DIR = I
PORT m_axis_tdata = "", DIR = O, VEC = [(C_M_AXIS_DATA_WIDTH-1):0], ENDIAN = LITTLE
PORT m_axis_tstrb = "", DIR = O, VEC = [((C_M_AXIS_DATA_WIDTH/8)-1):0], ENDIAN = LITTLE
PORT m_axis_tvalid = "", DIR = O
PORT m_axis_tready = "", DIR = I
PORT m_axis_tlast = "", DIR = O
PORT s_axis_tdata = "", DIR = I, VEC = [(C_S_AXIS_DATA_WIDTH-1):0], ENDIAN = LITTLE
PORT s_axis_tstrb = "", DIR = I, VEC = [((C_S_AXIS_DATA_WIDTH/8)-1):0], ENDIAN = LITTLE
PORT s_axis_tvalid = "", DIR = I
PORT s_axis_tready = "", DIR = O
Esto hace que no sean reconocidas como puertos funcionales en el XPS. Borra estas líneas y
reemplázalas por lo siguiente:
############################################################################################
##########################PARAMETROS DE LA INTEFAZ AXI-Stream#################################
############################################################################################
BUS_INTERFACE BUS = M_AXIS, BUS_STD = AXIS, BUS_TYPE = INITIATOR #Interfaz axi master stream
BUS_INTERFACE BUS = S_AXIS, BUS_STD = AXIS, BUS_TYPE = TARGET #interfaz axi slave stream
PARAMETER C_M_AXIS_DATA_WIDTH = 32, DT = INTEGER, BUS = M_AXIS
PARAMETER C_S_AXIS_DATA_WIDTH = 32, DT = INTEGER, BUS = S_AXIS
PARAMETER C_M_AXIS_PROTOCOL = XIL_AXI_STREAM_ETH_DATA, DT = STRING, BUS = M_AXIS
PARAMETER C_S_AXIS_PROTOCOL = XIL_AXI_STREAM_ETH_DATA, DT = STRING, BUS = S_AXIS

PORT axi_aclk = "", DIR = I, SIGIS = CLK, BUS = M_AXIS:S_AXIS


PORT axi_resetn = ARESETN, DIR = I, SIGIS = RST, BUS = M_AXIS:S_AXIS

#PORT m_axis_aresetn = ARESETN, DIR = O, BUS = M_AXIS


PORT m_axis_tdata = TDATA, DIR = O, VEC = [C_M_AXIS_DATA_WIDTH-1:0], BUS = M_AXIS, ENDIAN = LITTLE
PORT m_axis_tstrb = TSTRB, DIR = O, VEC = [(C_M_AXIS_DATA_WIDTH/8)-1:0], BUS = M_AXIS, ENDIAN = LITTLE
PORT m_axis_tvalid = TVALID, DIR = O, BUS = M_AXIS
PORT m_axis_tready = TREADY, DIR = I, BUS = M_AXIS
PORT m_axis_tlast = TLAST, DIR = O, BUS = M_AXIS

#PORT s_axis_aresetn = ARESETN, DIR = I, BUS = S_AXIS


PORT s_axis_tdata = TDATA, DIR = I, VEC = [C_S_AXIS_DATA_WIDTH-1:0], BUS = S_AXIS, ENDIAN = LITTLE
PORT s_axis_tstrb = TSTRB, DIR = I, VEC = [(C_S_AXIS_DATA_WIDTH/8)-1:0], BUS = S_AXIS, ENDIAN = LITTLE
PORT s_axis_tvalid = TVALID, DIR = I, BUS = S_AXIS
PORT s_axis_tready = TREADY, DIR = O, BUS = S_AXIS
PORT s_axis_tlast = TLAST, DIR = I, BUS = S_AXIS
En el menú Project haz click en Rescan User Repositories. Ahora tu módulo estará con las otras dos
interfaces agregadas:

Finalmente ya tenemos nuestro periférico listo para ser usado en un proyecto. El siguiente paso
será verificar su funcionamiento.
VERIFICACION DEL FUNCIONAMIENTO DEL MODULO
Vamos a realizar la conexión entre el microblaze y nuestro periférico. Ya que la interfaz stream del
microblaze no usa las señales STRB, no puede hacerse la conexión directamente en la vista de
interfaz de buses, tiene que pasarse a la vista Puertos. En esta se conectan las señales del
periférico con las respectivas señales del microblaze del siguiente modo:

Aun habiendo hecho estas conexiones, no se reflejara en la vista de Interfaces de bus. Revisa las
conexiones de los relojes y la asignación de direcciones de memoria. El diseño está listo para
compilarse y grabarse en el FPGA.
SOFTWARE DE VERIFICACION

Exporta el diseño al SDK Eclipse para programar el software del microblaze que se encarga de
verificar el funcionamiento de este módulo. Usa el siguiente programa para verificar el diseño:
#include <stdio.h>
#include "platform.h"
#include "xparameters.h"
#include "xbasic_types.h"
#include "xutil.h"
#include "fsl.h"

int main()
{
int j;
printf("Hello World\n\r");
unsigned int readed;
for(j=0; j< 4; j++){
myNor[j] = 0x01U;
readed = (myNor[j]);
}
volatile unsigned int* myNor = XPAR_MY_FIRST_IP_0_BASEADDR;
init_platform();
unsigned int writed = 0x32U;
putfslx(writed, 0, FSL_NONBLOCKING);
getfslx(readed, 0, FSL_NONBLOCKING);

cleanup_platform();

return 0;
}

Al momento de depurar el programa revisa los valores de la variable readed, versa que va
cambiando de acuerdo a lo que se espera del diseño.

ENLACES
 Documentación de Xilinx sobre sus herramientas de desarrollo:
http://www.xilinx.com/support/documentation/

También podría gustarte