UVM Tutorial for Candy Lovers – 35. Defining do_record

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). The get_default_tr_database funtion returns an instance of uvm_text_tr_database, which is the default implementation for the uvm_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.

UVM recorder classes
UVM recorder classes

EDA Playground

You can view and run the code on EDA Playground.

Leave a Reply