Plantilla para microcontroladores Espressif

 

ESP32-C3 WROOM

Debido a la escasez de microcontroladores que seguimos teniendo y a la subida considerable del precio de los mismos, he optado por cambiar de las marcas occidentales a las del mercado asiático. En concreto a Espressif Systems.

HAMSatTracker: Parte 4 (Software)

Llegamos a al última parte del proyecto, el programa tanto para PC/Adroid como para la Raspberry Pi. Encargado de controlar la antena y calcular la posición del satélite con respecto a nuestra posición.

Ventana principal

HAMSatTracker: Parte 3 (Antena)

Otra parte del proyecto es la antena para poder comunicarse con los satélites. Su diseño está basado en un artículo sobre la construcción de una antena DIY por Kent Britain (WA5VJB). Una copia en pdf se encuentra en el repositorio junto con los archivos del diseño 3D.

Versión de 5 elementos (UHF)

HAMSatTracker: Parte 2 (Electrónica)

La placa de circuito impreso (PCB) se encarga de comunicar los drivers de los motores y la placa Raspberry Pi Zero W. Donde se realizan los cálculos de la órbita de los satélites.

El programa utilizado ha sido KiCad, software libre para el diseños de circuitos electrónicos.

PCB de HamSatTracker v1.0

HAMSatTracker: Parte 1 (Diseño y mecánica)

El objetivo principal del diseño era hacerlo compacto, con el menor número de piezas necesarias para no gastar mucho tiempo en la impresión, a la vez que se ahorra en filamento. 

El programa utilizado ha sido FreeCAD Link branch , es una variante realizada por Realthunder que ofrece mejoras significativas y arregla el problema de la topología de nombres en la rama oficial (en concreto se ha usado la versión 2022.01.11 estable). Además incluye el módulo de ensamblado Assembly3.

Dentro del repositorio se encuentran carpetas con las diferentes partes: caja general de la electrónica, caja para la pequeña placa de mosfets, antena, placa de circuito impreso (PCB), toda la estructura (parte mecánica) que permite mover la antena y archivo de ensamblado de todas las piezas.

Dentro de cada carpeta se pueden encontrar subcarpetas con diferentes tipos de archivos, su descripción es la siguiente:

  • Carpeta raíz: suele tener archivos con extensión FCStd, que son los pertenecientes a FreeCAD y contienen las piezas modeladas en 3D.
  • Capeta stl: contiene los archivos stl con objetos 3D importados de otros, como tornillos, tuercas, etc...
  • Carpeta step: contiene los archivos step importados de terceros, como rodamientos, motores, etc...
  • Carpeta amf: contiene los archivos amf, que son cada una de las piezas que se necesitan imprimir para montar el proyecto.
  • Carpeta 3mf: contiene los archivos 3mf, que incluyen información adicional para su impresión.

Con respecto a este último punto, los archivos 3mf se han exportado con Prusa Slicer, que es el programa utilizado para la impresión. Y dado que cada pieza tiene diferentes opciones de impresión: unas tienen más paredes para darles más fuerza, otras tienen diferentes patrones de relleno y cantidades de relleno diferentes, otras se imprimen a más baja velocidad por los detalles en su primera capa (como son los engranajes), así como algunas tienen una altura de capa mayor o menor según el detalle de la pieza. Por lo tanto es un engorro especificar los parámetros de impresión de cada una de las piezas. Por ese motivo he optado por el formato 3mf, que no solo tiene la información de la pieza 3D (como es el caso del amf), sino que también todos los parámetros de impresión utilizados en cada una de ellas, de forma que si alguien quiere imprimirla, solo tiene que instalar el programa y configurar su impresora en él. Al abrir cada archivo 3mf aparecerá la pieza en cuestión con todos los parámetros que he utilizado para imprimirlas correctamente (en una impresora cartesiana).

A lo anterior hay que sumar que cada archivo suele incluir una hoja de cálculo dentro de FreeCAD con ciertas dimensiones parametrizadas, de modo que sea muy sencillo cambiar ciertas medidas base de la pieza, así como sus tolerancias.

Cada pieza se ha modelado con unas dimensiones fijas y las tolerancias en la hoja de cálculo. Por defecto son las utilizadas por mi impresora (0.15 mm), pero se incluye un archivo de pruebas (clearance_test_015.amf), con el cual se puede probar el encaje de rodamientos y ciertas piezas hasta encontrar las correctas, utilizando los valores de tolerancia obtenidos en las demás piezas.

 

