23 votos

¿A qué se compilan/sintetizan las HDL?

Soy ingeniero de software. Como programador, entiendo lo que mi compilador hace por mí porque he escrito manualmente una representación textual cercana de lo que produce (por ejemplo, ensamblaje). Para obtener detalles precisos de lo que sale puedo mirar las especificaciones ELF/COFF/MachO (por ejemplo, el tipo de archivo al que traduce mi código, los resultados pueden variar según el lenguaje). Para saber cuáles son las codificaciones de las instrucciones puedo mirar el manual de instrucciones de mi procesador. Eso me da suficiente información para entender el tipo de datos que el compilador está produciendo. También me da el vocabulario para hacer preguntas como "¿Cómo inspecciono los detalles de un archivo ELF?" y esa pregunta está relativamente bien formada. También podría preguntar "¿Cómo veo el ensamblaje generado por mi compilador?" y esa pregunta estaría bien formada. Finalmente, los bytes especificados por el archivo ELF se introducen en la memoria, y el procesador ejecuta cada instrucción en orden y yo entiendo la semántica de cada instrucción.

Los pasos/preguntas equivalentes no están del todo claros para una FPGA. No sé a qué se traducen Verilog o VHDL. No sé cuáles son las primitivas subyacentes con las que opera la FPGA. No sé cómo hacer preguntas como las dos preguntas bien formadas de arriba porque simplemente me faltan las palabras para hacerlas. Puede ser que las preguntas equivalentes no tengan sentido en este contexto, pero no tengo forma de saberlo en este momento. Todo lo que sé es que puedo escribir un poco de Verilog y luego termina siendo ejecutado en un simulador o en una FPGA.

Escribo algo de Verilog que luego se sintetiza en... ¿algo? ¿Qué es ese algo? ¿Es un archivo que puedo inspeccionar? ¿Existe un formato estándar que pueda consultar? Por ejemplo, si quisiera escribir un simulador yo mismo, ¿qué formato consumiría mi simulador?

Después, la salida sintetizada se programa en una FPGA. ¿Qué primitivas utiliza esa FPGA? Si se tratara de un dispositivo embebido, generalmente los bytes se escribirían en bruto en una memoria flash o en algún tipo de almacenamiento. ¿Existe un equivalente para las FPGAs? Tal vez una pregunta más abstracta y con mejor respuesta sería "¿qué bytes van sobre la escritura cuando se está programando una FPGA?"

23voto

RWH Puntos 21

Al igual que un lenguaje de programación procedimental pasa por varios pasos (compilar, ensamblar, enlazar) para producir un ejecutable, los HDL deben pasar por varios procesos antes de que se genere un archivo de configuración utilizable para la FPGA. Estos procesos incluyen

  • Síntesis --- convertir el código HDL en un netlist que describa las conexiones entre los elementos lógicos.

  • Mapping --- Convierte el netlist en un netlist más refinado que utiliza los recursos realmente disponibles en su dispositivo FPGA.

  • Colocar y enrutar: seleccione qué recursos reales del dispositivo se utilizarán para cada uno de los elementos requeridos en la salida del mapeador, y elija qué recursos de enrutamiento se utilizarán para interconectarlos.

  • Generación de archivos de bits --- convertir la salida de lugar y ruta al formato realmente utilizado para programar el dispositivo.

Así que si, cuando preguntas cuál es el resultado de la síntesis, te refieres a cuál es el resultado del primer paso de este proceso, entonces es un archivo intermedio utilizado como entrada para el mapeador. Si te refieres a cuál es la salida de todo el proceso, es un archivo de bits que la FPGA puede utilizar para configurar todos sus recursos lógicos y de enrutamiento.

16voto

MarkU Puntos 3743

Lógica de transferencia de registros (RTL) es el resultado de la primera fase de traducción, antes de ser mapeado a los recursos específicos del proveedor, que no son portables entre proveedores o incluso entre diferentes FPGA del mismo proveedor. Esencialmente, la RTL muestra tanto la lógica combinacional como los registros síncronos (flip flops D), por lo que las máquinas de estado son reconocibles. La RTL es bastante consistente entre Altera y Xilinx, y es probablemente la fase más interesante y útil para inspeccionar. Los problemas de síntesis se hacen visibles por primera vez en la fase RTL, y el diseño sigue siendo reconocible. Una vez que pasa al mapeo específico del proveedor, se trocea y se desordena. Tratar de decodificar un flujo de bits específico de un chip es muy costoso y poco beneficioso, y será inútil cuando se cambie de proveedor o incluso de tamaño de FPGA de la misma familia. Puedes ver lo que necesitas ver en el nivel RTL.

