Full text
Proyecto Fin de Carrera Ingeniería de Telecomunicación Formato de Publicación de la Escuela Técnica Superior de Ingeniería Autor: F. Javier Payán Somet Tutor: Juan José Murillo Fuentes Dep. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2013 Trabajo Fin de Máster Ingeniería de las Tecnologías Industriales Estudio de viabilidad y desarrollo de infraestructura para plataforma de inyección de fallos a través de PCI express en Kintex Ultrascale Autor: Javier González Moreno Tutor: Hipólito Guzmán Miranda Departamento de Ingeniería Electrónica Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2022
Trabajo Fin de Máster Ingeniería de las Tecnologías Industriales Estudio de viabilidad y desarrollo de infraestructura para plataforma de inyección de fallos a través de PCI express en Kintex Ultrascale Autor: Javier González Moreno Tutor: Hipólito Guzmán Miranda Profesor Titular Departamento de Ingeniería Electrónica Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2022
Trabajo Fin de Máster: Estudio de viabilidad y desarrollo de infraestructura para plataforma de inyección de fallos a través de PCI express en Kintex Ultrascale Autor: Javier González Moreno Tutor: Hipólito Guzmán Miranda El tribunal nombrado para juzgar el trabajo arriba indicado, compuesto por los siguientes profesores: Presidente: Vocal/es: Secretario: acuerdan otorgarle la calificación de: El Secretario del Tribunal Fecha:
Agradecimientos Grow as we go. Ben Platt En primer lugar quisiera expresar mi agradecimiento a Hipólito, director de este TFM (Trabajo Final de Máster), ya que ha sido su valiosa experiencia, orientación y motivación lo que ha permitido su realización. Siempre es un placer trabajar al lado de un gran profesional que, además, es una grandísima persona. En segundo lugar, pero no menos importante, quiero agradecer la ayuda, cariño y paciencia que me han brindado aquellos que, desde el anonimato, han aportado mucho a este trabajo. Con esto me refiero a mis padres, grandes revisores y correctores, pero sobre todo un apoyo incondicional. Fueron ellos lo que, desde pequeño, motivaron mi interés por entender el funcionamiento de todo lo que me rodeaba y gracias a los cuales he llegado hasta donde estoy hoy. También me gustaría recordar en este momento a las personas que han formado una parte muy importante de mi vida, pero que a día de hoy no pueden compartir este momento conmigo. A mi abuelo Manolo, por enseñarme todo lo que puede llegar a transmitir el silencio de una mirada. A mi abuela Pilar, por su habilidad para ver todo bueno que había dentro de mí hasta el final. A mi abuelo Manolo, por la unión tan fuerte que teníamos, la cantidad de momentos compartidos y cómo me dejaba ser lo que el llamaba "el báculo de su vejez". Y a mi tío Gabriel, una persona incansable en el amor y entrega hacia los demás y un gran ejemplo a seguir. Tampoco me quiero olvidar de aquellos que forman parte de mi rutina: mis hermanos, Emma e Ignacio, mi abuela María Luisa y toda mi familia completa. Son personas muy importantes para mí y me han aportado muchísimas cosas a lo largo de todos estos años. De mis amigos y compañeros de carrera también me gustaría acordarme, por los ratos compartidos y por todo el camino recorrido. Del magnífico grupo que nos dedicamos a organizar todo tipo de eventos tampoco me quiero olvidar, pues son ellos los que son capaces de conseguir que la rutina nunca nos absorba y que todos salgamos siempre a flote. Por último, no me olvido de la persona más importante para mí a día de hoy. Gracias María por tanto amor, tanta paciencia y, sobretodo, por sacar siempre lo mejor de mí. Javier González Moreno Alumno Interno de la Universidad de Sevilla Sevilla, 2020 I
Resumen Es te Trabajo Fin de Máster parte de la oportunidad de participar en el diseño de una plataforma de inyección de fallos en la tarjeta ADM-XRC-KU1 de Alpha Data, así como del estudio de la misma realizado en mi Trabajo Fin de Grado [5]. Concretamente, se centra en desarrollar la infraestructura mínima necesaria para demostrar la viabilidad de implantar un sistema de inyección de fallos completo en la FPGA bajo estudio (XCKU060). Para ello, se comienza resolviendo las comunicaciones entre el ordenador en el que se conecta la tarjeta y las interfaces de entrada y salida de un sistema de inyección de fallos. En paralelo, se trabaja para mejorar la infraestructura que maneja y prepara las instrucciones (comandos y datos) a enviar a través del sistema de comunicaciones. Por otro lado, se diseña un intérprete de comandos sencillo (a nivel hardware) capaz de interpretar y ejecutar varios comandos propios de un sistema de inyección de fallos. Por último, se genera un proyecto que permite la reconfiguración parcial con el objetivo de obtener bitstreams parciales funcionales, ya que son necesarios para poder inyectar fallos. El objeto de este documento es presentar toda la información recabada durante el desarrollo del trabajo, así como los resultados de las pruebas y arquitecturas diseñadas con el fin de obtener los elementos mínimos necesarios para demostrar la viabilidad de un sistema de inyección de fallos. III
Índice Agradecimientos I Resumen III Abstract V Índice Abreviado VII Glosario XIII 1 Introducción 1 1.1 Inyección de fallos: FT-UNSHADES 1 1.1.1 FT-Unshades 2 1.2 Tarjeta ADM-XRC-KU1 2 1.2.1 PCIe 3 2 Alcance del Proyecto 5 2.1 Antecedentes 5 2.2 Plataforma de Inyección de Fallos: FTU-Lite 5 2.2.1 Infraestructura mínima necesaria 5 2.3 Alcance del proyecto 6 3 Interfaz de Comunicaciones 9 3.1 Estudio de viabilidad de direcciones bRAM como señales de inicio/final de transmisión: Test 7 9 3.1.1 Arquitectura 10 3.1.2 Host Program 10 3.1.3 Resultados y conclusiones 11 3.2 Transmisión de datos desde bRAM a ftu_stream: Test 8 11 3.2.1 Arquitectura 11 FSM: bram2ftu_stream 13 3.2.2 Host Program 13 3.2.3 Resultados y conclusiones 14 3.3 Interfaz de comunicaciones entre bRAM y ftu_stream: Test 9 14 3.3.1 Arquitectura 14 FSM: ftu_stream2bram 15 3.3.2 Host Program 16 3.3.3 Resultados y conclusiones 17 4 Mejoras Software 19 4.1 Implementación del sistema de control con python 19 4.1.1 Sistema de control mediante argumentos 19 4.1.2 Preparación de instrucciones para el programa en C++ 19 4.1.3 Logger de python 20 4.1.4 Ejecución del test 20 XI
XII Índice 4.2 Mejora del Host Program 20 4.2.1 Gestión de datos entrada y salida 20 4.2.2 Logger de C++ 20 4.3 Conclusiones 21 5 Intérprete de comandos en la FPGA 23 5.1 Comandos 23 5.1.1 Comando echo 23 5.1.2 Comandos bit_up y bit_get 24 5.2 Intérprete de comandos: Test 10 24 5.2.1 Arquitectura 24 Sistema de inyección de fallos: ftu_core 25 Intérprete de comandos: core_fsm 26 5.2.2 Host Program 26 5.2.3 Resultados y conclusiones 28 6 Reconfiguración Parcial 31 6.1 Reconfiguración Parcial en Vivado 31 6.2 Reconfiguración Parcial: Test 11 31 6.2.1 Arquitectura 32 6.2.2 Host Program 32 6.2.3 Resultados 32 Resultado Primera Ejecución (con reconfiguración parcial) 33 Resultado Segunda Ejecución (sin reprogramar la tarjeta ni reconfigurar parcialmente) 34 Resultado tercera Ejecución (sin reprogramar la tarjeta ni reconfigurar parcialmente) 35 Conclusiones 35 7 Desensamblador de bitstreams 37 7.1 Adaptación del desensamblador de bitstreams a KU 37 7.1.1 Versión inicial 37 7.1.2 Modificaciones y mejoras implementadas 37 7.2 Comandos 38 7.2.1 Comandos Tipo 1 38 7.2.2 Comandos Tipo 2 38 7.3 Resultado 39 7.4 Conclusión 39 8 Conclusiones y trabajos futuros 41 8.1 Resultados y conclusiones 41 8.1.1 Conclusión personal 42 8.2 Trabajos futuros 42 Índice de Figuras 43 Índice de Códigos 45 Bibliografía 47
Glosario API Application Programming Interface ARM Advanced RISC Machine AMBA Advanced Microcontroller Bus Architecture AVR Familia de microcontroladores AXI, AXI4 Advanced eXtensible Interface bRAM Block RAM COTS Commercial Off The Shelf DDR4 SDRAM Double Data Rate 4 Synchronous Dynamic RAM DMA Direct Memory Access DSP Digital Signal Processor FIFO First In, First Out FPGA Field-Programmable Gate Array FT-UNSHADES (FTU) Fault Tolerance Universidad de Sevilla Hardware Debugging System GIE Grupo de Ingeniería Electrónica JTAG Joint Test Action Group KU Kintex Ultrascale LUT Look-Up Table MPTL Modular Plug Terminated Link OCP Open Core Protocol PCIe Peripheral Component Interconnect Express RAM Random Access Memory SRAM Static RAM USB Universal Serial Bus VPWR Voltage Input Power V5 Virtex 5 XMC Switched Mezzanine Card XIII
1 Introducción Todo se andará hijito. Pilar Vicence Recuero El ser humano ha demostrado desde siempre un gran interés por investigar, descubrir y conocer su entorno. Últimamente, esa mirada va mucho más allá del planeta Tierra: las galaxias cercanas, el resto de planetas del sistema solar y el espacio exterior cada vez toman más relevancia. Gracias a los avances científicos y al desarrollo en la carrera espacial, se ha conseguido reducir los costes de lanzamiento, tanto de los satélites puramente científicos, como de aquellos que proporcionan servicios. Nos encontramos ante una nueva era espacial, en la que los grandes proyectos exclusivos han dejado de ser la norma. Esta nueva visión del sector espacio, conocida como New Space, se caracteriza por un crecimiento cada vez mayor de misiones low-cost, en la que la cantidad pasa a ser mucho más importante que la la calidad. Un ejemplo muy ilustrativo de esta nueva estrategia son las constelaciones de satélites, como Starlink de SpaceX [11] y OneWeb [1]. Entre las dos tienen más de 2700 satélites en órbita. Debido a esto, enviar satélites al espacio plantea retos cada vez más complejos, debido a la necesidad de emplear componentes low-cost. La filosofía de utilizar elementos de bajo coste se conoce como COTS (Commercial Off The Shelf ) y va ligada al concepto de New Space. El espacio es un entorno muy agresivo, por lo que siempre se han sometido todos los dispositivos a pruebas muy estrictas antes de ponerlos en órbita. Concretamente, destacan el test térmico y de vacío (se suelen hacer a la vez), los ensayos de vibraciones y el test de radiación. Aun así, algunas de estas pruebas dejan de tener sentido cuando introducimos los COTS, dejando sitio a otros métodos tales como las plataformas de inyección de fallos. Estas toman cada vez más importancia, para mejorar la robustez en diseños implementados en Field-Programmable Gate Arrays (FPGAs) COTS. 1.1 Inyección de fallos: FT-UNSHADES Esta técnica consiste en la introducción de fallos en el sistema y el posterior estudio del comportamiento del sistema en presencia de estos, comparando la salida del sistema antes y después del test. De esta forma, se pueden validar diseños tolerantes a fallos, al estudiar la robustez y fiabilidad de los mismos durante el proceso de diseño [12]. Si se tienen resultados de radiación, normalmente no son necesarios los resultados de inyección de fallos. Es por ello que la inyección de fallos se utiliza como ayuda al diseño de sistemas robustos, ya que hacer inyección de fallos a un diseño y trabajar para mejorar su robustez en función de los resultados de dicha inyección es mucho más económico en tiempo, esfuerzo y coste que fabricar un diseño, irradiarlo y, si se quiere mejorar su robustez o modificarlo, volverlo a fabricar y volverlo a irradiar. 1
2Capítulo 1. Introducción Por otro lado, los resultados de inyección de fallos se pueden combinar con resultados de sensibilidad de la tecnología para poder obtener la sensibilidad de un diseño, ver [10] y [13]. 1.1.1 FT-Unshades FT-Unshades (FTU) es un sistema de inyección de fallos híbrido (utiliza conceptos de inyección por hardware y software) basado en FPGA y no instrumentado [ 2 ]. Esto se traduce en que no es necesario modificar el circuito para poder realizar la inyección de los fallos. Fue desarrollado por el grupo de investigación GIE (Grupo de Ingeniería Electrónica) del departamen- to de Ingeniería Electrónica de la Universidad de Sevilla. La segunda versión de este sistema (FT-Unshades2) utiliza el Universal Serial Bus para comunicarse con las FPGAs y realizar la inyección de fallos. Este método empieza estar obsoleto, ya que el Peripheral Component Interconnect Express (PCIe) ofrece más prestaciones y mayor velocidad. Es por ello que las nuevas líneas de investigación están enfocadas a este tipo de interfaces. 1.2 Tarjeta ADM-XRC-KU1 Se trata de una tarjeta de desarrollo distribuida por Alpha Data (imagen 1.1) cuyas características podrían permitir la integración de una plataforma de inyección de fallos aprovechando el PCIe. Está recomendada por Xilinx para el desarrollo de sistemas aeroespaciales, ya que, al tratarse de una tarjeta muy completa, permite diseñar sin restricciones. De esta forma, se pueden recortar gastos y facilitar el diseño, ya que no se fabrica la tarjeta final hasta que no se ha validado por completo el diseño. Figura 1.1 Tarjeta ADM-XRC-KU1 [3].
1.2 Tarjeta ADM-XRC-KU1 3 En cuanto a las características, cabe destacar las siguientes: • Se trata de una Switched Mezzanine Card (XMC) de alto rendimiento basada en la familia Xilinx Kintex Ultrascale de FPGAs, concretamente cuenta con una XCKU060 (target FPGA). •Posee una interfaz PCIe Gen2, conectable a un PC mediante una Carrier Board. • Cuenta con 4x2GB DDR4-2400 de memoria externa, puertos de E/S de alta densidad y un sistema de monitoreo del sistema. •Además, cuenta con memoria flash de arranque. • Por otro lado, la placa se gestionada mediante la combinación de una FPGA Artix (bridge FPGA) y un microcontrolador AVR los cuales permiten administrar la tarjeta a través del PCIe o USB. • Por último, posee una Application Programming Interface (API) integral multiplataforma con soporte para Microsoft Windows, Linux y VxWorks, desarrollada por Alpha Data, que proporciona acceso a la funcionalidad completa de todas las características del hardware. 1.2.1 PCIe El principal atractivo de esta tarjeta, tal y como se menciona al principio de la sección, es la interfaz PCIe ya que, además de ofrecer mejores prestaciones que el JTAG o USB, permite nuevas formas de trabajo a nivel del software que se ejecuta en el PC. Todo eso gracias a la API proporcionada por Alpha Data, ya que ofrece, entre otras cosas, mapear la memoria interna de la FPGA al mapa de memoria del PC.
2 Alcance del Proyecto Tanto Cuanto. José Luis González Moreno 2.1 Antecedentes Este trabajo parte de la oportunidad de continuar trabajando con la tarjeta ADM-XRC-KU1, investigando la viabilidad y las diferentes opciones para conseguir un sistema de inyección de fallos completo. Se parte de los conocimientos adquiridos durante la realización del Trabajo de Fin de Grado [ 5 ], que investiga la interfaz ADM-XRC-KU1-HSAXI (proporcionada por Alpha data) y propone varios sistemas para adaptarla a un sistema de inyección de fallos. Concretamente, se decide continuar con uno de los trabajos propuestos tras realizar el estudio, que consiste en el desarrollo de una interfaz que permita la interpretación y la ejecución de comandos, así como la gestión de datos, basada en la tecnología bRAM [5]. 2.2 Plataforma de Inyección de Fallos: FTU-Lite Los elementos mínimos necesarios a implementar para estudiar la viabilidad de un sistema de inyección de fallos en la tarjeta ADM-XRC-KU1, se basan en la arquitectura propuesta por el Grupo de Ingeniería Electrónica (GIE) de la Universidad de Sevilla para el FTU-Lite [6] (imagen 2.1). Por un lado, es importante tener un sistema de comunicaciones que permita tanto enviar y recibir datos a la FPGA, como inyectar fallos a través del SelectMap. Además, debe contener una interfaz que controle el sistema (controller en la figura 2.1), encargada de manejar los datos y realizar las inyecciones. El resto de sistemas que aparecen en la imagen 2.1 no se consideran esenciales para demostrar la viabilidad de diseñar una plataforma de inyección de fallos en la tarjeta ADM-XRC-KU1, por lo que no se considerarán en este proyecto. 2.2.1 Infraestructura mínima necesaria A partir de los mencionado en el párrafo anterior, se deduce que para poder implementar un sistema de inyección de fallos en la tarjeta bajo estudio se ha de comenzar resolviendo al completo las comunicaciones entre el ordenador y la FPGA (interfaces de entrada y salida de la plataforma de inyección de fallos). Una vez se han resuelto las comunicaciones, se ha de trabajar en la arquitectura propia de un sistema de inyección de fallos. Concretamente, se ha de desarrollar una interfaz que permita controlar todo el sistema (core_fsm o intérprete de comandos). 5
12 Capítulo 3. Interfaz de Comunicaciones Figura 3.3 Posición de los datos en la bRAM. Figura 3.4 Arquitectura Test 8.
3.2 Transmisión de datos desde bRAM a ftu_stream: Test 8 13 FSM: bram2ftu_stream Para enviar los datos almacenados en la bRAM a un ftu_stream se diseña una máquina de estados cuyo diagrama de bloques simplificado se puede ver en la figura 3.5. Figura 3.5 FSM: bram2ftu_stream. Esta máquina de estados hace lo siguiente: 1. Espera a que el host termine de escribir los datos y la flag correspondientes. 2. Lee de la dirección 0x0000 los el número de datos a procesar. 3. Empieza a leer los datos de la bRAM (empezando en la dirección 0x0001) y los va escribiendo en el ftu_stream. 4. Cuando no quedan datos que leer, borra la flag del host, escribe la suya propia en la dirección 0x7FFF y vuelve al punto inicial. 3.2.2 Host Program El host program de este test es, de nuevo, una versión más avanzada del anterior, ya que no solo envía el ack en la flag, sino también el tamaño. Además, llena de unos ( [0xFF] ) los bits de la dirección 0x0001,
14 Capítulo 3. Interfaz de Comunicaciones simulando la escritura de datos, antes de enviar la flag. A continuación se enumera todo lo que realiza el host: 1. Abre el dispositivo, mapea la bRAM en la memoria del host y bloquea el buffer para las transferencias a través del DMA Engine. 2. Escribe en la dirección 0x0001 de la bRAM0 (a través del DMA Engine 0) los datos. 3. Escribe en la dirección 0x0000 de la bRAM0 el ack y el número de datos enviados (16 bytes en este test). 4. A continuación, lee el dato almacenado en la última dirección de la bRAM cada 1 segundo, hasta que obtiene el ack de la FPGA. 5. Por último, desbloquea el buffer del DMA Engine, desmapea la bRAM de la memoria del host y cierra el dispositivo. 3.2.3 Resultados y conclusiones Los resultados que devuelve este test son los siguientes: Código 3.2 Resultados Test 8. Target configured data buffer: [ffffffffffffffffffffffffffffffff] Writing to fpga flags buffer: [ff000000000000000000000000000001] Reading fpga (Reset buffer first) flags buffer: [00000000000000000000000000000000] flags buffer: [ff000000000000000000000000000000] Test succeeded De este test se concluye que el sistema de comunicaciones entre la bRAM y el ftu_stream funciona correctamente y acorde a lo esperado. Lo único que no se comprueba es si los datos han sido correctamente escritos en el ftu_stream, por lo que se simula y se observa que la escritura funciona correctamente. 3.3 Interfaz de comunicaciones entre bRAM y ftu_stream: Test 9 Una vez se tiene una interfaz capaz de transferir datos desde el host (que escribe en una bRAM mediante un DMA Engine) hasta la interfaz de entrada de un sistema de inyección de fallos (ftu_stream), se procede a diseñar el sistema de comunicaciones completo. El objetivo de este test es, a partir del trabajo realizado en los tests 7 y 8, completar el sistema de comunicaciones de forma que se pueda enviar información (comandos y datos) desde el host hasta la FPGA y viceversa. Para ello, se diseña una nueva interfaz que permita enviar datos desde un ftu_stream a una bRAM y se integra dentro de la arquitectura del test anterior. 3.3.1 Arquitectura Para poder probar a fondo el sistema de comunicaciones, se modifica la arquitectura del test anterior (test 7: 3.1), quedando tal y como se puede ver en la figura 3.6. De esta forma, la arquitectura contiene los siguientes elementos: •La interfaz ADM-XRC-KU1-HSAXI, aprovechando tanto DMA Engine 0 como el DMA Engine 1. •Una bRAM de entrada de 512kB (bRAM0) en la que escribe los datos el host para la FPGA. •Una bRAM de salida de 512kB (bRAM1) en la que escribe los datos la FPGA para el host. •Dos interfaces que conectan el bus AXI del los DMA Engines con las bRAMs.
3.3 Interfaz de comunicaciones entre bRAM y ftu_stream: Test 9 15 • Dos ftu_streams, uno de entrada (ftu_stream_in) y otro de salida (ftu_stream_out) del sistema de inyección de fallos. • Una interfaz que se encarga de coger los datos escritos por el host de la bRAM0 y enviarlos al ftu_stream_in. • Una interfaz que coge los datos del ftu_stream de entrada y los envía (copia) al ftu_stream de salida, diseñada en el Test 7 (sección 3.1). • La interfaz diseñada para este test, que espera a que el ftu_stream de salida tenga datos, los va escribiendo en la bRAM1 y cuando acaba, escribe el flag correspondiente en la bRAM1, indicando el número de bytes transferidos y el ack. Cabe destacar que al utilizar dos bRAMs, una de entrada y otra de salida, se modifica un poco el protocolo desarrollado anteriormente para avisar de que los datos están listos. Concretamente, se decide únicamente usar la dirección 0x0000 de ambas memorias para avisar de que los datos están listos para ser leídos. De esta forma, si el host quiere enviar datos a la FPGA, los escribe en la bRAM0 y escribe la flag correspondiente. A continuación, la FPGA los lee y, cuando acaba, borra la flag que había escrito el host, avisándole que puede iniciar una nueva transacción cuando quiera. El envío de datos en el otro sentido funciona exactamente igual. Figura 3.6 Arquitectura Test 9. FSM: ftu_stream2bram Para enviar los datos en el ftu_stream de salida se diseña una máquina de estados cuyo diagrama de bloques simplificado se puede ver en la figura 3.7. Esta máquina de estados hace lo siguiente: 1. Espera a que el ftu_stream_out tenga datos listos para procesar. 2. Le pide datos al ftu_stream_out y los escribe en la bRAM1 hasta que ya no queda espacio en la misma, o el ftu_stream está vacío durante varios ciclos. 3. Escribe la flag correspondiente a la transmisión efectuada (número de datos y ack) . 4. Espera a que el host borre la flag y vuelve al punto inicial.
16 Capítulo 3. Interfaz de Comunicaciones Figura 3.7 FSM: ftu_stream2bram. 3.3.2 Host Program Para este test, se aprovecha el diseñado en el anterior (descrito en la sección 3.2.2, modificándolo para que realice lo siguiente: 1. Abre el dispositivo, mapea las bRAMs en la memoria del host y bloquea el buffer para las transferencias a través de los DMA Engines. 2. Envía un patrón pseudoaleatorio (data) a la bRAM0 a través del DMA Engine 0 (empezando en la dirección 0x0001). 3. Escribe en la dirección 0x0000 de la bRAM0 el ack y el número de datos enviados (12 bytes en este test). 4. A continuación, lee el dato almacenado en la última dirección de la bRAM1 cada 1 segundo, hasta que obtiene el ack de la FPGA. 5. Lee los datos escritos por la FPGA en la bRAM1 (empezando en la dirección 0x0001) y comprueba que son iguales a los datos originales (escritos en la bRAM0 por el host) al comienzo del test. 6. Por último, desbloquea el buffer del DMA Engine, desmapea la bRAM de la memoria del host y cierra el dispositivo.
3.3 Interfaz de comunicaciones entre bRAM y ftu_stream: Test 9 17 3.3.3 Resultados y conclusiones Los resultados que devuelve este test son los siguientes: Código 3.3 Resultados Test 9. Number of bytes to send: 12 data: [020009010203040506070809] Data reversed data_buffer: [090807060504030201090002] Data prepared to be inserted to ftu_stream_in (8 byte reversed) data_buffer: [060708090200090102030405] --------------------------------------------------------- Target configured --------------------------------------------------------- Writing to bram0 via dma0 flag_buffer: [ff00000000000000000000000000000c] --------------------------------------------------------- Reading bram1 via dma1 (reset buffers first) Buffers reset flag_buffer: [00000000000000000000000000000000] data_buffer: [000000000000000000000000] FPGA ACK Received flag_buffer: [ff00000000000000000000000000000c] Data received data_buffer: [090807060504030201090002] -------------------------------------------------------- Data matched: Test SUCCEEDED Observando los resultados obtenidos, se concluye que se ha cumplido con el primer objetivo de este proyecto, ya que se diseñado un sistema de comunicaciones que permite enviar y recibir datos desde el host hasta las interfaces de entrada y salida de una plataforma de inyección de fallos (ftu_stream).
4 Mejoras Software Neither ever, nor never, goodbye. Apparat, Goodbye Un a vez se ha demostrado que las interfaces de comunicaciones diseñadas funcionan correctamente, se decide invertir tiempo en mejorar la infraestructura del host program (programa que se ejecuta para enviar y recibir datos a través del sistema de comunicaciones) con el objetivo de enfocarlo a una futura plataforma de inyección de fallos. Es por ello que se decide trabajar en dos líneas distintas. Por un lado, se crea un script de python que permite controlar todos los parámetros del sistema, ya que prepara los datos a enviar, configura la profundidad del logger y ejecuta el test con los parámetros correspondientes. Por otro, se mejora el propio programa en C++ (utilizado para los tests 7, 8 y 9), implementando un logger y un sistema de entrada y salida de información (datos y comandos) a enviar y recibir a la FPGA. 4.1 Implementación del sistema de control con python 4.1.1 Sistema de control mediante argumentos Como se comentaba en el párrafo anterior, lo primero en lo que se trabaja es en implementar un script de python que permita controlar todos los parámetros necesarios para efectuar los tests. Para ello, se utiliza la librería getopt[8], incluida en la biblioteca estándar de python. De esta forma, el script acepta los siguiente argumentos: •"-h": Imprime por el terminal los diferentes argumentos posibles y cómo utilizarlos. •"-t": Selecciona el número concreto de test a realizar. •"-l": Selecciona el nivel del logger (debug,info,warning,error ocritical). A continuación se muestra el resultado de ejecutar el script con el comando -h (código 4.1). Código 4.1 Python arguments example. src git:(fit) python3 main.py -h main.py -l <level> -t <test> 4.1.2 Preparación de instrucciones para el programa en C++ Se implementa una función que se encarga de coger las instrucciones almacenadas en el fichero inst (escritas por la persona que ejecuta el test), analizarlas y prepararlas para que el código en C++ sea capaz de realizar la transmisión sin problema. 19
20 Capítulo 4. Mejoras Software Esta preparación de los datos consiste en la alineación y separación en líneas con los datos que caben en cada dirección de la bRAM de entrada. Una vez preparadas, la función las escribe en el fichero data_in, que leerá el programa en C++. Es importante destacar que estas instrucciones son comandos para la FPGA, ya que es el firmware de la FPGA el debe responder a los comandos enviados desde el host. 4.1.3 Logger de python En paralelo, se añade un sistema de logging que se encarga de guardar en un log todos los resultados impresos por el terminal. Para su desarrollo se emplea la librería logging [ 9 ], incluida en a biblioteca estándar de python. El nombre del fichero de log contiene la fecha en la que se ha llevado a cabo el test y el formato del mismo se puede ver en el código 4.2 Código 4.2 Python logger example: 2022-07-04.log. src git:(fit) sudo python3 main.py -t test -l DEBUG 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - | STARTING NEW TEST: 2022-07-04 15:40:54 | 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - Logger created and configured 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - Instructions successfully prepared -> ./data_in 2022-07-04 15:40:54: INFO - ---------------------------------------------------- [...] C++ logger outputs info about the test here [...] 2022-07-04 15:40:55: INFO - ------------------------------ 2022-07-04 15:40:55: INFO - -- END OF FIRST TRANSACTION -- 2022-07-04 15:40:55: INFO - ------------------------------ 4.1.4 Ejecución del test Por último, el script de python ejecuta el test correspondiente y espera pacientemente a que el programa en C++ termine. Una vez ha terminado, procede a dar por finalizado el test por completo (código 4.2). 4.2 Mejora del Host Program 4.2.1 Gestión de datos entrada y salida Lo primero que se implementa en el host program es un sistema que se encarga de la gestión de datos de entrada y salida del programa. Este funciona de la siguiente forma: 1. Coge las instrucciones preparadas por el script de python, contenidas en el fichero data_in. 2. Las divide en trozos del tamaño del máximo número de datos posible que caben en la bRAM de entrada. 3. Envía el el primer grupo de instrucciones a la FPGA. 4. Recibe los datos de la FPGA y los escribe en un fichero de salida data_out. 5. Repite el proceso hasta que no queden datos que enviar, recibiendo los datos correspondientes después de cada envío. 4.2.2 Logger de C++ Por último, se implementa un logger que trabaja simultáneamente con el de python. El formato de la información que este maneja es exactamente igual que el descrito en el código 4.2. A continuación se puede observar el resultado final (código 4.3).
4.3 Conclusiones 21 Código 4.3 Both loggers example: 2022-07-04.log. 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - | STARTING NEW TEST: 2022-07-04 15:40:54 | 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - Logger created and configured 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - Instructions successfully prepared -> ./data_in 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - STARTING 1o ¯TRANSACTION 2022-07-04 15:40:54: INFO - Number of bytes to send: 2 2022-07-04 15:40:54: DEBUG - Data reversed 2022-07-04 15:40:54: DEBUG - data_buffer_in: [1513] 2022-07-04 15:40:54: DEBUG - Data prepared for ftu_stream_in (8 byte reversed) 2022-07-04 15:40:54: DEBUG - data_buffer_in: [1315] 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - Writing to bram0 via dma0 2022-07-04 15:40:54: DEBUG - flag_buffer: [ff000000000000000000000000000002] 2022-07-04 15:40:54: INFO - ---------------------------------------------------- 2022-07-04 15:40:54: INFO - Reading bram1 via dma1 (reset buffers first) 2022-07-04 15:40:54: DEBUG - Buffers reset 2022-07-04 15:40:54: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-04 15:40:54: DEBUG - data_buffer_in: [0000] 2022-07-04 15:40:55: INFO - FPGA ACK Received 2022-07-04 15:40:55: DEBUG - flag_buffer: [ff000000000000000000000000000001] 2022-07-04 15:40:55: INFO - Number of bytes to read: 1 2022-07-04 15:40:55: DEBUG - Data received 2022-07-04 15:40:55: DEBUG - data_buffer_out: [01] 2022-07-04 15:40:55: INFO - Data recieved written -> ./data_out 2022-07-04 15:40:55: INFO - Flag cleared 2022-07-04 15:40:55: DEBUG - Testing if flag was cleared 2022-07-04 15:40:55: DEBUG - flag_buffer: [01010101010101010101010101010101] 2022-07-04 15:40:55: DEBUG - Reading bram1 2022-07-04 15:40:55: DEBUG - flag_buffer: [ff000000000000000000000000000001] 2022-07-04 15:40:55: INFO - ------------------------------ 2022-07-04 15:40:55: INFO - -- END OF FIRST TRANSACTION -- 2022-07-04 15:40:55: INFO - ------------------------------ 4.3 Conclusiones Gracias a las mejoras implementadas en este capítulo, se ha obtenido una mejor infraestructura con la que realizar tests fácilmente, cumpliendo, por tanto, con el objetivo del mismo. Esto es fundamental de cara a al futuro desarrollo de la plataforma de inyección de fallos completa, ya que se ha facilitado el envío de instrucciones desde el host hasta la FPGA a través del sistema de comunicaciones.
28 Capítulo 5. Intérprete de comandos en la FPGA 5.2.3 Resultados y conclusiones El Test 10a devuelve lo siguiente: Código 5.4 Test 10a. 2022-07-05 20:24:35: INFO - ---------------------------------------------------- 2022-07-05 20:24:35: INFO - | STARTING NEW TEST: 2022-07-05 20:24:35 | 2022-07-05 20:24:35: INFO - ---------------------------------------------------- 2022-07-05 20:24:35: INFO - Logger created and configured 2022-07-05 20:24:35: INFO - ---------------------------------------------------- 2022-07-05 20:24:35: INFO - Instructions successfully prepared -> ./data_in 2022-07-05 20:24:35: INFO - ---------------------------------------------------- 2022-07-05 20:24:35: INFO - Starting FPGA Test 2022-07-05 20:24:37: INFO - ---------------------------------------------------- 2022-07-05 20:24:37: INFO - Target configured 2022-07-05 20:24:37: INFO - ---------------------------------------------------- 2022-07-05 20:24:37: INFO - STARTING 1o ¯TRANSACTION 2022-07-05 20:24:37: INFO - Number of bytes to send: 47 2022-07-05 20:24:37: DEBUG - Data reversed 2022-07-05 20:24:37: DEBUG - data_buffer_in: [0000020b0a19181716151413120a0000] 2022-07-05 20:24:37: DEBUG - Data prepared for ftu_stream_in (8 byte reversed) 2022-07-05 20:24:37: DEBUG - data_buffer_in: [1718190a0b02000000000a1213141516] 2022-07-05 20:24:37: INFO - ---------------------------------------------------- 2022-07-05 20:24:37: INFO - Writing to bram0 via dma0 2022-07-05 20:24:37: DEBUG - flag_buffer: [ff00000000000000000000000000002f] 2022-07-05 20:24:37: INFO - ---------------------------------------------------- 2022-07-05 20:24:37: INFO - Reading bram1 via dma1 (reset buffers first) 2022-07-05 20:24:37: DEBUG - Buffers reset 2022-07-05 20:24:37: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-05 20:24:37: DEBUG - data_buffer_in: [00000000000000000000000000000000] 2022-07-05 20:24:38: INFO - FPGA ACK Received 2022-07-05 20:24:38: DEBUG - flag_buffer: [ff00000000000000000000000000002c] 2022-07-05 20:24:38: INFO - Number of bytes to read: 44 2022-07-05 20:24:38: DEBUG - Data received 2022-07-05 20:24:38: DEBUG - data_buffer_out: [00000009010203040506070809000000] 2022-07-05 20:24:38: INFO - Data recieved written -> ./data_out 2022-07-05 20:24:38: INFO - Flag cleared 2022-07-05 20:24:38: DEBUG - Testing if flag was cleared 2022-07-05 20:24:38: DEBUG - flag_buffer: [01010101010101010101010101010101] 2022-07-05 20:24:38: DEBUG - Reading bram1 2022-07-05 20:24:38: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-05 20:20:39: INFO - ---------------------------------------------------- 2022-07-05 20:20:39: INFO - Test Finished Para comprobar que el sistema devuelve los datos de entrada, es decir, que ha ejecutado bien el comando echo es necesario ver el contenido de data_out, ya que el host program solo imprime 32 caracteres como máximo. Código 5.5 Test 10a: fichero data_out. 000000090102030405060708090000000 a12131415161718191a1b0000000d232425262728292a2b2c2d2e2f Como se puede observar en la tabla 5.2, se han obtenido los datos esperados, ya que estos coinciden con los enviados a la FPGA al principio del test.
5.2 Intérprete de comandos: Test 10 29 Tabla 5.2 Test 10a: Datos a la salida. Tamaño Dato 00000009 010203040506070809 0000000a 12131415161718191a1b 0000000d 232425262728292a2b2c2d2e2f De esta forma se concluye que el sistema funciona correctamente. El resultado del Test 10b se puede ver a continuación: Código 5.6 Test 10b. 2022-07-05 20:20:20: INFO - ---------------------------------------------------- 2022-07-05 20:20:20: INFO - | STARTING NEW TEST: 2022-07-05 20:20:20 | 2022-07-05 20:20:20: INFO - ---------------------------------------------------- 2022-07-05 20:20:20: INFO - Logger created and configured 2022-07-05 20:20:20: INFO - ---------------------------------------------------- 2022-07-05 20:20:20: INFO - Instructions successfully prepared -> ./data_in 2022-07-05 20:20:20: INFO - ---------------------------------------------------- 2022-07-05 20:20:20: INFO - Starting FPGA Test 2022-07-05 20:20:22: INFO - ---------------------------------------------------- 2022-07-05 20:20:22: INFO - Target configured 2022-07-05 20:20:22: INFO - ---------------------------------------------------- 2022-07-05 20:20:22: INFO - STARTING 1o ¯TRANSACTION 2022-07-05 20:20:22: INFO - Number of bytes to send: 4 2022-07-05 20:20:22: DEBUG - Data reversed 2022-07-05 20:20:22: DEBUG - data_buffer_in: [15131313] 2022-07-05 20:20:22: DEBUG - Data prepared for ftu_stream_in (8 byte reversed) 2022-07-05 20:20:22: DEBUG - data_buffer_in: [13131315] 2022-07-05 20:20:22: INFO - ---------------------------------------------------- 2022-07-05 20:20:22: INFO - Writing to bram0 via dma0 2022-07-05 20:20:22: DEBUG - flag_buffer: [ff000000000000000000000000000004] 2022-07-05 20:20:22: INFO - ---------------------------------------------------- 2022-07-05 20:20:22: INFO - Reading bram1 via dma1 (reset buffers first) 2022-07-05 20:20:22: DEBUG - Buffers reset 2022-07-05 20:20:22: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-05 20:20:22: DEBUG - data_buffer_in: [00000000] 2022-07-05 20:20:23: INFO - FPGA ACK Received 2022-07-05 20:20:23: DEBUG - flag_buffer: [ff000000000000000000000000000001] 2022-07-05 20:20:23: INFO - Number of bytes to read: 1 2022-07-05 20:20:23: DEBUG - Data received 2022-07-05 20:20:23: DEBUG - data_buffer_out: [03] 2022-07-05 20:20:23: INFO - Data recieved written -> ./data_out 2022-07-05 20:20:23: INFO - Flag cleared 2022-07-05 20:20:23: DEBUG - Testing if flag was cleared 2022-07-05 20:20:23: DEBUG - flag_buffer: [01010101010101010101010101010101] 2022-07-05 20:20:23: DEBUG - Reading bram1 2022-07-05 20:20:23: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-05 20:20:39: INFO - ---------------------------------------------------- 2022-07-05 20:20:39: INFO - Test Finished La conclusión tras este test es doble, ya que se ha comprobado que el contador de 8 bits funciona correctamente y que las instrucciones enviadas para controlarlo han sido procesadas y ejecutadas sin ningún problema.
6 Reconfiguración Parcial We remember the good times and the bad ones, forgetting that most times are neither good nor bad. They just are. Brandon Sanderson, The Way of Kings La finalidad de este capítulo es obtener un bitstream funcional que permita reconfigurar parcialmente la FPGA. Para ello, se cuenta con la guía de reconfiguración parcial de Vivado (Vivado Design Suite User Guide) [ 16 ], así como el tutorial de reconfiguración parcial (Vivado Design Suite Tutorial) [ 17 ], ambos desarrollados por Xilinx. Estos documentos explican cómo generar un proyecto en Vivado que permita la reconfiguración parcial. Se procede a estudiar los elementos necesarios y los pasos a seguir, se modifica el Test 10 (sección 5.2) de forma que se pueda reconfigurar el contador y se adapta un desensamblador de bitstreams (desarrollado y proporcionado por Hipólito Guzmán Miranda, tutor del TFM) de forma que procese bitstreams de la familia Kintex Ultrascale (KU). 6.1 Reconfiguración Parcial en Vivado Para desarrollar un diseño que permita reconfigurar parcialmente la FPGA, es necesario realizar lo siguiente: • Obligar a los pines del SelectMap a que persistan, para que la FPGA admita nuevos bitstreams después de ser configurada por primera vez. • Establecer las regiones estáticas (no reconfigurables) y las regiones en las que se va a realizar la reconfiguración parcial. • Definir las diferentes configuraciones (elementos diferentes a colocar en las regiones reconfigurables) •Sintetizar, implementar y crear los bitstreams para cada una de las configuraciones establecidas. El segundo punto de esta lista es de vital importancia para FTU-Lite (la plataforma cuya viabilidad se está estudiando), ya que al convivir el diseño bajo prueba con el firmware de la plataforma de inyección de fallos en la misma FPGA, es crítico separar bien uno del otro, con el objetivo de evitar que los fallos inyectados afecten al firmware de la plataforma, ya que sólo se quiere que afecten al diseño bajo test. 6.2 Reconfiguración Parcial: Test 11 Una vez se conocen los requisitos necesarios, se procede a modificar el Test 10, de forma que permita reconfigurar parcialmente el contador. Con ese objetivo, se diseña otro contador de 8 bits casi igual que el original, con la única diferencia en que este comienza en [10000000] ( 0x80 en hexadecimal ) en vez de en [00000000] ( 0x00 en hexadecimal). 31
32 Capítulo 6. Reconfiguración Parcial A continuación, se crean dos configuraciones, una con el contador a cero (counter_low) y otra con el contador a 0x80 (config_high). Por último se añaden las constraints necesarias para obligar a los pines del SelectMap a que persistan. 6.2.1 Arquitectura Para este test, se utilizan dos arquitecturas diferentes, tal y como se explicaba en el párrafo anterior. La primera es exactamente igual a la del test anterior (sección 5.2) y en la segunda solo cambia el contador, ya que se coloca el que comienza contando por 0x80. A la primera configuración se le llamará a partir de ahora counter_low y a la segunda counter_high. 6.2.2 Host Program El Host Program parte del desarrollado en el capítulo 4. Este se modifica de forma que se realicen dos transmisiones: la primera antes de reconfigurar parcialmente la FPGA y la segunda justo después. De esta forma, se pueden estudiar los efectos de la reconfiguración parcial. Esta es la versión final del host program, por lo que a continuación se describe todo lo que este realiza (incluyendo lo descrito en los capítulos anteriores): 1. El script de python configura el logger, coge las instrucciones del fichero inst, las prepara para que el código en C++ pueda procesarlas y las escribe en el fichero data_in. 2. A continuación, ejecuta el código en C++. 3. Este coge los datos preparados de data_in y los divide en paquetes (del tamaño máximo admisible por el sistema de comunicaciones). 4. Abre el dispositivo, mapea las bRAMs en la memoria del host y bloquea el buffer para las transferencias a través de los DMA Engines. 5. Escribe, a partir de la dirección 0x0001 de la bRAM0, el primer paquete de instrucciones, empezando la primera transmisión. 6. Escribe en la dirección 0x0000 de la bRAM0 el ack y el número de datos enviados. 7. A continuación, lee el dato almacenado en la última dirección de la bRAM1 cada 1 segundo, hasta que obtiene el ack de la FPGA. 8. Lee los datos escritos por la FPGA en la bRAM1 (empezando en la dirección 0x0001) y los escribe en el fichero de salida data_out. 9. Vuelve al punto 5, si todavía quedan paquetes por enviar. 10. A continuación, reconfigura la FPGA con el bistream parcial con la configuración config_low y repite el envío de instrucciones (segunda transmisión). 11. Una vez ha acabado, desbloquea el buffer del DMA Engine, desmapea la bRAM de la memoria del host y cierra el dispositivo. Por último, cabe mencionar que en este test se envían dos instrucciones bit_up (0x13) seguidas de una bit_get (0x15). 6.2.3 Resultados A la hora de realizar este test, es muy importante comprobar que el sistema sigue funcionando correctamente tras la reconfiguración parcial, por lo que se ejecuta el test 3 veces. La primera vez hace exactamente lo mismo que se especificaba en la sección anterior (6.2.2). La segunda y la tercera, omiten ambas configuraciones: tanto la del principio, como la reconfiguración parcial.
6.2 Reconfiguración Parcial: Test 11 33 Es importante mencionar que en la segunda ejecución del test, se cambian las instrucciones, enviando solo una del tipo bit_up y otra de bit_get. En la tercera se envía un comando echo. Esto se hace así para comprobar que el sistema sigue funcionando correctamente tras la reconfiguración parcial. Todo esto queda recogido en la tabla 6.1 Tabla 6.1 Instrucciones Test 11. Ejecución Instrucciones Programación Inicial Reconfiguración Parcial Primera 13 13 15 SI SI Segunda 13 15 NO NO Tercera 02 00000003 010203 NO NO Resultado Primera Ejecución (con reconfiguración parcial) Código 6.1 Test 11: Primera Ejecución (con reconfiguración parcial). 2022-07-07 18:26:09: INFO - ---------------------------------------------------- 2022-07-07 18:26:09: INFO - | STARTING NEW TEST: 2022-07-07 18:26:09 | 2022-07-07 18:26:09: INFO - ---------------------------------------------------- 2022-07-07 18:26:09: INFO - Logger created and configured 2022-07-07 18:26:09: INFO - ---------------------------------------------------- 2022-07-07 18:26:09: INFO - Instructions successfully prepared -> ./data_in 2022-07-07 18:26:09: INFO - ---------------------------------------------------- 2022-07-07 18:26:09: INFO - Starting FPGA Test 2022-07-07 18:26:11: INFO - Target configured 2022-07-07 18:26:11: INFO - ---------------------------------------------------- 2022-07-07 18:26:11: INFO - STARTING 1o ¯TRANSACTION 2022-07-07 18:26:11: INFO - Number of bytes to send: 3 2022-07-07 18:26:11: DEBUG - Data reversed 2022-07-07 18:26:11: DEBUG - data_buffer_in: [151313] 2022-07-07 18:26:11: DEBUG - Data prepared for ftu_stream_in (8 byte reversed) 2022-07-07 18:26:11: DEBUG - data_buffer_in: [131315] 2022-07-07 18:26:11: INFO - ---------------------------------------------------- 2022-07-07 18:26:11: INFO - Writing to bram0 via dma0 2022-07-07 18:26:11: DEBUG - flag_buffer: [ff000000000000000000000000000003] 2022-07-07 18:26:11: INFO - ---------------------------------------------------- 2022-07-07 18:26:11: INFO - Reading bram1 via dma1 (reset buffers first) 2022-07-07 18:26:11: DEBUG - Buffers reset 2022-07-07 18:26:11: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-07 18:26:11: DEBUG - data_buffer_in: [000000] 2022-07-07 18:26:12: INFO - FPGA ACK Received 2022-07-07 18:26:12: DEBUG - flag_buffer: [ff000000000000000000000000000001] 2022-07-07 18:26:12: INFO - Number of bytes to read: 1 2022-07-07 18:26:12: DEBUG - Data received 2022-07-07 18:26:12: DEBUG - data_buffer_out: [02] 2022-07-07 18:26:12: INFO - Data recieved written -> ./data_out 2022-07-07 18:26:12: INFO - Flag cleared 2022-07-07 18:26:12: INFO - ------------------------------ 2022-07-07 18:26:12: INFO - -- END OF FIRST TRANSACTION -- 2022-07-07 18:26:12: INFO - ------------------------------ 2022-07-07 18:26:14: DEBUG - Starting FPGA Partial Reconfiguration 2022-07-07 18:26:16: INFO - Target reconfigured 2022-07-07 18:26:16: INFO - ---------------------------------------------------- 2022-07-07 18:26:16: INFO - STARTING 2o ¯TRANSACTION 2022-07-07 18:26:16: INFO - Number of bytes to send: 3 2022-07-07 18:26:16: DEBUG - Data reversed 2022-07-07 18:26:16: DEBUG - data_buffer_in: [151313] 2022-07-07 18:26:16: DEBUG - Data prepared for ftu_stream_in (8 byte reversed)
34 Capítulo 6. Reconfiguración Parcial 2022-07-07 18:26:16: DEBUG - data_buffer_in: [131315] 2022-07-07 18:26:16: INFO - ---------------------------------------------------- 2022-07-07 18:26:16: INFO - Writing to bram0 via dma0 2022-07-07 18:26:16: DEBUG - flag_buffer: [ff000000000000000000000000000003] 2022-07-07 18:26:16: INFO - ---------------------------------------------------- 2022-07-07 18:26:16: INFO - Reading bram1 via dma1 (reset buffers first) 2022-07-07 18:26:16: DEBUG - Buffers reset 2022-07-07 18:26:16: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-07 18:26:16: DEBUG - data_buffer_in: [000000] 2022-07-07 18:26:17: INFO - FPGA ACK Received 2022-07-07 18:26:17: DEBUG - flag_buffer: [ff000000000000000000000000000001] 2022-07-07 18:26:17: INFO - Number of bytes to read: 1 2022-07-07 18:26:17: DEBUG - Data received 2022-07-07 18:26:17: DEBUG - data_buffer_out: [82] 2022-07-07 18:26:17: INFO - Data recieved written -> ./data_out 2022-07-07 18:26:17: INFO - Flag cleared 2022-07-07 18:26:17: INFO - ------------------------------- 2022-07-07 18:26:17: INFO - -- END OF SECOND TRANSACTION -- 2022-07-07 18:26:17: INFO - ------------------------------- 2022-07-07 18:26:17: INFO - ---------------------------------------------------- 2022-07-07 18:26:17: INFO - Test Finished Resultado Segunda Ejecución (sin reprogramar la tarjeta ni reconfigurar parcialmente) Código 6.2 Test 11: Segunda Ejecución. 2022-07-07 18:27:39: INFO - ---------------------------------------------------- 2022-07-07 18:27:39: INFO - | STARTING NEW TEST: 2022-07-07 18:27:39 | 2022-07-07 18:27:39: INFO - ---------------------------------------------------- 2022-07-07 18:27:39: INFO - Logger created and configured 2022-07-07 18:27:39: INFO - ---------------------------------------------------- 2022-07-07 18:27:39: INFO - Instructions successfully prepared -> ./data_in 2022-07-07 18:27:39: INFO - ---------------------------------------------------- 2022-07-07 18:27:39: INFO - Starting FPGA Test 2022-07-07 18:27:39: INFO - ---------------------------------------------------- 2022-07-07 18:27:39: INFO - STARTING 1o ¯TRANSACTION 2022-07-07 18:27:39: INFO - Number of bytes to send: 2 2022-07-07 18:27:39: DEBUG - Data reversed 2022-07-07 18:27:39: DEBUG - data_buffer_in: [1513] 2022-07-07 18:27:39: DEBUG - Data prepared for ftu_stream_in (8 byte reversed) 2022-07-07 18:27:39: DEBUG - data_buffer_in: [1315] 2022-07-07 18:27:39: INFO - ---------------------------------------------------- 2022-07-07 18:27:39: INFO - Writing to bram0 via dma0 2022-07-07 18:27:39: DEBUG - flag_buffer: [ff000000000000000000000000000003] 2022-07-07 18:27:39: INFO - ---------------------------------------------------- 2022-07-07 18:27:39: INFO - Reading bram1 via dma1 (reset buffers first) 2022-07-07 18:27:39: DEBUG - Buffers reset 2022-07-07 18:27:39: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-07 18:27:39: DEBUG - data_buffer_in: [000000] 2022-07-07 18:27:40: INFO - FPGA ACK Received 2022-07-07 18:27:40: DEBUG - flag_buffer: [ff000000000000000000000000000001] 2022-07-07 18:27:40: INFO - Number of bytes to read: 1 2022-07-07 18:27:40: DEBUG - Data received 2022-07-07 18:27:40: DEBUG - data_buffer_out: [83] 2022-07-07 18:27:40: INFO - Data recieved written -> ./data_out 2022-07-07 18:27:40: INFO - Flag cleared 2022-07-07 18:27:40: INFO - ------------------------------ 2022-07-07 18:27:40: INFO - -- END OF FIRST TRANSACTION -- 2022-07-07 18:27:40: INFO - ------------------------------
6.2 Reconfiguración Parcial: Test 11 35 Resultado tercera Ejecución (sin reprogramar la tarjeta ni reconfigurar parcialmente) Código 6.3 Test 11: Tercera Ejecución (sin configuración de ningún tipo). 2022-07-07 18:28:19: INFO - ---------------------------------------------------- 2022-07-07 18:28:19: INFO - | STARTING NEW TEST: 2022-07-07 18:28:19 | 2022-07-07 18:28:19: INFO - ---------------------------------------------------- 2022-07-07 18:28:19: INFO - Logger created and configured 2022-07-07 18:28:19: INFO - ---------------------------------------------------- 2022-07-07 18:28:19: INFO - Instructions successfully prepared -> ./data_in 2022-07-07 18:28:19: INFO - ---------------------------------------------------- 2022-07-07 18:28:19: INFO - Starting FPGA Test 2022-07-07 18:28:19: INFO - ---------------------------------------------------- 2022-07-07 18:28:19: INFO - STARTING 1o ¯TRANSACTION 2022-07-07 18:28:19: INFO - Number of bytes to send: 8 2022-07-07 18:28:19: DEBUG - Data reversed 2022-07-07 18:28:19: DEBUG - data_buffer_in: [0302010300000002] 2022-07-07 18:28:19: DEBUG - Data prepared for ftu_stream_in (8 byte reversed) 2022-07-07 18:28:19: DEBUG - data_buffer_in: [0200000003010203] 2022-07-07 18:28:19: INFO - ---------------------------------------------------- 2022-07-07 18:28:19: INFO - Writing to bram0 via dma0 2022-07-07 18:28:19: DEBUG - flag_buffer: [ff000000000000000000000000000008] 2022-07-07 18:28:19: INFO - ---------------------------------------------------- 2022-07-07 18:28:19: INFO - Reading bram1 via dma1 (reset buffers first) 2022-07-07 18:28:19: DEBUG - Buffers reset 2022-07-07 18:28:19: DEBUG - flag_buffer: [00000000000000000000000000000000] 2022-07-07 18:28:19: DEBUG - data_buffer_in: [0000000000000000] 2022-07-07 18:28:20: INFO - FPGA ACK Received 2022-07-07 18:28:20: DEBUG - flag_buffer: [ff000000000000000000000000000007] 2022-07-07 18:28:20: INFO - Number of bytes to read: 7 2022-07-07 18:28:20: DEBUG - Data received 2022-07-07 18:28:20: DEBUG - data_buffer_out: [00000003010203] 2022-07-07 18:28:20: INFO - Data recieved written -> ./data_out 2022-07-07 18:28:20: INFO - Flag cleared 2022-07-07 18:28:20: INFO - ------------------------------ 2022-07-07 18:28:20: INFO - -- END OF FIRST TRANSACTION -- 2022-07-07 18:28:20: INFO - ------------------------------ Conclusiones Tras observar los resultados obtenidos se concluye que el bitstream parcial compilado funciona correctamente. Por otro lado, se ha comprobado (mediante la segunda y tercera ejecución) que tanto el el contador como el resto del sistema siguen funcionando perfectamente tras la reconfiguración parcial.
7 Desensamblador de bitstreams Nunca dejarás de sorprenderme. Emma Moreno Socías La principal motivación de este capítulo es que, para poder hacer inyección de fallos usando reconfiguración parcial, no se basta con hacer sólo una operación de escritura (que es lo que se consiguió en el capítulo 7). Por tanto, se tiene que hacer lo que se conoce como un read-modify-write (si no, se machacan todos los bits de usuario que estén en ese frame con el valor de INIT que haya en el bitstream, y no se busca eso, sólo cambiar 1 bit), lo que implica hacer readback del frame de la FPGA que se quiere modificar. Para poder hacer readback, el software de Xilinx no genera nada, por lo que, en el futuro cercano será necesario comparar las cabeceras de readback y reconfiguración que se tienen de la versión anterior de la plataforma (en Virtex-5) con las cabeceras de reconfiguración de la KU060 (generadas por Vivado). De esta forma, se pueden determinar (con la ayuda de la documentación de Vivado [ 15 ] y reconfiguración de la familia Kintex Ultrascale) los comandos necesarios para hacer readback. 7.1 Adaptación del desensamblador de bitstreams a KU Una vez se ha conseguido obtener un bitstream parcial, se procede a adaptar el desensamblador de bitstreams (para bistreams de la familia Virtex-5) a la familia a la que pertenece la tarjeta bajo estudio: Kintex Ultrascale (KU). Es importante mencionar que este desensamblador se ha creado específicamente para este proyecto, a partir de un sistema diseñado por el tutor del TFM (Hipólito Guzmán Miranda) para bitstreams de la familia Virtex-5 (V5). Este se ha modificado, adaptado y mejorado para que funcione con los bitstreams de la familia KU. 7.1.1 Versión inicial La versión inicial del desensamblador, el cual está escrito en python, hace lo siguiente: 1. Lee una palabra (4 bytes) del bitstream a desensamblar. 2. La compara con el diccionario propio de la familia a la que pertenece el bitstream, obteniendo una pequeña descripción de lo que hace. 3. Imprime por el terminal y escribe en un archivo de texto la palabra con su descripción al lado. 4. Vuelve al paso 1, repitiendo el proceso hasta leer y analizar todos los bytes del bitstream. 7.1.2 Modificaciones y mejoras implementadas Para adaptar el sistema a la familia KU, se realizan las siguientes modificaciones: 37
Índice de Códigos 3.1 Resultados Test 7 11 3.2 Resultados Test 8 14 3.3 Resultados Test 9 17 4.1 Python arguments example 19 4.2 Python logger example: 2022-07-04.log 20 4.3 Both loggers example: 2022-07-04.log 21 5.1 Ejemplo comando echo 23 5.2 Test 10a: Instruciones enviadas a la FPGA 26 5.3 Test 10b: Instruciones enviadas a la FPGA 27 5.4 Test 10a 28 5.5 Test 10a: fichero data_out 28 5.6 Test 10b 29 6.1 Test 11: Primera Ejecución (con reconfiguración parcial) 33 6.2 Test 11: Segunda Ejecución 34 6.3 Test 11: Tercera Ejecución (sin configuración de ningún tipo) 35 7.1 Ejemplo resultado desensamblar counter_high.bit. 39 45
Bibliografía [1] Oneweb, (2022), Online. Accedido el 10 de junio de 2022. [2] M. A. Aguirre, J. Barrientos, H. Guzmán-Miranda, F. Márquez, F. Muñoz, and L. Sanz, https://ftu.us.es/, Online. Accedido el 10 de junio de 2022. [3] Alfa Data, ADM-XRC-KU1 Datasheet, Revision 1.1, https://www.alpha-data.com/pdfs/adm-xrc-ku1_- v1.1.pdf, Online. Accedido el 13 de diciembre de 2019. [4] ,ADM-XRC-KU1 SDK, Revision 1.0.0, https://support.alphadata.com/pub/admxrcg3/linux/archive/admxrcku1_sdk-1.0.0.tar.gz, Online. Accedido el 13 de diciembre de 2019. [5] Javier González Moreno, Estudio de interfaz MPTL-AXI en la tarjeta ADM-XRC-KU1 y adaptación a sistema de inyección de fallos, Universidad de Sevilla Escuela Técnica Superior de Ingeniería – Trabajo Fin de Grado. Director: Hipólito Guzmán Miranda, 2020. [6] H. Guzmán-Miranda, L. Sanz, M. Muñoz-Quijada, F. Muñoz, F. Márquez, and D. Vela-Calderón, Ft-unshades2 ccn3: Milestone 1 presentation. contrato esa nº: 22981/09/nl/jk. [7] Maria Muñoz-Quijada, Luis Sanz, and Hipolito Guzman-Miranda, A virtual device for simulation-based fault injection, Electronics 9(2020), no. 12. [8] Python, C-style parser for command line options, https://docs.python.org/3/library/getopt.html, Online. Accedido el 17 de septiembre de 2021. [9] ,Logging facility for python, https://docs.python.org/3/library/logging.html, Online. Accedido el 14 de septiembre de 2021. [10] S. Rezgui, R. Velazco, R. Ecoffet, S. Rodriguez, and J.R. Mingo, Estimating error rates in processorbased architectures, IEEE Transactions on Nuclear Science 48 (2001), no. 5, 1680–1687. [11] SpaceX, https://www.starlink.com/, 2022, Online. Accedido el 10 de junio de 2022. [12] R. M. Tawfeek, M. G. Egila, Y. Alkabani, and I. M. Hafez, Fault injection for fpga applications in the space, 2017 12th International Conference on Computer Engineering and Systems (ICCES), 2017, pp. 390–395. [13] Raoul Velazco and Fabien Faure, Error rate prediction of digital architectures: Test methodology and tools, pp. 233–258, Springer Netherlands, Dordrecht, 2007. [14] Xilinx, ug570 ultrascale configuration, 2016, Online. Accedido el 02 de julio de 2022. [15] , ug908 vivado programming debugging, 2016, Online. Accedido el 27 de junio de 2022. [16] ,ug909 vivado partial reconfiguration user guide, 2016, Online. Accedido el 10 de mayo de 2021. [17] ,ug947 vivado partial reconfiguration tutorial, 2016, Online. Accedido el 10 de mayo de 2021. 47