miércoles, 30 de noviembre de 2011

Problemas con System Generator / Simulink - 1

Hace poco terminé de dictar uno de mis cursos favoritos basado en el flujo de diseño DSP/FPGA. El curso tuvo mucho éxito, pero como siempre que se implementa algo surgen problemas que solo aparecen cuando uno hace algo.... la teoría es muy linda hasta que  se tiene que implementar.... :) . . . 

Uno de los grupos de alumnos, Layla y Esteban, tuvieron problemas que no estaban documentados por ningún lado, y a fin de que Uds. no gasten tanto tiempo como ellos en encontrar soluciones, decidieron compartir problemas con soluciones. 

Problema 1- Error Debido a la Configuración de Idiomas de la PC
Dentro de un bloque Simulink cuando se le asigna una constante expresada en decimal a un bloque 'CMult' de System Generator, y luego al querer simular el sistema aparece un error relacionado al bloque pero cuyo mensaje es bastante encriptado.... 




Seguramente este mensaje de error es generado porque existe un problema de 'mal entendimiento' en la representación de números decimales: System Generator lo representa de un modo diferente al modo representado por el sistema operativo de la PC. Esto es muy común que nos pase a los que tenemos la PC configurada para el idioma español. Por defecto el número decimal, en todas las opciones del español, se representa con una coma. Mientras que System Generator lo representa con un punto. entonces !, existe una incongruencia que el compilador no sabe que hacer y genera el mensaje de error encriptado. En el ejemplo mostrado en la figura arriba el error se genera por querer asignar un valor de 2,3 a CMult. Si en su lugar se asigna 2.3  no existe ningún error. 

Solución
Cambiar la configuración regional de su PC a Inglés: Panel de Control -> Opciones Regionales y Lenguaje.

viernes, 11 de noviembre de 2011

Error: "Port 'clock' has illegal connections.This port is connected to an input buffer and other componentes"

Este mensaje de error realmente no de mucha idea de cual es el problema, es por ello que deseo aclararlo acá.

Lo que realmente significa este mensaje, es que la entrada de reloj () está siendo ruteada al buffer de entrada y de alli a un DCM, por ejemplo. Por ello no es posible usar esta misma señal de entrada, clock, como señal de reloj en cualquier componente sincrónico. Esto se debe a que cuando uno usa un DCM el ruteo entre el pin de entrada y el DCM es un ruteo dedicado de bajo skew y bajo retardo, y no tiene derivaciones, es decir no puede usarse esa señal en otro lugar porque no tiene ruteo disponible. Así, el unico reloj disponible es la salida del DCM. 

Un solución a este problema es usar otro pin de E/S por el que entra el mismo reloj, pero sin enviarlo a un DCM. En este caso se puede usar un pin E/S como entrada de reloj del DCM, y otro pin E/S, con el mismo reloj, que puede ser usado para los componentes sincronicos que necesiten ser controlados por este reloj. 

La otra solución es usar también dos pines E/S, y dos DCMs, uno para cada frecuencia de trabajo que se necesite.

Greetings..... 

viernes, 28 de octubre de 2011

Generando el Hex del ASCII para ROM/RAM usando Matlab

En un previo post , http://hdl-fpga.blogspot.com/2011/06/memorias-rom-fpga-vhdl-como.html, detallé la codificación en VHDL para inferir memorias ROM e implementarlas en FPGAs. Una de las partes mas 'aburridas' de esta codificación es primero pasar de la letra al ASCII y después del ASCII al Hex respectivo. Especialmente para el caso de un string o número muy largo, o varios strings. 
Por ello, en uno de mis últimos cursos que dicté uno de mis alumnos no quería 'aburrirse' realizando las dos conversiones, entonces uso sus conocimientos y me presentó una solución tan ingeniosa como efectiva: escribió una pequeña función en Matlab que hace no solo las mencionadas conversiones sino que también genera directamente la sintaxis VHDL respectiva para la asociación del arreglo ROM  con sus valores respectivos. Gracias Ihosvanni por evitar que nos aburramos !. Acá va un screenshot del .m:




Básicamente lo que hace este código .m es tomar tres mensajes, y convertirlos en ASCII y luego al Hex respectivo. Para este caso planteado el resultado de la ejecución es algo como esto: 

0=>x"56",1=>x"61",2=>x"6C",3=>x"6F",4=>x"72",
5=>x"65",6=>x"73",7=>x"20",8=>x"64",9=>x"65",
. . . . . .
51=>x"20",52=>x"21",others=>x"20"


Así, lo único que queda por hacer es copiar y pegar estos valores en el arreglo ROM declarado tal como se detalló en el previo bloq. 
Este .m se puede perfectamente adaptar a distintos casos, por ejemplo remover mensajes, agregar más mensajes, etc. Por supuesto tener la precaución de que si se remueve algún mensaje, se deben remover todas las referencias al mismo, si se agregan mensajes, agregar las referencias respectivas. También se puede usar para casos en los que se quiere inicializar una memoria tipo RAM con un arreglo definido tal como se detalla en el previo blog.

El código Matlab lo puedes bajar de este link: ascii2rom.m

Espero que sea de utilidad, si es así ... bueno, házmelo saber ! 

jueves, 27 de octubre de 2011

Mensaje de error: "Can't find net or instance name"

