uvm driver、sequencer、sequence工作方式

参考:http://blog.eetop.cn/blog-1561828-5940197.html

1、driver&sequencer:

driver同sequencer之间的TLM通信采取了get模式,即由driver发起请求,从sequencer一端获得item,再由sequencer将其传递至driver。

1、由于driver是请求发起端,所以在driver一侧例化了下面的两种端口:

  • uvm_seq_item_pull_port #(REP, RSP) seq_item_port

  • uvm_analysis_port #(RSP) rsp_port

2、sequencer一侧则为请求的响应端,在sequencer一侧例化了与上面对应的两种端口:

  • uvm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export

  • uvm_analysis_export #(RSP) rsp_export

3、通常情况下,用户可以通过匹配的第一对TLM接口完成item的完整传送:

      即通过driver::seq_item_port.connect(sequencer::seq_item_export)完成。而这一种类型的TLM接口主要支持如下的方法:

  • task get_next_item(output REQ req_arg):采取blocking的方式等待从sequence获取下一个item。

  • task try_next_item(output REQ req_arg):采取nonblocking的方式从sequencer获取item,如果立即返回的结果req_arg为null,则表示sequence还没有准备好。

  • function void item_done(input RSP rsp_arg=null):用来通知sequence当前的sequence item已经消化完毕,可以有选择性地传递RSP参数,返回状态值。

  • task wait_for_sequences():等待当前的sequence直到产生下一个有效的item。

  • function bit has_do_available():如果当前的sequence准备好而且可以获取下一个有效的item,则返回1,否则返回0。

  • function void put_response(input RSP rsp_arg):采取nonblocking方式发送response,如果成功返回1,否则返回0。

  • task get(output REQ req_arg):采用get方式获取item。

  • task peek(output REQ req_arg):采用peek方式获取item。

  • task put(input RSP rsp_arg):采取blocking方式将response发送回sequence。

4、上面的这一类接口功能是主要用来做request获取和response返回的。读者们在这里需要了解的是,关于REQ和RSP类型的一致性。由于uvm_sequencer与uvm_driver实际上都是参数化的类:

  • uvm_sequencer #(type REQ=uvm_sequence_item,RSP=REQ)

  • uvm_driver #(type REQ=uvm_sequence_item, RSP=REQ)

5、用户在自定义sequencer或者driver的类型:

  • 它们可以使用缺省类型type REQ=uvm_sequence_item,以及RSP与REQ类型一致。同时这会带来一个潜在的类型转换要求,即driver得到REQ对象(uvm_sequence_item)在进行下一步处理时,需要进行动态的类型转换,将REQ转换为uvm_sequence_item的子类型才可以从中获取有效的成员数据;(driver中需要$cast的情况)
  • 而另外一种可行的方式是在自定义sequencer和driver时就标明了其传递的具体item类型,这样也就不用再进行二次的类型转换了。通常情况下,RSP类型与REQ类型保持一致,这么做的好处是为了便于统一处理,方便item对象的拷贝、修改等操作。

6、driver返回response:

  • 在driver消化完当前的request,即可以通过item_done(input RSP rsp_arg=null)方法来告知sequence此次传输已经结束,参数中的RSP可以选择填入,返回正确的状态值。
  • driver也可以单独通过put_response()或者put()方法来单独发送response。
  • 此外,发送response还可以通过成对的uvm_driver::rsp_port和uvm_driver::rsp_export端口来完成,方法为uvm_driver::rsp_port::write(RSP)来完成。

  • flat_seq作为动态创建的数据生成载体,在它的主任务flat_seq::body()中做了如下的几件事情:
  • 通过方法create_item()创建request item对象。

  • 调用start_item()准备发送item。

  • 在完成发送item之前对item进行随机处理。

  • 调用finish_item()完成item发送。

  • 有必要的情况下可以从driver那里获取response item。

  • 在定义sequencer时,默认了REQ类型为uvm_sequence_item类型,这与稍后定义driver时采取默认REQ类型保持一致。

  • 在定义driver时,在它的主任务driver::run_phase()中也应通常做出如下的处理:

    • 通过seq_item_port.get_next_item(REQ)从sequencer获取有效的request item。

    • 从request item中获取数据,进而产生数据激励。

    • 对request item进行克隆生成新的对象response item。

    • 修改response item中的数据成员,最终通过seq_item_port.item_done(RSP)将response item对象返回给sequence。

sequencer作为sequence与driver之间握手的桥梁:

 

 

posted on 2019-03-01 11:01  hematologist  阅读(2204)  评论(0编辑  收藏  举报

导航