UVM Tutorial for Candy Lovers – 31. Provides Responses?

This is a short article about when we should set the provides_responses bit of the register adapter.

Original Jelly Bean Driver

This is the orignal jelly_bean_driver used in Register Abstraction. The driver gets requests using get_next_item (line 23), then updates the request itself to store the response from the DUT (line 33). Finally, it calls item_done (line 35). Since the driver does not return separate responses, we set the provides_responses of jelly_bean_reg_adapter to be zero.

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
class jelly_bean_driver extends uvm_driver#( jelly_bean_transaction );
   `uvm_component_utils( jelly_bean_driver )
 
   virtual jelly_bean_if jb_if;
 
   function new( string name, uvm_component parent );
      super.new( name, parent );
   endfunction: new
 
   function void build_phase( uvm_phase phase );
      super.build_phase( phase );
   endfunction: build_phase
 
   task main_phase( uvm_phase phase );
      jelly_bean_transaction jb_tx;
 
      forever begin
         @jb_if.master_cb;
         jb_if.master_cb.command < = jelly_bean_types::NO_OP;
         jb_if.master_cb.color   <= jelly_bean_types::NO_COLOR;
         jb_if.master_cb.flavor  <= jelly_bean_types::NO_FLAVOR;
 
         seq_item_port.get_next_item( jb_tx ); // get the request         @jb_if.master_cb;
         jb_if.master_cb.command <= jb_tx.command;
         if ( jb_tx.command == jelly_bean_types::WRITE ) begin
            jb_if.master_cb.flavor     <= jb_tx.flavor;
            jb_if.master_cb.color      <= jb_tx.color;
            jb_if.master_cb.sugar_free <= jb_tx.sugar_free;
            jb_if.master_cb.sour       <= jb_tx.sour;
         end else if ( jb_tx.command == jelly_bean_types::READ ) begin
            @jb_if.master_cb;
            jb_tx.taste = jelly_bean_types::taste_e'( jb_if.master_cb.taste ); // update the request itself         end
         seq_item_port.item_done();      end
   endtask: main_phase
endclass: jelly_bean_driver

Driver That Returns Separate Responses

If the provides_responses is one, I would rewrite the driver as follows. (Usually this would be the other way around; if the driver provides separate responses, then we set the provides_responses to be one.)

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
class jelly_bean_driver extends uvm_driver#( jelly_bean_transaction );
   `uvm_component_utils( jelly_bean_driver )
 
   virtual jelly_bean_if jb_if;
 
   function new( string name, uvm_component parent );
      super.new( name, parent );
   endfunction: new
 
   function void build_phase( uvm_phase phase );
      super.build_phase( phase );
   endfunction: build_phase
 
   task main_phase( uvm_phase phase );
      jelly_bean_transaction jb_tx;
      jelly_bean_transaction jb_rsp; 
      forever begin
         @jb_if.master_cb;
         jb_if.master_cb.command < = jelly_bean_types::NO_OP;
         jb_if.master_cb.color   <= jelly_bean_types::NO_COLOR;
         jb_if.master_cb.flavor  <= jelly_bean_types::NO_FLAVOR;
 
         seq_item_port.get( jb_tx );     // get the request         $cast( jb_rsp, jb_tx.clone() ); // create a response         jb_rsp.set_id_info( jb_tx );    // copy the sequence_id and the transaction_id 
         @jb_if.master_cb;
         jb_if.master_cb.command <= jb_tx.command;
         if ( jb_tx.command == jelly_bean_types::WRITE ) begin
            jb_if.master_cb.flavor     <= jb_tx.flavor;
            jb_if.master_cb.color      <= jb_tx.color;
            jb_if.master_cb.sugar_free <= jb_tx.sugar_free;
            jb_if.master_cb.sour       <= jb_tx.sour;
         end else if ( jb_tx.command == jelly_bean_types::READ ) begin
            @jb_if.master_cb;
            jb_rsp.taste = jelly_bean_types::taste_e'( jb_if.master_cb.taste ); // update the response         end
         seq_item_port.put( jb_rsp ); // return the response      end
   endtask: main_phase
endclass: jelly_bean_driver

The driver gets the request using get (line 24), then clones the request to create a separate response (lines 25 and 26). The set_id_info function copies some IDs from the request to the response so that the sequencer can route the response back to the originating sequence. Finally, the driver updates the response (line 37) and returns it to the sequencer (line 39). Hope this helps.

2 thoughts on “UVM Tutorial for Candy Lovers – 31. Provides Responses?”

  1. To provide the responses back to sequence, shouldn’t we use item_done ?
    Please let me know what is the better approach.

Leave a Reply