FreeCAD

A continuación unas capturas del desarrollo 3D en FreeCAD:

Modelo terminado (Assembly 3)
Lateral derecho

Detalle del cilindro para la rotación de la antena
Sketch en 2D durante el diseño de una pieza


El ensamblado se ha realizado en tres módulos distintos a fin de probar cual es el más adecuado. Assembly 4 (realizado por otro autor y utiliza un enfoque diferente), Assembly 3 (realizado por el mismo que la rama Link de FreeCAD) y A2Plus. 

  • Assembly4 carece de ciertas opciones y restricciones, pero es fácil de usar.
  • A2Plus es el más intuitivo de todos y bastante utilizado por la comunidad.
  • Assembly3 es el menos intuitivo y tiene muchas opciones y restricciones diferentes, haciéndolo el más difícil de abordar a primeras.

Aunque ha sido este último el elegido al final, dado que es el único que me ha permitido hacer cambios en la piezas una vez hecho el ensamblaje, y con pequeñas modificaciones o arreglo en las restricciones, seguir trabajando de forma iterativa.

En los demás era necesario volver a importar la pieza modificada y se rompían todas las restricciones obligando a gastar un tiempo considerable en rehacerlas, incluso llegando ha tener que empezar de nuevo si la pieza era la base del ensamblado.

Lo mismo ocurre con el módulo Explode, que permite animar el ensamblaje y ver como se montan los componentes. Hay que tenerlo todo terminado antes de realizar las animaciones, consume bastante tiempo y al cambiar alguna pieza en el futuro obliga a rehacerlo. Aunque he dejado de A2Plus y Explode un archivo (Main_Assembly_A2Plus_Explode.FCStd) con el ensamblaje de prueba. El definitivo en Assembly3 es assembly.FCStd.

Detalle de ensamblado (Explode) Nº 1

Detalle de ensamblado (Explode) Nº 2

Detalle de ensamblado (Explode) Nº3

Detalle de ensamblado (Explode) Nº4

 

Impresión 3D

Más fotos, esta vez de las piezas ya impresas en PETG:

Engranajes y cilindro para la antena
Engranaje nuevo (izquierda) y antiguo (derecha) para eje de azimut

Se cambió los engranajes para el eje de azimut y así conseguir un ratio 2,5:1. Los pertenecientes al eje de elevación mostrados más arriba tienen un ratio 4:1, a fin de incrementar el torque.

Piezas descartadas (arriba y engranaje central)

En la foto de arriba se pueden ver las piezas descartadas, ya que la base y abrazadera se hicieron más gruesas, así como se alargó la base del cilindro para situar el motor de rotación más hacia atrás y hacer mejor contrapeso.

El engranaje central es el que se fija a un pié fotográfico, ya que tiene la misma forma que las zapatas para cámara. Aunque se modifica más tarde por el de la derecha para alcanzar el nuevo ratio debido a la falta de fuerza de los motores (reciclados de una impresora 3D anterior).

Base con los engranajes para azimut ya montados
Motor y base para el cilindro de rotación para la antena
Parte para la elevación montada (nueva base para el cilindro de rotación)
Eje, espaciadores y piezas para el perfil de aluminio
Rodamientos colocados
Detalle de montaje en trípode de fotografía
Montaje terminado
Electrónica montada y nuevo motor para elevación
Detalle de la electrónica
Vista frontal del driver para el motor de elevación

El conversor DC/DC que sobresale de la caja impresa es visible por un error en el diseño de la placa versión 1.0, en el repositorio está la versión 1.1 con este y otras pequeña correcciones en la serigrafía arreglados.

La caja impresa debajo del conversor alberga una pequeña placa con tres mosfets, que se encargan de dar señal de 5V al driver externo para los pulsos, dirección y encendido.

Detalle de la PCB con los mosfets
Probando distintos drivers para los motores

 

Los drivers probados son unos Pololu A4988 y unos TMC2100, clones de una antigua impresora 3D, así como los motores. Al final se han utilizado los últimos a 24V por ser mucho más silenciosos. En configuración de 3200 pasos por vuelta ya que vienen fijos en la PCB y no se pueden cambiar. 

Para el eje de elevación se sustituye el motor por uno de más torque y un driver externo para soportar la potencia requerida.

  • Azimut y rotación: 2 motores provenientes de una impresora 3D. De 1.8 grados por pulso, 3.3V, corriente de 1.5A y torque de 400 mN.m.
  • Elevación: motor nuevo de 1.8 grados por pulso, resistencia de 1.6 ohm, corriente de 2.1A y torque de 650 mN.m.

El driver para este motor es un DM542T configurado a 1.36A RMS y 1.92A de pico, corriente completa y 800 pasos por vuelta. Mientras que para los motores de azimut y rotación la corriente está configurada para 700 mA, ya que de lo contrario se calientan mucho.

Todos los ficheros de diseño 3D se encuentran disponibles en el repositorio.

HAMSatTracker (RESUMEN E INDICE)

Este proyecto consiste en una antena y un "mástil" motorizado que permite el seguimiento de satélites de radioaficionados. Además de los típicos ejes para azimut y elevación, incluye otro para la rotación de la antena permitiendo hacer coincidir la polarización con la del satélite.

Proyecto terminado

Comienzos con nMigen

iCE40UP5K-B-EVN

El propósito de este artículo es compartir el código de los ejercicios realizados en mi comienzo en este lenguaje FHDL para FPGAs. Antes de nada, indicar el motivo de la elección de nMigen y la experiencia previa que tenía con las FPGAs.

El proyecto final de estudios que realicé fue con una FPGA, debido a mi curiosidad y el potencial de procesamiento en paralelo que ofrecen. Pero como se suele decir, empecé de la manera difícil "the hard way", libros sobre lógica digital, lenguaje VHDL, herramientas del fabricante con infinidad de opciones y gigantescas en tamaño (más de 20 GB), había que usar Windows, etc...

Realicé desde pequeños ejercicios hasta utilizar un "sofcore" conectado a varios módulos que leían sensores,  encoders en cuadratura, antirrebotes para las entradas, y controlaba un par de motores todo por hardware. Las ordenes y comunicación con el ordenador las realizaba mediante el "softcore". Fueron unos pocos meses, pero se investigó y leyó bastante. Se probó a diseñar mediante VHDL y gráficamente mediante esquemas. Y tras entregar el proyecto, quedó claro que el desarrollo de hardware es difícil, y el tiempo que pasaba cada vez que realizaba un pequeño cambio y tenia que sintetizar todo era "apreciable", sin contar con que la FPGA que usaba tenia infinidad de pines y 3 o 4 fuentes de alimentación diferentes para funcionar. Con lo que se descartó por completo tratar de usarlas en proyectos personales, o realizar una PCB que tuviera una FPGA.

Han pasado unos pocos años y gracias a las herramientas FLOSS (Free/Libre Open Source Software) es posible trabajar con las FPGAs en sistemas GNU/Linux, ocupan poco tamaño y son mucho más rápidas a la hora de sintetizar. Para más información leer sobre el proyecto IceStorm y Symbiflow, que hacen posible utilizar las FPGAs ICE 40 y ECP5 de Lattice sin ningún software del fabricante.

Esto junto con la proliferación de PCBs con las FPGAs ICE40 UP5K, me hizo pensar que ya si que podría utilizar una si hiciera falta en un proyecto personal a modo de hobby. La FPGA en cuestión es muy pequeña, con solo 48 pines en la versión SG48, con un consumo muy bajo y solo necesita 2 voltajes de alimentación diferentes para funcionar, habiendo reguladores que convierten directamente los 5V de entrada (USB por ejemplo) en 3.3V y 1.2V que necesita.

Sus características principales son las siguientes:

  • 5280 LUTS + Flip-Flop.
  • 120 Kbits de memoria EBR.
  • 1024 Kbits de memoria SPRAM.
  • Memoria de configuración no volátil NVCM.
  • 1 bloque PLL en hardware.
  • 8 bloques DSP en hardware.
  • 2 unidades I2C en hardware, con 2 pines capaces de I3C.
  • 2 unidades SPI en hardware.
  • 1 oscilador interno a 48 Mhz.
  • 1 oscilador interno a 10 Khz.
  • Driver RGB por hardware, hasta 24mA por pin directamente.
  • 1 bloque PWM en hardware.
  • 2 unidades de delay de 50ns por hardware. 
  • 2 unidades de filtro de 50ns por hardware.
  • Empaquetado QFN de 48 pines (0.5mm x 7mm x 7mm).
  • 39 pines de entrada y salida.
  • Consumo de hasta 100 uA en reposo.
Más información sobre la FPGA en la página del fabricante y sobre la placa de desarrollo utilizada.


