01signal.com

Guía práctica: reconfiguración parcial con Vivado

Introducción

Esta es la segunda entrada de una serie de cuatro sobre la reconfiguración parcial (partial reconfiguration; también Dynamic Function eXchange, DFX) con Vivado de Xilinx. La intención de esta entrada es repasar y explicar los pasos para habilitar la reconfiguración parcial en un diseño de FPGA. Si aún no lo has hecho, es recomendable leer la primera entrada, donde se explican los conceptos en los que se basan estos pasos.

Xilinx renombró la reconfiguración parcial como "Dynamic Function eXchange" (DFX) en 2020. DFX es la expresión que aparece en los menús y notas informativas de Vivado. No obstante, aquí se usa el término técnico "reconfiguración parcial".

Para simplificar, esta entrada supone que el proyecto tiene una única partición reconfigurable. Ampliarlo a varias particiones es bastante sencillo.

El procedimiento descrito en esta entrada comienza antes de que el proyecto se haya habilitado para la reconfiguración parcial. Así que, a grandes rasgos, los pasos son:

Preparación para la planificación física

La planificación física (floorplanning) es, más que cualquier otra tarea, la que exige trabajo intelectual. Es un equilibrio sutil entre no malgastar área de lógica de la FPGA y asegurarse de que tanto la partición estática como las particiones reconfigurables no tengan obstáculos importantes durante la colocación y el encaminamiento (place and route).

Por eso, la mayor parte de esta entrada trata sobre este tema.

En un pasado lejano, la planificación física era una técnica que se usaba para el cierre de temporización (timing closure). Ayudaba a las herramientas a colocar la lógica de forma sensata. Como las herramientas de diseño de FPGA han mejorado con el tiempo, han pasado muchos años desde la última vez que vi que la planificación física ayudara a cumplir las restricciones de temporización (timing constraints). Hoy en día, la mejor estrategia para cumplir las restricciones de temporización es casi siempre dejar que las herramientas tomen las decisiones.

Con la reconfiguración parcial, la planificación física es obligatoria, así que el objetivo no es empeorar las cosas. Hacerlo bien suele ser cuestión de prueba y error. Sin embargo, el método más simple para obtener buenos resultados es realizar una implementación del diseño sin planificación física y, a continuación, partir de cómo se coloca la lógica de forma natural. El siguiente paso es intentar organizar las zonas de una manera que tenga sentido para la reconfiguración parcial, usando la colocación inicial de la lógica como guía.

En el escenario de uso tipo plugin, la planificación física se puede actualizar a medida que el proyecto evoluciona. No ocurre así en el escenario de actualización remota (Remote Update), es decir, cuando la reconfiguración parcial se utiliza como medio para actualizar por versiones un diseño que ya se ha publicado: con la actualización remota, todos los flujos de bits parciales deben corresponderse con el flujo de bits inicial. Por consiguiente, la lógica estática del diseño queda congelada en cuanto se publica el flujo de bits inicial. Eso significa, entre otras cosas, que la planificación física debe permanecer igual.

Así que, incluso antes de empezar con la reconfiguración parcial, la primera tarea consiste en encontrar un área adecuada en la FPGA para la lógica estática. No merece la pena perder demasiado tiempo en esto: solo hay que obtener el punto de partida para continuar después de dividir el proyecto en dos partes.

No te confundas: el propósito de este primer paso no es la planificación física en sí, sino ver cómo coloca Vivado la lógica sin restricciones y, a partir de ahí, decidir qué zona debe asignarse a la lógica estática. Los pasos son:

Configurar un proyecto para la reconfiguración parcial

El documento UG909 de Xilinx sugiere dos procedimientos de trabajo para la reconfiguración parcial:

Voy a usar aquí el flujo con proyecto, aunque tiene algunas limitaciones, algunas de las cuales tienen que ver con el tipo de fuentes del módulo reconfigurable (en particular, con el uso de block designs). En cualquier caso, es mejor empezar con el flujo con proyecto, porque los scripts que genera para la implementación son una buena base para el flujo sin proyecto, si hiciera falta.

Estos son los pasos para activar el soporte de reconfiguración parcial en un proyecto existente:

Si intentas implementar el proyecto en este punto, lo más probable es que falle con un error parecido a: «[DRC HDPR-30] Missing PBLOCK On Reconfigurable Cell: HD.RECONFIGURABLE cell 'pr_block_ins' must have PBLOCK assigned to itself or its descendant cells». En palabras sencillas, significa que la planificación física es necesaria.

