How to integrate the UVM scoreboard

The UVM scoreboard is easily integrated into your existing testbench environment.

Compiling the UVM scoreboard

To get the UVM scoreboard compiled you need to add src/pk_syoscb.sv to your list of files that are complied when compiling your testbench. How this is done is highly dependent on the verification environment since some environments compile everything into different libraries and some do not etc.

Accessing the UVM scoreboard from your own code

Once the UVM scoreboard is compiled with the verification environment then it is accessible either by explicit scoping:

   class myclass;
     pk_syoscb::cl_syoscb my_new_scb;
     ...

or by importing the complete package into your scope:

   import pk_syoscb::*;

   class myclass;
     cl_syoscb my_new_scb;
     ...

Instantiating the UVM scoreboard

The UVM scoreboard itself needs to be instantiated along with the configuration object. The simplest way to to this is to add the UVM scoreboard and the configuration object to the UVM environment - note that the configuration object is passed to the scoreboard via the config_db:

   import pk_syoscb::*;

   class cl_scbtest_env extends uvm_env;

     cl_syoscb     syoscb;   
     cl_syoscb_cfg syoscb_cfg;
    
     `uvm_component_utils_begin(cl_scbtest_env)
       `uvm_field_object(syoscb,     UVM_ALL_ON)
       `uvm_field_object(syoscb_cfg, UVM_ALL_ON)
     `uvm_component_utils_end
    
     ... 

   endclass: cl_scbtest_env

   function void cl_scbtest_env::build_phase(uvm_phase phase);
     super.build_phase(phase);
   
     // Create the scoreboard configuration object
     this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");

     // Pass the scoreboard configuration object to the config_db
     uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);

     // Create the scoreboard
     this.syoscb = cl_syoscb::type_id::create("syoscb", this);
   
     ...
               
   endfunction: build_phase

Configuring the UVM scoreboard

The UVM scoreboard configuration object needs to be configured after it has been created. The following example shows how two queues Q1 and Q2 wit Q1 as the primary queue. Furthermore, one producer P1 is added to both queues:

   function void cl_scbtest_env::build_phase(uvm_phase phase);
     super.build_phase(phase);
   
     // Create the scoreboard configuration object
     this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");

     // Configure the scoreboard
     this.syoscb_cfg.set_queues({"Q1", "Q2"});
     void'(this.syoscb_cfg.set_primary_queue("Q1")); 
     void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"})); 

     // Pass the scoreboard configuration object to the config_db
     uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);

     // Create the scoreboard
     this.syoscb = cl_syoscb::type_id::create("syoscb", this);
               
     ...

   endfunction: build_phase

Function based API hook up

The function based API is very easy to use once you have done the configuration and instantiation of the scoreboard as describe above.

Whenever you need to add an UVM sequence item to a queue produced by a specified producer then you simply invoke the cl_syoscb::add_item() method:

   // *NOTE*: Assumes syoscb is handle to an instance of the scoreboard and
   //         item1 is a handle to a UVM sequence item

   ...

   // Insert UVM sequence item for queue: Q1, for producer: P1
   syoscb.add_item("Q1", "P1", item1);

Invoking the cl_syoscb::add_item() method will simply wrap the UVM sequence item in a cl_syoscb_item object, add it the correct queue and finally invoke the configured compare method.

The UVM environment will typically contain a handle to the scoreboard as described above. This can then be utilized if UVM sequences needs to be added from a test case:

   class cl_scbtest_seq_item extends uvm_sequence_item;
     //-------------------------------------
     // Randomizable variables
     //-------------------------------------
     rand int unsigned int_a;
   
     //-------------------------------------
     // UVM Macros
     //-------------------------------------
     `uvm_object_utils_begin(cl_scbtest_seq_item)
       `uvm_field_int(int_a, UVM_ALL_ON)
     `uvm_object_utils_end
   
     //-------------------------------------
     // Constructor
     //-------------------------------------
     function cl_scbtest_seq_item::new (string name = "cl_scbtest_seq_item");
        super.new(name);
     endfunction
   endclass: cl_scbtest_seq_item

   class cl_scbtest_test extends uvm_test;
     //-------------------------------------
     // Non randomizable variables
     //-------------------------------------
     cl_scbtest_env scbtest_env;
   
     //-------------------------------------
     // UVM Macros
     //-------------------------------------
     `uvm_component_utils(cl_scbtest_test)
   
     //-------------------------------------
     // Constructor
     //-------------------------------------
     function new(string name = "cl_scbtest_test", uvm_component parent = null);
       super.new(name, parent);
     endfunction: new
   
     //-------------------------------------
     // UVM Phase methods
     //-------------------------------------
     function void build_phase(uvm_phase phase);
       super.build_phase(phase);
       scbtest_env = cl_scbtest_env::type_id::create("scbtest_env", this);
     endfunction: build_phase
   
     task run_phase(uvm_phase phase);
       super.run_phase(phase);
       begin
         cl_scbtest_seq_item item1;
         item1 = cl_scbtest_seq_item::type_id::create("item1");
         item1.int_a = 'h3a;
         scbtest_env.syoscb.add_item("Q1", "P1", item1);
       end
       begin
         cl_scbtest_seq_item item1;
         item1 = cl_scbtest_seq_item::type_id::create("item1");
         item1.int_a = 'h3a;
         scbtest_env.syoscb.add_item("Q2", "P1", item1);
       end
     endtask: run_phase
   endclass: cl_scbtest_test

