SystemVerilog では、disable
構文を使用して名前付きブロックまたはタスクを終了できます。しかし今日、クラス インスタンス内のタスクを無効にすると、すべてのクラス インスタンス内のタスクのすべてのコピーに影響することがわかりました。
その中でいくつかのタスクが定義されているクラスを考えてみましょう。クラスの内部で への呼び出しがある場合、クラスのすべてのインスタンスでタスクのすべてのコピーdisable <taskname>
が無効になります。これは私が期待した動作ではありませんが、LRM によれば正しい動作です。
タスクが複数回有効になっている場合、そのようなタスクを無効にすると、タスクのすべてのアクティブ化が無効になります。
クラスの特定のインスタンス内のタスクのみを無効にするメカニズムまたは回避策はありますか?
以下のコードは、私が直面している問題を強調しています。基本的に、他のイベントのために無効にしたいタイマータスクがあります。これはすべてクラス内に含まれています。私の検証環境では、このクラスの複数のインスタンスがあり、それらは完全に独立して動作します。したがって、1 つのインスタンス内でタイマーを無効にしても、他のインスタンスには影響しません。しかし、disable
それが機能する方法は、他のインスタンスに影響を与えています。
私は試しdisable this.timer
ましたが、それはコンパイルされませんでした。
この例でclass c
は、タスクを含む2 つのインスタンスがありtimer
ます。disabler
を呼び出す、並行して開始されるタスクがありますdisable timer
。この例の目的はtimer
、カウントの途中で無効にすることです。したがってc1
は時間 5 でc2
無効になり、時間 10 で無効になります。ただし、 でdisable timer
発信された呼び出しが との両方でc1
タスクを無効にするため、両方とも時間 5 で無効になります。c1
c2
module top();
class c;
string name;
int count;
function new(string _name, int _count);
name = _name;
count = _count;
endfunction
task t1();
timer();
$display("%t %s timer completed", $time, name);
endtask
task run();
fork
t1();
disabler();
join
endtask
task timer();
$display("%t %s starting timer with count=%0d", $time, name, count);
repeat(count) #1;
endtask
task disabler();
repeat(count/2) #1;
disable timer;
endtask
endclass
class ex;
c c1;
c c2;
function new();
c1 = new("c1", 10);
c2 = new("c2", 20);
endfunction
task run();
fork
c1.run();
c2.run();
join_none
endtask
endclass
ex e = new;
initial begin
e.run();
end
endmodule
出力:
0 c1 starting timer with count=10
0 c2 starting timer with count=20
5 c2 timer completed
5 c1 timer completed
を使用せずにこれを書き直して動作させることができることはわかっていdisable
ますが、タスクを早期に終了するのは非常に簡単な方法であるため、欠けているものがあることを願っています。