不枉初心,砥砺前行

皮皮祥的博客

欢迎留言,评论

导航

线程控制 fork

线程控制

1. 线程控制

1.1. 并行线程

  • fork...join需要所有的并行的线程都结束以后才会继续执行
  • fork...join_any则会等到任何一个线程结束以后就继续执行
  • fork...join_none则不会等待其他子线程而继续执行
    在这里插入图片描述
fork
  begin	// thread-1
    $display("First Block!\n");
    # 20ns;
  end
  begin	// thread-2
    $display("Second Block!\n");
    @eventA;
  end
join
  • fork...join_anyfork_join_none继续执行后,其一些未完成的子程序仍将在后台运行
  • 如果要等待这些子程序全部完成,或者停止这些子程序可以使用wait fork或者disable fork
task mt_test;
  fork
    exce1();
    exce2();
  join_any
  fork
    exec3();
    exec4();
  join_none
  wait fork; // block until exec1 ... exec4 complete
endtask

1.2. 一些代码示例

1.2.1. 多个initial并行执行

module tb;
  task automatic exec(int id, int t);
    $display("@%t exec[%0d entered]", $time, id);
    #t;
    $display("@%t exec[%0d exited]", $time, id);
  endtask

  initial begin exec(1, 10); end
  initial begin exec(2, 20); end
  initial begin exec(3, 30); end
  initial begin exec(4, 40); end
endmodule

在这里插入图片描述

1.2.2. 单个initial内串行执行

module tb2;
  task automatic exec(int id, int t);
    $display("@%t exec[%0d entered]", $time, id);
    #t;
    $display("@%t exec[%0d exited]", $time, id);
  endtask

  initial begin
    exec(1, 10);
    exec(2, 20);
    exec(3, 30);
    exec(4, 40);
  end
endmodule

在这里插入图片描述

1.2.3. fork…join内并行执行

module tb3;
  task automatic exec(int id, int t);
    $display("@%t exec[%0d entered]", $time, id);
    #t;
    $display("@%t exec[%0d exited]", $time, id);
  endtask

  initial begin
    fork
      exec(1, 10);
      exec(2, 20);
      exec(3, 30);
      exec(4, 40);
    join
  end
endmodule

在这里插入图片描述

1.2.4. join_any和join_none

module tb4;
  task automatic exec(int id, int t);
    $display("@%t exec[%0d entered]", $time, id);
    #t;
    $display("@%t exec[%0d exited]", $time, id);
  endtask

  initial begin: ini_proc1
    $display("@%t fork-join_any entered", $time);
    fork
      exec(1, 10);
      exec(2, 20);
    join_any
    $display("@%t fork-join_any exited", $time);
    $display("@%t fork-join_none entered", $time);
    fork
      exec(3, 30);
      exec(4, 40);
    join_none
    $display("@%t fork-join_none exited", $time);
    $display("@%t ini_proc1 exited", $time);
  end

  
  initial begin
    #200;
  end
endmodule

在这里插入图片描述
initial本该在10ns的时候退出,但是fork块内的线程还没有结束

1.2.5. wait fork

wait fork可以让当前initial块等待前面的fork执行完后再继续

module tb5;
  task automatic exec(int id, int t);
    $display("@%t exec[%0d entered]", $time, id);
    #t;
    $display("@%t exec[%0d exited]", $time, id);
  endtask

  initial begin: ini_proc1
    $display("@%t fork-join_any entered", $time);
    fork
      exec(1, 10);
      exec(2, 20);
    join_any
    $display("@%t fork-join_any exited", $time);
    $display("@%t fork-join_none entered", $time);
    fork
      exec(3, 30);
      exec(4, 40);
    join_none
    $display("@%t fork-join_none exited", $time);
    wait fork;
    $display("@%t ini_proc1 exited", $time);
  end
  
  initial begin
    #200;
  end
endmodule

1.2.6. disable fork

disable fork可以让当前initial内没有执行完的fork线程结束

module tb6;
  task automatic exec(int id, int t);
    $display("@%t exec[%0d entered]", $time, id);
    #t;
    $display("@%t exec[%0d exited]", $time, id);
  endtask

  initial begin: ini_proc1
    $display("@%t fork-join_any entered", $time);
    fork
      exec(1, 10);
      exec(2, 20);
    join_any
    $display("@%t fork-join_any exited", $time);
    $display("@%t fork-join_none entered", $time);
    fork
      exec(3, 30);
      exec(4, 40);
    join_none
    $display("@%t fork-join_none exited", $time);
    disable fork;
    $display("@%t ini_proc1 exited", $time);
  end
  
  initial begin
    #200;
  end
endmodule

在这里插入图片描述

1.2. 时序控制

  • SV可以通过延迟控制或者时间等待来对过程块完成时序控制
  • 延迟控制即通过#来完成
    #10 rega = regb;
  • 事件(event)控制即通过@来完成
    @r rega = regb;
    @(posedge clk) rega = regb;
  • wait语句也可以与事件或者表达式结合来完成
    real AOR[];
    initial wait(AOR.size() > 0) …;

posted on 2022-10-04 23:31  皮皮祥  阅读(111)  评论(0编辑  收藏  举报