Siempre es una buena práctica probar tu código Verilog o VHDL recién desarrollado instanciándolo dentro de un banco de pruebas o un simple módulo de nivel superior, e inspeccionando el código RTL. Xilinx ISE es muy bueno para inspeccionar la RTL como un esquema (aunque a veces se le escapan cosas.) Los problemas más comunes son:

  • Redes de 1 bit donde estaba previsto un bus
  • trozos de lógica que son eliminados inesperadamente por el optimizador... de forma similar a como un simple bucle de retardo spinlock es eliminado silenciosamente por la optimización del código.
  • salidas no completamente especificadas, debido al enfoque procedimental en lugar del enfoque de tabla de verdad. Si la herramienta piensa que la salida termina siempre en 0 o siempre en 1, abandonará toda la lógica que genera ese resultado.
  • la lógica del módulo se recorta porque uno de los submódulos se ha optimizado para que sea siempre 0 o siempre 1; esto puede ocurrir en cascada hasta el nivel superior

Esta inspección RTL se vuelve muy difícil de manejar a menos que mantenga sus módulos pequeños y simples. El uso de un banco de pruebas es una herramienta importante.

Yo también vengo de la programación de sistemas embebidos primero y de verilog después, y el mayor peligro para la gente como nosotros al aprender la codificación HDL es que mira como un lenguaje de programación procedimental, y se siente como un lenguaje de programación procedimental (durante la simulación), pero luego todo salta por los aires cuando se intenta sintetizar el código de trabajo. Realmente hay que pensar en lo que el hardware tiene que ser, y asegúrese de que el código RTL incluye todo el hardware que espera.

Aparte del hecho de que Verilog/VHDL implican teclear un código fuente en un archivo informático, no hay realmente mucho parecido con el C/C++/etc. tradicional. Se transferirá muy poco de su experiencia en programación. Céntrate en dividir los grandes problemas en pequeños problemas, documentar todo con gran detalle y escribir bancos de pruebas. Invierte también en un buen osciloscopio de muestreo digital si no tienes ya uno. Echa un vistazo a algunos de los códigos de ejemplo publicados en opencores.org, ya que con C/C++ puedes aprender mucha técnica (tanto buena como mala) leyendo el código de otras personas.

Una cosa que me vuelve loco sobre el desarrollo de FPGAs es que el control de fuentes no es algo que los vendedores de cadenas de herramientas parecen pensar que es una característica importante. Xilinx Vivado es particularmente malo en este sentido, su consejo parece ser volver a generar los archivos del proyecto desde cero al hacer un nuevo checkout. Tratar de hacer un traspaso de proyecto con archivos zip de más de 100Mb es desalentador.

La otra cosa que me vuelve loco sobre el desarrollo de FPGAs es que las herramientas Quartus/ISE/Vivado no tienen realmente una forma satisfactoria de sofocar la avalancha de mensajes de advertencia. Cuando escribo programas en C/C++, espero ser capaz de abordar cada mensaje de advertencia individualmente y arreglarlo o sancionarlo, de modo que finalmente pueda obtener una compilación limpia con cero advertencias. Nunca he visto a nadie lograr eso en el desarrollo de FPGAs; otros desarrolladores de FPGAs (que son más inteligentes que yo) parecen simplemente aceptar que un proyecto normal tiene un montón de mensajes de diagnóstico, que a menudo simplemente ignoran, dejándolo para hacer el trabajo de laboratorio y verificar en el hardware real.

Si alguna vez desarrollas tu propia placa FPGA (cosa que no recomiendo), asegúrate de sacar todos los pines de E/S que no utilices a una cabecera en algún lugar - tantos como puedas manejar - porque eso va a ser tu salvación cuando tengas que depurar el código de la FPGA, o implementar algún parche de última hora.

Has mencionado la programación en lenguaje ensamblador como una forma de ejercer un control preciso sobre lo que hace el ordenador, y es posible ejercer un control igualmente preciso sobre el código de la FPGA utilizando primitivas no portables y específicas del proveedor. Esto será diferente para cada proveedor y cada FPGA, al igual que el lenguaje ensamblador es diferente para diferentes CPUs. En el caso de Xilinx, se escribiría un archivo de restricciones (diferente para la cadena de herramientas ISE o Vivado). El archivo de restricciones llamaría a instancias específicas o redes específicas, y especificaría los requisitos de sincronización. Normalmente, los CLBs/LUTs/lo que sea de las unidades de bajo nivel están organizados en una cuadrícula, por lo que se puede fijar una primitiva de bajo nivel específica para vivir en una ubicación específica de la cuadrícula X,Y. Busca el antiguo "FPGA Editor" de Xilinx para la serie Spartan 3, solían animar a la gente a usarlo así. Creo que los nuevos chips de la serie 7 y Zynq no están soportados. Al igual que el ensamblaje, es muy específico para la tecnología, y por lo tanto es un tipo de habilidad volátil.