Este mensaje suele ser comun cuando queremos restringir (constraint) alguna net o componente de nuestro diseño mediante el uso de constraints en el .ucf. Usualmente eso se debe a que en el .ucf usamos un nombre, normalmente el nombre de la señal o componente en nuestro código VHDL/Verilog, que la herramienta de Síntesis o de Place and Route modificó y nosotros no nos enteramos y consecuentemente el constraint usado en el .ucf hace alusión a una señal o componente que no existe. 
Xilinx ofrece un programa, ejecutable desde comando de linea, llamado netgen, que lee el archivo .ngc o .ngd del sistema implementado y genera el .vhd o .v respectivo para llevar a cabo una simulación funcional (usando .ngc) o post place and route simulación (usando el .ngd). Aún cuando la idea no es llevar a cabo la simulación, el archivo .vhd/.v puede perfectamente ser usado para los fines que buscamos: encontrar los nombres de la señal o componente que necesitamos restringir. 
Los pasos a seguir para usar netgen son similares a los ya explicados anteriormente para pasar de .ngc a .vhd, pero acá los detallos de nuevo.

Pasos para usar 'netgen' (para pasar de .ngc a .vhd) 
  1. Abrir una ventana de 'comandos' o 'DOS': Inicio -> Ejecutar. En la ventanita que se abre escribir 'cmd' y presione 'Aceptar'. 
  2. La ventana de comandos de Window se abrirá normalmente en tu directorio de documentos. 
  3. Usando el viejo comando 'cd' ir hasta el directorio donde está el archivo .ngc que se desea convertir.
  4. Escribir 'netgen -ofmt vhdl mi_archivo.ngc' y presione enter para generar el archivo 'mi_archivo.vhd'. En caso de obtener un mensaje de error diciendo que no reconoce como ejecutable al programa 'netgen', deberá anteponerle el camino del directorio donde reside el ejecutable, por ejemplo:
  5. f:\mi_proyecto>f:\Xilinx\12.1\ISE_DS\ISE\bin\nt\netgen -ofmt  mi_archivo.ngc 
    Si deseas que el archivo .vhd tenga otro nombre usá el siguiente comando: 
    f:\mi_proyecto>f:\Xilinx\12.1\ISE_DS\ISE\bin\nt\netgen -ofmt  mi_archivo.ngc mi_vhd.vhd
Ahora si ya podés abrir el .vhd y buscar las señales o componentes de tu interés. Si bien el archivo .vhd, que en realidad es un modelo de simulación del  sistema implementado. Parece bastante complicado, pero se puede 'leer' e interpretar la implementación, notando el uso de componentes tipo 'primitivas'. Usando un 'search' o búsqueda podemos encontrar las señales o componentes que necesitamos. 

miércoles, 26 de octubre de 2011

Necesitas pasar de .ngc a .edf ?

Como bien es sabido las herramientas de síntesis producen como resultado un archivo comúnmente llamado EDIF (Electronic Design Interchange File) cuya extensión es .edf que básicamente describe en un formato de texto los componentes del diseño y sus conexiones (netlist). Este tipo de archivos es independiente del fabricante de la herramienta de síntesis, teniendo como objetivo establecer un formato común entre los diferentes vendedores de herramientas EDA (Electronic Design Automation). A pesar de ser un formato comumnente adaptado y usado, Xilinx prefirió tener su propio archivo resultado de síntesis llamado NGC, .ngc, que en realidad contiene información del netlist y del archivo de restricciones físicas (llamado .ncf). Este archivo .ngc NO es un archivo de texto por lo que no se puede leer. Sin embargo, sabiendo Xilinx que a algunos Ingenieros nos gusta saber que hay en el netlist, ofrece un ejecutable que convierte de .ngc a .edf. Este program se llama ngc2edif.exe y se debe ejecutar desde una ventana tipo DOS. 

Pasos para convertir NGC a EDIF
  1. Abrir una ventana de 'comandos' o 'DOS': Inicio -> Ejecutar. En la ventanita que se abre escribir 'cmd' y presione 'Aceptar'. 
  2. La ventana de comandos de Window se abrirá normalmente en tu directorio de documentos. 
  3. Usando el viejo comando 'cd' ir hasta el directorio donde está el archivo .ngc que se desea convertir.
  4. Escribir 'ngc2edif.exe mi_archivo.ngc mi_archivo.edf' y presione enter. En caso de obtener un mensaje de error diciendo que no reconoce como ejecutable al programa 'ngc2edif', deberá anteponerle el camino del directorio donde reside el ejecutable, por ejemplo:
  5. f:\mi_proyecto>f:\Xilinx\12.1\ISE_DS\ISE\bin\nt\ngc2edif mi_archivo.ngc mi_archivo.edf
  6. Ahora ya podés abrir el .edf y 'ver' el netlist respectivo...

domingo, 21 de agosto de 2011

Como almacenar en ROM un archivo de audio en Simulink/SysGen

Describiré a continuación los pasos necesarios para poder usar una memoria ROM como medio para almacenar los datos digitalizados de un archivo de audio. Posteriormente, una vez con los datos en la ROM, es posible llevar a cabo el necesario procesamiento de la senal. En caso de implementar el diseño en el FPGA, la inicialización de la memoria ROM es automáticamente llevada a cabo. 

