01signal.com

Más allá de la lógica: los rasgos humanos de un diseñador de FPGA

Esta página es la quinta y última de una serie de páginas sobre cómo convertirse en diseñador profesional de FPGA. A diferencia de las anteriores, no trata de cuestiones técnicas. En su lugar, el foco está en nosotros como seres humanos y en qué características hacen la vida del diseñador de FPGA más fácil y mejor.

Esto importa de verdad

Puede parecer raro hablar de la personalidad y la actitud de los diseñadores de FPGA, en particular en un sitio web centrado en temas técnicos. Sin embargo, en una guía dirigida a alguien que aspira a ser diseñador de FPGA, me parece adecuado tratar también las cualidades y comportamientos humanos que marcan la diferencia entre tenerlo todo bajo control y trabajar en el caos más absoluto.

Hay una personalidad adecuada para prácticamente todas las profesiones: es difícil ser comercial de coches si se te dan mal las relaciones con la gente, y no serás un buen profesor si no te gustan los niños. Del mismo modo, hay ciertos rasgos de personalidad que te ayudan como ingeniero de FPGA, y otros que no.

No estoy sermoneando ni intento disuadir a nadie. Tampoco vengo con el "hay que trabajar duro". Al contrario: la intención es hacer las cosas correctamente y alcanzar los objetivos con menos esfuerzo.

En esta página intentaré describir qué hace falta para ser un diseñador de FPGA de éxito, además de tener estos u otros conocimientos profesionales, para vivir en paz con esta profesión. Esta página va de la personalidad del ingeniero. No sorprenderá a nadie que sea mejor tener autodisciplina y autocontrol, y ser del tipo meticuloso. Una ligera obsesión por los detalles tampoco viene mal.

Pero no confundas esto con alguna idea de sufrir en la vida o de matarse a trabajar. Es justo lo contrario: si tienes la capacidad de trabajar de una determinada manera, lo conseguirás más rápido y con menos esfuerzo. Será divertido y gratificante. Que salga bien a la primera es el ideal, y es alcanzable.

Por otro lado, si sientes que no encajas en mis descripciones del diseñador de FPGA ideal que vienen a continuación, ni de lejos, mmm, ¿cómo lo digo? ¿Quizá plantearte otra vez toda esta idea?

"Funciona" no es suficiente

En el mundo del software, en particular en sitios web y aplicaciones, la práctica habitual es apuntar algo de código, probarlo, corregir lo que esté mal y volver a probar. Con la IA, incluso la fase de apuntar código se salta, y una máquina hace tanto la codificación como las pruebas y, al final, confirma el resultado en el repositorio de Git.

La idea subyacente es: si el código pasa las pruebas, el trabajo está hecho. Si sigue habiendo un fallo, lo encontrará el QA o pronto llegará la queja de algún usuario. En ese caso, se emitirá una petición para corregirlo como procedimiento estándar. Y después se corrige el fallo. Un montón de equipos de software están estructurados para trabajar exactamente así.

Que esta práctica sea adecuada para desarrollar software o no es una discusión aparte. Lo que quiero dejar claro es que es profundamente errónea para el diseño profesional de FPGA. "Funciona" no es ni de lejos suficiente para un proyecto de FPGA. Quizá lo sea para los aficionados, pero desde luego no para un proyecto que va a producción real. Es tentador caer en esta trampa, sobre todo cuando te alegra que algo por fin funcione tras una larga sesión de depuración, y das el día por terminado.

Esto puede sonar a sermón purista, pero es la pura verdad: la única forma de conseguir un diseño de FPGA fiable es demostrarte a ti mismo, de una vez por todas, que lo que has diseñado tiene garantizado que va a funcionar. No terminas una tarea cuando el diseño pasa todas las pruebas, sino solo cuando puedes convencerte de que es imposible que falle.

Lo compararé con un teorema matemático: no dices que es correcto porque lo has probado unas cuantas veces con números y ha salido bien todas las veces. Consideras que la ecuación es correcta cuando tienes una demostración matemática.

