UVM的seq/sqr/driver是紧密相连的,从user的角度来看,有一套common的模板,user就只管用就行了。
很多时候,我就只是只知道怎么用,并不清楚里面的实现机制,一旦出现不常见的bug时,就只能干瞪眼,所以作为一名IC验证工程师是十分有必要了解一下源码的。
TLM相关的东西,我们先不详细讲解。
公共模板
- seq_item_port.get_next_item(req):向seqr发送请求seq
- rsp/req都是在uvm_sequence里面已经定义好的
- rsp.set_id_info(req):设置对应的id信息
- seq_item_port.put_response(rsp):将rsp传递给seq
- seq_item_port.item_done():表示发送完成
-
get_response(rsp):获得从driver传送的rsp
-
在顶层将drv.seq_item_port与sqr.seq_item_export连接起来
response handler 的使用
在driver中的put_response与seq中的get_response是成对存在的,也就是说,seq中要get driver中的put,是阻塞的。
- put_response会response_queue.push_back
- get_response会response_queue.pop_front,如果队列为空的话,就会一直等待,从而是阻塞的。
可以使用response handler来处理这种阻塞问题。response handler实际上是只调用了driver一侧的put_response,但是在seq一侧又预留了接口,用于处理response。
- driver中照样进行put_response,但是在seq中不用get_response,而是使用response_handler.
- response_handler的调用是在put_response中由driver调起来,调到seq中实现的,所以就没有get_response,但是在seq一段又能看到driver来的response。这样的会就没有了阻塞的问题
前面我们说过,seq的启动的方式,有三种,但其实他们的本质上都是调用了uvm_sequence_item的start函数,start函数里面的body()task就是一个callback函数。所以user在应用的时候,都会在body里面进行重写。