这是代码
module aks();
initial begin
rad temp ;
temp = new;
temp.fork_ll();
end
endmodule
//这是在上面的模块中使用的类
class rad;
task fork_ll();
fork
begin:MYLOOP
$display("%t %M:I AM HERE ",$time);
disable SECOND;//I expected it should kill the SECOND BLOCk
end:MYLOOP
begin:SECOND
$display("%t %M:STEP 2 ",$time);
#10us $display("%t %M:STEP3 ",$time);
end:SECOND
join
endtask
endclass
我期望输出为
I AM HERE
STEP 2
但实际上我的输出为
0 $unit_0x5d440f27.rad.fork_ll.MYLOOP:I AM HERE
0 $unit_0x5d440f27.rad.fork_ll.SECOND:STEP 2
10000 $unit_0x5d440f27.rad.fork_ll.SECOND:STEP3
为什么禁用SECOND未被杀死的SECOND语句块
答案 0 :(得分:2)
正如您在IEEE Std 1800-2012中所见(第9.6.2节 - 禁用声明):
如果当前没有执行该块,则禁用无效。
此代码可以解决您的问题:
task fork_ll();
fork
begin
$display("%t %M:I AM HERE ",$time);
#10;
end
begin
$display("%t %M:STEP 2 ",$time);
#10us $display("%t %M:STEP3 ",$time);
end
join_any
disable fork;
endtask
另一种解决方案:
task fork_ll();
fork
begin: FIRST
$display("%t %M:I AM HERE ",$time);
#1 disable SECOND;
end
begin: SECOND
$display("%t %M:STEP 2 ",$time);
#10us $display("%t %M:STEP3 ",$time);
end
join_any
endtask
因此,输出将是:
IAM HERE
STEP 2
答案 1 :(得分:2)
执行顺序可以是非确定性的(在调度区域内)。我每次使用的每个模拟器都根据执行顺序和编译顺序执行。
Verilog在程序上执行所有代码。它(大多数情况下)似乎是并发的,因为Verilog调度程序多线程化每个程序块。一个程序流程将一次运行,并将完成该过程,除非它被阻止声明(#
,@
,wait
)暂停。
在您的情况下,MYLOOP
在SECOND
开始之前完成。 disable
无法禁用。
以下是一些选项:
禁用任务本身(SECOND
永远不会启动):
task fork_ll();
fork
begin : MYLOOP
$display("%t %M:I AM HERE ",$time);
disable fork_ll;
end
begin : SECOND
$display("%t %M:STEP 2 ",$time);
#10us $display("%t %M:STEP3 ",$time);
end
join
endtask
我在这里
使用MYLOOP
暂时暂停#0
(谨慎使用,#0
有自己的竞争条件问题):
task fork_ll();
fork
begin : MYLOOP
$display("%t %M:I AM HERE ",$time);
#0; // let other procedural blocks start, then continue
disable SECOND; //
end
begin : SECOND
$display("%t %M:STEP 2 ",$time);
#10us $display("%t %M:STEP3 ",$time);
end
join
endtask
我在这里 第2步
使用事件触发器:
task fork_ll();
event e;
fork
begin : MYLOOP
$display("%t %M:I AM HERE ",$time);
@(e); // let other procedural blocks start
disable SECOND; //
end
begin : SECOND
->e; // unblock FIRST, SECOND is still active
$display("%t %M:STEP 2 ",$time);
// ->e; // event trigger could be here too
#10us $display("%t %M:STEP3 ",$time);
end
join
endtask
我在这里 第2步
工作示例here