En la práctica, esto significa tratar cada línea de un archivo Verilog como una ecuación en una derivación matemática, y lo mismo vale para las restricciones de temporización (timing constraints) y otros archivos fuente relacionados. Puede sonar un poco extremo, pero ser tan cuidadoso da sus frutos a largo plazo.

Lo mismo vale para las conexiones de la FPGA con otros componentes electrónicos: no das por bueno que la interfaz eléctrica esté bien solo porque funcione. Te demuestras a ti mismo que se cumplen los requisitos de las hojas de características: tanto los de la hoja de características de la FPGA como los de los demás componentes. ¿Son correctos los niveles de tensión? ¿Garantiza el diseño de la FPGA que se cumplen todos los requisitos de temporización por ambos lados?

¿Significa esto que mis diseños están siempre libres de fallos? Por supuesto que no. Soy humano y cometo errores. Igual que puede que no consiga una demostración matemática 100% correcta, aunque lo intente. Puede que me olvide de comprobar casos límite, puede que cambie un más por un menos y meta la pata en general.

Pero lo bueno de este enfoque riguroso es que los pocos fallos con los que acabo suelen ser evidentes y relativamente fáciles de corregir. Y una vez corregidos, el diseño simplemente funciona. Sin fallos, sin misterios, sin brujería. Un trozo de electrónica que funciona de forma sólida.

Es el camino lento para llegar rápido al objetivo.

¿De verdad trabaja la gente así de rigurosamente?

Respuesta corta: desde luego que no. Lo sé en particular por mi época como freelance. Mi primera tarea, con cada nuevo cliente, era estabilizar el proyecto de FPGA. Esto se parecía un poco a lo que hacen los médicos cuando estabilizan a un paciente en urgencias. Y los ingenieros responsables del proyecto a menudo parecían necesitar también algún tipo de estabilización, tras mucho tiempo de estrés y frustración.

La actitud de apuntar código y luego depurar es, por desgracia, habitual también en la industria de la FPGA. No es de extrañar, ya que el simulador se presenta a menudo en los cursos de Verilog con el mismo espíritu que un depurador en el mundo del software. La sugerencia que subyace es a menudo alcanzar el resultado deseado por ensayo y error. Simula hasta que funcione en el ordenador, y luego sintetiza y corrige hasta que funcione también en el hardware.

Para empeorarlo, hay jefes que fomentan este tipo de método de trabajo. Están impacientes por ver resultados y, en cuanto ven algo que parece estar bien, esperan que pases a la siguiente tarea. El calendario aprieta, y "ya corregiremos los fallos más adelante".

Como resultado de este enfoque, es difícil, y a veces imposible, conseguir un diseño de FPGA verdaderamente fiable. Esto se compensa con extensas pruebas de regresión en simulación, así como con extensas pruebas con hardware. Algunas empresas hacen pruebas de temperatura a cada placa fabricada antes de que salga de la línea de producción, si lleva una FPGA. Probar el hardware antes de la entrega se convierte en su propio departamento, con su propio hardware y software, que tiene un único propósito: asegurar que la FPGA hace realmente lo que debe.

Detrás de todo esto hay ingenieros de FPGA muy estresados, que van con retraso mientras persiguen frenéticamente fallos que aparecen y desaparecen misteriosamente.

No siempre es tan malo. Cuando la FPGA funciona a una frecuencia relativamente baja, cuando los requisitos son sencillos y cuando los fallos esporádicos no son tan graves, la actitud de ensayo y error puede funcionar bastante bien.

Además, en realidad, la mayoría de la gente que trabaja con FPGA está en algún punto intermedio de la escala: no en el extremo de considerar el Verilog como ecuaciones matemáticas, pero sí con un nivel elevado de paciencia, autodisciplina y respeto por la precisión. Así es como consiguen sacar el trabajo adelante en este campo.

Sabe lo que estás haciendo

Si te he convencido de que el ensayo y error no es el camino a seguir con las FPGA, está claro que se requiere una senda más rigurosa y precisa. Pero eso por sí solo no basta. Una actitud rigurosa no sirve de nada si no entiendes exactamente lo que estás haciendo.

