线程控制 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) …;
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值