This is the last article about the “do” hook series. The do_record
function is the user-definable hook called by the record
function of uvm_object
which records the object properties.
Defining do_record
Defining do_record
is not very difficult. Let’s define the do_record
for the jelly_bean_transaction
. I recorded the same properties as I printed in the do_print
. I used the recording macros UVM defined (the lines 14 to 19).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
Using do_record
The record
function of uvm_object
calls the do_record
. Let’s call the record
in our jelly bean scoreboard. The record
function takes a recording policy object as the argument (line 14). It is optional, but unless it is specified, no recording takes place. UVM provides the default recorder implementation called uvm_text_recorder
. The lines 8 to 10 show how to get this default recorder.
The line 8 gets an instance of UVM transaction database (
uvm_tr_database
). Theget_default_tr_database
funtion returns an instance ofuvm_text_tr_database
, which is the default implementation for theuvm_tr_database
. Then the line 9 opens a stream within the database. Finally, the line 10 opens a new transaction recorder on the stream.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
Simulation
By default, uvm_text_tr_database
uses a file named tr_db.log
to record. After running a simulation, you should get a text file like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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} |
For your reference, these are the classes I used in this article.
You can view and run the code on EDA Playground.