Tutorial de Verilog

Las herramientas libres utilizan Verilog, por lo que es conveniente conocer un poco el lenguaje para ver posteriormente el código para depurar errores que genera nMigen o poder reutilizar módulos de otras personas escritos en Verilog. Para ello recomiendo encarecidamente el tutorial de Juan González Gómez (Obijuan).

Durante la realización de este tutorial se han creado unas tareas en VS Code para no tener que escribir tantos comandos en la consola. También se ha utilizado el plugin para Verilog.
En el repositorio se encuentran unos pocos ejercicios del tutorial indicado anteriormente junto con la configuración.
Destacar que en el ejemplo del prescaler se ha instanciado el driver RGB que incluye la FPGA, lo que se denomina "hard IP".
A continuación se muestran unas capturas de pantalla con las tareas que se pueden elegir:

Tareas para Verilog

A destacar las tareas que engloban a otras:
  • Simulate(ALL): ejecuta en orden las tareas de compilación, ejecución y visualización de la simulación.
  • Synthesis(ALL): ejecuta en orden las tareas de síntesis, colocación, enrutado y generación del bitstream.
  • Syntesis&Program: ejecuta lo mismo que la tarea anterior y además programa la FPGA.
  • View schematics: ejecuta primero la tarea de generación del esquema y después lo muestra. En este caso mediante una imagen svg.

Configuración de tareas

Al comienzo del archivo task.json se pueden configurar algunos parámetros, al igual que la versión para nMigen: El nombre del archivo, que no es necesario cambiar, ya que se incluye un archivo de tareas por cada ejemplo; el modelo de fpga, el empaquetado de la misma y el programa para visualizar los archivos svg.

Esquema de un contador de 26 bits en Verilog

Este es el esquema del ejercicio del contador de 26 bits generado por la tarea  View schematics.


nMigen

Dado que el diseño con los lenguajes de modelado tradicionales es muy lento y propenso a errores, algunos lo comparan con programar en ensamblador (aunque hay que tener en cuenta que no se está programando, se está diseñando), han surgido otros lenguajes. Y muchos de estos lenguajes coinciden en abandonar el paradigma conducido por eventos que se llevaba utilizando hasta el momento.

Estos nuevos lenguajes tratan de elevar el nivel de abstracción y hacer posible el diseño de sistemas digitales complejos de forma muchos más fácil, y deja en manos de los generadores de código el producir módulos y librerías reutilizables y libres de los errores comunes que se han observado durante el diseño de sistemas en Verilog o VHDL a lo largo de los años. Estos generadores crean al final código de representación intermedia o Verilog o VHDL. 
Uno de ellos es Chisel, que utiliza el lenguaje Scala y se ha usado para diseñar las CPUs en la universidad  de Berkeley, destacando la arquitectura RISC-V. También lo utilizan los ingenieros de SiFive a la hora de diseñar el hardware.    Por lo que se ha podido investigar, este parece el más maduro, pero su curva de aprendizaje es alta y es más adecuado para quienes trabajan a diario en el diseño de hardware.

Otro de los lenguajes o librerías es nMigen, que está basada en Python y según ellos es un lenguaje FHDL (Fragmented Hardware Description Language), en el cual se separan las declaraciones en dos grupos: síncronas y combinacionales, las reglas aritméticas son las mismas que en las matemáticas con enteros, y permite generar y simular la lógica en Python.

nMigen es el descendiente de Migen, el cual se ha usado en producción durante años y permite crear diseños complejos de forma mucho más fácil y rápida. Recomiendo ver el siguiente video de una charla sobre como se ha implementado una PCB para la captura  de video en conferencias y emisión por streaming, incluyendo la señal HDMI de los proyectores, pasándola a USB. En el proyecto del vídeo se ha usado Litex, que contiene componentes diseñados con Migen y permite crear de forma rápida SoC, incluyendo componentes como: cores con o sin CPU, buses y streams (Wishbone, AXI, Avalon-ST), cores comunes con RAM, ROM, Timer, UART, etc... , así como DRAM, PCIe, Ethernet, SATA, etc...

Esto permite crear sistemas que antes no eran posibles(a nivel aficionado o uso esporádico), bien por los conocimientos necesarios o por el tiempo que llevaría realizarlos.

