Verilog disable语句不终止fork语句中的其他块
这是密码Verilog disable语句不终止fork语句中的其他块,verilog,system-verilog,Verilog,System Verilog,这是密码 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); di
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
为什么禁用第二个语句块不被终止,如第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
如第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
在调度区域内,执行顺序可能是不确定的。我使用的每个模拟器都是基于执行顺序和编译顺序执行的 Verilog按程序执行所有代码。它看起来大部分是并发的,因为Verilog调度程序对每个过程块执行多线程。一次将运行一个过程进程,并将完成该过程,除非它被阻塞语句@,wait挂起 在您的情况下,MYLOOP在第二个启动之前就完成了。没有什么可以禁用的 以下是一些选项: 禁用任务本身第二次将永远不会启动:
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
我在这里
使用0时暂时挂起MYLOOP小心,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
工作示例在调度区域内,执行顺序可能是不确定的。我使用的每个模拟器都是基于执行顺序和编译顺序执行的 Verilog按程序执行所有代码。它看起来大部分是并发的,因为Verilog调度程序对每个过程块执行多线程。一次将运行一个过程进程,并将完成该过程,除非它被阻塞语句@,wait挂起 在您的情况下,MYLOOP在第二个启动之前就完成了。没有什么可以禁用的 以下是一些选项: 禁用任务本身第二次将永远不会启动:
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
我在这里
使用0时暂时挂起MYLOOP小心,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
工作示例fork join中的两个块同时执行9.3块语句。是的,我同意。但是,当第一个块执行语句disable时,可能没有看到作用域中有第二个块。如果我更改块的顺序,我可以删除延迟1,代码将按预期工作。2个begin块的执行顺序是不确定的。模拟器可以选择在时间0时首先执行哪一个$display语句。fork join中的两个块都是9.3块语句并发执行的。是的,我同意。但是,当第一个块执行语句disable时,可能没有看到作用域中有第二个块。如果我更改块的顺序,我可以删除延迟1,代码将按预期工作。2个begin块的执行顺序是不确定的。模拟器可以选择在时间0时首先执行哪一个$display语句。