¿Cuáles son las mejores prácticas para los lenguajes de descripción de hardware (Verilog, VHDL, etc.) [cerrado]

StackOverflow https://stackoverflow.com/questions/326880

  •  11-07-2019
  •  | 
  •  

Pregunta

¿Qué mejores prácticas se deben observar al implementar el código HDL?

¿Cuáles son los puntos en común y las diferencias en comparación con los campos de desarrollo de software más comunes?

¿Fue útil?

Solución

El mejor libro sobre este tema es Manual de metodología de reutilización . Cubre tanto VHDL como Verilog.

Y en particular algunos problemas que no tienen una coincidencia exacta en el software:

  • Sin pestillos
  • Tenga cuidado con los reinicios
  • Verifique su sincronización interna y externa
  • Usar solo código sintetizable
  • Registre sus salidas de todos los módulos
  • Tenga cuidado con el bloqueo frente a las tareas sin bloqueo
  • Tenga cuidado con las listas sensibles para la lógica combinatoria (o use @ (*) en Verilog)

Algunos que son iguales incluyen

  • Usar CM
  • Tener revisiones de código
  • Pruebe (simule) su código
  • Reutilice el código cuando corresponda
  • Tener un horario actualizado
  • Tener una especificación o casos de uso o un cliente ágil

Otros consejos

Algo así como un hilo viejo, pero quería poner mis $ 0.02. Esto no es realmente específico para Verilog / VHDL ... más sobre diseño de hardware en general ... diseño específicamente sintetizable para ASIC personalizados.

Esta es mi opinión basada en años de experiencia en la industria (en oposición a la académica) en diseño. No están en un orden particular

Mi declaración general es Diseñar para la ejecución de validación. En diseño de hardware, la validación es primordial. Los errores son mucho más caros cuando se encuentran en el silicio real. No puedes simplemente volver a compilar. Por lo tanto, al pre-silicio se le da mucha más atención.

  • Conozca la diferencia entre las rutas de control y las rutas de datos. Esto le permite crear código mucho más elegante y fácil de mantener. También le permite guardar puertas y minimizar la propagación de X. Por ejemplo, las rutas de datos nunca deberían necesitar flops reiniciables, las rutas de control siempre deberían necesitarlo.

  • Demuestre la funcionalidad antes de la validación. Ya sea a través de un enfoque formal o mediante formas de onda. Esto tiene muchas ventajas, explicaré 2. Primero, le ahorrará tiempo perdido al pelar la cebolla a través de los problemas. A diferencia de muchos diseños de nivel de aplicación (especialmente durante el aprendizaje) y la mayoría del trabajo del curso, el tiempo de respuesta para los cambios de código es muy grande (de 10 minutos a días, dependiendo de la complejidad). Cada vez que cambia el código, debe pasar por la elaboración, la verificación de la pelusa, la compilación, la aparición de la forma de onda y, finalmente, la simulación real ... lo que en sí mismo puede llevar horas. En segundo lugar, es mucho menos probable que tenga casos difíciles de esquivar. Tenga en cuenta que esto es con respecto a la validación previa al silicio. Estos seguramente llegarán a un nivel posterior al silicio que le costará mucho $$$. Confía en mí, el costo inicial de probar la funcionalidad minimiza en gran medida el riesgo y vale la pena el esfuerzo. A veces es difícil convencer a los graduados universitarios recientes.

  • Tener " trozos de pollo " ;. Los bits de pollo son bits en MMIO establecidos a través del controlador para deshabilitar una función en silicio. Su objetivo es revertir los cambios realizados en los que la confianza no es alta (la confianza es directamente proporcional a los esfuerzos de validación). Es casi imposible alcanzar todos los estados posibles en pre-silicio. La confianza en su diseño no puede cumplirse realmente hasta que se demuestre en post-silicio. Incluso si solo hay 1 estado que se golpea el 0.000005% del tiempo que expone el error, HABITARÁ en post-silicio, pero no necesariamente en pre-silicio.

  • Evite excepciones en la ruta de control a toda costa. Cada nueva excepción que tengas duplica tus esfuerzos de validación. Este es difícil de explicar. Digamos que hay un bloque DMA que guardará los datos en la memoria que usará otro bloque. Digamos que la estructura de datos guardada depende de que se realice alguna función. Si decidió diseñar de manera que la estructura de datos guardada fuera diferente entre las diferentes funciones, simplemente multiplicó sus esfuerzos de validación por el número de funciones DMA. Si se sigue esta regla, la estructura de datos guardada sería un superconjunto de todos los datos disponibles para cada función donde las ubicaciones de contenido están codificadas. Una vez que la lógica de guardado de DMA se valida para 1 función, se valida para todas las funciones.

  • Minimizar interfaces (leer rutas de control de minimizar). Esto está relacionado con minimizar las excepciones. Primero, cada nueva interfaz requiere validación. Esto incluye nuevos verificadores / rastreadores, aserciones, puntos de cobertura y modelos funcionales de bus en su banco de pruebas. En segundo lugar, puede aumentar sus esfuerzos de validación exponencialmente. Digamos que tiene 1 interfaz para leer datos en cachés. Ahora digamos (por alguna extraña razón) que decide que desea otra interfaz para leer la memoria principal. Acaba de cuadruplicar sus esfuerzos de validación. Ahora debe validar estas combinaciones en cualquier momento n :

    • sin lectura de caché, sin lectura de memoria
    • sin lectura de caché, lectura de memoria
    • lectura de caché, sin memo

