Saturday 1 October 2016

Build an UVM scoreboard in few minutes

If you feel doing repetitive coding is a boring task, then this blog is for you! UVM provides many inbuilt features which can be easily plugged in to our testbench with little modification. So, we can reduce our coding time and achieve our goal of verification. In this post, we will see how the UVM is useful for building a scoreboard quickly.

Generally, scoreboard has a function for creating analysis ports (expected transaction and actual transaction) which is connected with transmitter's analysis port and receiver's analysis port, a function which converts a transaction class into another transaction class, FIFOs for storing transactions and methods for getting transaction and compare them. In most of the projects, we are using the same kind of scoreboard structure and mostly transaction conversion method differs from project to project. 

UVM provides all these features in "uvm_algorithmic_comparator" class and you can easily plug-n-play the scoreboard component in your environment. Just, you need to concentrate on writing a method which translates a transaction class into another type of transaction class. So, you can easily save your time in terms of coding and compiling the scoreboard code. 

Below is the example of "uvm_algorithmic_comparator".

Step (1): Create a transformer class and overwrite "transform" method which converts an input transaction class into another type of (output) transaction class.
In this example, "m_transformer" class is created and "a_item" transaction class is converted into "b_item" transaction using "transform" method in it.

class m_transformer extends uvm_component;
    ...  
    function b_item transform(a_item a_i);
        b_item b_i;
        b_i      = new("b_i");
        b_i.b   = a_i.a;
        b_i.bb = a_i.aa;
        return b_i;
    endfunction
endclass : m_transformer

Step (2): Instantiate the transformer class into "environment" class along with other agents in "uvm_algorithmic_comparator" class.
"uvm_algorithmic_comparator" has three parameters:
BEFORE: A transaction class which needs to be converted 
AFTER:   A transaction class which needs to be compared 
TRANSFORMER: A component which contains "transform" method

Note that, you must have to implement "convert2string" and "do_compare" method in ~AFTER~ transaction class.

Step (3): Connect analysis port having ~BEFORE~ transaction class with "before_export" port of algorithmic comparator and analysis port having ~AFTER~ transaction class with "after_export" port.

class m_env extends uvm_env;
    // Agent class handle
    a_agent a_ag;
    b_agent b_ag;
    // STEP - 2
    uvm_algorithmic_comparator #(a_item, b_item, m_transformer) algo;
    m_transformer transf;

    ...  

    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        transf = new("transf",this);
        algo   = new("algo",this, transf);
        a_ag  = a_agent::type_id::create("a_ag", this);
        b_ag  = b_agent::type_id::create("b_ag", this);
    endfunction : build_phase
  
    // STEP - 3
    function void connect_phase(uvm_phase phase);
        a_ag.drv.a_ap.connect(algo.before_export);
        b_ag.drv.b_ap.connect(algo.after_export);
    endfunction : connect_phase
endclass :m_env


Alright, you are done with the scoreboard and good to go for simulation!!!

Here, when "a_ag.drv" broadcast any transaction on "a_ap" analysis port, it will be converted in to "b_item" transaction class and stored in "m_before_fifo" tlm analysis fifo of "uvm_in_order_comparator" class. Similarly, when "b_ag.drv" broadcast any transaction on "b_ap" analysis port, it will be stored in "m_after_fifo" tlm analysis fifo of "uvm_in_order_comparator" class. In run phase, when any transaction available in "m_before_fifo" and "m_after_fifo", they will be compared.

Now, when any transaction mismatch, this scoreboard will give a warning (UVM_WARNING) message "Comparator Mismatch" that you can override to error (UVM_ERROR) message based on your project need.




9 comments:

  1. Good Artical Munjal !!

    It will compare only in order transactions. It does not have support of Out of Oder transaction.

    Also would like to know that, does it have support of scorboard re-locking ? For erroneous scenarios, we may require to have re-locking mechanism. What others feature are provided by "uvm_algorithmic_comparator"?


    ReplyDelete
    Replies
    1. Thank you Chetan!
      Yes, as mentioned in second last para, it compares only in order transaction. For out of order transactions, you can override the run phase and apply logic for it.
      It doesn't provide in built locking mechanism as it varies project to project.

      Delete
  2. Good explanation Munjal !!
    One question , can output from transform function can be null ?
    I mean packet is expected to be dropped.

    ReplyDelete
    Replies
    1. Hi Parth,

      You should not send null packet from transform method otherwise tool will give fatal for null packet.
      But you can override the "write" method. So whenever you want to drop the packet, just don't call the transform method.

      Delete
  3. Explanation was good @munjal

    ReplyDelete
  4. How can I override warning(UVM_WARNING)?

    ReplyDelete
    Replies
    1. You can use uvm_report_catcher and while adding callback in first argument use "null" as comparator is a local object.

      Delete
  5. It doesn't work.
    algo.set_report_severity_id_override(UVM_WARNING,"Comparator Mismatch",UVM_ERROR);

    ReplyDelete
  6. It occurs compile error.
    algo.comp.set_report_severity_id_override(UVM_WARNING,"Comparator Mismatch",UVM_ERROR);

    ReplyDelete