Por ejemplo, es bastante común ver resets asíncronos (asynchronous resets) en código Verilog (también lo he mencionado en páginas anteriores). Es un método legítimo para resetear lógica, pero solo si se aplica correctamente. En la gran mayoría de los casos, este reset se usa de forma incorrecta y, por lo tanto, no garantiza que la lógica se comporte como se espera. Pero en la realidad, todo funciona bien. Normalmente. Hay una página aparte sobre este tema.

El motivo de este uso incorrecto del reset asíncrono es probablemente que la gente copia y pega código Verilog de otras fuentes en el suyo. El patrón de codificación es tan familiar y obvio que la gente no se para a pensar qué significa en realidad. Y, en este caso, qué no significa ni garantiza.

Saber lo que estás haciendo es un requisito previo para poder demostrarte a ti mismo que tu diseño tiene garantizado que va a funcionar. Esto significa entender exactamente qué significa cada expresión de Verilog y cómo podría interpretarla el sintetizador (synthesizer). El mismo principio se aplica a las restricciones de temporización (timing constraints) y a otra información que las herramientas de desarrollo consumen en relación con el diseño de la FPGA.

Pero, como ya he admitido, la mayoría de los diseñadores de FPGA no son lo bastante rigurosos como para demostrar que el diseño funciona. Saber el significado exacto de lo que escribes es, aun así, un paso en la dirección correcta.

Piensa de forma abstracta

Si has hecho algún curso académico de informática, puede que hayas visto cómo se inventan criaturas abstractas con el fin de describir software. Por ejemplo, estructuras de datos siempre organizadas de una manera concreta, clases y objetos, flujos de datos, e invariantes que se mantienen tras cada iteración de un bucle, etcétera. En informática se inventan criaturas imaginarias todo el tiempo, para que los humanos podamos mirar más allá de los pequeños detalles internos y relacionarnos en cambio con una representación más sencilla. Esto reduce la carga sobre nuestro cerebro y hace posible entender diseños de software complicados. A esto lo llamamos abstracción.

En el lado opuesto de la abstracción tenemos la forma de pensar concreta. ¿O debería llamarla "contar historias"? Con esta actitud, un programa de ordenador se trata como un relato. Primero hacemos esto, y luego hacemos aquello, y si esto es verdad hacemos esto, si no, aquello. Solo hay que seguir la secuencia de acontecimientos con el dedo recorriendo el código, y lo entiendes todo.

Contar historias funciona bien para desarrollar scripts sencillos, sitios web, aplicaciones móviles y otro software simple. Si el usuario pulsa este botón, ve a esta pantalla o página web, y a partir de ahí sigue. El software avanza en un único hilo de ejecución sencillo y puede entenderse en un único hilo de pensamiento.

Me gustaría mostrar la diferencia entre las dos formas de pensar con un ejemplo. Veamos esta función, escrita en C, que calcula n!, el factorial de n:

unsigned int factorial(unsigned int n) {
  if (n == 0)
    return 1;

  return n * factorial(n - 1);
}

Este es el ejemplo clásico de recursión. ¿Cómo entiendes el código de arriba?

La forma de contar historias es "probarlo". Suena más o menos así: "Supongamos que se llamó a la función con n=3. Se llamará a sí misma con n=2, luego con n=1 y luego con n=0. Ahora desenrollamos: así que devuelve 1 para la llamada con n=0, luego 1*1, luego devuelve 2*1 y finalmente 3*2, que es 6, y esa es la respuesta correcta. Genial, funciona". Puede que este proceso mental se haga con un depurador, usando ejecución paso a paso.

La otra forma se parece a una demostración por inducción matemática. Suponemos que la función devuelve efectivamente el factorial de n y confirmamos que, si funciona para n-1, también funciona para n. Por último, confirmamos que da el valor correcto para n=0, y que la recursión siempre acaba llegando a n=0. La secuencia de ejecución es irrelevante, ya que la función se trata como una criatura abstracta que simplemente cumple su propósito.

Y puedes preguntar: ¿por qué complicar las cosas? Contar historias lo explicaba perfectamente. A esto respondo: sí, pero funcionó solo porque el ejemplo es sencillo.