Las HDL como Verilog y VHDL realmente parecen alentar el código de espagueti. La mayoría de los módulos consisten en varios bloques 'siempre' (Verilog) o 'proceso' (VHDL) que pueden estar en cualquier orden. El algoritmo o función general del módulo a menudo está totalmente oculto. Descubrir cómo funciona el código (si no lo escribió) es un proceso doloroso.

Hace unos años me encontré con este documento que describe un método más estructurado para Diseño VHDL. La idea básica es que cada módulo tiene solo 2 bloques de proceso. Uno para código combinatorio y otro para síncrono (los registros). Es excelente para producir código legible y mantenible.

  • en HDL, algunas partes del código pueden funcionar al mismo tiempo, por ejemplo, dos líneas de código "pueden funcionar" Al mismo tiempo, esta es una ventaja, para utilizar con prudencia. esto es algo que un programador que está acostumbrado a los lenguajes línea por línea puede encontrar difícil de entender al principio:

    • Se pueden crear tuberías largas y específicas para sus necesidades.
    • Puede hacer que sus grandes módulos funcionen al mismo tiempo.
    • en lugar de una unidad para realizar una acción repetida en diferentes datos, puede crear varias unidades y hacer el trabajo en paralelo.
  • Se debe prestar especial atención al proceso de arranque: una vez que su chip es funcional, ha hecho un gran esfuerzo.

La depuración en hardware suele ser mucho más difícil que la depuración de software, por lo que:

  • Se prefiere un código simple, a veces hay otras formas de acelerar su código, después de ya se está ejecutando, por ejemplo, utilizando un chip de mayor velocidad, etc.

  • Evita " inteligente " protocolos entre componentes.

  • Un código de trabajo en HDL es más valioso que en otro software, ya que el hardware es tan difícil de depurar, así que reutilice, y también considere usar bibliotecas " de módulos que algunos son gratuitos y otros vendidos.

  • El diseño
  • debe considerar no solo los errores en el código HDL, sino también las fallas en el chip que está programando y en otros dispositivos de hardware que interactúan con el chip, por lo que uno realmente debería pensar en un diseño que sea fácil de comprobar.

