UVM Tutorial for Candy Lovers – 5. Environment

This post will provide a continued explanation on the rest of the verification components.

Subscribers

Functional Coverage

The functional coverage subscriber (jelly_bean_fc_sucbscriber) identifies the generated jelly beans to take a total tally. The jelly_bean_transaction sent from the monitor is sampled by the write function on the line 21, and takes the cross coverage of the flavor, color, and other characteristics of the jelly bean.

class jelly_bean_fc_subscriber extends uvm_subscriber#(jelly_bean_transaction);
   `uvm_component_utils(jelly_bean_fc_subscriber)
 
   jelly_bean_transaction jb_tx;
 
   covergroup jelly_bean_cg;
      flavor_cp:     coverpoint jb_tx.flavor;
      color_cp:      coverpoint jb_tx.color;
      sugar_free_cp: coverpoint jb_tx.sugar_free;
      sour_cp:       coverpoint jb_tx.sour;
      cross flavor_cp, color_cp, sugar_free_cp, sour_cp;
   endgroup: jelly_bean_cg
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
      jelly_bean_cg = new;
   endfunction: new
 
   function void write(jelly_bean_transaction t);
      jb_tx = t;
      jelly_bean_cg.sample();
   endfunction: write
endclass: jelly_bean_fc_subscriber

Scoreboard

In the functional coverage subscriber, the jelly_bean_transaction was sampled in the write function. Similar to the functional coverage subscriber, focus on the write function is the key. The scoreboard subscriber uses the write function to call the check_jelly_bean_taste function in the parent component (jelly_bean_scoreboard). This check_jelly_bean_taste function compares the DUT response against the expected response.

typedef class jelly_bean_scoreboard;
 
class jelly_bean_sb_subscriber extends uvm_subscriber#(jelly_bean_transaction);
   `uvm_component_utils(jelly_bean_sb_subscriber)
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
   endfunction: new
 
   function void write(jelly_bean_transaction t);
      jelly_bean_scoreboard jb_sb;
 
      $cast( jb_sb, m_parent );
      jb_sb.check_jelly_bean_taste(t);
   endfunction: write
endclass: jelly_bean_sb_subscriber

The check_jelly_bean_taste function expects the DUT module to “respond negatively to the sour chocolate-flavor jelly bean, while reacting positively to the other combinations.” When the DUT responds properly, the jelly-bean flavor and color are printed. When the DUT is not functioning correctly, the function will print an error message.

class jelly_bean_scoreboard extends uvm_scoreboard;
   `uvm_component_utils(jelly_bean_scoreboard)
 
   uvm_analysis_export#(jelly_bean_transaction) jb_analysis_export;
   local jelly_bean_sb_subscriber jb_sb_sub;
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
   endfunction: new
 
   function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      jb_analysis_export = new( .name("jb_analysis_export"), .parent(this));
      jb_sb_sub = jelly_bean_sb_subscriber::type_id::create(.name("jb_sb_sub"), .parent(this));
   endfunction: build_phase
 
   function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);
      jb_analysis_export.connect(jb_sb_sub.analysis_export);
   endfunction: connect_phase
 
   virtual function void check_jelly_bean_taste(jelly_bean_transaction jb_tx);
      uvm_table_printer p = new;
      if (jb_tx.flavor == jelly_bean_transaction::CHOCOLATE && jb_tx.sour) begin
         if (jb_tx.taste == jelly_bean_transaction::YUCKY) begin
            `uvm_info("jelly_bean_scoreboard",
                       { "You have a good sense of taste.\n", jb_tx.sprint(p) }, UVM_LOW);
         end else begin
            `uvm_error("jelly_bean_scoreboard",
                        { "You lost sense of taste!\n", jb_tx.sprint(p) });
         end
      end else begin
         if (jb_tx.taste == jelly_bean_transaction::YUMMY) begin
            `uvm_info("jelly_bean_scoreboard",
                       { "You have a good sense of taste.\n", jb_tx.sprint(p) }, UVM_LOW);
         end else begin
            `uvm_error("jelly_bean_scoreboard",
                        { "You lost sense of taste!\n", jb_tx.sprint(p) });
         end
      end
   endfunction: check_jelly_bean_taste
endclass: jelly_bean_scoreboard

Many consider it a hassle to create a separate scoreboard class. In our case, it may be more straightforward to check expected response in the jelly_bean_sb_subscriber, because the expected response is created from the inside. Yet, there are times when two analysis ports are necessary, one for expected data and the other for actual data. The write function of a subscriber does not support multiple analysis ports. One solution to this problem is to develop a scoreboard class with two subscribers. Thinking about the extendability in the future, creating two layers like our scoreboard might be a good idea.

Environment

To provide a conclusion, this section will explain the verification environment that contains all the verification components. Simply stated, the environment connects the previously explained agent and the subscribers. Taking a look at the first post of the series will help better understand this concept.

class jelly_bean_env extends uvm_env;
   `uvm_component_utils(jelly_bean_env)
 
   jelly_bean_agent         jb_agent;
   jelly_bean_fc_subscriber jb_fc_sub;
   jelly_bean_scoreboard    jb_sb;
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
   endfunction: new
 
   function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      jb_agent  = jelly_bean_agent::type_id::create(.name("jb_agent"), .parent(this));
      jb_fc_sub = jelly_bean_fc_subscriber::type_id::create(.name("jb_fc_sub"), .parent(this));
      jb_sb     = jelly_bean_scoreboard::type_id::create(.name("jb_sb"), .parent(this));
    endfunction: build_phase
 
   function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);
      jb_agent.jb_ap.connect(jb_fc_sub.analysis_export);
      jb_agent.jb_ap.connect(jb_sb.jb_analysis_export);
   endfunction: connect_phase
endclass: jelly_bean_env

The next post will show the anticipated test using these components.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章