Características del Bloque ROM de SysGen
- Datos son almacenados por individualmente, por palabra, y todos los datos tienen el mismo tipo (signed, unsigned, etc.), el mismo ancho (cantidad de bits) y la misma posición para el punto binario. 
- Cada dato es asociado con exactamente una dirección de memoria.
- El rango de direcciones de la memoria es desde 0 hasta N-1, siendo N la profundidad de la memoria (cantidad de datos). 
- La dirección de la memoria debe ser controlado por un dato entero, sin signo (unsigned) y en tipo punto fijo. 
- El bloque ROM tiene un puerto de entrada para las direcciones, y un puerto de salida para los datos de salida. 
- El bloque ROM puede ser implementado en:
    - RAM distribuida (LUTs y lógica discreta asociada).
    - Bloque dedicados de memoria RAM. 
- La performance máxima de un bloque ROM se logra cuando: 
    - La opción 'Provide reset port for output register' no es seleccionada. 
    - La opcion 'Depth' es menor a 16.384.
    - La 'Latency' es 2 o mayor. 

Como calcular el tamaño del Bloque ROM
Para poder almacenar un archivo de audio en un Bloque ROM es necesario saber el tamano del archivo a fin de poder dimensionar la ROM, pues los parametros principlaes del bloque ROM, tal como se vera mas abajo, son su profundidad (cantidad de datos) y el ancho del datos (cantidad de bits por dato). 
Para obtener esta informacion se hace uso de algunas funciones basicas de Matlab, las cuales son ejecutadas en la ventana de comandos de Matlab:
- 'wavread': ésta función lee un archivo de audio tipo wave, .wav, de Microsoft. 
   Uso 1:
          archivo_audio = wavread('musica.wav);
le asigna a la variable archivo_audio los datos del archivo musica.wav.
   Uso 2:
          tamano = wavread('musica.wav', 'size');
le asigna a la variable tamano la cantidad de datos del archivo 'musica'wav'. 
   Uso 3:
          [archivo_audio_1, Fs, nbits] = wavread('audio.wav');
le asigna a la variable archivo_audio_1 los datos del archivo musica.wav; a la variable Fs la frecuencia de muestreo del archivo musica.wav y a la variable nbits el numero de bits por muestra. 
- 'size': esta función también puede usarse para determinar el tamaño del archivo correspondiente. 
   Uso: 
       tamano_2 = size(wavread('musica.wav'),1);
Notar que el uso de size('  ',1); retorna la cantidad de filas del arreglo '   ', mientras que size('  ',2) retorna la cantidad de columnas del arreglo. 

A continuación se muestra la ejecución de los comandos detallados arriba y su correspondiente resultado en la ventana workspace. 




Configuración de los Parámetros del Bloque ROM
Una vez ejecutados los comandos descritos anteriormente, se puede proceder a la configuración de los parámetros del bloque ROM. Para ello, por supuesto, se debe agregar el bloque ROM al sistema que se quiere diseñar en Simulink. Al hacer doble click sobre el bloque ROM se abrirá la ventana de configuración del bloque. 
Tab 'Basic': 
A fin de escribir los parámetros en forma genérica se puede configurar la ROM usando los comandos antes ejecutados. Estos se detallan en la siguiente figura. 




Tab 'Output Type':
en este tab los parametros se refieren al dato de salida. Por supuesto que existe una relacion directa entre el dato que se grabo en la ROM con el dato que sale de la ROM. Como la grabacion o almacenamiento del dato se hizo en forma automatica, de algun modo se debe conocer el rango de los datos almacenados en la ROM a fin de que los datos de salida sean configurados de modo que se pueda reproducir la senal correctamente. 
Para ello se puede ejecutar en la ventana de comandos de Matlab el comando: 


        rango_datos=wavread('musica.wav')


Para luego inspeccionar la variable rango_datos al presionar dos veces sobre la misma en la ventana Workspace, Así, se mostrará en la ventana 'Variable Editor' del entorno Matlab, todos los datos de la respectiva variable. Por ejemplo, comúnmente se puede observar que los datos .wav tienen un rango desde +1.0 a -1.0. También es posible obtener estos valores usando: 


       max(rango_datos)


       min(rango_datos)

Basado en lo valores obtenidos, +1.0 a -1.0, se puede decir que se necesitan como mínimo 2 bits para la parte entera. Mientras que para la parte decimal, la cantidad de bits dependerá de la precisión que se desea. Aunque una gran precisión implica una gran numero de bits, lo que implica mayores recursos, sobre todo mayor cantidad de bloques ROM. Un valor de compromiso puede ser 6 bits para la parte decimal. La configuracion para este tab puede verse en la siguiente figura. 




Direccionamiento del Bloque ROM 

Normalmente se usa un contador para generar las direcciones del bloque ROM. El contador debe contar desde la dirección 0 hasta la máxima dirección de memoria, que es el valor asignado al parámetro 'Depth' durante la configuración del bloque ROM. 




Esquema del Sistema con Bloque ROM 
Finalmente juntando los bloques, el sistema debería ser semejante al mostrado a continuación.  
Bien, espero que esta guía te haya ahorrado mucho tiempo.... pues yo perdí un monnnnnnnnnnnnnnnnnnntón de tiempo buscando algo similar que nunca pude encontrar.... :) 



miércoles, 10 de agosto de 2011

System Generator: Co-Simulación en Hardware