Algunos consejos de depuración:

  • Si un diseño incluye varios bloques de construcción, uno probablemente querría crear líneas desde las interfaces entre esos bloques a puntos de prueba fuera del chip.

  • Querrá guardar suficientes líneas en su diseño para desviar datos interesantes para ser inspeccionados con dispositivos externos. también puede usar estas líneas y su código como una forma de indicarle el estado actual de ejecución, por ejemplo, si recibe datos en algún momento punto, escribe algún valor en las líneas, en una etapa posterior de la ejecución escribe otro valor, etc. '

    Si su chip es reconfigurable, esto será aún más útil, ya que puede adaptar pruebas específicas y reprogramar las salidas para cada prueba a medida que avanza (esto se ve muy bien con leds :). )

Edición :

Por protocolos inteligentes, he querido decir que si dos de sus unidades físicas se conectan, deberían comunicarse con el protocolo de comunicación más simple disponible. es decir, no use ningún protocolo sofisticado hecho en casa, entre ellos.

La razón es esta: Fidning bugs '' dentro '' un FPGA / ASIC es relativamente fácil ya que tiene simuladores. Entonces, si está seguro de que los datos llegan como los desea y se envían cuando su programa los envía, ha alcanzado la utopía de hardware: poder trabajar a nivel de software :) (con el simulador). Pero si sus datos no llegan a usted, de la forma en que lo desea, y tiene que descubrir por qué ... tendrá que conectarse a las líneas, y eso no es tan fácil.

Encontrar un error en las líneas es difícil, ya que tiene que conectarse a las líneas con un equipo especial, que registra los estados de las líneas, en diferentes momentos, y tendrá que asegurarse de que sus líneas actúen de acuerdo con el protocolo.

Si necesita conectar dos de sus unidades físicas, realice el " protocolo " tan simple como sea posible, hasta el punto no se llamará protocolo :) Por ejemplo, si las unidades comparten un reloj, agregue x líneas de datos entre ellas, y haga que una unidad escriba esas y la otra unidad lea, pasando así una '' palabra '' que tiene x bits entre ellos en cada caída de reloj, por ejemplo. Si tiene FPGA, si la velocidad del reloj original es demasiado rápida para datos paralelos, puede controlar la velocidad de esto, de acuerdo con sus experimentos, por ejemplo, haciendo que los datos permanezcan en líneas de al menos 't' ciclos de reloj, etc. Asumo datos paralelos t

Esta es la pregunta que requiere los 10 mandamientos de JBDAVID para el diseño de hardware.

  1. Use Revisión / Control de versiones, al igual que en Software. SVN y Hg son gratis.
  2. Requiere que el código pase la verificación de sintaxis antes del check-in. Una herramienta LINT es mejor.
  3. Utilice un lenguaje de verificación de hardware completo para la verificación del diseño. System-Verilog es casi una opción segura.
  4. Errores de seguimiento. Bugzilla y GNATS son herramientas gratuitas. FogBugz requiere un poco de $.
  5. Usar aserciones para detectar problemas con el uso incorrecto.
  6. La Tríada de Cobertura ofrece un diseño estable: cobertura de código de medida, cobertura funcional y cobertura de afirmación tanto en herramientas formales como de simulación.
  7. El poder es el rey: use CPF o UPF para capturar, hacer cumplir y verificar su intención de poder.
  8. el diseño real es a menudo señal mixta, utilice un lenguaje de señal mixta para verificar lo analógico con lo digital. Verilog-AMS es una de esas soluciones. Pero no te vayas por la borda. El modelado de números reales puede lograr la mayoría de los aspectos funcionales del comportamiento de señales mixtas.
  9. ¡Use Aceleración de hardware para validar el software que tiene que funcionar con el silicio!
  10. Los editores de texto compatibles con la sintaxis para su HDL / HVL son un requisito mínimo para el IDE de desarrollador.

Para FPGA, Xilinx tiene esta página . Casi todos se aplicarían a otros proveedores de FPGA, o tendrían reglas equivalentes. Mucho es aplicable a los diseños ASIC.

Intel ha recomendado estilos de codificación HDL y recomendaciones de diseño (PDF) en esta página .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top