TLM based API hook up

The TLM API is even easier to use than the function based API. The scoreboard provides generic UVM subscribers which can be connected to anything which has a UVM analysis port (e.g. a UVM monitor). Typically, the UVM agents inside the UVM environment contain one or more monitors with UVM analysis ports which should be connected to the scoreboard. The following example has two agents which each has a monitor. The monitors are connected to Q1 and Q2 in the scoreboard:

   import pk_syoscb::*;

   class cl_scbtest_env extends uvm_env;

     cl_syoscb     syoscb;   
     cl_syoscb_cfg syoscb_cfg;
     myagent       agent1;
     myagent       agent2;

     ...

     function void build_phase(uvm_phase phase);
       
       ...     

       // Configure and create the scoreboard
       // Create and configure the agents
       
       ...     

     endfunction: build_phase

     ...

     function void connect_phase(uvm_phase phase);
       super.connect_phase(phase);

       begin
         cl_syoscb_subscriber subscriber;

         // Get the subscriber for Producer: P1 for queue: Q1 and connect it
         // to the UVM monitor producing transactions for this queue
         subscriber = this.syoscb.get_subscriber("Q1", "P1");
         this.agent1.mon.<analysis port>.connect(subscriber.analysis_export);

         // Get the subscriber for Producer: P1 for queue: Q2 and connect it
         // to the UVM monitor producing transactions for this queue
         subscriber = this.syoscb.get_subscriber("Q2", "P1");
         this.agent1.mon.<analysis port>.connect(subscriber.analysis_export);
       end
     endfunction: connect_phase

Factory overwrites

Finally, the wanted queue and compare algorithm implementation needs to be selected. This is done by factory overwrites since they can be changed test etc.

NOTE: This MUST be done before creating the scoreboard!

The following queue implementations are available:

  1. Standard SV queue (cl_syoscb_queue_std)

and the following compare algorithms are available:

  1. Out-of-Order (cl_syoscb_compare_ooo)
  2. In-Order (cl_syoscb_compare_io)

The following example shows how they are configured:

   cl_syoscb_queue::set_type_override_by_type(cl_syoscb_queue::get_type(),              
                                              cl_syoscb_queue_std::get_type(),
                                              "*");

   factory.set_type_override_by_type(cl_syoscb_compare_base::get_type(),
                                     cl_syoscb_compare_ooo::get_type(),
                                     "*");

The full build phase, including the factory overwrites, of cl_scbtest_env is shown here for completeness:

   function void cl_scbtest_env::build_phase(uvm_phase phase);
     super.build_phase(phase);

     // Use the standard SV queue implementation as scoreboard queue
     cl_syoscb_queue::set_type_override_by_type(cl_syoscb_queue::get_type(),              
                                                cl_syoscb_queue_std::get_type(),
                                                "*");

     // Set the compare strategy to be OOO
     factory.set_type_override_by_type(cl_syoscb_compare_base::get_type(),
                                       cl_syoscb_compare_ooo::get_type(),
                                       "*");

     // Create the scoreboard configuration object
     this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");

     // Configure the scoreboard
     this.syoscb_cfg.set_queues({"Q1", "Q2"});
     void'(this.syoscb_cfg.set_primary_queue("Q1")); 
     void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"})); 

     // Pass the scoreboard configuration object to the config_db
     uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);

     // Create the scoreboard
     this.syoscb = cl_syoscb::type_id::create("syoscb", this);
               
     ...

   endfunction: build_phase
 All Classes Functions Variables

Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.2.3

Copyright 2014-2015 SyoSil ApS
All Rights Reserved Worldwide

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
doxygen
Doxygen Version: 1.6.1
IDV SV Filter Version: 2.6.2
Mon Sep 28 02:57:58 2015
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV