前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >disable fork,你真的会用吗?

disable fork,你真的会用吗?

作者头像
IC验证
发布2020-06-30 11:37:37
3.2K0
发布2020-06-30 11:37:37
举报
文章被收录于专栏:杰瑞IC验证

来源| 杰瑞IC验证(ID:Jerry_IC) |原创作者| Q哥

前面几篇文章给大家讲解了如何使用fork创建多进程。SystemVerilog允许大家在使用fork + join/join_any/join_none创建进程之后,通过disable fork来提前结束这些进程。

例如下面的代码片段1,fork + join_any产生了两个并行的子进程:

第一个子进程等待valid信号,然后打印第12行的信息;

第二个子进程等待max_delay个ns,然后打印第16行的信息。

不论是哪一种结果,都会导致join_any跳出fork,接着执行disable fork来结束这个fork进程及其子进程。

代码片段1

这个task在等待valid的同时,为了避免长时间等待,加了一个超时机制。不论是等到valid,还是超时了,都不必再等待另一个子进程继续执行下去。这段代码乍一看好像没什么问题啊?

别急,继续往下看。

假如还有另一个task B,需要在启动task A之前启动,常见的做法就是先fork + join_none的方式启动B,再启动A。

如下面代码片段2所示。

代码片段2

执行task C,会惊奇的发现:不论task A里面是否wait valid成功,当执行后面的disable fork之后,task B始终都没有打印第27行的信息?

为什么会这样?是不是开始怀疑人生了?

别急,这是因为当disable fork的时候,不仅杀掉了task A里面的fork进程,连task C里面的fork/join_none进程也杀死了。disable的杀伤力,远远超出了想象,有没有?

不是我不小心,只是……

要避免这样的误杀,办法其实很多。最常见的做法是添加所谓的guard fork,来限制disable fork的作用范围。

如下面的代码片段3所示:

代码片段3

还有一种不太好做法是给fork的进程添加别名,然后disable这个指定的进程,如下面的代码片段4所示:

代码片段4

这种做法看似也OK,但是会引入另外一种风险。思考一下,不知道你是否猜到了?

Q哥带你揭晓答案。

如下面所示的代码片段5,task D里面通过fork join同时启动了两个调用task A的子进程并行执行。当调用A(1000)执行到disable p1的时候,会惊奇地发现,A(2000)也被意外地终结了。

代码片段5

给fork进程命名,弄巧成拙了。推荐大家还是使用guard fork,这是一种良好的coding style。

——The End——

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杰瑞IC验证 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档