在 SystemVerilog 中,可以使用该disable
构造来终止命名块或任务。但是我今天发现禁用类实例中的任务会影响所有类实例中任务的所有副本。
考虑一个在其中定义了一些任务的类。如果在类内部调用disable <taskname>
,这将禁用该类的所有实例中的所有任务副本。这不是我所期望的行为,但根据 LRM 是正确的:
如果多次启用任务,则禁用此类任务将禁用该任务的所有激活。
是否有一种机制或解决方法来仅禁用类的特定实例中的任务?
下面的代码突出了我面临的问题。基本上,我有一个计时器任务,由于其他一些事件,我想禁用它。这都包含在一个类中。在我的验证环境中,我有这个类的多个实例,它们完全独立运行。因此,在一个实例中禁用计时器不应影响其他实例。但是它的disable
工作方式正在影响其他实例。
我试过disable this.timer
了,但没有编译。
在这个例子中,我有两个实例,class c
其中包含一个timer
任务。有一个disabler
并行启动的任务调用disable timer
. 此示例中的目的是在timer
计数中途禁用。所以c1
会在时间 5c2
被禁用,并在时间 10 被禁用。但是,它们都在时间 5 被禁用,因为disable timer
发起的调用在和c1
中都禁用了任务。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
,但这是一种提前终止任务的简单方法,我希望我缺少一些东西。