2.2 event_pool
前言
本文章以uvm-1.2/examples/simple/basic_examples/event_pool为例,简单介绍uvm_event_pool的创建和打印,另外通过参考这个例子,可以学习到如何判断测试用例是否pass,并向log文件中,写入测试用例pass或者fail的关键字。
一、基本介绍
uvm_event_pool顾名思义,就是存放uvm_event事件的一个池子。
这个测试用例创建的uvm_event_pool如下所示。
-------------------------------------------------
Name Type Size Value
-------------------------------------------------
ep uvm_obj_str_pool - -
pool aa_object_string 2 -
[fred] uvm_event - -
num_waiters int 32 'd0
on bit 1 'b0
trigger_time time 64 0
trigger_data object - -
[george] uvm_event - -
num_waiters int 32 'd0
on bit 1 'b0
trigger_time time 64 0
trigger_data object - -
-------------------------------------------------
二、代码分析
这个测试用例只有一个代码文件。
1、test.sv
测试文件test.sv代码如下所示。
/*
About: 'ep' event poll
This test is a simple test that will cover the creation of two uvm_events using the uvm_event_pool. Then use the uvm_event_pool methods to print those objects.
For a full documentation of the uvm_event and uvm_event_pool, check the files:
- uvm/src/base/uvm_event.svh
- uvm/src/base/uvm_event.sv
*/
module test;
import uvm_pkg::*;
uvm_event_pool ep=new("ep");
initial begin static uvm_coreservice_t cs_ = uvm_coreservice_t::get();
uvm_event e;
e = ep.get("fred");
e = ep.get("george");
uvm_default_table_printer.knobs.reference = 0;
ep.print();
begin
uvm_report_server svr;
svr = cs_.get_report_server();
svr.summarize();
if (svr.get_severity_count(UVM_FATAL) +
svr.get_severity_count(UVM_ERROR) == 0)
$write("** UVM TEST PASSED **\n");
else
$write("!! UVM TEST FAILED !!\n");
end
end
endmodule
第16行,新建一个ep命名的uvm_event_pool;
第18行,获取一个单例的UVM通用服务;
uvm_coreservice_t
The singleton instance of uvm_coreservice_t provides a common point for all central uvm services such as uvm_factory, uvm_report_server, … The service class provides a static ::get which returns an instance adhering to uvm_coreservice_t the rest of the set_< facility> get_< facility> pairs provide access to the internal uvm services
Custom implementations of uvm_coreservice_t can be included in uvm_pkg:: * and can selected via the define UVM_CORESERVICE_TYPE. They cannot reside in another package.
第21和22行,分别通过调用uvm_event_pool的get函数,建立fred和george这两个uvm_event事件,放入ep中。
第24行,调用打印函数,将ep中的信息打印出来。
第27和28行,通过18行get到的通用服务,获取到report服务的句柄。
第30行,打印report。
第32到36行,通过调用get_severity_count函数,获取report中UVM_ERROR和UVM_FATAL的总和是否为0,如果为0则打印pass关键字,否则打印fail关键字。
2、仿真结果
-------------------------------------------------
Name Type Size Value
-------------------------------------------------
ep uvm_obj_str_pool - -
pool aa_object_string 2 -
[fred] uvm_event - -
num_waiters int 32 'd0
on bit 1 'b0
trigger_time time 64 0
trigger_data object - -
[george] uvm_event - -
num_waiters int 32 'd0
on bit 1 'b0
trigger_time time 64 0
trigger_data object - -
-------------------------------------------------
UVM_INFO ../../../../src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 1
UVM_WARNING : 0
UVM_ERROR : 0
UVM_FATAL : 0
** Report counts by id
[UVM/RELNOTES] 1
** UVM TEST PASSED **
总结
通过这个测试用例,有两个知识点是比较有借鉴意义的:第一,如何创建一个uvm_event_pool并往其中放入uvm_event事件,同时打印出来,便于观察和debug;第二,通过获取uvm单例的服务句柄,进一步得到report的句柄,再调用get_severity_count函数,筛查并判断UVM_FATAL和UVM_ERROR的个数,从而往log中写入pass或者fail的关键字。
关于上述的第二点再强调一下,可能测试用例不多的时候,这个功能看起没什么用,但是当测试用例几十上百个的时候,特别到了到后期跑测试用例的回归,这个功能就比较有用了,不用每个log文件都打开看一遍,直接通过简单的脚本grep一下log中的关键字,就可以快速判断这些case是否pass。
这里附上grep的脚本供参考:
mkdir check_log
cd check_log
rm pass.log fail.log
grep -r "** UVM TEST PASSED **" ../*/vcs.log > pass.log
grep -r "!! UVM TEST FAILED !!" ../*/vcs.log > fail.log
gvim -p pass.log fail.log