Al igual que con el ensamblaje, para cualquier cosa que no sea un ejercicio trivial de "deberes", realmente quieres minimizar la cantidad de ensamblaje que escribes; utiliza C/C++ para el 98%-99% y sólo escribe ensamblaje para el 1% que es sensible al rendimiento. Si, por ejemplo, tienes un diseño de FPGA que requiere que algún subproceso se ejecute a 200MHz, vale la pena sumergirse en el mapeo de bajo nivel para ver qué hacen las herramientas. La mejor recompensa para la optimización es si puedes eliminar las etapas de trabajo innecesarias. Sólo después de haber reducido los elementos calientes al mínimo, merece la pena empezar a enrutar manualmente qué IOBs pertenecen a qué ubicaciones de la rejilla. Deje que la máquina haga la mayor parte del trabajo, para que usted pueda concentrar sus esfuerzos.

11voto

Toor Puntos 777

La primitiva física de una FPGA es un bloque lógico configurable (CLB).

Cada bloque lógico tiene una ubicación dedicada en la memoria, la llamada memoria de configuración, que determina cómo se configura y a dónde se conecta.

El HDL termina en última instancia como un montón de unos y ceros, un llamado flujo de bits que se coloca en esta memoria de configuración.

La mayoría de las FPGAs no tienen una memoria de configuración no volátil incorporada. En su lugar, el flujo de bits de configuración se almacena en una ROM FLASH de configuración externa y, al encenderla, la FPGA carga ese flujo de bits de la memoria no volátil externa en su SRAM de configuración interna, que está directamente conectada a los CLBs y los controla.

A diferencia del software, este flujo de bits no se "ejecuta". Sólo se carga y después simplemente "es". Se parece menos a las instrucciones que se ejecutan y más a los registros que contienen configuraciones.

Es un archivo como un *.bit. No hay un formato estándar. No estoy seguro de por qué querrías escribir un simulador tú mismo cuando las herramientas de desarrollo de FPGA vienen con un simulador. Se ha puesto mucho esfuerzo en esto y conocen sus dispositivos mejor que nadie porque, a diferencia del software, cada primitiva que se especifica en el flujo de bits debe estar ubicada físicamente en algún lugar del troquel de la FPGA y el plano puede hacer o deshacer algunos diseños.

5voto

Graham Puntos 141

¿qué bytes pasan por encima de la escritura cuando se está programando una FPGA?

Esto es menos responder de forma general, ya que es 100% específico del fabricante y del dispositivo. Algunos fabricantes publican hojas de datos al respecto, mientras que otros lo consideran un "secreto comercial" y habría que firmar un acuerdo de confidencialidad para averiguarlo.

De todos modos, con un compilador de C (o de cualquier otro lenguaje), los bytes en bruto no son la parte más básica. La parte más básica es la serie de instrucciones del procesador que implementan tu programa, y los bytes brutos son simplemente la forma de decirle al procesador cuáles son esas instrucciones. Estas instrucciones hacen que el procesador lleve a cabo operaciones utilizando sus diversas instalaciones de hardware, como sumadores, multiplicadores y similares, y que almacene o recupere datos en registros y memorias.

Esto es muy similar en una FPGA, excepto que estás empezando en un nivel más bajo. En lugar de tener una lista de instrucciones para ejecutar, lo que tienes es una lista de cómo debe interconectarse cada puerta en la FPGA. La mayoría de las FPGAs también contienen secciones especializadas para la RAM y otras características, y tu programa también incluirá cómo se conectan.

Lo que se obtiene entonces es un Lista de redes es lo mismo que si estuvieras diseñando una PCB con un millón de chips lógicos. Esta es conceptualmente la salida más básica de tu compilador de FPGA para decirte lo que está haciendo, de la misma manera que un listado en ensamblador es conceptualmente la salida más básica de tu compilador de C para decirte lo que está haciendo el procesador.

Por supuesto, el compilador sigue produciendo un archivo binario que programará la FPGA con ese netlist, del mismo modo que un compilador de C sigue produciendo un archivo binario que programa tu micro con ese ensamblador.

2voto

ozba Puntos 1558

"¿Qué bytes pasan por encima de la escritura cuando se está programando una FPGA?"

Simplificando, estos bytes contienen la información para:

1) Configurar los bloques lógicos y de E/S de la FPGA (¿quieres que este bloque sea un registro, un multiplexor, una tabla de búsqueda de propósito general), y

2) Configurar la interconexión en la FPGA para conectar los bloques lógicos entre sí y con el mundo exterior.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X