前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【011】Verilog Task Concurrent Activation

【011】Verilog Task Concurrent Activation

作者头像
icsoc
发布2020-07-06 15:09:17
3820
发布2020-07-06 15:09:17
举报
文章被收录于专栏:ICSOC.TECHICSOC.TECH

最近做一个模块级的仿真,需要在两个过程中反复调用同一个Task。这种场景还是比较常见的,比如一个过程作为普通的配置过程,一个作为中断服务过程,这个Task可以是寄存器读或写。在某些Case下,发现该Task的防止并发执行的逻辑并不能正常工作。于是做了些阅读和实验,弥补了一下自己在Task并发执行上的知识漏洞。

先来个不符合预期的例程和运行结果。

从运行结果可以看到,task<1>、<2>、<3>均没有正常结束,都被task<4>覆盖掉了。什么原因呢?在Verilog标准IEEE.1363-2005里有这样的解释:

All variables of a static task shall be static in that there shall be a single variable corresponding to each declared local variable in a module instance, regardless of the number of concurrent activations of the task. Variables declared in static tasks, including input, output, and inout type arguments, shall retain their values between invocations.

对应上述的例程,就是在static task test中,输入端口id这个参数是静态的,无论task被调用多少次,只保留一份参数。所以参数的最终取值决定于最后一次调用时传入的值。这样就可以理解为什么每次结束时,打印出的id都是4了。

如何解决这种并发性调用,有两个思路。一个思路是建立一个类似Command FIFO的机制,每个过程中对task的调用都往同一个FIFO里写,然后按FIFO的出口顺序执行。这样似乎从逻辑上根本上解决了并发的问题,回避了Verilog的语法解释问题。另一个思路就是Verilog标准提供的Automatic Task,在标准中是这样描述的:

All variables of an automatic task shall be replicated on each concurrent task invocation to store state specific to that invocation.

就是Verilog自动为task的每次调用分配独立的变量空间,做到互不干扰。

下面是采用第二种思路的例程和运行结果。

代码中,只有第33行有变动,添加了automatic关键字。

运行结果却完全不同,对task的四次调用都互不干扰了。但是也注意到task<2>、<3>、<4>的执行顺序却和调用顺序不同,应该容易理解,这是task调用的栈机制导致的。把task<2>、<3>、<4>压入栈,出栈时顺序自然相反了。

这也说明,只依靠Verilog自身的语法,对于并发性的控制是不理想的,有时甚至是完全不符合预期的。还是需要从逻辑上来根本解决。

在Verilog标准中,还提到:

However, static tasks in different instances of a module shall have separate storage from each other.

现在进一步实验,先把之前的task放入一个module中,这样test_num、test_busy就成了该module的instance之间独立的变量。

然后在testbench中例化两次这个module,并分别调用这两个module instance中的相同task。

运行结果也证明了这点,test_num在module instance之间独立变化。只不过因为仍是static task,所以每个module的多次task调用存在覆盖的问题。

把static task改为automatic task后的运行结果如下,符合期望。但是出栈顺序导致执行顺序与调用顺序不符。

很有意思,对吧?

最后附上标准中的一段话作为结尾。

The keyword automatic declares an automatic task that is reentrant with all the task declarations allocated dynamically for each concurrent task entry. Task item declarations can specify the following:

  • Input arguments
  • Output arguments
  • Inout arguments
  • All data types that can be declared in a procedural block
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 icsoc 微信公众号,前往查看

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

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

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