Debido a todo lo anterior decidí usar nMigen, que intenta solventar los problemas que se han tenido y tienen mientras se trabaja con Migen. Aunque hay que decir que nMigen está en estado muy prematuro, la versión disponible es la 0.1 y en la rama de desarrollo están trabajando en la 0.2, en la que piensan arreglar problemas con el simulador. También quieren mejorar el código generado en Verilog para que sea más fácil de leer.

Las únicas fuentes de información que se han encontrado son las siguientes:


Por lo que entre lo dicho anteriormente y que gran parte del código no está comentado actualmente, es un poco complicado empezar. Se ha tenido que leer mucho código fuente y realizar pruebas para tratar de comprender como trabajan ciertas funciones o como conectar los diseños con el hardware real. Por ello comparto el código con ejercicios que funcionan en la placa de desarrollo.

A la hora de instalar el software necesario consultar las instrucciones de Robert Baruch y las de SymbiYosys.


Verificación formal

nMigen soporta la verificación formal, al igual que verilog gracias a SymbiYosys. Solo soporta unas pocas declaraciones formales en comparación con SystemVerilog, pero son suficientes.

La verificación formal trata de probar que un algoritmo es correcto tratando de hacer que no cumpla con las especificaciones mediante métodos formales y matemáticas. De forma muy simple, intenta ejercitar las entradas, de un módulo por ejemplo, para encontrar un caso en el que no se cumplan las especificaciones.

Se utilizan las siguientes declaraciones:

  • Assert(): para indicar que el resultado de una expresión tiene que ser verdadera.
  • Assume(): para asumir el valor de una expresión, de forma que se excluyan casos que no se quieran probar o que se sepa que no van a ocurrir.
  • Past(): devuelve el valor de una expresión un número de ciclos en el pasado.
  • Stable(): devuelve verdadero si la expresión no ha cambiado con respecto al ciclo de reloj anterior.
  • Rose(): devuelve verdadero si la señal se ha activado durante el flanco positivo del último ciclo de reloj.
  • Fell(): igual que la anterior pero para el flanco de bajada.
Para más información recomiendo este y este artículo, ambos en inglés y usando Verilog. Es la mejor información que e encontrado de momento, pero los conceptos son los mismos para nMigen. También podemos mirar la CPU 6800 que está realizando Robert Baruch, todo en nMigen y con verificación formal.

En el repositorio hay algunos ejemplos, los archivos terminados en _formal.py, son muy simples pero dan una idea de como utilizar las declaraciones anteriores.


Ejercicios en nMigen

En la carpeta del repositorio se encuentran los archivos del tutorial de Obijuan realizados con nMigen. Los archivos tienen el mismo nombre que en el tutorial pero acabados en .py, _tb.py y _formal.py, para módulo, testbench y verificación formal respectivamente. La idea es que se siga el tutorial, donde se explican los ejercicios, y se compare el código Verilog con el de nMigen.

Decir que el código no sigue las convención pep8, ni está documentado correctamente, solo es el código que se ha realizado durante los ejercicios con el fin de aprender nMigen. Para muestra de un código Python comentado según Sphinx y que sigue el pep8, mirar un proyecto terminado, por ejemplo PyControlPanel.

En la carpeta deberían existir 3 subcarpetas:

  • Src: contiene los archivos Python.
  • Build: contiene los archivos generados por nMigen. 
  • Output: contiene los archivos generados por las tareas de VS Code. 
De no existir output hay que crearla, de lo contrario darán error las tareas que intenten crear los archivos en ella. En cuando build, debería de crearse la primera vez que se ejecuta la tarea nMigen build.

En la carpeta de configuración de VS Code (.vscode) se encuentra el archivo de tareas task.json.

Al pulsar F1 se abrirá un dialogo en el que tenemos que buscar el lanzador de tareas.

Lanzador de tareas
 

Esto leerá el archivo y nos mostrará las tareas que se han definido en él.

Tareas para nMigen
 

De esta forma no tenemos que escribir tantos comandos en la consola. Las tareas que empiezan por __(doble barra baja) no hace falta usarlas ya que las llaman internamente el resto de tareas.

La descripción de las tareas es la siguiente:

  • nMigen Build: ejecuta el archivo del ejercicio seleccionado para su construcción, realizando también la programación de la FPGA.
  • nMigen Simulate: ejecuta el archivo de testbench del ejercicio seleccionado.
  • SysbiYosys: ejecuta el archivo de verificación formal del ejercicio seleccionado.
  • Timming Analysis: muestra el análisis de tiempos generado por Yosis cuando se ejecutó nMigen Build.
  • View schematic: genera y muestra un pdf con un esquema gráfico que representa el módulo seleccionado. Es necesario tener dot instalado en el sistema.
  • View simulation: muestra el testbench generado anteriormente mediante Gtkwave.
  • View SymbiYosys --- 1st generated trace: muestra la primera traza generada por la verificación formal en Gtkwave. Distinguiendo entre las generadas por BMC, COVER o PROVE.

