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语句。