Y ahora por fin llego al grano: si te limitas a contar historias para entender software, eso va a ser un obstáculo para ti como diseñador de FPGA. La primera y obvia razón es que en una FPGA todo ocurre a la vez. Muy poco en una FPGA puede describirse con "primero esto, luego aquello".

La segunda razón, y más importante, es que los diseños de FPGA a menudo son complejos. La abstracción suele ser necesaria para que seas mentalmente capaz de captar lo que está pasando. Por ejemplo, es una buena costumbre definir un módulo Verilog de forma que su funcionalidad pueda describirse en unas pocas frases y sin demasiados detalles. Las interfaces de sus puertos también deberían ser sencillas de describir. Cuando es posible reducir un bloque lógico complicado a unas pocas ideas simples, hay menos probabilidad de error humano. Este principio también se aplica al software, pero no siempre es igual de crucial.

La tercera razón para pensar de forma abstracta tiene que ver con la capacidad de demostrarte a ti mismo la corrección. Contando historias solo cubres los escenarios que eres capaz de imaginar. Una demostración de verdad lo cubre todo.

Al abordar tareas complicadas, puede ser necesario inventar nuevas criaturas teóricas antes de escribir una sola línea de Verilog. Por ejemplo, si necesitas un módulo que tanto reciba como emita paquetes de datos, puede ayudar definir N como el número de paquetes que están almacenados actualmente en su búfer de memoria. Con esto, puedes demostrar que el búfer nunca se llena. Puede que no parezca gran cosa, pero dar este paso hacia el pensamiento matemático puede ayudar mucho. Bien podría ser que toda la lógica del módulo esté relacionada de algún modo con mantener esa N dentro de los límites correctos.

El truco está en encontrar las criaturas abstractas correctas que de verdad ayuden a que la lógica salga bien. Esto puede significar no escribir ni una sola línea de Verilog durante unos días y, de repente, tener un módulo Verilog corto escrito en un abrir y cerrar de ojos. El código concebido así suele ser corto, elegante, fácil de entender y funciona al primer intento y para siempre.

Sin embargo, puede que esto no funcione tan bien si tu jefe te pregunta todos los días qué estás haciendo: durante unos días no hay nada que mostrar, y cuando por fin se te ocurre algo, la respuesta puede ser "¿y todo lo que tienes es este módulo trivial?".

Así que, una vez más, ser puramente matemático con el diseño de FPGA no es necesariamente lo adecuado para todo el mundo. Pero sigo sugiriendo que te deshagas de la costumbre de contar historias, si la tienes.

No te fíes de las herramientas

O, más precisamente: las herramientas de desarrollo no te van a impedir cometer errores horribles. Puede que ni siquiera te avisen.

Ningún compilador de software del mundo producirá jamás código ejecutable que haga algo distinto de lo que pide el código fuente. Si lo hace, informa de un fallo. Un sintetizador (synthesizer), en cambio, puede perfectamente generar lógica que no cumpla el comportamiento pedido por el código Verilog. Si tienes suerte, habrá un aviso sobre ello. Si tienes aún más suerte, te darás cuenta de ese aviso entre los cientos de otros mensajes y avisos inocentes que escupe el sintetizador.

Las otras partes de la suite de desarrollo de FPGA también pueden jugarte malas pasadas. La más evidente es que la mayoría generarán un flujo de bits (bitstream) que puedes cargar en la FPGA, aunque no se cumplan las restricciones de temporización (timing constraints). Esto significa que la FPGA puede funcionar como el sintetizador pretendía, o puede que no. O quizá funcione un poco y luego deje de funcionar. Recibirás un aviso o incluso un aviso crítico (Critical Warning). Pero, ¿terminaría un compilador de software una compilación y daría un ejecutable que puede que no funcione?

Hay infinitas otras formas de estropear un diseño de FPGA sin que las herramientas te detengan. Esto es en cierto modo una cuestión cultural. Es como si alguien quisiera intencionadamente que tratar con FPGA fuera difícil.