Configurando tareas
 

Podemos configurar varios parámetros en el apartado env del archivo de tareas: en filename escribimos el nombre del archivo Python sin extensión y todas las tareas estarán referidas al mismo; en fpga_arch elegimos el modelo de la fpga a usar, en fpga_package el empaquetado del chip, en pdf_viewer el visor a utilizar para los pdfs y en pythonPath la ruta al interprete Python a utilizar por las tareas.
Los parámetros relacionados con la fpga se pasan a Yosis u otros comandos del proyecto IceStorm.

Configuración para depurado
 

También se encuentra un archivo launch.json que se puede utilizar a la hora de depurar código Python. Solo basta con cambiar el nombre (name) y la ruta al archivo (program).


Archivos a destacar

Existen algunos archivos aparte de los propios ejercicios que hay que mencionar:

  • ice40_up5k_b_env.py: este archivo añade soporte para la placa utilizada a nMigen, ya que no se incluye ninguno en el repositorio oficial.
  • masm.py: pasa el código ensamblador a código máquina para el último ejercicio: microbio. Realizado por Obijuan y modificado ligeramente para no añadir comentarios al lado de las instrucciones.
  • verilog_module.py: es un ejemplo de como instanciar un módulo escrito en Verilog y usarlo en nMigen.


Capturas

Todos los ejercicios, a excepción de los que utilizan el zumbador, han sido probados en la placa junto con un analizador lógico. Y las simulaciones coinciden con las mostradas en el tutorial.

A continuación algunas capturas de ejercicios:

baudtx2.py
 Salida del transmisor UART del ejercicio baudtx2.py del capítulo 21.

fsmtx.py
Salida del transmisor UART mediante una máquina de estados, del ejercicio fsmtx.py del capítulo 23.

buffer.py
Salida del transmisor UART que almacena el mensaje en un buffer en RAM, del ejercicio buffer.py del capítulo 28.

fsmtx_tb.py
  Comparación de la simulación de nMiguen con la generada en Verilog en el tutorial. Capítulo 23, ejercicio fsmtx_tb.py.

scicad1_tb.py
Perteneciente al ejercicio scicad1_tb.py del capítulo 24. El simulador de nMigen exporta el nombre del estado en el que se encuentra la máquina de estados.

Contador nMigen
Archivo generado con la tarea View schematic del contador del capítulo 4.

Microbio nMigen
Esquema del pequeño microprocesador Microbio del capítulo 30. Se puede encontrar el pdf en el repositorio.


Conclusiones

Después de realizar los ejercicios y por lo que se ha visto, está claro que el diseño es más rápido que con Verilog o VHDL, pero nMiguen todavía está en una fase de desarrollo muy temprana como se ha dicho anteriormente (V 0.1), falta mucha documentación y hay algunos problemas con el simulador. Habrá que estar atento para ver como avanza el desarrollo.

Si uno quiere dedicarse al diseño de hardware de forma profesional, el más recomendable de los "nuevos" lenguajes es Chisel, pero para un uso esporádico, pequeños proyectos, o no muy complicados, recomendaría usar Migen o MyHDL. Este último utiliza también Python, pero sigue el tradicional modelo basado en eventos, por lo que sería como diseñar en Verilog pero usando Python. Desde luego que es mucho más ameno y rápido que Verilog o VHDL.

El motivo de volver a las FPGAs es poder realizar diseños sencillos pero prácticos en los proyectos, como poder disponer de múltiples decodificadores de encoders en cuadratura, o puertos UART o SPI adicionales, leer sensores a alta frecuencia y mediante buffers pasar los datos a un microcontrolador, realizar partes de la lógica en hardware (siguen funcionando si el micro se bloquea y pueden controlar o monitorizar aspectos relacionados con la seguridad), circuitos de reset para otros integrados, etc...

Espero que sirva de ayuda para el que quiera empezar con nMigen y no sepa por donde.

Como siempre, dar las gracias a quienes se han tomado el tiempo de leer este artículo y recordar que el código fuente se encuentra en el repositorio