wire reg libro español ejemplos concatenar verilog vhdl hdl

reg - vhdl vs verilog español



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

¿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?


Los HDL como Verilog y VHDL realmente parecen fomentar el código de spaghetti. La mayoría de los módulos constan de 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. Averiguar cómo funciona el código (si no lo escribiste) es un proceso doloroso.

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


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

  1. Use Revisión / Control de versiones, como en Software. SVN y Hg son gratuitos.
  2. Requerir que el código pase la comprobación de sintaxis antes del check-in. Una herramienta LINT es mejor.
  3. Use un lenguaje de verificación de hardware completo para la verificación de diseño. System-Verilog es casi una elección segura.
  4. Seguimiento de errores. Bugzilla y GNATS son herramientas gratuitas. FogBugz requiere un poco de $.
  5. Use las afirmaciones para detectar problemas con el uso incorrecto.
  6. La tríada de cobertura permite un diseño estable: medir cobertura de código, cobertura funcional y cobertura de afirmación tanto en simulación como en herramientas formales.
  7. Power is King: usa CPF o UPF para capturar, aplicar y verificar tu poder de intención.
  8. el diseño real es a menudo una señal mixta, use un lenguaje de señal mixta para verificar el análogo con el digital. Verilog-AMS es una de esas soluciones. Pero no te excedas El modelado de números reales puede lograr la mayoría de los aspectos funcionales del comportamiento de señales mixtas.
  9. Use la aceleración de hardware para validar el software que debe funcionar con el silicio.
  10. Los editores de texto de Syntax Aware para su HDL / HVL son un requisito mínimo para el IDE del desarrollador.

  • 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 usar con prudencia. esto es algo que un programador acostumbrado a los idiomas de línea por línea puede encontrar difíciles 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 realizado una gran labor.

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

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

  • Evite los protocolos "inteligentes" entre los 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, por lo tanto, reutilizar, y también considerar el uso de "bibliotecas" de módulos que algunos son gratuitos y otros se venden.

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

Algunos consejos para eliminar errores:

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

  • Deberá guardar suficientes líneas en su diseño para desviar datos interesantes para inspeccionar con dispositivos externos. también puede usar estas líneas y su código como una forma de decirle el estado actual de la ejecución; por ejemplo, si recibe datos en algún momento, 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, será aún más útil, ya que puede adaptar pruebas específicas y reprogramar las salidas para cada prueba sobre la marcha (esto se ve muy bien con leds :). )

Editar:

Mediante protocolos inteligentes, quiero 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" de un FPGA / ASIC es muy fácil ya que tienes simuladores. Por lo tanto, si está seguro de que los datos llegan como lo desea, y se apagan cuando lo envía su programa, ha alcanzado la utopia de Hardware, pudiendo trabajar a nivel de software :) (con el simulador). Pero si sus datos no le llegan a usted, de la manera que usted 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 debes conectarte a las líneas con equipos especiales, que registran los estados de las líneas, en diferentes momentos, y tendrás que asegurarte de que tus líneas actúen de acuerdo con el protocolo.

Si necesita conectar dos de sus unidades físicas, haga que el "protocolo" sea lo más simple posible, hasta el punto en que no se denomine protocolo :) Por ejemplo, si las unidades comparten un reloj, agregue x líneas de datos entre ellas y hacer que una unidad escriba esas y la otra unidad leída, pasando así una "palabra" que tiene x bits entre ellas en cada caída de reloj, por ejemplo. Si tiene FPGA, si la frecuencia del reloj original es demasiado rápida para datos en paralelo, puede controlar la velocidad de esto, de acuerdo con sus experimentos, por ejemplo, hacer que los datos permanezcan en líneas de al menos ''t'' ciclos de reloj, etc. '' Supongo que la transferencia de datos en paralelo es más simple, ya que puede trabajar con frecuencias de reloj más bajas y obtener las mismas interpretaciones, sin la necesidad de dividir sus palabras en una unidad y volver a unir en la otra. (Esperamos que no haya demora entre el ''reloj'' que recibe cada unidad). Incluso esto es probablemente demasiado complejo :)