La idea de este blog es presentar los pasos necesarios para llevar a cabo la Co-Simulación en Hardware (CSH) de un sistema construido en Simulink usando los bloques del Xilinx Blockset. La teoría detrás de todo esto está bastante detallada en los documentos provistos por Xilinx, así es que no abarcaré la misma. 
Qué es CSH? 
Es una herramienta disponible en el ambiente de desarrollo Simulink/System Generator que permite co-simular en hardware lo que se simula en software. Veamos que significa esto: En primer lugar cuando uno trabaja en el entorno Simulink/System Generator los sistemas que se construyen son simulados en ese mismo entorno, es decir TODO se realiza en software. Sin embargo se puede fácilmente construir el hardware equivalente de ese sistema (construido en software), configurar el FPGA respectivo, y simular en hardware lo mismo que se simular en software e incluso al mismo tiempo. Por eso, este proceso es justamente llamado 'Co-Simulación', porque se simulan ambos sistemas, hardware y software, al mismo tiempo. 
Pasos a seguir:

Paso 1:
Sigue los pasos que normalmente ejecutas para construir tu sistema en Simulink. A modo de ejemplo, supongamos que ya he construido el siguiente sistema y lo quiero co-simular. 




Paso 2:
Compilar el sistema para CSH: abrir el bloque 'System Generator', y en 'Compilation' seleccioná 'Hardware Co-Simulation'. Aparecerá un menú de los boards que por defecto trae instalado System Generator, tal como se muestra en la siguiente figura. 




En este paso debes, cuidadosamente, seleccionar el board que va ser usado para la co-simulación, y a su vez que tipo de conexión usarás para comunicar el board (JTAG o Ethernet) con la PC. En caso de que el board no aparezca dentro del listado de los boards que vienen por defecto, deberás seguir todo un procedimiento para agregar el board a la lista de boards disponibles. Este procedimiento ya lo expliqué en un blog anterior "Como agregar el XUPV5 board para Co-Simulación en Hardware".
Como voy a usar el XUPV5 para la Co-Simulación, y además como ya seguí los pasos del blog mencionado anteriormente (que buen blog !!! :) ), selecciono XUPV5 JTAG para la compilación del sistema. 






Paso 3:
Presionar 'Generate' para comenzar la 'Compilación del Sistema'. Qué genera 'Generate'? 
  • El hardware asociado con el sistema en Simulink
  • La interface física para la comunicación entre la PC y el board XUPV5.
Si una presiona la opción 'Show Details' de la ventana de compilación, se puede ver los diferentes pasos que se ejecutan durante 'Generate'. En sí lo que se ejecuta es un script que invoca todas las herramientas del ISE necesarias para llegar finalmente al archivo de configuración del FPGA. Es decir herramientas como XST, Translate, MAP, P&R, TRACE, y BitGen. 


Paso 4:
Terminada la compilación System Generator crea un nuevo bloque. Este bloque es la versión 'hardware' del sistema en Simulink (versión software). 
Este bloque hardware se usará en el sistema que se desea co-simular. Debes copiar y pegar este bloque tal como muestra la siguiente figura. 


Este bloque se usa igual que cualquier otro bloque del sistema, es decir se pueden excitar sus entradas y leer sus salidas. Durante la co-simulación el bloque CSH interactúa con el board para:
  • Configurar el FPGA
  • Control del reloj del board.
  • Transmisión y Recepción de datos a y desde el FPGA por medio del cable JTAG
Este bloque tiene unos parámetros de configuración que es conveniente modificarlos tal como se detalla en el siguiente paso. 



Paso 5:
Abrí el bloque CSH, comúnmente llamado 'JTAG Cosim', presionando dos veces el mouse sobre el bloque. La ventana de configuración del bloque aparecerá tal como se muestra a continuación. 


Dejar las opciones que por defectos son mostradas. 
En la opción de 'Cable' usá la siguiente configuración: 
  • Type: Xilinx Platform USB (o el tipo de cable que usa para la conexión PC-Board).
  • Speed: 1.5MHz


Si durante este paso el board está conectado, puedes usar la opción 'Blink Cable LED' para comprobar si la conexión PC-Board es correcta. 

Paso 6:
Volviendo al sistema en Simulink, conectá la(s) entrada(s) del bloque CSH o JTAG Cosim, a lo(s) mismo(s) estímulos usados para los otros bloques. La salida conéctela a un 'Sink' similar al usado para el sistema, facilitando así la comparación. Debajo puede observar el sistema que he completado en este paso. 


Paso 7:
Verificá que el board esté conectado a la PC por medio del cable oportunamente seleccionado en la configuración del bloque JTAG Cosim (Paso 5), y que el board esté encendido.
Ejecutá  la simulación como siempre lo haces.
Los dos sistemas son simulados al mismo tiempo, y como 'teóricamente' son los mismos sistemas, uno en software y otro en hardware, las formas de ondas vistas en los bloques 'Sink' deberían ser las mismas tal como se muestra en la siguiente figura. 



Si has llegado a este punto solo leyéndo,.... bueno es hora de 'meterle manos' al hardware y animarte a hacer una Co-Simulación... eso sí, me contas como salió todo ! :) ... 

Hasta la próxima...


Version .pdf del blog? presiona acá :) 

Como agregar el XUPV5 board para Co-Simulación en Hardware con System Generator/Simulink

