Verilog タスク
function
task
は入力に対して何らかの処理を行い、単一の値を返すことを意図しています。 より一般的で、複数の結果値を計算し、output を使用してそれらを返すことができます そしてinout 型引数。タスクには、@ などのシミュレーションに時間がかかる要素を含めることができます 、ポージング その他。
構文
タスクは、ポート リストに引数のセットを持つ必要はありません。その場合は、空のままにすることができます。
// Style 1
task [name];
input [port_list];
inout [port_list];
output [port_list];
begin
[statements]
end
endtask
// Style 2
task [name] (input [port_list], inout [port_list], output [port_list]);
begin
[statements]
end
endtask
// Empty port list
task [name] ();
begin
[statements]
end
endtask
静的タスク
タスクが静的である場合、そのすべてのメンバー変数は、同時に実行するために起動された同じタスクの異なる呼び出し間で共有されます
task sum (input [7:0] a, b, output [7:0] c);
begin
c = a + b;
end
endtask
// or
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
タスクを有効にする引数 (x、y、z) は、タスクによって定義された引数 (a、b、c) に対応します。 ある以来 そしてb 入力、x の値 そしてy a に配置されます そしてb それぞれ。なぜなら c 出力として宣言され、z に接続されます 呼び出し中、合計は自動的に変数 z に渡されます c から .
自動タスク
キーワード automatic
タスクを再入可能にします。それ以外の場合は、デフォルトで静的になります。 自動内のすべてのアイテム タスクは呼び出しごとに動的に割り当てられ、同時に実行されている同じタスクの呼び出し間で共有されません。 automatic
に注意してください タスク アイテムは、階層参照によってアクセスできません。
説明のために、static を考えてみましょう 異なる initial
から呼び出されるタスク表示 同時に実行されるブロック。この場合、タスク内で宣言された整数変数は、タスクのすべての呼び出し間で共有されるため、表示される値は呼び出しごとに増加する必要があります。
module tb;
initial display();
initial display();
initial display();
initial display();
// This is a static task
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.
タスクが自動化されている場合、タスクの呼び出しごとにシミュレーション メモリ内の異なる領域が割り当てられ、異なる動作をします。
module tb;
initial display();
initial display();
initial display();
initial display();
// Note that the task is now 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.
グローバル タスク
すべてのモジュールの外で宣言されたタスクは global と呼ばれます タスクはグローバル スコープを持ち、任意のモジュール内で呼び出すことができるためです。
// This task is outside all modules
task display();
$display("Hello World !");
endtask
module des;
initial begin
display();
end
endmodule
シミュレーションログ xcelium> run Hello World ! xmsim: *W,RNQUIE: Simulation is complete.
タスクがモジュール des 内で宣言されている場合は、モジュール インスタンス名を参照して呼び出す必要があります。
module tb;
des u0();
initial begin
u0.display(); // Task is not visible in the module 'tb'
end
endmodule
module des;
initial begin
display(); // Task definition is local to the module
end
task display();
$display("Hello World");
endtask
endmodule
シミュレーションログ xcelium> run Hello World Hello World xmsim: *W,RNQUIE: Simulation is complete.
function
の違い と task
Verilog の関数とタスクは同様の目的を果たしますが、いくつかの顕著な違いがあります。
関数 | タスク |
---|---|
時間制御ステートメント/遅延を持つことはできないため、同じシミュレーション時間単位で実行されます | 時間制御ステートメント/遅延を含めることができ、別の時間にのみ完了する場合があります |
上記のルールのため、タスクを有効にできません | 他のタスクや機能を有効にできます |
少なくとも 1 つの入力引数が必要であり、出力または inout 引数を持つことはできません | 任意の型の 0 個以上の引数を持つことができます |
単一の値のみを返すことができます | 値を返すことはできませんが、出力引数を使用して同じ効果を得ることができます |
関数が task
を呼び出そうとしたとき または時間のかかるステートメントが含まれている場合、コンパイラはエラーを報告します。
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)].
タスクを無効にする
disable
を使用してタスクを無効にすることができます キーワード。
module tb;
initial display();
initial begin
// After 50 time units, disable a particular named
// block T_DISPLAY inside the task called '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
表示時 タスクは最初の initial
によって開始されました ブロック、T_DISPLAY が開始され、時間が 50 単位に達したときに無効になりました。すぐに次のブロック S_DISPLAY が開始され、80 単位で完了するまで実行されました。
xcelium> run [0] T_Task started [60] S_Task started [80] S_Task ended xmsim: *W,RNQUIE: Simulation is complete.
Verilog