Planificación física

En este punto, el proyecto está configurado lo justo para la tarea de planificación física.

Antes de desglosar esta tarea en pasos pequeños, conviene mencionar algunas cosas que hay que tener presentes:

Ahora, paso a paso:

Corregir la planificación física

Esta es probablemente la parte menos agradable de la reconfiguración parcial: dejar la planificación física bien ajustada. Si lo haces para el caso de la actualización remota, esta fase es extra importante, porque esa planificación física permanecerá durante toda la vida del proyecto.

Las correcciones en la planificación física son necesarias por dos motivos principales: como respuesta a los avisos críticos, y en una fase posterior para optimizar el uso de la FPGA: el objetivo es reducir el desperdicio de recursos y, al mismo tiempo, evitar crear obstáculos para la colocación y el encaminamiento.

Hacer modificaciones no es difícil, porque basta con arrastrar los bordes de un Pblock. También es fácil ampliar un Pblock con rectángulos adicionales: haz clic con el botón derecho en el Pblock y selecciona «Add Pblock Rectangle».

Los avisos críticos suelen indicar qué correcciones son necesarias; aun así, asegúrate de haber leído el capítulo correspondiente (6, 7 u 8) de la guía de usuario de Xilinx, UG909, sobre las limitaciones de planificación física de tu FPGA concreta.

El resto de esta sección comenta los posibles problemas con FPGA de la serie 7. Con las FPGA Ultrascale es mucho más fácil trabajar.

Un error frecuente con FPGA de la serie 7 es la división de columnas de tiles de interconexión. Por ejemplo:

[Constraints 18-993] The Pblock pblock_pr_block_ins has defined an area that causes the splitting of interconnect tile columns. Dynamic Function eXchange requires that the left and right paired interconnect tile columns cannot be split by a reconfigurable boundary.  This is caused by either the left or right edge of a Pblock boundary, or by the Pblock spanning over logic types not included in the Pblock ranges.  To avoid an unroutable situation, placement will be prohibited from both of these columns. To avoid placement restrictions, modify the Pblock to avoid splitting the two columns.
The column of the split contains interconnect tile INT_L_X48Y299  (SLICE_X79Y299 SLICE_X78Y299).
Please refer to the Xilinx document on Dynamic Function eXchange.
Resolution: Set the Pblock property SNAPPING_MODE to value of ON, or modify the column/X specification of the pblock to avoid this edge.

y

[Constraints 18-996] The split between the left and right columns occurs between a reconfigurable Pblock and Static logic. The static sites are not reconfigurable. The Pblock should be adjusted to remove the column from the Pblock, unless the excluded reconfigurable and static sites are not needed for the design. Note that adjusting the Pblock will prevent prohibits and improve placement of the design, but may reduce the routability if the removed sites were needed to span across the static logic. Failure to modify the Pblock may lead to an unplaceable design if these prohibited sites are required by the design. Resolution: Set the Pblock property SNAPPING_MODE to value of ON, or modify the column/X specification of the pblock to avoid this edge. and

Para solucionarlo, pon la propiedad SNAPPING_MODE del Pblock en ROUTING o en ON (probablemente ROUTING no baste, así que elige ON), como sugiere el primer aviso. Seguramente esto añadirá muchas restricciones al archivo XDC, de este tipo:

set_property PROHIBIT true [get_sites SLICE_X79Y349]
set_property PROHIBIT true [get_sites SLICE_X78Y349]
[ ... ]
set_property PROHIBIT true [get_sites SLICE_X79Y191]
set_property PROHIBIT true [get_sites SLICE_X78Y191]
set_property PROHIBIT true [get_sites PMV_X0Y2]
set_property PROHIBIT true [get_sites SLICE_X36Y190]
set_property PROHIBIT true [get_sites SLICE_X37Y190]
[ ... ]
set_property PROHIBIT true [get_sites SLICE_X79Y176]
set_property PROHIBIT true [get_sites SLICE_X78Y176]
set_property PROHIBIT true [get_sites T14]
set_property PROHIBIT true [get_sites R15]
set_property PROHIBIT true [get_sites XADC_X0Y0]
set_property PROHIBIT true [get_sites SLICE_X36Y175]
set_property PROHIBIT true [get_sites SLICE_X37Y175]
[ ... ]

y continúa.

Los PROHIBIT correspondientes a los slices son los que silencian el aviso crítico mencionado. Las demás asignaciones PROHIBIT se añaden para los emplazamientos lógicos que están dentro de la región geométrica, pero que no están permitidos para la reconfiguración parcial en la FPGA utilizada. Las FPGA Ultrascale y posteriores generan muchas menos líneas con PROHIBIT, si es que generan alguna.