En cuanto a SPI, I2C, etc. ''No he implementado ninguno de ellos, puedo decir que he conectado las patas de dos FPGA que se ejecutan desde el mismo reloj, (no recuerdo la formación exacta de resistencias en el medio), a mucho tasas más altas, así que realmente no puedo pensar en una buena razón para usarlas, ya que la principal forma de pasar datos entre tus propias FPGA, a menos que las FPGA estén ubicadas muy lejos una de la otra, que es una razón para usar una serie que un bus paralelo.

JTAG es utilizado por algunas empresas de FPGA para probar / programar sus productos, pero no está seguro si se usa como medio para transportar datos a altas velocidades, y es un protocolo ... (aún uno que puede tener incorporado un chip) apoyo).

Si tiene que implementar cualquier protocolo conocido, considere usar un código HDL prefabricado para esto, que se puede encontrar o comprar.


El mejor libro sobre este tema es el 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
  • Verifica tu tiempo interno y externo
  • Use solo código sintetizable
  • Registra tus salidas de todos los módulos
  • Tenga cuidado con las asignaciones de bloqueo y no de bloqueo
  • Tenga cuidado con las listas sensibles de lógica combinatoria (o use @ (*) en Verilog)

Algunos que son los mismos incluyen

  • Use CM
  • Tener revisiones de código
  • Prueba (simula) tu código
  • Reutilizar el código cuando sea apropiado
  • Tener un horario actualizado
  • Tener una especificación o casos de uso o un cliente ágil

Una especie de hilo viejo, pero quería poner en mi $ 0.02. Esto no es realmente específico de Verilog / VHDL ... más sobre el 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 diseño industrial (en oposición a académica). No están en ningún orden particular