Co-Simulación en Hardware (Hardware Co_Simulation) es una poderosa herramienta en el ambiente de desarrollo Simulink-System Generator. Permite al diseñador simular en 'paralelo' en real-hardware, lo mismo que se simula en software usando los bloques de SysGen. 
Cando uno installa la version full de ISE, al instalar System Generator por defecto se instalan lo que se llaman 'plug-in' de los boards DSP de Xilinx. Sin embargo, dado que el XUPV5 board no es considerado un 'board DSP' no aparece en la lista de opciones de los boards para llevar a cabo co-simulation. Si aparece el ML505 board, que CASI igual que el XUPV5, pero con una 'pequeña' diferencia: el ML505 tiene un Virtex 5 XC5VLX50T, mientras que el XUPV5 tiene un XC5VLX110T. Pequeña gran diferencia que hace que NO se pueda usar el plug-in del board ML505 para el board XUPV5. Entonces... cual es la salida/solución si uno tiene el XUPV5 y quiere hacer Co-Simulación?????? 

Agregando el XUPV5 a la Lista de Boards de Co-Simulación
Paso 1:
Una vez abierto Simulink y abriendo colocado el bloque 'System Generator' en un diseño cualquiera, abrir el bloque 'System Generator' (doble click sobre el bloque). La ventana de configuración del bloque 'SysGen' aparecerá. Seleccione en 'Compilation' la opción 'Hardware Co-Simulation', y luego en el menú siguiente seleccione 'New Compilation Target'. 




Paso 2:
La ventana 'System Generator Board Description Builder' se abrirá. 




En esta ventana hay varios elementos a configurar. 
Paso 3: 
'Target Board Identification': Board Name: puede usarse cualquier nombre. Convenientemente use uno que facilite la identificación del board. Por ejemplo, XUPV5.
Paso 4:
'System Clock': 1- Frequency(MHZ): escribir la frecuencia del reloj del board que se usará normalmente como fuente de reloj para el FPGA. El oscilador de entrada al LX110T es de 100MHz. 2- Pin Location: el pin de E/S por el cual entra el oscilador el FPGA: AH15.
Paso 5:
'JTAG Options': por defecto la comunicación entre el board y el PC es hara usando JTAG. Hay otra opción que es la de usar Ethernet, pero como la configuración es mas complicada explicare ahora la de JTAG, después, de acuerdo a los pedidos, puedo explicar la de Ethernet. Las opciones de la configuración JTAG son: 1- Boundary Scan Position: esta es la posición del FPGA en la cadena JTAG de dispositivos en el board. El valor a introducir acá es 5, es decir es el quinto dispositivo de la cadena. Usando iMPACT es posible 'ver' la cadena y deducir la posición del FPGA. 2- IR Length: este es un parámetro necesario para la comunicación a través de JTAG. Si está el board conectado a su PC/Laptop por medio del cable JTAG, presione 'Detect' para que automáticamente se invoque iMPACT y llene los datos requeridos. Sino tiene el board conectado directamente escriba: 16,16,8,8,10.


Paso 6:
'Targetable Devices': en esta sección se debe introducir el FPGA que usa el board XUPV5. Click 'Add' y seleccione: Virtex 5, XC5VLX110T, Speed -1, package ff1136. Click OK.
Hasta acá la configuración de esta ventana debería ser similar a la mostrada a continuación: 


Paso 7:
En la sección 'Non-Memory Mapped Ports' click el botón 'Add' para agregar algunos puertos de E/S del FPGA que considere necesarios. La ventana 'Configure a Port' aparecerá. Introduzca el nombre del puerto de E/S, seleccione la direccion del mismo, y la ubicacion (Location). Opcionalmente puede tambien seleccionar si el puerto deber ser configurado con el resistor de Pullup o Pulldown. Una vez terminado con estas configuraciones, Click 'Add Pin'. El puerto de E/S configurado sera ahora mostrado en la parte llamada 'Pin List'. Para introducir otro puerto seleccione 'Save and Starte New'. Se pueden introducir tantos puertos como hagan falta. Una vez concluida esta tarea, presione 'Save and Close'.




Nota importante: Se aclara que este paso es totalmente OPCIONAL para la Co-Simulación. 


Paso 8:
Una vez completados los pasos anteriores, la siguiente figura debería ser similar a la que tienes en tu computadora (excepto por los 'Non-Memory Mapped Ports', que pueden no estar o pueden ser otros)




Paso 9:
Presionar 'Install' para instalar la configuracion del XUPV board en el directorio de plug-in de SysGen.




Navegue hasta el directorio:  ../Xilinx/
 En ese directorio debería ahora aparecer el directorio XUPV5 JTAG, tal como muestra la siguiente figura: 




Paso 10:
Finalizada la instalación un ventana de Simulink aparecerá con los puertos de E/S configurados. 




Grabe la librería de los puertos de E/S. Estos puertos pueden ahora usarse en cualquier sistema con System Generator. 

Paso 11:
Para probar que todo esta instalado correctamente. Cierre Matlab y luego ábralo nuevamente. En cualquier sistema de Simulink con el bloque System Generator, abra el bloque System Generator, y seleccione en 'Compilation', 'Hardware Co-Simulation'. Ahora deberia aparecer en la lista XUPV5 JTAG. 




Paso 12:
Listo ! ... el XUPV5 puede ahora usarse para correr Co-Simulación en Hardware de su sistema Simulink. 

Versión pdf   :)


domingo, 7 de agosto de 2011

Navegador de Documentos de Xilinx (Xilinx Document Navigator) -> Muy Recomendable

