Virtual function in system verilog

In reply to dave_59:

So I’ll explain my question.

I’m working on a top verification environment.
for now what I have is:

  1. coverage class for each block
  2. base coverage class, each ‘block coverage class’ extends the ‘base coverage claass’
  3. coverage top - which creates an instance for each ‘block coverage class’,
    this ‘coverage top’ is created and instanced within the env.

now, each ‘block coverage class’ will implement different cover-groups and cover-points on registers accesses, each is related for this specific block.

for now the “write” function of the register analysis port is implemented in 1 ‘block coverage class’
and now I need to added registers coverage each are related to another ‘block coverage class’
I don’t like to copy the “write” function again, and connect the analysis port again.
I expect it to be in more then 2 ‘block coverage class’
so I thought maybe I can implement the ‘write’ function in the base, and in each ‘block coverage class’ implement just the registers cover-group and sample.

I will show in the example the way I can do it if I’m not using the base and virtual idea.

Block 1 coverage class:



class coverage1 extends base_coverage;
   
    uvm_analysis_imp #(uvm_reg_item, base_coverage)   in_ap;
    covergroup coverage1_register_addresses();
        reg_addr_block_A_cp :coverpoint reg_addr{
            bins bin_num1 = {32'h8000_0000};
            bins bin_num2 = {32'h9000_0000};
        }
    endgroup   

    `uvm_component_utils(coverage1)
 
    function new(string name, uvm_component parent= null);
        super.new(name, parent);
        in_ap = new("in_ap",  this);
        coverage1_register_addresses = new();
    endfunction : new
 
   
    function void write(uvm_reg_item t);
        uvm_reg r;
    
        $cast(r,t.element);
       
        reg_addr = r.get_address();
        reg_data = r.get();
         
        coverage1_register_addresses.sample();
     
    endfunction 

endclass



Block 2 coverage class:



class coverage2 extends base_coverage;
   
    uvm_analysis_imp #(uvm_reg_item, base_coverage)   in_ap;

    covergroup coverage2_register_addresses();
        reg_addr_block_B_cp :coverpoint reg_addr{
            bins bin_num1 = {32'hAAAA_0000};
            bins bin_num2 = {32'hBBBB_0000};
        }
    endgroup   

    `uvm_component_utils(coverage2)
 
    function new(string name, uvm_component parent= null);
        super.new(name, parent);
        in_ap = new("in_ap",  this);
        coverage2_register_addresses= new();
    endfunction : new
 
   
    function void write(uvm_reg_item t);
        uvm_reg r;
    
        $cast(r,t.element);
       
        reg_addr = r.get_address();
        reg_data = r.get();
         
        coverage2_register_addresses.sample();
     
    endfunction 

endclass



Base coverage class:



class base_coverage extends uvm_component;
    
    int                         coverage_enable=1; 
    int unsigned                reg_addr;
    int unsigned                reg_data;

    `uvm_component_utils(base_coverage)
 
    function new(string name, uvm_component parent= null);
        super.new(name, parent);
    endfunction : new
 
endclass



coverage top class:



class coverage_top extends uvm_component;
 
    coverage1 cov1;
    coverage2 cov2;

    `uvm_component_utils(coverage_top)
 
    function new(string name, uvm_component parent= null);
        super.new(name, parent);
    endfunction : new
 
    function void build_phase(uvm_phase phase);
        supeer.build_pahse(phase);
        cov1       = coverage1::type_id::create("cov1",this);  
        cov2       = coverage2::type_id::create("cov2",this); 
    endfunction : build_phase
  
endclass


env:



class env extends uvm_component;
 
    coverage_top cov_top;
    reg_monitor reg_mon;

    `uvm_component_utils(env)
 
    function new(string name, uvm_component parent= null);
        super.new(name, parent);
    endfunction : new
 
    function void build_phase(uvm_phase phase);
        supeer.build_pahse(phase);
        cov_top    = coverage_top::type_id::create("cov_top",this);  
        reg_mon    = reg_monitor::type_id::create("reg_mon",this);
    endfunction : build_phase
 
    function void connect_phase(uvm_phase phase);
        reg_mon.reg_ap.connect(cov_top.cov1.in_ap);
        reg_mon.reg_ap.connect(cov_top.cov2.in_ap);
    endfunction : connect_phase
 
endclass