A los solos efectos de silenciar el aviso crítico, probablemente sea aceptable eliminar todas las líneas con PROHIBIT y dejar una sola línea solo para los slices. Esto se hace cubriendo el rango de slices que Vivado añadió como respuesta al cambio en SNAPPING_MODE. Convierte ese rango en algo como:

set_property PROHIBIT true [get_sites -range {SLICE_X79Y0 SLICE_X79Y349}]

Este es el tipo de línea en el archivo XDC que puede resolver el problema de la división de la interconexión sin que el archivo se haga enorme.

Independientemente de lo anterior, también puede aparecer en el archivo XDC una línea de este tipo. Al parecer, también se puede eliminar sin problema:

set_property HD.PLATFORM_WRAPPER true [get_cells pr_block_ins]

Reducir el archivo XDC al mínimo que silencie los avisos críticos puede parecer superficial, pero la alternativa es un archivo de restricciones enorme, que es una receta para la confusión más adelante. Por mi experiencia, la ausencia de avisos de este tipo puede tomarse como una aprobación de que la planificación física del diseño está bien.

Lo más probable es que devolver la propiedad SNAPPING_MODE a OFF vuelva a causar problemas, independientemente de los cambios en el XDC.

Añadir un módulo reconfigurable

Hasta ahora, la implementación consigue prácticamente lo mismo que el diseño jerárquico, con algunas restricciones adicionales. Aunque se genera un flujo de bits parcial, es bastante inútil, porque cargarlo deja el diseño igual.

El objetivo, por tanto, es crear otro flujo de bits parcial basado en otro módulo reconfigurable. Para ello hay que añadir una implementación hija (Child Implementation).

Asegúrate de tener fresca la entrada anterior antes de seguir leyendo, en particular la parte sobre implementaciones padre e hijas y sobre el asistente Dynamic Function eXchange. Recuerda también, como se dijo antes en esta entrada, que la pestaña «Partition Definitions» contiene los módulos reconfigurables definidos y sus fuentes.

Abre el asistente Dynamic Function eXchange desde el menú Tools y haz clic en Next en la ventana de bienvenida.

En la ventana Edit Reconfigurable Modules, haz clic en «+». Se abre un cuadro de diálogo para añadir un módulo reconfigurable. Lo único interesante de este cuadro de diálogo es el Reconfigurable Module Name: es el nombre que se usa para identificar la lógica reconfigurable, como ya se explicó antes.

El cuadro también exige asociar este módulo con el nombre de una definición de partición, pero de todos modos solo hay una (porque esta entrada supone que solo se define una partición).

Hay que añadir al menos un archivo fuente Verilog o VHDL para poder continuar; se pueden añadir más desde la pestaña «Partition Definitions» más adelante. Indicar el nombre del módulo de nivel superior de este módulo reconfigurable no viene mal, sobre todo si no queda claro a partir de los propios archivos fuente.

De vuelta en el asistente, haz clic otra vez en Next, hasta la ventana Edit Configurations. Haz clic en «+» y escribe un nombre de configuración. La única importancia de este nombre es que aparece en la ventana Design Runs. Un nombre como config_2 vale.

Aparece una fila nueva en la lista de configuraciones. Modifica el módulo reconfigurable en la columna correspondiente a la partición, de modo que cada configuración tenga un módulo reconfigurable distinto.

La última ventana es Edit Configuration Runs, para asignar ejecuciones a las configuraciones. La forma fácil es eliminar todas las ejecuciones listadas (si las hay) y hacer clic en «automatically create configuration runs». Eso hace lo que harías manualmente de todos modos: crea una ejecución padre llamada impl_1, y luego crea ejecuciones hijas, nómbralas como quieras y haz que sean hijas de impl_1.

El asistente elige una configuración para cada ejecución, pero es fácil cambiarla. Lo único importante es qué configuración se asocia con la ejecución padre.

Y, por cierto, si eliminas todas las ejecuciones en el asistente, desaparecen todas las hijas, pero impl_1 se queda.

Por fin: implementación del diseño

Para generar los flujos de bits, haz clic en «Generate Bitstreams» en Vivado como siempre. Como ya se mencionó en la entrada anterior, se crean dos o tres flujos de bits para cada configuración en un proyecto de reconfiguración parcial.

Por ejemplo, en una FPGA Ultrascale los archivos de bits pueden ser:

