Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Verilog

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

  1. Verilog meistern: Komplettes Tutorial für digitales Schaltungsdesign
  2. Verilog Concatenation meistern: Praktischer Leitfaden
  3. Verilog Assignments verstehen: Typen, Syntax und Best Practices
  4. Verilog Blocking vs. Non-Blocking: Wichtige Unterschiede erklärt
  5. Verilog Functions meistern für effizientes RTL-Design
  6. Verilog Tasks verstehen: Functions vs. Tasks, Syntax und Verwendung
  7. Verilogs hierarchischen Referenz-Gültigkeitsbereich meistern: Namenskonflikte in Modulen und Blöcken vermeiden
  8. Verilog Clock Generator: Design & Implementierungsleitfaden
  9. Verilog Display Tasks meistern: Effizientes Debugging & Logging
  10. Verilog Math Functions meistern für effizientes Hardware-Design