pipeline高端玩法—看下FlushNext的用法

描述

看完了flush,再看下flushNext的用法

》flushNext     

在Stage里,有关flushNext提供的API有:

def flushNext() : Unit = flushNext(ConditionalContext.isTrue)

def flushNext(cond : Bool) : Unit = internals.request.flushNext += cond

调用flushNext,最终会将flushNext的需求暂存到internals.request.flushNext中。

在Pipeline中,propagateRequirements函数中对于每一级Stage的处理:

var flushNext = stage.internals.request.flushNext.nonEmpty generate orR(stage.internals.request.flushNext)

如果flushNext不为空,则将所有条件或后得到flushNext电路对象。   

仿真器

在上面的这段描述中,针对驱动当前Stage的Conntection处理,flushNext电路将会被存储在clFlushNext(l)中。如果flushNext不为空(line:5),可以看到在line7:9行处理时,不管flush是存在,都会创建一个flush电路对象,也就意味着一般情况下flush,flushNext不需要同时使用。

而在line11:14中,以M2S为例,alwasContainsSlaveToken为True,会将flushNext清空。此时在line16:17时,仅会对驱动当前Stage的Stage Master调动flushIt函数,也就意味着flushNext将会向前传播,前级相当于执行flushIt。

clFlushNext的使用仅在Connection中使用到。还是以M2S为例,其处理逻辑为:

if(flushNext != null && !flushPreserveInput) s.valid clearWhen(flushNext && s.ready)

在这里,如果flushNext不为空(flushPreserveInput默认为true),s.valid仅会在slave端ready和flushNext同时为高时才会清零。对比flush操作:

if (flush != null && !flushPreserveInput) s.valid clearWhen(flush)

也就意味着flushNext存在ready的情况下才具有意义。

》example

结合上面的分析,flushNext与flush的最大区别在于存在ready传播的情况。这里先给出一个flsuhIt的例子:

仿真器

这里是一个三级pipeline,最后一级调用flushIt操作,flushRoot参数传递为true。

采用下面的仿真代码:

仿真器

我们这里在index==5时将cond拉高一拍,data_out.ready拉低一拍。

仿真波形如下:

仿真器

可以看到,由于这里流水线为3级,在index=5时执行flush数据3,4,5不会从data_out有效输出。

将flushRoot参数修改为false:

仿真器

cond为高时data_out.valid仍然为高电平,下一个时钟周期拉低。虽然此时ready为低电平,这个数据没有被消耗,但其拉低时间不考虑ready信号的高低电平。

再将上面的代码换成flushNext:

仿真器

可以看到,虽然cond为高,但其仍会坚持将此时已经传播到stage2的3给稳定传输出去,仅有4,5不会被data_out输出。






审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分