电子说
sequence作为UVM几个核心机制之一,它有效地将transaction的产生从driver中剥离出来,并且通过和sequencer相互配合,成功地将driver的负担降低至仅聚焦于根据协议将transaction发送到接口上,而具体发送什么数据、数据有多少,则通通交给了sequence和sequencer解决。
对于发送数据,建立起了 sequence → sequencer → driver → interface → DUT 的单向数据传输通路。
但有时,sequence并不能着急产生数据,而需要根据driver对transaction的反应,或者说sequence需要接收到driver发出的”我准备好了,你可以根据我目前的情况决定下一笔发送什么数据了“的信号,再产生transaction发送给driver。此时就需要建立起 driver → sequencer → sequence的通路,通路中传输的信息即”rsp”。这是通过在driver中调用put_response( ),在sequencer中调用get_response( )实现的。同时,为了保证sequencer上有多个sequence时,rsp不会认错sequence,最好给rsp设置好id等信息。
下面是小杜今天遇到的场景:
通过SMBus转APB总线向DUT中发送read请求和address信息发送给DUT,DUT随后将目标地址的寄存器中的数据反向发送出来,并且当监测到rsp中某个关键信息满足特定条件时,即可停止仿真。
停止仿真可以通过调用系统函数$finish( )实现,但如何监测rsp中具体某一位数据呢?
首先我们需要确定rsp 的数据类型,可以通过systemverilog的系统函数$typename( )来查看:
task body;
...
get_response(rsp, req.get_transaction_id());
$display($typename(this.rsp));
...
endtask
打印结果:
class xxx.xxx_master_transaction
可以看到,返回的rsp是一个类,并且和我们发送的req是同一个类型。想一下也合理,req、rsp是建立在同一条数据通路上的,只是数据传输方向相反。即sequence sequencer driver interface DUT 是一条完整的双向数据通路。(这是小杜目前的理解,如有错误,还请批评指正)
下面是整个body( )代码:
task body;
//发送数据
`uvm_create_on(req, sequencer)
...//对req进行处理
`uvm_send(req)
//获取返回值并打印
get_response(rsp, req.get_transaction_id());
$display("rsp = ", rsp);
//监控并判断rsp的具体位,满足条件就停止仿真
if(rsp.data[x] == 'hxx) begin
$finish();
end
endtask: body
全部0条评论
快来发表一下你的评论吧 !