Verilog Tasks verstehen: Functions vs. Tasks, Syntax und Verwendung
Eine function dient dazu, Eingaben zu verarbeiten und einen einzelnen Wert zurückzugeben, während eine task allgemeiner ist und mehrere Ergebniswerte berechnen und diese über output- und inout-Argumente zurückgeben kann. Tasks können Simulationszeit verbrauchende Elemente wie @, posedge und andere enthalten.
Syntax
Eine Task muss nicht zwingend eine Reihe von Argumenten in der Port-Liste haben; in diesem Fall kann diese leer gehalten werden.
// Stil 1
task [name];
input [port_list];
inout [port_list];
output [port_list];
begin [statements] end
endtask
// Stil 2
task [name] (input [port_list], inout [port_list], output [port_list]);
begin [statements] end
endtask
// Leere Port-Liste
task [name] ();
begin [statements] end
endtask
Statische Task
Wenn eine Task statisch ist, werden alle ihre Mitgliedsvariablen über verschiedene Aufrufe derselben Task geteilt, die parallel gestartet wurden.
task sum (input [7:0] a, b, output [7:0] c);
begin
c = a + b;
end
endtask
// oder
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
Die Task-aufrufenden Argumente (x, y, z) entsprechen den Argumenten (a, b, c), die von der Task definiert wurden. Da a und b Inputs sind, werden die Werte von x und y in a und b gelegt. Da c als Output deklariert und bei der Instanziierung mit z verbunden ist, wird die Summe automatisch von c an die Variable z übergeben.
Automatische Task
Das Schlüsselwort automatic macht die Task reentrant, ansonsten ist sie standardmäßig statisch. Alle Elemente innerhalb automatischer Tasks werden für jeden Aufruf dynamisch allokiert und nicht zwischen Aufrufen derselben Task, die parallel laufen, geteilt. Beachten Sie, dass automatic-Task-Elemente nicht über hierarchische Referenzen zugegriffen werden können.
Zur Veranschaulichung betrachten wir die statische Task display, die von verschiedenen initial-Blöcken aufgerufen wird, die parallel laufen. In diesem Fall wird die innerhalb der Task deklarierte Integer-Variable unter allen Aufrufen der Task geteilt, weshalb der angezeigte Wert für jeden Aufruf inkrementiert werden sollte.
module tb;
initial display();
initial display();
initial display();
initial display();
// Dies ist eine statische Task
task display();
integer i = 0;
i = i + 1;
$display("i=%0d", i);
endtask
endmodule
Simulationslog:
xcelium> run i=1 i=2 i=3 i=4 xmsim: *W,RNQUIE: Simulation is complete.
Wenn die Task automatisch gemacht wird, wird jedem Aufruf der Task ein anderer Speicherplatz im Simulationsspeicher zugewiesen und sie verhält sich anders.
module tb;
initial display();
initial display();
initial display();
initial display();
// Beachten Sie, dass die Task jetzt automatic ist
task automatic display();
integer i = 0;
i = i + 1;
$display("i=%0d", i);
endtask
endmodule
Simulationslog:
xcelium> run i=1 i=1 i=1 i=1 xmsim: *W,RNQUIE: Simulation is complete.
Globale Tasks
Tasks, die außerhalb aller Module deklariert sind, werden globale Tasks genannt, da sie einen globalen Gültigkeitsbereich haben und innerhalb jedes Moduls aufgerufen werden können.
// Diese Task ist außerhalb aller Module
task display();
$display("Hello World !");
endtask
module des;
initial begin
display();
end
endmodule
Simulationslog:
xcelium> run Hello World ! xmsim: *W,RNQUIE: Simulation is complete.
Wenn die Task innerhalb des Moduls des deklariert wäre, müsste sie in Bezug auf den Modulinstanznamen aufgerufen werden.
module tb;
des u0();
initial begin
u0.display(); // Task ist im Modul 'tb' nicht sichtbar
end
endmodule
module des;
initial begin
display(); // Task-Definition ist lokal zum Modul
end
task display();
$display("Hello World");
endtask
endmodule
Simulationslog:
xcelium> run Hello World Hello World xmsim: *W,RNQUIE: Simulation is complete.
Unterschied zwischen function und task
Obwohl Verilog-Funktionen und -Tasks ähnliche Zwecke erfüllen, gibt es einige bemerkenswerte Unterschiede zwischen ihnen.
| Function | Task |
|---|---|
| Kann keine zeitgesteuerten Anweisungen/Delays enthalten, daher führt sie in derselben Simulationszeiteinheit aus | Kann zeitgesteuerte Anweisungen/Delays enthalten und möglicherweise erst zu einem späteren Zeitpunkt abgeschlossen werden |
| Kann keine Task aktivieren, wegen der obigen Regel | Kann andere Tasks und Funktionen aktivieren |
| Sollte mindestens ein Input-Argument haben und kann keine Output- oder Inout-Argumente haben | Kann null oder mehr Argumente beliebigen Typs haben |
| Kann nur einen einzelnen Wert zurückgeben | Kann keinen Wert zurückgeben, aber denselben Effekt über Output-Argumente erzielen |
Wenn eine Funktion versucht, einen task aufzurufen oder eine zeitverbrauchende Anweisung zu enthalten, meldet der Compiler einen Fehler.
module tb;
reg signal;
initial wait_for_1(signal);
function wait_for_1(reg signal);
#10;
endfunction
endmodule
Simulationslog:
#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)].
Task deaktivieren
Tasks können mit dem Schlüsselwort disable deaktiviert werden.
module tb;
initial display();
initial begin
// Nach 50 Zeiteinheiten einen bestimmten benannten
// Block T_DISPLAY innerhalb der Task 'display' deaktivieren
#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
Als die display-Task vom ersten initial-Block gestartet wurde, begann T_DISPLAY und wurde deaktiviert, als die Zeit 50 Einheiten erreichte. Sofort begann der nächste Block S_DISPLAY und lief bis 80 Einheiten zur Vollendung.
Simulationslog:
xcelium> run [0] T_Task started [60] S_Task started [80] S_Task ended xmsim: *W,RNQUIE: Simulation is complete.
Verilog
- Verilog meistern: Komplettes Tutorial für digitales Schaltungsdesign
- Verilog Concatenation meistern: Praktischer Leitfaden
- Verilog Assignments verstehen: Typen, Syntax und Best Practices
- Verilog Blocking vs. Non-Blocking: Wichtige Unterschiede erklärt
- Verilog Functions meistern für effizientes RTL-Design
- Verilog Tasks verstehen: Functions vs. Tasks, Syntax und Verwendung
- Verilogs hierarchischen Referenz-Gültigkeitsbereich meistern: Namenskonflikte in Modulen und Blöcken vermeiden
- Verilog Clock Generator: Design & Implementierungsleitfaden
- Verilog Display Tasks meistern: Effizientes Debugging & Logging
- Verilog Math Functions meistern für effizientes Hardware-Design