He trabajado con varios fabricantes de FPGA distintos y con bastantes herramientas de desarrollo para FPGA. Resulta bastante intrigante que todos tengan esta misma tendencia a complicar las cosas y que las redes de seguridad sean algo que uno desea. No es un fabricante de FPGA concreto, barato y malvado. Son todos.

Y encima, no es raro que las herramientas de desarrollo de FPGA tengan fallos. Si tienes suerte, se cuelgan mientras intentan construir el proyecto, así que al menos no es un fallo que haga que tu diseño funcione mal. Sin embargo, sí ocurren fallos que dan lugar a un defecto en el flujo de bits (bitstream), aunque no muy a menudo. Es peor cuando se lanza una suite de diseño nueva. En el mundo de la FPGA, lo último que sale no significa necesariamente lo mejor, que quede claro.

Dicho esto, no sospeches de las herramientas si tu diseño no funciona, sobre todo si eres nuevo en este campo. Y si crees que las herramientas te han fallado, encuentra la prueba irrefutable. Encuentra la celda lógica de la FPGA donde debería haber sido una cosa y resultó ser otra. Convéncete de que de verdad es culpa de las herramientas que haya acabado así. No basta con que sientas que las herramientas están locas. Casi siempre hay una explicación más sencilla para lo que lo parece.

Y en particular, si cambias algo no relacionado en tu código Verilog y un fallo desaparece, no significa que haya un fallo en las herramientas. Ese comportamiento es más típico de restricciones de temporización (timing constraints) mal definidas y otros errores similares.

La clave para abordar este asunto con las herramientas de desarrollo es, a riesgo de repetirme, saber lo que estás haciendo. En concreto para este tema, leer los avisos y mensajes que emiten las herramientas y entender qué significan, o al menos con qué están relacionados a grandes rasgos. Es cuestión de experiencia aprender qué avisos son inofensivos, aparecen siempre y pueden y deben ignorarse. En cuanto a por qué las herramientas siguen emitiendo muchos avisos inútiles, versión tras versión... ¿he mencionado la cultura?

Por eso es una buena costumbre echar un vistazo a todos los avisos de vez en cuando y ver si algo llama la atención. Hazlo incluso, y en particular, cuando todo funcione perfectamente. No solo porque "funciona" no es suficiente, sino también como forma de aprender qué avisos son inofensivos.

Y, de hecho, algunos avisos son una indicación de que has hecho las cosas bien. Por ejemplo, si un aviso dice que se ha eliminado un registro del diseño porque tiene un valor constante o es equivalente a otro registro. Esa es una oportunidad para detenerse un segundo y pensar si eso tiene sentido en su contexto. Muy a menudo, estos avisos te ayudan a darte cuenta de cosas interesantes sobre tu propio código.

Del requisito al diseño

Cuando escribes software, normalmente hay una línea bastante directa entre el requisito y lo que tienes que escribir. Esto es especialmente cierto para software sencillo (sitios web y aplicaciones móviles, por ejemplo).

Con el diseño de FPGA, puede que no sea tan fácil. El requisito para una FPGA a menudo suena más bien a "aquí están los componentes, queremos que se comporte de esta manera".

Por ejemplo, el planteamiento puede ser una placa con un sensor de cámara, una FPGA y cables que van a otra unidad. La tarea es tomar la imagen del sensor de la cámara, hacer un procesado de señal básico sobre los píxeles y enviar la salida a la otra unidad, siguiendo el formato específico de tu empleador para transmitir datos de vídeo.

Tú lo sabes todo sobre FIFO, máquinas de estados (state machines), segmentaciones (pipelines) y diseño RTL. ¿Cómo creas lo que te piden? Nadie te dice "escribe una máquina de estados". Se espera que crees algo que funcione.

Si tienes suerte, los requisitos se parecen a los de muchos proyectos anteriores. Copia el diagrama de bloques, imita la lógica y quizá copies algunas partes. Pero muy a menudo hay algo en los requisitos de tu proyecto que hace que esa imitación no sea razonable.

