Tuesday, 18 November 2014

Inject error values into DUT - SERIES 2

In SERIES 1, errors are driven by inserting error values into cfg_db and passing this instance of cfg_db into respective testcase.

Another method is to use nested transaction class in test class and override this nested class with original transaction class. this method provides encapsulation of error injection into that particular test. This can be understood with below discussion in verification academy forum.

***********************************************************************************
There are separate sequences running on multiple instances of UVC. In a testcase, I want to override the transaction item in particular instance of sequence. I tried the below, which is not working. Any clue ?
class baseseq extends uvm_sequence;
 
task body();
basetrans = trans::type_id::create ("trans");
start_item(trans);
trans.randomize();
finish_item(trans);
endtask
 
endclass
 
class basetest extends uvm_test;
 task run;
   foreach (seq[id]) begin      // Let's say id is from 0 to 4
     seq[id]=baseseq::type_id::create($sformatf("seq_%0d",id), ,get_full_name());
     seq[id].start(seqr[id]);
    end
 endtask
endclass
 
class mytest extends basetest;
 
 class errtrans extends basetrans;
   // additional functionalities
 endclass
 
 task run;
   foreach (seq[id]) begin
     seq[id]=baseseq::type_id::create($sformatf("seq_%0d",id), ,get_full_name());
     seq[id].start(seqr[id]);
    end
   basetrans::type_id:set_inst_override(errtrans:get_type(), {get_full_name,".seq_4"});
   // I expect the override type should effect from now, but is not happening !!
   foreach (seq[id]) begin
     seq[id]=baseseq::type_id::create($sformatf("seq_%0d",id), ,get_full_name());
     seq[id].start(seqr[id]);
    end
 endtask
endclass
 
**********************************************************************************************
Instance overrides just require the create() name of the instance to match the pattern of the override. You have an override that looks like it would be intended to override the sequence, not the transaction. It looks like you have followed most of the recommendations in the cookbook page Sequences/Overrides - just a couple of things need changed in your code to make it work:
(1) give your transaction instance some context when you create it in class baseseq, otherwise you can't easily match it with an instance override. Recommend you change the create() to add the 3rd context argument:

basetrans trans = basetrans::type_id::create("trans",,get_full_name());
                                                    ^^^^^^^^^^^^^^^^^
The transaction (that you wish to override) now has a context which is the get_full_name() OF THE SEQUENCE.
You need to match that up with (a) your create() of the sequence and (b) your instance override.
(2) in the sequence creation and override, use the get_full_name() of seqr[4], not of the test, and append the actual transaction name to the instance override (or a wildcard):

basetrans::type_id::set_inst_override(errtrans::get_type(), {seqr[4].get_full_name,".seq_4.trans"});
                                                             ^^^^^^^^                     ^^^^^^
    foreach (seq[id]) begin
      seq[id]=baseseq::type_id::create($sformatf("seq_%0d",id), ,seqr[id].get_full_name());
                                                                 ^^^^^^^^^
BTW kudos for using a NESTED CLASS for your definition of errtrans, inside your test. That is a great technique for keeping all aspects of a testcase together in one file, especially when the override is as simple as e.g. adding a random constraint on the base transaction. Just remember that class still needs a `uvm_object_utils so that the factory knows about it, and you need to ensure all such nested classes have unique names!
 
***********************************************************************************
 
Gordon, Thanks for the solution. It did work :) I have also tried the below method previously

basetrans trans = basetrans::type_id::create("trans");
$display ("Full_NAME=%0s", trans.get_full_name());
 
This was to get the hierarchical path of the transaction item. It was giving the result "env.seqr_4.seq_4.trans" and in the test, I had done the following

basetrans::type_id::set_inst_override(errtrans::get_type(), env.seqr_4.seq_4.* );
 
But, it was not working. Now that after adding context when creating
transaction item as given below, it is working

basetrans trans = basetrans::type_id::create("trans", , get_full_name());
Why is it required to specify context while creating transaction item?
 

No comments:

Post a Comment