Técnicas de simulación en Verilog para verificación RTL confiable
Verilog es un lenguaje de descripción de hardware y no hay requisito para que los diseñadores simulen sus diseños RTL para poder convertirlos en puertas lógicas. Entonces, ¿cuál es la necesidad de simular?
La simulación es una técnica de aplicar diferentes estímulos de entrada al diseño en diferentes momentos para verificar si el código RTL se comporta de la manera prevista. Esencialmente, la simulación es una técnica bien seguida para verificar la robustez del diseño. También es similar a cómo un chip fabricado se usará en el mundo real y cómo reacciona a diferentes entradas.
Por ejemplo, el diseño de arriba representa un detector de flanco positivo con entradas clock y signal que se evalúan en intervalos periódicos para encontrar la salida pe como se muestra. La simulación nos permite ver el diagrama de temporización de señales relacionadas para entender cómo se comporta realmente la descripción del diseño en Verilog.
Hay varias empresas de EDA que desarrollan simuladores capaces de determinar las salidas para varias entradas al diseño. Verilog está definido en términos de un modelo de ejecución de evento discreto y diferentes simuladores son libres de usar diferentes algoritmos para proporcionar al usuario un conjunto consistente de resultados. El código Verilog se divide en múltiples procesos e hilos y puede evaluarse en diferentes momentos en el transcurso de una simulación, lo cual se tocará más adelante.
Ejemplo
El testbench llamado tb es un contenedor para contener un módulo de diseño. Sin embargo, en este ejemplo no hemos usado instancias de diseño. Hay dos variables o señales que pueden asignarse ciertos valores en tiempos específicos. clk representa un reloj que se genera dentro del testbench. Esto se hace por la declaración always alternando el valor del reloj cada 5ns. El bloque initial contiene un conjunto de declaraciones que asignan diferentes valores a ambas señales en diferentes momentos.
module tb;
reg clk;
reg sig;
// Generación de reloj
// Proceso comienza en tiempo 0ns y cicla cada 5ns
always #5 clk = ~clk;
// Bloque initial: Proceso comienza en tiempo 0ns
initial begin
// Esta tarea de sistema imprimirá los valores de señal cada vez que cambien
$monitor("Time = %0t clk = %0d sig = %0d", $time, clk, sig);
// También llamado estímulo, simplemente asignamos diferentes valores a las variables
// después de algún "retraso" de simulación
sig = 0;
#5 clk = 0; // Asignar clk a 0 en tiempo 5ns
#15 sig = 1; // Asignar sig a 1 en tiempo 20ns (#5 + #15)
#20 sig = 0; // Asignar sig a 0 en tiempo 40ns (#5 + #15 + #20)
#15 sig = 1; // Asignar sig a 1 en tiempo 55ns (#5 + #15 + #20 + #15)
#10 sig = 0; // Asignar sig a 0 en tiempo 65ns (#5 + #15 + #20 + #15 + #10)
#20 $finish; // Terminar simulación en tiempo 85ns
end
endmodule
El simulador proporciona la siguiente salida después de la ejecución del testbench anterior.
ncsim> run Time = 0 clk = x sig = 0 Time = 5 clk = 0 sig = 0 Time = 10 clk = 1 sig = 0 Time = 15 clk = 0 sig = 0 Time = 20 clk = 1 sig = 1 Time = 25 clk = 0 sig = 1 Time = 30 clk = 1 sig = 1 Time = 35 clk = 0 sig = 1 Time = 40 clk = 1 sig = 0 Time = 45 clk = 0 sig = 0 Time = 50 clk = 1 sig = 0 Time = 55 clk = 0 sig = 1 Time = 60 clk = 1 sig = 1 Time = 65 clk = 0 sig = 0 Time = 70 clk = 1 sig = 0 Time = 75 clk = 0 sig = 0 Time = 80 clk = 1 sig = 0 Simulation complete via $finish(1) at time 85 NS + 0
¿Qué es una forma de onda de simulación?
Las simulaciones nos permiten volcar señales de diseño y testbench en una forma de onda que puede representarse gráficamente para analizar y depurar la funcionalidad del diseño RTL. La forma de onda mostrada a continuación se obtiene de una herramienta EDA y muestra el progreso de cada señal con respecto al tiempo y es la misma que el diagrama de temporización mostrado antes.
Cada cambio en el valor de una variable o red se llama evento de actualización (update event). Y los procesos son sensibles a eventos de actualización de tal manera que estos procesos se evalúan cada vez que ocurre el evento de actualización y se llama evento de evaluación (evaluation event). Debido a la posibilidad de tener múltiples procesos evaluados arbitrariamente, el orden de cambios tiene que rastrearse en algo llamado cola de eventos (event queue).
Naturalmente, están ordenados por el tiempo de simulación. La colocación de un nuevo evento en la cola se llama programación (scheduling). El tiempo de simulación se usa para referirse al valor de tiempo mantenido por el simulador para modelar el tiempo real que tomaría el circuito simulado. Los valores de tiempo para el ejemplo anterior se muestran en nanosegundos ns en el diagrama de temporización.
module des;
wire abc;
wire a, b, c;
assign abc = a & b | c;
// abc se actualiza via la declaración assign (proceso) cuando a, b o c cambian -> evento de actualización
endmodule
Actualice Verilog y vea un ejemplo !
Regiones en la cola de eventos
La cola de eventos de Verilog está lógicamente dividida en cinco regiones, y los eventos pueden agregarse a cualquiera de ellas. Sin embargo, solo pueden eliminarse de la región activa.
| Eventos | Descripción |
|---|---|
| Activa | Ocurren en el tiempo de simulación actual, y pueden procesarse en cualquier orden |
| Inactiva | Ocurren en el tiempo de simulación actual, pero se procesan después de que todos los eventos activos terminen |
| No bloqueante | Evaluados en algún tiempo previo, pero la asignación se hace en el tiempo de simulación actual después de eventos activos e inactivos |
| Monitor | Procesados después de todos los eventos activos, inactivos y no bloqueantes |
| Futura | Ocurren en algún tiempo de simulación futuro |
Un ciclo de simulación es donde se procesan todos los eventos activos. El estándar garantiza un cierto orden de programación excepto en algunos casos. Por ejemplo, las declaraciones dentro de un bloque begin-end solo se ejecutarán en el orden en que aparecen.
module tb;
reg [3:0] a;
reg [3:0] b;
initial begin
// Las declaraciones se ejecutan una tras otra en tiempos de simulación apropiados
a = 5; // En tiempo 0ns, a se asigna 5
b = 2; // En el mismo paso de simulación (tiempo 0ns), b se asigna 2
#10 a = 7; // Cuando la simulación avanza a 10ns, a se asigna 7
end
endmodule
La cola de eventos define que la asignación a b debe ocurrir después de la asignación a a.
Verilog
- Dominar Verilog: Tutorial completo para diseño de circuitos digitales
- Dominar la concatenación en Verilog: Guía práctica
- Comprender las asignaciones en Verilog: tipos, sintaxis y mejores prácticas
- Bloqueante vs. No bloqueante en Verilog: Diferencias clave explicadas
- Dominar las funciones en Verilog para diseño RTL eficiente
- Comprender las Tasks en Verilog: Funciones vs Tasks, sintaxis y uso
- Compilación condicional en Verilog: `ifdef explicado
- Comprender la semántica de programación en Verilog: Temporización, eventos y orden de ejecución
- Generador de reloj en Verilog: Guía de diseño e implementación
- Dominar las tareas de visualización en Verilog: Depuración y registro eficientes
- Dominar las funciones matemáticas en Verilog para diseño de hardware eficiente