Can I use base class object in the extend class?

I’m trying to use one object which is declared in base class and I want to use it under extend class.

Can I use a base class’s object under the extend class?

For example,

//TEST Class.


class my_base_test extends uvm_test;
...
function void build_phase(uvm_phase phase);
       ...
       my_base_test  = my_base::type_id::create("my_base_test", this);
endfunction
function void connect_phase(uvm_phase phase);
        ...
        my_seq0_seq.my_ral = ral_env.model;
        my_seq1_seq.my_ral = ral_env.model;
        my_seq2_seq.my_ral = ral_env.model;
        my_seq3_seq.my_ral = ral_env.model;
        my_seq4_seq.my_ral = ral_env.model;
        my_seq5_seq.my_ral = ral_env.model;
        my_seq6_seq.my_ral = ral_env.model;
        my_seq7_seq.my_ral = ral_env.model;
        ...
endfunction
endclass


class my_base_seq extends uvm_sequence;
    my_reg_model    my_ral;
    ...
    my_ral = my_reg_mode::type_id_create("my_ral", this);
    ...
endclass

class my_seq0_seq; extends my_base_seq;
    ...
    virtual task body();
    ...
    my_ral.DATA.read(status, rdata);
    ...
endclass

class my_seq1_seq extends my_base_seq;
    ...
    virtual task body();
    ...
    my_ral.DATA.read(status, rdata);
    ...
endclass

class my_seq2_seq extends my_base_seq;
    ...
    virtual task body();
    ...
    my_ral.DATA.read(status, rdata);
    ...
endclass
...

If I have 100 sequence classes and I want to use “my_seq” object, then do I need to assign all 100 sequences as the below instead of just one assignment in the base class? because all “my_seq” has extended from base class. so I thought that I assigned it in the base class and I can use it without assigning to each extended class.

    my_seq0_seq.my_ral = ral_env.model;
    my_seq1_seq.my_ral = ral_env.model;
    my_seq2_seq.my_ral = ral_env.model;
    my_seq3_seq.my_ral = ral_env.model;
    my_seq4_seq.my_ral = ral_env.model;
    ...

Instead of implementing everything as above, I implement " my_base_seq.my_ral = ral_env.model;" then my_seq0 get the problem of NULL point error.

In reply to UVM_LOVE:

Your question is very confusing as you re-use the same class name (my_base_class) so it’s difficult to understand what you are trying to accomplish.

If you have many different sequences defined, I wouldn’t declare/create them in the base test, as they will be test specific. You should only declare/create the required sequences in each test.

In reply to cgales:

Sorry my bad and typo.

Each sequence is extended by my_base_seq.
In the example, my_seq0_seq is not declared with “my_reg_model my_ral;”. This is because the declaration was made in “my_base_seq” and it was expanded to create my_seq0_seq.

If the objects declared in my_base_seq are available in the extended sequence, then I can declare as the below.

    my_seq0_seq.my_ral = ral_env.model;
    my_seq1_seq.my_ral = ral_env.model;
    my_seq2_seq.my_ral = ral_env.model;
    my_seq3_seq.my_ral = ral_env.model;
    my_seq4_seq.my_ral = ral_env.model;
    my_seq5_seq.my_ral = ral_env.model;
    my_seq6_seq.my_ral = ral_env.model;
    my_seq7_seq.my_ral = ral_env.model;

We don’t need to declare like this, we can just declare it like " my_base_seq.my_ral = ral_env.model;" in my_base_test class.

However, contrary to my expectations, " my_base_seq.my_ral = ral_env.model;" has a null pointer error.

In reply to UVM_LOVE:

As cgales pointed out your wording is a bit confusing, why not just use config_db to set the RAL model and then in your base sequence you can get it with config_db get (please do not take the code as working example is just an idea)


//In the env class
uvm_config_db#(ral_model)::set(null, "*", "ral_model", ral_model);

// in the sequence
if ( !uvm_config_db#(int)::get(get_sequencer(), "", "ral_model", seq_ral_model))


HTH,

-R

In reply to rgarcia07:

I got your point. I will use uvm_config_db. Thanks.

In reply to rgarcia07:

You don’t want to use the config_db() in this case. The best technique is to add a function in your base test which assigns ral_model to the sequence my_ral handle.

Again, you don’t want to instantiate every sequence in the base_test class. You should only use the required sequences in each derived test.


class my_base_seq extends uvm_sequence;
    my_reg_model    my_ral;
    ...
    my_ral = my_reg_mode::type_id_create("my_ral", this);
    ...
endclass
 
class my_seq0_seq; extends my_base_seq;
    ...
    virtual task body();
    ...
    my_ral.DATA.read(status, rdata);
    ...
endclass
 
class my_seq1_seq extends my_base_seq;
    ...
    virtual task body();
    ...
    my_ral.DATA.read(status, rdata);
    ...
endclass
 
class my_seq2_seq extends my_base_seq;
    ...
    virtual task body();
    ...
    my_ral.DATA.read(status, rdata);
    ...
endclass

class my_base_test extends uvm_test;
...
// Only have environment & config objects
// Don't create any sequences in the base test - they are test specific
function void build_phase(uvm_phase phase);
       ...
endfunction

function assign_ral(my_base_seq seq);
  seq.my_ral = ral_env.model;
endfunction

function void connect_phase(uvm_phase phase);
        ...
        ...
endfunction
endclass

class my_test1 extends my_base_test;
task run_phase(uvm_phase phase);
  my_seq1_seq seq1 = my_seq1_seq::type_id::create("seq1");
  my_seq2_seq seq2 = my_seq2_seq::type_id::create("seq2");
  assign_ral(seq1);
  assign_ral(seq2);
  seq1.start(env.agent.seqr);
  seq2.start(env.agent.seqr);
endtask
endclass


In reply to cgales:

Thank you cgales.