Mi declaración general es Diseño para la ejecución de validación. En el 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 mucho más enfoque.

  • Conozca la diferencia entre las rutas de control y las rutas de datos. Esto le permite crear un código mucho más elegante y fácil de mantener. También le permite guardar puertas y minimizar la propagación X. Por ejemplo, las rutas de datos nunca deberían necesitar fracasos 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 a través de formas de onda. Esto tiene muchas ventajas, explicaré 2. En primer lugar, le ahorrará perder tiempo en la cebolla pelando a través de 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 (entre 10 minutos y días, dependiendo de la complejidad). Cada vez que cambias el código, debes pasar por la elaboración, el control de pelusas, la compilación, la generación de forma de onda y, finalmente, la simulación real ... que en sí misma puede llevar horas. En segundo lugar, es mucho menos probable que tenga casos de esquina difíciles de alcanzar. Tenga en cuenta que esto es con respecto a la validación pre-silicio. Estos seguramente golpearán en post-silicio que le cuesta mucho $$$. Créanme, el costo inicial de la funcionalidad de prueba minimiza en gran medida el riesgo y bien vale la pena el esfuerzo. Esto a veces es difícil de convencer a los graduados recientes de la universidad.

  • Tener "trozos de pollo". Los bits de pollo son bits en MMIO configurados a través del controlador para desactivar 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 el pre-silicio. La confianza en su diseño no se puede cumplir de verdad hasta que se pruebe en post-silicio. Incluso si solo hay 1 estado que se golpea 0.000005% del tiempo que expone el error, se golpeará en post-silicio, pero no necesariamente en pre-silicio.

  • Evite las excepciones en la ruta de control a toda costa. Cada nueva excepción que ha duplica sus 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 tal que la estructura de datos guardada fuera diferente entre diferentes funciones, simplemente multiplicó sus esfuerzos de validación por el número de funciones de 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.

  • Minimice las interfaces (léase minimice las rutas de control). Esto está relacionado con minimizar las excepciones. Primero, cada nueva interfaz requiere validación. Esto incluye nuevas fichas / rastreadores, afirmaciones, puntos de cobertura y modelos funcionales de autobuses en su banco de pruebas. En segundo lugar, ¡puede aumentar sus esfuerzos de validación exponencialmente! Digamos que tienes 1 interfaz para leer datos en cachés. Ahora digamos (por alguna extraña razón) usted decide que quiere otra interfaz para leer la memoria principal. Acabas de cuadruplicar tus esfuerzos de validación. Ahora necesita validar estas combinaciones en un momento dado n :

    • sin lectura de caché, sin lectura de memoria
    • no hay lectura de caché, lectura de memoria
    • lectura en caché, sin lectura de memoria
    • lectura de caché, lectura de memoria
  • Comprender y comunicar suposiciones. La falta de este es el principal motivo por el bloqueo para bloquear problemas de comunicación. Podrías tener un bloque perfecto totalmente validado ... sin embargo, sin entender todas las suposiciones, tu bloque fallará cuando esté conectado.

  • Minimice los estados potenciales. Cuantos menos estados (previstos o no) tenga un diseño, menos esfuerzo se requiere para validar. Es una buena práctica agrupar funciones similares en 1 función de nivel superior (como secuenciadores y árbitros). Es muy difícil identificar y definir esta función de alto nivel de manera que abarque la mayor cantidad posible de funciones más pequeñas, pero al hacerlo, usted elimina enormemente el estado y, a su vez, el potencial de errores.

  • Siempre brinde una señal fuerte dejando su bloque. La mayoría de las veces el fracaso es la solución. No tiene idea de qué harán los bloques de punto final con él. Podría encontrarse con problemas de sincronización que pueden tener un impacto directo en su implementación perfecta.

  • Evite los FSM de tipo harinoso a menos que el rendimiento se vea afectado negativamente. Las FSM de Mealy son más propensas a producir problemas de sincronización con Moore

  • ... y finalmente, el que más me disgustó: "si no está roto, no lo arregles". Debido al riesgo involucrado y el alto costo de los errores, muchas veces el pirateo es una solución más práctica para resolver problemas. Otros han eludido esto al mencionar la utilización de los componentes existentes.

En cuanto a comparar con un diseño de software más tradicional :

  • la programación basada en eventos discretos es un paradigma completamente diferente. La gente ve la sintaxis verilog y piensa "oh, es como C" ... sin embargo, esto no puede estar más lejos de la verdad. Aunque la sintaxis es similar, uno debe pensar de manera diferente. Por ejemplo, un depurador tradicional es virtualmente insignificante en RTL sintetizable (el diseño de Testbench es diferente). Las formas de onda en papel son la mejor herramienta disponible. Sin embargo, dicho esto, el diseño de FSM a veces puede imitar la programación de procedimientos. Las personas con experiencia en software tienden a volverse locas con FSM (sé que lo hice al principio).

  • El sistema Verilog tiene muchas (muchas) características específicas del banco de pruebas. Está completamente orientado a objetos. En cuanto al diseño del banco de pruebas, es muy similar al diseño de software tradicional. Sin embargo, tiene una dimensión más asociada, la del tiempo. las condiciones de carrera y los retrasos de protocolo deben ser contabilizados

  • En cuanto a la validación, también es diferente (y lo mismo). Hay 3 enfoques principales;

    • Verificación propagativa formal (FPV): demuestras a través de la lógica que siempre funcionará
    • Prueba aleatoria dirigida. Establece aleatoriamente retrasos, valores de entrada y habilitación de características según lo definido por una semilla. dirigido significa que la semilla pone peso en caminos que tienen menos confianza. Este enfoque utiliza puntos de cobertura para indicar la salud
    • Prueba de enfoque. Esto es similar a las pruebas de software tradicionales

... para completar, también necesito hablar sobre las mejores prácticas de diseño de banco de pruebas ... pero eso es para otro día

Perdón por la duración ... Estuve en "The Zone" :)