Comprender las Tasks en Verilog: Funciones vs Tasks, sintaxis y uso
Una function está destinada a procesar la entrada y devolver un solo valor, mientras que una task es más general y puede calcular múltiples valores de resultado y devolverlos usando argumentos de tipo output e inout. Las tasks pueden contener elementos que consumen tiempo de simulación como @, posedge y otros.
Sintaxis
Una task no necesita tener un conjunto de argumentos en la lista de puertos, en cuyo caso puede mantenerse vacía.
// Estilo 1
task [nombre];
input [lista_puertos];
inout [lista_puertos];
output [lista_puertos];
begin
[declaraciones]
end
endtask
// Estilo 2
task [nombre] (input [lista_puertos], inout [lista_puertos], output [lista_puertos]);
begin
[declaraciones]
end
endtask
// Lista de puertos vacía
task [nombre] ();
begin
[declaraciones]
end
endtask
Task estática
Si una task es estática, todas sus variables miembro se compartirán entre diferentes invocaciones de la misma task que se hayan lanzado para ejecutarse concurrentemente.
task sum (input [7:0] a, b, output [7:0] c);
begin
c = a + b;
end
endtask
// o
task sum;
input [7:0] a, b;
output [7:0] c;
begin
c = a + b;
end
endtask
initial begin
reg [7:0] x, y , z;
sum (x, y, z);
end
Los argumentos de habilitación de task (x, y, z) corresponden a los argumentos (a, b, c) definidos por la task. Dado que a y b son entradas, los valores de x e y se colocarán en a y b respectivamente. Porque c se declara como salida y se conecta con z durante la invocación, la suma se pasará automáticamente a la variable z desde c.
Task automática
La palabra clave automatic hará que la task sea reentrante; de lo contrario, será estática por defecto. Todos los elementos dentro de tasks automatic se asignan dinámicamente para cada invocación y no se comparten entre invocaciones de la misma task ejecutándose concurrentemente. Tenga en cuenta que los elementos de task automatic no pueden ser accedidos por referencias jerárquicas.
Para ilustración, considere la task estática display que se llama desde diferentes bloques initial que se ejecutan concurrentemente. En este caso, la variable entera declarada dentro de la task se comparte entre todas las invocaciones de la task y por tanto el valor mostrado debería incrementarse para cada invocación.
module tb;
initial display();
initial display();
initial display();
initial display();
// Esta es una task estática
task display();
integer i = 0;
i = i + 1;
$display("i=%0d", i);
endtask
endmodule
xcelium> run i=1 i=2 i=3 i=4 xmsim: *W,RNQUIE: Simulation is complete.
Si la task se hace automática, cada invocación de la task se asigna un espacio diferente en la memoria de simulación y se comporta de manera diferente.
module tb;
initial display();
initial display();
initial display();
initial display();
// Nota que la task ahora es automatic
task automatic display();
integer i = 0;
i = i + 1;
$display("i=%0d", i);
endtask
endmodule
xcelium> run i=1 i=1 i=1 i=1 xmsim: *W,RNQUIE: Simulation is complete.
Tasks globales
Las tasks declaradas fuera de todos los módulos se llaman globales ya que tienen alcance global y pueden ser llamadas dentro de cualquier módulo.
// Esta task está fuera de todos los módulos
task display();
$display("¡Hola Mundo!");
endtask
module des;
initial begin
display();
end
endmodule
xcelium> run ¡Hola Mundo! xmsim: *W,RNQUIE: Simulation is complete.
Si la task se declarara dentro del módulo des, tendría que ser llamada en referencia al nombre de la instancia del módulo.
module tb;
des u0();
initial begin
u0.display(); // La task no es visible en el módulo 'tb'
end
endmodule
module des;
initial begin
display(); // La definición de task es local al módulo
end
task display();
$display("Hola Mundo");
endtask
endmodule
xcelium> run Hola Mundo Hola Mundo xmsim: *W,RNQUIE: Simulation is complete.
Diferencia entre function y task
Aunque las funciones y tasks de Verilog sirven propósitos similares, hay algunas diferencias notables entre ellas.
| Function | Task |
|---|---|
| No puede tener declaraciones controladas por tiempo/retraso, y por tanto ejecuta en la misma unidad de tiempo de simulación | Puede contener declaraciones controladas por tiempo/retraso y puede completarse solo en otro tiempo |
| No puede habilitar una task, debido a la regla anterior | Puede habilitar otras tasks y funciones |
| Debe tener al menos un argumento de entrada y no puede tener argumentos output o inout | Puede tener cero o más argumentos de cualquier tipo |
| Puede devolver solo un valor único | No puede devolver un valor, pero puede lograr el mismo efecto usando argumentos output |
Cuando una función intenta llamar a una task o contener una declaración que consume tiempo, el compilador reporta un error.
module tb;
reg signal;
initial wait_for_1(signal);
function wait_for_1(reg signal);
#10;
endfunction
endmodule
#10; | xmvlog: *E,BADFCN (testbench.sv,7|4): illegal time/event control statement within a function or final block or analog initial block [10.3.4(IEEE)].
Deshabilitar Task
Las tasks pueden deshabilitarse usando la palabra clave disable.
module tb;
initial display();
initial begin
// Después de 50 unidades de tiempo, deshabilitar un bloque nombrado
// T_DISPLAY dentro de la task llamada 'display'
#50 disable display.T_DISPLAY;
end
task display();
begin : T_DISPLAY
$display("[%0t] T_Task started", $time);
#100;
$display("[%0t] T_Task ended", $time);
end
begin : S_DISPLAY
#10;
$display("[%0t] S_Task started", $time);
#20;
$display("[%0t] S_Task ended", $time);
end
endtask
endmodule
Cuando la task display fue lanzada por el primer bloque initial, T_DISPLAY comenzó y se deshabilitó cuando el tiempo alcanzó 50 unidades. Inmediatamente el siguiente bloque S_DISPLAY comenzó y corrió hasta completarse en 80 unidades.
xcelium> run [0] T_Task started [60] S_Task started [80] S_Task ended xmsim: *W,RNQUIE: Simulation is complete.
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
- Dominar el alcance de referencia jerárquica en Verilog: Evitar colisiones de nombres en módulos y bloques
- 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
- Dominar $timeformat en Verilog: Control de precisión y visualización