你的 disable fork 用的对吗?

我们先来看一段代码:

timescale 1ns/1ps;

task jobs();

    fork
        begin
            #10;
            $display("delay 10ns");
        end
        begin
            #20;
            $display("delay 20ns");
        end
     join_any
     disable_fork
endtask 

这个简单的 fork  join_any 会在 打印 “delay 10ns” 这句话之后结束整个 fork join_any 逻辑。这个例子简单,我们接着往下看:

timescale 1ns/1ps;

task job_delay_200ns();
    #200ns;
    $display("job_delay_200ns end");
endtask

task jobs_test();
    fork
        job_delay_200ns();
    join_none

    jobs();
endtask

根据fork join_none的语法,我们知道 job_delay_200ns() 和 jobs(),会同时执行,当打印 “delay 10ns” 这句话之后,按我们的理解,应该再延迟190ns,就应该打印“job_delay_200ns end” 这句话,但实际上会打印这句话吗?大家可以去跑一个简单的case,测试一下,实际上经过测试,永远都不会打印“job_delay_200ns end”,这是为什么呢?

  这块就涉及到disable fork的作用范围了, disable fork的作用范围是当前线程的子线程,以及子线程的子线程,子子孙孙全被终结。

从这个jobs_test 的task能看出来,在整个task内,fork join_none  和 jobs() 在一个线程内,这样就相当于 处于job_delay_200ns 这个task 处于 jobs内 disable fork的子线程的位置上,因此也会受到disable fork的影响。

这里有一个很简单的办法,来避免这种误杀,请看代码:

timescale 1ns/1ps;

task jobs();
    fork : guard_fork
        begin
            fork
                 begin
                     #10;
                     $display("delay 10ns");
                 end
                 begin
                     #20;
                     $display("delay 20ns");
                 end
             join_any
             disable fork
        end
    join : guard_fork
endtask 

这样处理的结果类似于把 jobs 内部分disable fork在降一级,相当于 和  job_delay_200ns()内的 fork join_none 平级了,因此也消除了disable fork对其的影响。

还有一种方法,是给dsiable fork起名字,比如说  disable : xxxxx_fork,这样指定也是可以的,如果你讲这个fork 封装在了task内,并且会调用多次这个task时,你会发现 disable 一旦生效,所有task内的线程都结束了,也不是最好的解决办法。最好的办法还是采用第一种,给带disable 的fork套上套子,让他限定在fork join 内权力不要外溢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值