这是关于“do”钩子函数系列的最后一篇文章。 do_record函数是由记录对象属性的uvm_object记录函数调用的用户可定义的钩子。
定义do_record
定义do_record不是很困难。我们来定义jelly_bean_transaction的do_record。我记录了与我在do_print中打印的属性相同的属性。我使用了UVM定义的记录宏(第14至19行)。
class jelly_bean_transaction extends uvm_sequence_item;
virtual function void do_print( uvm_printer printer );
super.do_print( printer );
printer.print_string( "name", get_name() );
printer.print_string( "flavor", flavor.name() );
printer.print_string( "color", color.name() );
printer.print_field_int( "sugar_free", sugar_free, .size( 1 ) );
printer.print_field_int( "sour", sour, .size( 1 ) );
printer.print_string( "taste", taste.name() );
endfunction: do_print
virtual function void do_record( uvm_recorder recorder );
super.do_record( recorder );
`uvm_record_string( "name", get_name() )
`uvm_record_string( "flavor", flavor.name() )
`uvm_record_string( "color", color.name() )
`uvm_record_int( "sugar_free", sugar_free, 1 ) // SIZE=1
`uvm_record_int( "sour", sour, 1 ) // SIZE=1
`uvm_record_string( "taste", taste.name() )
endfunction: do_record
// ...
endclass: jelly_bean_transaction
使用do_record
uvm_object的记录函数调用do_record。让我们在我们的jelly bean记分板中调用记录。记录功能将录制策略对象作为参数(第14行)。它是可选的,但除非指定,否则不进行记录。 UVM提供了名为uvm_text_recorder的默认记录器实现。第8至10行显示了如何获得这个默认记录器。
第8行获取UVM事务数据库(uvm_tr_database)的实例。 get_default_tr_database函数返回uvm_text_tr_database的一个实例,这是uvm_tr_database的默认实现。然后第9行在数据库中打开一个流。最后,第10行在流上打开一个新的事务记录器。
class jelly_bean_sb_subscriber extends uvm_subscriber#( jelly_bean_transaction );
uvm_tr_database tr_db;
uvm_tr_stream tr_strm;
uvm_recorder rec;
virtual function void build_phase( uvm_phase phase );
super.build_phase( phase );
tr_db = uvm_coreservice_t::get().get_default_tr_database();
tr_strm = tr_db.open_stream( "tr_strm" );
rec = tr_strm.open_recorder( "rec" );
endfunction: build_phase
function void write( jelly_bean_transaction t );
t.record( rec );
endfunction: write
// ...
endclass: jelly_bean_sb_subscriber
仿真
默认情况下,uvm_text_tr_database使用名为tr_db.log的文件进行记录。运行仿真之后,您应该得到这样的文本文件。
CREATE_STREAM @0 {NAME:tr_strm T: SCOPE: STREAM:2893}
OPEN_RECORDER @0 {TXH:2899 STREAM:2893 NAME:rec TIME:0 TYPE=""}
CREATE_STREAM @0 {NAME:jb_seq T:Transactions SCOPE:uvm_test_top.jb_env.jb_agent.jb_seqr STREAM:2957}
SET_ATTR @25 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @25 {TXH:2899 NAME:flavor VALUE:BUBBLE_GUM RADIX:UVM_STRING BITS=18}
SET_ATTR @25 {TXH:2899 NAME:color VALUE:RED RADIX:UVM_STRING BITS=11}
SET_ATTR @25 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @25 {TXH:2899 NAME:sour VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @25 {TXH:2899 NAME:taste VALUE:YUMMY RADIX:UVM_STRING BITS=13}
SET_ATTR @45 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @45 {TXH:2899 NAME:flavor VALUE:BUBBLE_GUM RADIX:UVM_STRING BITS=18}
SET_ATTR @45 {TXH:2899 NAME:color VALUE:RED RADIX:UVM_STRING BITS=11}
SET_ATTR @45 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @45 {TXH:2899 NAME:sour VALUE:0 RADIX:UVM_HEX BITS=1}
SET_ATTR @45 {TXH:2899 NAME:taste VALUE:YUMMY RADIX:UVM_STRING BITS=13}
SET_ATTR @65 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @65 {TXH:2899 NAME:flavor VALUE:BUBBLE_GUM RADIX:UVM_STRING BITS=18}
SET_ATTR @65 {TXH:2899 NAME:color VALUE:RED RADIX:UVM_STRING BITS=11}
SET_ATTR @65 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @65 {TXH:2899 NAME:sour VALUE:0 RADIX:UVM_HEX BITS=1}
SET_ATTR @65 {TXH:2899 NAME:taste VALUE:YUMMY RADIX:UVM_STRING BITS=13}
SET_ATTR @85 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @85 {TXH:2899 NAME:flavor VALUE:BUBBLE_GUM RADIX:UVM_STRING BITS=18}
SET_ATTR @85 {TXH:2899 NAME:color VALUE:RED RADIX:UVM_STRING BITS=11}
SET_ATTR @85 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @85 {TXH:2899 NAME:sour VALUE:0 RADIX:UVM_HEX BITS=1}
SET_ATTR @85 {TXH:2899 NAME:taste VALUE:YUMMY RADIX:UVM_STRING BITS=13}
SET_ATTR @105 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @105 {TXH:2899 NAME:flavor VALUE:CHOCOLATE RADIX:UVM_STRING BITS=17}
SET_ATTR @105 {TXH:2899 NAME:color VALUE:GREEN RADIX:UVM_STRING BITS=13}
SET_ATTR @105 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @105 {TXH:2899 NAME:sour VALUE:0 RADIX:UVM_HEX BITS=1}
SET_ATTR @105 {TXH:2899 NAME:taste VALUE:YUMMY RADIX:UVM_STRING BITS=13}
SET_ATTR @125 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @125 {TXH:2899 NAME:flavor VALUE:CHOCOLATE RADIX:UVM_STRING BITS=17}
SET_ATTR @125 {TXH:2899 NAME:color VALUE:GREEN RADIX:UVM_STRING BITS=13}
SET_ATTR @125 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @125 {TXH:2899 NAME:sour VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @125 {TXH:2899 NAME:taste VALUE:YUCKY RADIX:UVM_STRING BITS=13}
SET_ATTR @145 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @145 {TXH:2899 NAME:flavor VALUE:CHOCOLATE RADIX:UVM_STRING BITS=17}
SET_ATTR @145 {TXH:2899 NAME:color VALUE:BLUE RADIX:UVM_STRING BITS=12}
SET_ATTR @145 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @145 {TXH:2899 NAME:sour VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @145 {TXH:2899 NAME:taste VALUE:YUCKY RADIX:UVM_STRING BITS=13}
SET_ATTR @165 {TXH:2899 NAME:name VALUE:jb_tx RADIX:UVM_STRING BITS=13}
SET_ATTR @165 {TXH:2899 NAME:flavor VALUE:CHOCOLATE RADIX:UVM_STRING BITS=17}
SET_ATTR @165 {TXH:2899 NAME:color VALUE:BLUE RADIX:UVM_STRING BITS=12}
SET_ATTR @165 {TXH:2899 NAME:sugar_free VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @165 {TXH:2899 NAME:sour VALUE:1 RADIX:UVM_HEX BITS=1}
SET_ATTR @165 {TXH:2899 NAME:taste VALUE:YUCKY RADIX:UVM_STRING BITS=13}
为了您的参考,这些是我在本文中使用的类。
UVM recorder类图
您可以在EDA Playground上查看并运行代码。