Xilinx ofrece una herramienta para controlar sus miles de documentos de una manera muy facil.... En realidad es una herramienta poco conocida, pero que la recomiendo mucho mucho para los que trabajamos con esta empresa.

El software Xilinx Document Navigator (XDN) puede ser bajado del sitio de soporte de Xilinx http://www.xilinx.com/support/ . En la columna identificada como "Additional Resources" se encuentra el link para descargar la herramienta "Download Documentation Navigator", que está comprimida e nun archivo .zip. Installe el XDN siguiendo las indicaciones respectivas. 
Al abrir el XDN lo primero que debería hacer es configurar el directorio donde quiere que los documentos a ser descargados sean grabados. Para ello presione el mouse sobre el icono
La ventana de 'Preferences Dialog' se abrirá. Escriba el directorio que desea usar como directorio raíz de sus documentos a descargar. La siguiente figura muestra un ejemplo de configuración. 




Ahora sí podemos empezar a familiarizarnos con el XDN.
La ventana principal es mostrada en la siguiente figura: 




Veamos los puntos importantes: 
  1. La primer columna sobre la izquierda es la que determina que documentos serán mostrados en la columna (ventana) principal. Por defecto todos los documentos son seleccionados. Uno puede seleccionar los docs a mostrar posicionando el mouse sobre el producto a seleccionar, entonces sobre la derecha del producto aparece una flecha verde, presione sobre la flecha para seleccionar ese producto en particular. Inmediatamente la columna principal de documentos sera actualizada para mostrar los documentos seleccionados. XDN ofrece también la posibilidad de grabar una configuración de selección de productos que uno puede invocar posteriormente. Por ejemplo, si te interesan nada mas que los docs relacionados al V5, puedes seleccionar Virtex-5 tal como se explicó recientemente, y luego presionar boton derecho y seleccionar 'Save Settings As', y en la ventana de dialogo escriba V5 por ejemplo. Ahora en el 'pull-down' menú de la primer columna podrás elegir entre la configuración por defecto, 'All Documents' y la((s) configuración(es) que tu  crees. 
  2. La ventana principal muestra los documentos seleccionados. De estos docs hay mucha información detallada, entre la mas importantes está:
    • Columna de 'Location' (ubicación), indica si el doc es un doc que está en la web site de Xilinx, indicado como 'Web', o fué descargado y esta en el directorio de descarga de los docs, estos están indicados como 'Local'. Una tercera opción es para los docs que son solo para ser vistos en la web de Xilinx, indicados como 'Web Only', es decir no se pueden descargar estos docs.  
    • Columna 'Status', indica si el doc respectivo ha sido actualizado a una nueva versión, o si es un doc nuevo, o si ha sido removido.
  3. El icono de búsqueda (binoculares) abre una nueva ventana en la que es posible escribir la palabra de búsqueda, la cual será buscada en los documentos mostrados en la columna de documentos. Los docs que tienen la palabra buscada son mostrados en orden, colocando primero el doc que mas 'hits' tiene. 
Para descargar un doc de interés solo se debe seleccionar el doc,  colocando el mouse sobre el mismo, presionar botón derecho del mouse y seleccionar 'Download Document'. Lo mejor de esta herramienta que el doc que se descarga se graba en el directorio raíz, previamente configurado (tal como se explicó anteriormente), y en subsiguientes sub-directorios que la herramienta crea de acuerdo al producto origen del doc. Por ejemplo, si se descarga el doc " ML505/ML506/ML507 Reference Design User Guide", el doc será grabado en el directorio "/Virtex-5/documentation/boards_and_kits/" . Esto creo que es lo mejor de esta herramienta!! Una vez descargado un doc, en la columna 'Location' aparecerá ahora 'Local' (en lugar de Web), y en la columna 'Status' aparecerá 'Downloaded' (descargado). 
Lo unico que no me gusta es que los docs que uno ya ha descargado no son reconocidos por XDN, por lo que se deberian descargar de nuevo para que XDN los vea y los grabe en el directorio respectivo. De todos modos: 

La verdad es que hubiera deseado saber de esta herramienta antes !

jueves, 14 de julio de 2011

Qué es, Cómo, Cuando y Dónde usar Pipelining (Segmentación) ?

Pipelining es una técnica de diseño que se usa en sistemas digitales para mejorar el rendimiento (performance) de un sistema al dividir largo retardos combinacionales y de ruteo ejecutados en un solo ciclo de reloj, en varios pequeños retardos (cmb+ruteo) que son ejecutados en ciclos de reloj mucho mas cortos o en el mismo ciclo original pero ahora con mayor slack. 
Como siempre hay un 'pro' y un 'contra': se mejora la performance, pero se incrementa la latencia. 
Veremos a continuación en detalle como determinar si hace falta pipeline el diseño, como hacerlo y sus concecuencias. 

Cómo saber si hace falta Pipelining? 
La mejor manera es analizando la información dada por la herramienta de análisis de tiempo (Timing Analysis en Xilinx, TimeQuest en Altera, SmartTime en Actel). Esta herramienta analiza todos los caminos sincrónicos del sistema y verifica que el sistema pueda funcionar a la frecuencia solicitada de acuerdo a la restricción (constraint) respectiva del reloj configurada por el diseñador. Si el sistema puede funcionar a la frecuencia requerida el valor del slack es positivo; si el slack es negativo indica que el sistema no puede funcionar correctamente es la frecuencia requerida. Una técnica para solucionar el slack negativo o para mejorar un slack positivo muy pequeño es el reducir el retardo (lógico + ruteo) en el o los caminos críticos. Por ejemplo, a continuación se muestra el informe, dado por la herramienta de análisis del FPGA, del camino mas crítico de un sistema: 

Slack (setup path):     -1.576ns (requirement - (data path - clock path skew + uncertainty))
  Source:               in6_reg_3 (FF)
  Destination:          out_reg_15 (FF)
  Requirement:          7.500ns
  Data Path Delay:      9.076ns (Levels of Logic = 10)
  Clock Path Skew:      0.000ns
  Source Clock:         clk_BUFGP rising at 0.000ns
  Destination Clock:    clk_BUFGP rising at 7.500ns
  Clock Uncertainty:    0.000ns

  Maximum Data Path: in6_reg_3 to out_reg_15
    Location             Delay type         Delay(ns)  Physical Resource
                                                       Logical Resource(s)
    -------------------------------------------------  -------------------
    SLICE_X12Y35.XQ      Tcko                  0.592   in6_reg<3>
                                                       in6_reg_3
    SLICE_X12Y42.F2      net (fanout=1)        1.054   in6_reg<3>
    SLICE_X12Y42.X       Tilo                  0.759   s3<3>
                                                       s3<3>1
    SLICE_X13Y43.G1      net (fanout=1)        0.511   s3<3>
    SLICE_X13Y43.COUT    Topcyg                1.001   add2<2>
                                                       Madd_add2_lut<3>
                                                       Madd_add2_cy<3>
    SLICE_X13Y44.CIN     net (fanout=1)        0.000   Madd_add2_cy<3>
    SLICE_X13Y44.X       Tcinx                 0.462   add2<4>
                                                       Madd_add2_xor<4>
    SLICE_X16Y52.G3      net (fanout=3)        0.810   add2<4>
    SLICE_X16Y52.Y       Tilo                  0.759   Madd_add3C3
                                                       Madd_add3C31
    SLICE_X13Y52.BY      net (fanout=1)        0.682   Madd_add3C3
    SLICE_X13Y52.COUT    Tbycy                 0.972   out_reg<4>
                                                       Madd_add3_Madd_cy<5>
    SLICE_X13Y53.CIN     net (fanout=1)        0.000   Madd_add3_Madd_cy<5>
    SLICE_X13Y53.COUT    Tbyp                  0.118   out_reg<6>
                                                       Madd_add3_Madd_cy<6>
                                                       Madd_add3_Madd_cy<7>
    SLICE_X13Y54.CIN     net (fanout=1)        0.000   Madd_add3_Madd_cy<7>
    SLICE_X13Y54.COUT    Tbyp                  0.118   out_reg<8>
                                                       Madd_add3_Madd_cy<8>
                                                       Madd_add3_Madd_cy<9>
    SLICE_X13Y55.CIN     net (fanout=1)        0.000   Madd_add3_Madd_cy<9>
    SLICE_X13Y55.COUT    Tbyp                  0.118   out_reg<10>
                                                       Madd_add3_Madd_cy<10>
                                                       Madd_add3_Madd_cy<11>
    SLICE_X13Y56.CIN     net (fanout=1)        0.000   Madd_add3_Madd_cy<11>
    SLICE_X13Y56.COUT    Tbyp                  0.118   out_reg<12>
                                                       Madd_add3_Madd_cy<12>
                                                       Madd_add3_Madd_cy<13>
    SLICE_X13Y57.CIN     net (fanout=1)        0.000   Madd_add3_Madd_cy<13>
    SLICE_X13Y57.CLK     Tcinck                1.002   out_reg<14>
                                                       Madd_add3_Madd_cy<14>
                                                       Madd_add3_Madd_xor<15>
                                                       out_reg_15
    -------------------------------------------------  ---------------------------
    Total                                      9.076ns (6.019ns logic, 3.057ns route)
                                                       (66.3% logic, 33.7% route)

De este reporte los puntos mas importantes a analizar son los siguientes:  
1- Slack: en este caso es negativo (-1.576ns), lo que implica que el sistema no puede funcionar correctamente a la frecuencia requerida. 
2- Cantidad de niveles lógicos (logic levels): 10 en éste sistema. 
Con estos dos datos se puede deducir que, si el sistema lo permite, una solución para mejorar la performance del sistema es colocar flip-flops para cortar este larguísimo retardo combinacional y de ruteo. Ahora bien:

Dónde colocar los flip-flops de pipelining? 
Veamos, mediante el uso de otra herramienta disponible en todos los software de los distintos fabricantes de FPGA, normalmente llamada RTL Viewer, es posible 'ver' el esquemático, al nivel RTL, del sistema implementado. En la siguiente figura se muestra el RTL View generado por Quartus RTL Viewer del sistema bajo estudio: 




Al analizar el esquemático generado por el RTL Viewer es sencillo 'ver' el/los caminos de lógica combinacional más largos. Justamente estos caminos son los que se deben cortar colocando flip-flops. Así, los flip-flps de pipelining deberían ser: 4 sets de 16 flip-flops (bus es de 16 bits) a la salida de los multiplexer. 2 sets de 16 flip-flops entre los sumadores. Agregando estos flip-flops se corta el largo camino de 10 niveles lógicos (detallado por la herramienta de analisis de tiempo) y sus respectivos retardos de ruteo. De este modo, una vez modificado el código agregándole los respectivos flip-flops, se puede ver el RTL del 'nuevo' sistema:




Analizando ahora este sistema con la herramienta de análisis de tiempo da el siguiente resultado:



Slack (setup path):     2.452ns (requirement - (data path - clock path skew + uncertainty))
   Source:               add2_4 (FF)
   Destination:          out_reg_15 (FF)
   Requirement:          7.500ns
   Data Path Delay:      5.048ns (Levels of Logic = 6)
   Clock Path Skew:      0.000ns
   Source Clock:         clk_BUFGP rising at 0.000ns
   Destination Clock:    clk_BUFGP rising at 7.500ns
   Clock Uncertainty:    0.000ns
 
   Maximum Data Path: add2_4 to out_reg_15
     Location             Delay type         Delay(ns)  Physical Resource
                                                        Logical Resource(s)
     -------------------------------------------------  -------------------
     SLICE_X41Y29.XQ      Tcko                  0.514   add2<4>
                                                        add2_4
     SLICE_X15Y38.F1      net (fanout=1)        2.239   add2<4>
     SLICE_X15Y38.COUT    Topcyf                1.011   out_reg<4>
                                                        Madd_add3_lut<4>
                                                        Madd_add3_cy<4>
                                                        Madd_add3_cy<5>
     SLICE_X15Y39.CIN     net (fanout=1)        0.000   Madd_add3_cy<5>
     SLICE_X15Y39.COUT    Tbyp                  0.103   out_reg<6>
                                                        Madd_add3_cy<6>
                                                        Madd_add3_cy<7>
     SLICE_X15Y40.CIN     net (fanout=1)        0.000   Madd_add3_cy<7>
     SLICE_X15Y40.COUT    Tbyp                  0.103   out_reg<8>
                                                        Madd_add3_cy<8>
                                                        Madd_add3_cy<9>
     SLICE_X15Y41.CIN     net (fanout=1)        0.000   Madd_add3_cy<9>
     SLICE_X15Y41.COUT    Tbyp                  0.103   out_reg<10>
                                                        Madd_add3_cy<10>
                                                        Madd_add3_cy<11>
     SLICE_X15Y42.CIN     net (fanout=1)        0.000   Madd_add3_cy<11>
     SLICE_X15Y42.COUT    Tbyp                  0.103   out_reg<12>
                                                        Madd_add3_cy<12>
                                                        Madd_add3_cy<13>
     SLICE_X15Y43.CIN     net (fanout=1)        0.000   Madd_add3_cy<13>
     SLICE_X15Y43.CLK     Tcinck                0.872   out_reg<14>
                                                        Madd_add3_cy<14>
                                                        Madd_add3_xor<15>
                                                        out_reg_15
     -------------------------------------------------  ---------------------------
     Total                                      5.048ns (2.809ns logic, 2.239ns route)
                                                        (55.6% logic, 44.4% route) 


Fácilmente se puede observar el resultado de usar pipelining: se pasó de un slack negativo de -1.576ns a un slack positivo de +2.452ns. Del mismo modo, los niveles de lógica se redujerón de 10 niveles lógicos (sin pipe) a 6 niveles lógicos (con pipe). 

Observación
:
Es importante saber que la herramienta de análisis de tiempo también ofrece una 'vista' tipo esquemático del camino de mayor retardo. Este esquemático puede también ser usado como fuente para saber donde colocar los registros de pipelining. Sin embargo, el problema de usar este esquemático es que éste esquemático es solo del camino mas critico, ofreciendo una 'vista' muy parcial de todo el 'data path' del sistema. Si se desea usar este esquemático como fuente de la ubicación de los registros de pipe se deberá tener mucho cuidado de no 'desbalancear' los distintos caminos de los datos del sistema (data path). Es decir, balancear correctamente los distintos caminos; esto signinfica que cualquier dato proveniente de cualquier entrada de datos debe atravesar el mismo numero de registros (de pipeline)  para alcanzar cualquier salida del sistema.. Por ejemplo, en el esquemático que se detalla arriba, si se hubiera considerado solamente el camino más crítico y colocado registros solo en ese camino, el sistema hubiera quedado algo como se muestra en la siguiente figura: 



Analizando esta vista RTL del sistema se puede observar un desbalance entre los caminos de los datos a sumar: El dato que va por camino (path) naranja sale del mux, para por un flip-flop, un sumador y otro flip-flop. El dato que va por el camino (path) verde, sale del mux, pasa por el sumador y luego al siguiente sumador. Por ello existe un total desbalance entre los caminos, y esto es justamente lo más importante a evitar cuando se pipeline un sistema. 

Desventaja del uso de pipeline: la latencia del sistema original se incrementa en forma proporcional a la cantidad de registros sumados al camino crítico. Sin embargo se debe tener claro que latencia no altera la funcionalidad del circuito. En el ejemplo detallado la latencia se ha incrementado por 2 ciclos de reloj (debido a los dos flip-flops en cadena). Hay sistemas que pueden soportar esta latencia, otros sistema que necesitarían una modificación para tolerar esa latencia, y otros que directamente no toleran latencia. Para los dos primeros casos pipelining es una solución, para el tercer caso, habría que buscar otra solución ya sea modificando el código original, modificando parámetros de place and route, realizando floorplaning, etc.