Es entonces cuando te conviertes también en el arquitecto de la FPGA. Tú decides cómo se divide la tarea en unidades funcionales, qué hace cada una y cómo interactúan entre sí. Cuanto mejor lo hagas al comienzo mismo del proyecto, más fácil será escribir y mantener el proyecto. Con demasiada frecuencia, se impone el diagrama de bloques de un proyecto existente a un proyecto nuevo a falta de algo mejor. Este atajo tiene un coste.

Entonces, ¿cómo se llega a ser un buen arquitecto? Mucho de esto viene de la experiencia, y también de observar las soluciones elegidas en otros proyectos. He mencionado antes la abstracción: entender un diseño, ya sea tuyo o de otro, en términos abstractos te ayuda a construir mejor el siguiente proyecto. Si ves los módulos Verilog como bloques funcionales que realizan una tarea para la que tienes un nombre corto, tienes una paleta que usar para tu propio proyecto. Si ves cómo varios cables conectan dos módulos, y puedes ponerle un nombre a cómo interactúan los módulos a través de esos cables, estás en mejor posición para decidir cómo interactúan las distintas partes de tu nuevo proyecto. Cuanto mejor seas reconociendo las criaturas teóricas de un diseño existente, mejor se te dará construir uno nuevo.

Si la parte de arquitecto de FPGA suena difícil, déjame compartir un pequeño secreto: lo es de verdad. Lo he hecho unas cuantas veces, y hace falta muchísimo tiempo y también mucho arrepentimiento. Cada pequeño error en esta etapa inicial tiene consecuencias importantes.

Pero recuerda que probablemente no necesitarás diseñar un proyecto desde cero, y desde luego no como alguien nuevo en las FPGA. Esta tarea normalmente se le asigna al ingeniero de FPGA más veterano del equipo. Así que probablemente tengas algo de tiempo antes de ponerte el sombrero de arquitecto de sistemas. E incluso si te contratan como el único ingeniero de FPGA del equipo, lo más probable es que mantengas código existente o desarrolles un proyecto nuevo a partir de uno existente.

Pero nunca es demasiado pronto para empezar a prepararse para esta tarea.

Resumen

En muchos sentidos, el tema principal de esta página ha sido la autodisciplina en distintas formas. Es la capacidad de superar lo que a menudo se considera comportamiento humano: hacer las cosas sin precisión y sin pensarlas antes (escribir código Verilog y restricciones de temporización (timing constraints) en particular) y luego corregir los errores (simulación y depuración en hardware). Alegrarse de que algo funcione y estar ansioso por pasar a la siguiente tarea ("funciona" no es suficiente). Explicarte las cosas a ti mismo de forma simple y natural (contando historias), en lugar de buscar las ideas abstractas que hay detrás. Saltarse los detalles pequeños y aburridos, como los avisos que emiten las herramientas.

Nuestra naturaleza humana es, por desgracia, un enemigo para nosotros como diseñadores de FPGA. Pero fíjate en que no he dicho nada de trabajar duro. Esforzarse por trabajar menos no es pereza si haces el trabajo. El objetivo es en realidad trabajar menos y aun así obtener un mejor resultado. Y es posible si lo haces bien.

Tampoco se trata de convertirse en un robot. Se trata de tener autocontrol y precisión en tu vida laboral, pero desde luego no de trabajar como una máquina. Necesitamos nuestros cerebros humanos. Un robot puede trabajar muchas horas, pero nuestros cerebros se cansan. El autocontrol significa a veces dejar el escritorio y descansar tras un día largo y tedioso. Incluso cuando ese fallo sigue ahí.

Y para resumir toda esta serie de páginas —como ya debería ser evidente, el diseño de FPGA no es la más sencilla de las profesiones, y he enumerado bastantes razones para ello—. Si no te gusta estar aprendiendo cosas nuevas sobre electrónica todo el tiempo, puede que esto no sea para ti. Si crees que no tienes la autodisciplina para hacer las cosas a fondo y con precisión, esa es otra razón para replanteártelo.

Y si no he conseguido asustarte hasta ahora, te doy la bienvenida al club y te deseo la mejor de las suertes y la mayor de las destrezas. Y, más que nada, espero que disfrutes de esta elección tanto como yo.

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. (852e87d4)