Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

What is a scoreboard ?

UVM scoreboard is a verification component that contains checkers and verifies the functionality of a design. It usually receives transaction level objects captured from the interfaces of a DUT via TLM Analysis Ports.

For example, write and read values from a RW register should match. When a write operation is performed to the design, the scoreboard receives this packet and is the expected value. After that, the same register is read back from the design and the data is actual value which is sent to UVM scoreboard. Now the scoreboard can compare between the expected and actual values to see if they match.

What is a reference model ?

After receiving data objects, it can either perform calculations and predict the expected value or send it to a reference model to get expected values. The reference model is also called a predictor and would mimic the functionality of the design.

The final task is to compare expected results with the actual output data from DUT.

uvm scoreboard

It is recommended to inherit from uvm_scoreboard than uvm_component so that any additions to uvm_scoreboard class in a future release of UVM will automatically be included in the custom UVM scoreboard when you switch to the newer version.

Steps to create a UVM scoreboard

1. Create a custom class inherited from uvm_scoreboard, register with factory and call function new
 
// my_scbd is user-given name for this class that has been derived from "uvm_scoreboard"
class my_scbd extends uvm_scoreboard;
 
    // [Recommended] Makes this scoreboard more re-usable
    `uvm_component_utils (my_scoreboard)
 
    // This is standard code for all components
    function new (string name = "my_scoreboard", uvm_component parent = null);
      super.new (name, parent);
    endfunction
 
    // Code for rest of the steps come here
endclass
 
2. Add necessary TLM exports to receive transactions from other components and instantiat them in build_phase
 
  // Step2: Declare and create a TLM Analysis Port to receive data objects from other TB components
  uvm_analysis_imp #(apb_pkt, my_scoreboard) apb_export;
 
  // Instantiate the analysis port, because afterall, its a class object
  function void build_phase (uvm_phase phase);
    apb_export = new ("apb_export", this);
  endfunction
 
3. Define the action to be taken when data is received from the analysis port
 
  // Step3: Define action to be taken when a packet is received via the declared analysis port
  virtual function void write (apb_pkt data);
    // What should be done with the data packet received comes here - let's display it
    `uvm_info ("write", $sformatf("Data received = 0x%0h", data), UVM_MEDIUM)
  endfunction  
 
4. Perform checks

It is not required to perform checks only in the check_phase. Real checkers can also actively check during the run_phase.

 
  // Step4: [Optional] Perform any remaining comparisons or checks before end of simulation
  virtual function void check_phase (uvm_phase phase);
    ...
  endfunction  
 
5. Connect Analysis ports of scoreboard with other components in the environment
 
class my_env extends uvm_env;
  ...
 
  // Step5: Connect the analysis port of the scoreboard with the monitor so that 
  // the scoreboard gets data whenever monitor broadcasts the data.
  virtual function void connect_phase (uvm_phase phase);
    super.connect_phase (phase);
    m_apb_agent.m_apb_mon.analysis_port.connect (m_scbd.apb_export);
  endfunction
endclass  
 

UVM Scoreboard Example

my_scoreboard is a class inherited from uvm_scoreboard and registered with the factory. A UVM analysis implementation port called apb_export is defined to accept transactions of type apb_pkt (uvm_sequence_item).

Because apb_export is also a class, an object has to be created using the new method which has been done in the build_phase. Implementation of the analysis port is only complete when we define the write method to handle the incoming packet appropriately.

 
// Step1 : Create a new class that extends from uvm_scoreboard
class my_scoreboard extends uvm_scoreboard;
  `uvm_component_utils (my_scoreboard)
 
  function new (string name = "my_scoreboard", uvm_component parent);
    super.new (name, parent);
  endfunction
 
  // Step2a: Declare and create a TLM Analysis Port to receive data objects from other TB components
  uvm_analysis_imp #(apb_pkt, my_scoreboard) apb_export;
 
  // Step2b: Instantiate the analysis port, because afterall, its a class object
  function void build_phase (uvm_phase phase);
    apb_export = new ("apb_export", this);
  endfunction
 
  // Step3: Define action to be taken when a packet is received via the declared analysis port
  virtual function void write (apb_pkt data);
    // What should be done with the data packet received comes here - let's display it
    `uvm_info ("write", $sformatf("Data received = 0x%0h", data), UVM_MEDIUM)
  endfunction
 
  // Step3: Define other functions and tasks that operate on the data and call them
  // Remember, this is the main task that consumes simulation time in UVM
  virtual task run_phase (uvm_phase phase);
    ...
  endfunction
 
  // Step4: [Optional] Perform any remaining comparisons or checks before end of simulation
  virtual function void check_phase (uvm_phase phase);
    ...
  endfunction
endclass
 

How to connect analysis ports of UVM scoreboard ?

After a scoreboard has been defined, you also need to instantiate it in the environment and connect it with the appropriate analysis ports.

 
class my_env extends uvm_env;
  `uvm_component_utils (my_env)
 
  function new (string name = "my_env", uvm_component parent);
    super.new (name, parent);
  endfunction
 
  // Declare a handle so that we can connect TB components to this
  my_scoreboard   m_scbd;
 
  // Instantiate or Build the scoreboard using standard UVM factory create calls
  virtual function void build_phase (uvm_phase phase);
    super.build_phase (phase);
    m_scbd = my_scoreboard::type_id::create ("m_scbd", this);
  endfunction
 
  // Step5: Connect the analysis port of the scoreboard with the monitor so that 
  // the scoreboard gets data whenever monitor broadcasts the data.
  // Note: This agent is assumed to be present in this environment for example purpose
  virtual function void connect_phase (uvm_phase phase);
    super.connect_phase (phase);
    m_apb_agent.m_apb_mon.analysis_port.connect (m_scbd.apb_export);
  endfunction
endclass
 

Was this article helpful ?

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. You consent to our cookies if you continue to use our website. To find out more about the cookies we use and how to delete them, see our privacy policy.

  I accept cookies from this site.
Agree
EU Cookie Directive plugin by www.channeldigital.co.uk