pipeline高端玩法—haltIt介绍(九)

电子说

1.3w人已加入

描述

编 者 按

来看下Pipeline中HaltIt的用法

HaltIt

看名字,就基本能猜到这个函数的大体功能是流水线暂停。

在Stage中,流水线暂停提供了这么几个API:

def haltIt()(implicit loc: Location) : Unit = haltIt(ConditionalContext.isTrue)def haltIt(cond : Bool)(implicit loc: Location) : Unit = internals.request.halts += nameFromLocation(CombInit(cond), "haltRequest")def haltWhen(cond : Bool)(implicit loc: Location) : Unit = haltIt(cond)

三个API最终所实现的都是往internals.request.halts中添加cond条件。那么就看下request.halts在Pipeline构建时所起的作用。

首先,在进行 connectionsWithoutSinks(没有驱动其他级Stage)往前遍历的函数propagateRequirements中:

if(stage.request.halts.nonEmpty){    stage.arbitration.propagateReady = true    stage.isReady //Force creation}

可以看到,如果stage中的internals.request.halts非空,这里做了两件事:

  • stage.arbitration.propagateReady设置为true,即需向前级Stage传递Ready信号
  • 为本级创建input.ready信号

随后在propagateRequirements中的代码片段:

stageDriver.get(stage) match {        case Some(c : ConnectionModel) = > {          if(c.s.arbitration.propagateReady && c.m.output.ready == null){            c.m.output.ready = Bool()            if(c.m.input.ready == null){              c.m.input.ready = Bool()            }          }

这里在处理当前Stage中的ConnectionLogic时,因为当前stage.arbitration.propagateReady为true,如果驱动当前Stage的Master Stage的output.ready为空,那么这里就会确保Master Stage中具备input.ready以及output.ready,确保上级Stage具备这种握手机制。

而后在该函数中的递归调用:

for(m < - stageMasters(stage)){    if(stage.internals.arbitration.propagateReady) m.internals.arbitration.propagateReady = true    propagateRequirements(m)}

这里如果当前stage如果存在stage.arbitration.propagateReady为true,那么也会设置其Master Stage的.arbitration.propagateReady为true,通过递归调用,确保整个链路上ready信号一直向前传播,即确保反压一路到底。

最后,在处理Stage Internal Connection阶段时:

if(s.request.halts.nonEmpty){    val doHalt = s.request.halts.orR    when(doHalt){        s.input.ready := False        s.output.valid := False    }}

如果当前Stage中request.halts中条件满足,那么当前stage中的output.valid,input.ready信号将会统一拉低,从而暂停向下级传输。

Example

case class Test8() extends Component{  val io=new  Bundle{    val data_in=slave(Stream(UInt(8 bits)))    val data_out=master(Stream(UInt(8 bits)))    val cond=in Bool()  }  noIoPrefix()  val A=Stageable(UInt(8 bits))  val pip=new Pipeline{    val stage0=new Stage{      this.driveFrom(io.data_in)      A:=io.data_in.payload    }    val stage1=new Stage(Connection.M2S()){    }    val stage2=new Stage(Connection.M2S()){      io.data_out.valid:=this.internals.output.valid      io.data_out.payload:=A      internals.output.ready=Bool()      this.haltIt(io.cond)      internals.output.ready:=io.data_out.ready      this.internals.arbitration.propagateReady=true    }  }  pip.build()}

这里给出了一个haltIt的example。在staeg2阶段,如果cond为true,那么则流水线暂停。

这里需注意的是这里将stage2的output.ready由io.data_out.ready信号进行驱动,但output.ready信号是默认不会创建的,故这里显示创建internals.output.ready为Bool类型电路对象。

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

全部0条评论

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

×
20
完善资料,
赚取积分