Functional Coverage for Register model in UVM

Hi,
I need help in getting the functional coverage for register model. I generated Register model package and covergroups for each register using the Register Assistant tool from Mentor Graphics. Small code snippet for single register covergroup as shown below:

Class register0_reg extends uvm_reg;
`uvm_object_utils(register0_reg);

rand uvm_reg_field port;
rand uvm_reg_field ack;
rand uvm_reg_field response;

Covergroup c1;
port: coverpoint port.value[4:0];
ack : coverpoint ack.value[5:0];
response: coverpoint response.value[1:0];
endgroup

function new(string name=" ");
super.new(name,build_coverage(UVM_CVR_FIELD_VALS));
add_coverage(build_coverage(UVM_CVR_FIELD_VALS));
if(has_coverage(UVM_CVR_FIELD_VALS)
c1=new();
endfunction

virtual function void sample_values();
super.sample_values();
if(get_coverage(UVM_CVR_FIELD_VALS))
c1.sample();
endfunction

virtual function void build();
port = uvm_reg_field::type_id::create(“port”);
ack = uvm_reg_field::type_id::create(“ack”);
response = uvm_reg_field::type_id::create(“response”);

port.configure();
ack.configure();
response.configure();
endfunction

endclass

In the base test class, I have written the following code:

function void proj_test_base::build_phase(uvm_phase build);

// Register model

uvm_reg::include_coverage(“*”, UVM_CVR_FIELD_VALS);
proj_rm = proj_reg_block::type_id::create(“proj_rm”);
proj_rm.build();
endfunction

In the makefile, I used the following command:

vsim -c tb_mem -coverage -do “run -a; coverage save cov.ucdb; vcover report -html cov.ucdb ;q”

But, Questasim tool was not able to generate any UCDB files related to coverage.
Is there any code should be written to get the Register coverage? Please help me…

Make sure that you have enabled coverage to the register blocks which instantiate this register if you have a hierarchy of registers.

In reply to sivaji:

I’m curious to find out if you resolved this issue.
I too have a UVM Register layer in my design.
The covergroup at the register_block level is working fine and gathering coverage in simulation.
I also used the same code to anble this : uvm_reg::include_coverage(“*”, UVM_CVR_FIELD_VALS);

However, the covergroups in each of the register models (like yours shown in the code snippet above) are being created but no samples are being gathered. I set a breakpoint on the sample_values method and it is not being called.
I could call the sample_values method manually, but wondered if I’m missing a step to automate the sampling of the register level coverage.
Did you get this working ?

In reply to graeme_jessiman:

I have the same problem. Coverage object created, but sample_values() not invoked.
I verified that all the parent register blocks had UVM_CVR_ALL.

In reply to sujithsh:

How does one do that in the regassist tool?

I noticed this same issue was well when using the regassist tool.

First, it should be known that the ‘set_coverage(uvm_reg_cvr_t is_on)’ method must be called in order to turn of coverage for a given register or parent register block (e.g. reg model). This is in addition to the uvm_reg::include_coverage(“*”, UVM_CVR_FIELD_VALS) call.

If you only enable coverage for fields, and do not enable coverage for a ‘block’, then the regassist tool does not ever call the set_coverage function in the build function generated for the register model.

You can manually call the set_coverage(UVM_CVR_FIELD_VALS) (for example) on the reg model after the build function is called, and this should enable the coverage type generated by the regassist tool for the register objects.

Furthermore, the sample_values function created by the register assistant tool is meant to be invoked by a user (see UVM user guide - sample vs sample_values for uvm_reg*). If a parent uvm_reg_block containing registers has its ‘sample_values’ function called, then the default functionality is for it to iterate over each register and call its corresponding ‘sample_values’ function. For this reason, I had to put a handle to the register model in the reg adapter, and directly call reg_model.sample_values() in the reg2bus and bus2reg functions. This is a bit of a brute force approach since all registers will be sampled and not the specific register being accessed, but it works.

Finally, if you enable coverage for a ‘block’ using the regassist tool, then the set_coverage function is called in the build function of the generated reg model, BUT set_coverage is called ONLY for UVM_CVR_ADDR_MAP, and this will indirectly turn off the other coverage types (e.g. the UVM_CVR_FIELD_VALS for the register fields).

The work around for this is to recall the set coverage function on the register model after the build function is called to enable the desired coverage types:

reg_model.set_coverage(UVM_CVR_FIELD_VALS|UVM_CVR_ADDR_MAP);

This finally got everything to work for me. I’ve sent the issue to Mentor Graphics, and hopefully this message helps others.

In reply to sivaji:

Hi,

You need to call the sample_value() function present in RAL from the test, it will not automatically be called.

In reply to AbhishekM:

Hi All,

I was able to resolve the calling of sample_values in test or outside RAL to enable register coverage sampling issue.

There is an empty sample() function available in uvm_reg source code, which is executed when predictor receives any valid register access.
Extending this function in the generated register definition to execute the sample_values() function will automatically execute the coverage sampling when ever register access is executed.

Below are the additional changes added for getting register and block level coverage to be generated and sampled at simulation,

for each generated register add below function,


      virtual function void sample(uvm_reg_data_t  data,
                                          uvm_reg_data_t  byte_en,
                                          bit             is_read,
                                          uvm_reg_map     map);
          sample_values();
         
      endfunction: sample

Add below code in test to enable coverage (based on comment from ahdel.rahimi),


uvm_reg::include_coverage("*", UVM_CVR_FIELD_VALS|UVM_CVR_ADDR_MAP); 
//....
//create and build reg model
//....
<reg_model_instance_name>.set_coverage(UVM_CVR_FIELD_VALS|UVM_CVR_ADDR_MAP);