Observa que para todas las implementaciones se crea el mismo número de archivos de flujo de bits. En otras palabras, el flujo de bits inicial también se crea para las implementaciones hijas, así que es perfectamente posible cargar la FPGA con el flujo de bits inicial de una de las hijas y continuar a partir de ahí.

Para una forma sencilla de cargar flujos de bits parciales por PCIe o USB 3.x, consulta esta página.

Ninguna de las implementaciones debería tener avisos críticos ni fallar por quejas sobre el Pblock o la planificación física en general, porque esos problemas deberían haberse resuelto antes. Si aun así ocurre algo así, la planificación física debe corregirse como se explicó antes.

A veces, al hacer clic en «Generate Bitstream», si solo se han hecho cambios en las implementaciones hijas, Vivado puede responder: «Bitstream generation has already completed and is up-to-date. Re-run anyway?». Es algo confuso, pero haz clic en «Yes» y las implementaciones hijas se ejecutarán correctamente. Todo este asunto de las implementaciones hijas es una especie de complemento añadido a Vivado, y por eso la fila de estado durante la implementación dice algo como «write_bitstream complete. Child running».

Revisión de los resultados

Como la reconfiguración parcial tiene mucho que ver con la colocación, es buena idea revisar los diseños implementados. Puedes abrir una implementación concreta haciendo clic con el botón derecho en «Open Implemented Design» y pasando el ratón por el elemento del menú que dice «Open Implemented Design» (otra vez). Luego selecciona en la lista qué implementación quieres abrir. Si una implementación no aparece en la lista, probablemente ya está abierta.

Prueba a hacer clic con el botón derecho en la fila superior de la lógica reconfigurable en el panel Netlist de la vista del diseño implementado y elige «Highlight Leaf cells». Haz lo mismo con la lógica estática, con otro color.

Con el mismo clic derecho también está «Show Connectivity», que dibuja líneas rectas blancas entre los elementos lógicos que están conectados. Los caminos de encaminamiento reales en la FPGA son, por supuesto, distintos, así que las regiones de la planificación física que cruzan esas líneas no tienen importancia. Aun así, mirar la conectividad puede ayudar a detectar cuándo la organización general de la planificación física hace que las herramientas tengan que trabajar con dificultad.

Es bastante normal y está bien que algunas celdas que aparentemente pertenecen a la lógica estática aparezcan colocadas dentro de la zona reconfigurable, y viceversa. Lo que debe preocuparte es si parece haber congestión en algún sitio, es decir, si la lógica parece estar demasiado apretada en general o en alguna región concreta. Si es posible, los cambios en la planificación física pueden ayudar a aliviarlo.

Otra cosa que conviene mirar son las posiciones de los pines de partición (partition pins). Aparecen como barras horizontales blancas en la vista del dispositivo, así (haz clic en la imagen para ampliarla):

Partition pins in Vivado's device view

Como se mencionó en la entrada anterior, los pines de partición pueden estar en cualquier lugar dentro de la partición reconfigurable. Sin embargo, si están lejos de los bordes de la partición, puede indicar que el encaminador tuvo dificultades con la temporización durante la implementación padre.

También es posible obtener una lista de texto con las coordenadas de los pines de partición con este comando Tcl (cambia pr_block_ins por el nombre de la celda de lógica reconfigurable):

foreach s [get_pins -of [get_cells pr_block_ins]] { set partpin [get_pplocs -quiet -pins [get_pins $s]] ; puts "$s => $partpin"; }

Las coordenadas de los pines de partición corresponden a la rejilla de CLB (no a la de slices). En el dibujo mostrado, estos pines aparecen con el nombre de «Cell pins».

Puede que algunos pines de la celda no tengan asignado un pin de partición. Esto ocurre cuando hay un desajuste entre la lista de puertos del módulo reconfigurable (y/o la anchura de los vectores) y su instanciación por la lógica estática. Ese desajuste es perfectamente legal (en Verilog), pero el resultado puede ser no deseado. Ejecutar este comando Tcl permite detectar puertos inaccesibles, sobre todo cuando no es intencionado.


Con esto termina la parte técnica sobre cómo configurar el proyecto en Vivado. Sin embargo, la próxima entrada trata un aspecto importante del diseño de FPGA: cómo asegurarse de que la sustitución de lógica se haga de forma fiable y sin sobresaltos.

Esta página se ha traducido del inglés mediante traducción automática. En caso de duda, consulta el texto original.
Copyright © 2021-2026. All rights reserved. (dcc38493)