Jump to content

Selection of specific physical interface in default UVM register layer sequences


Recommended Posts

In our DUT, we have two separate independent physical interfaces (APB & I2C) (active 1 at a time) through which all registers can can be accessed,

 

Also in our register model, we created two reg_maps, one for each APB & I2C.
 
Now through testcase, we want only one physical interface at a time, to be subjected to default uvm sequences (i.e. uvm_reg_access_seq, uvm_reg_bit_bash_seq,etc) but it is not possible as uvm_sequence will get all the maps using get_maps();

 

  So without over-riding the default uvm_reg_access_seq, is it possible to achieve such type of configuration in testcase itself via using uvm_reg_map or some other methods.

 

Kindly refer following pseudo code

//Pseudo Code for Scenario
 class  dut_reg_test extends base_test;
  `uvm_component_uti ls(dut_reg_test)
  
  //Handle of default uvm register access sequence
  uvm_reg_access_seq my_reg_seq;
  // Select Physical Interface
  rand bit APB_I2C;
   
  uvm_reg_map test_map;
  dut_reg_model regmodel;
  
  task buid_phase (uvm_phase phase);
    super.build_phase(phase);
    // Select PHY Interface via commandline
      if ($value$plusargs("APB_I2C=%b", APB_I2C))
     else
        APB_I2C = $random;
    
    if (APB_I2C)
       test_map = regmodel.apb
    else
       test_map = regmodel.i2c
  endtask : build_phase

   task main_phase (uvm_phase phase); 
    //Create method for sequence
    my_reg_seq=uvm_single_access_seq::type_id::create("my_reg_seq");
    //Randomize with selected map
    my_reg_seq.randomize with { maps == test_map;});
    // Start default sequence
     my_reg_seq.start(NULL);
   endtask : main_phase
  
endclass : dut_reg_test

The above strategy cannot be implemented because uvm_reg_access sequence doesn't contain uvm_reg_map it's only present in uvm_reg_single_access_seq,

 

Similar kind of limitations persists will all uvm_reg_bit_bash_seq & reset sequences.

 

Can we have some strategy to resolve this issue ?

 

Thanks :)

Nikunj Hinsu

 

 

Link to comment
Share on other sites

Not sure where you got the idea from that you can do this for uvm_reg_single_access_seq. First of all, there isn't any field called maps defined in the sequence. The only place I see any reference to any maps is in body(), where it's a local variable. Second, you can't constrain object handles like that, since only integral expressions are allowed by the LRM.

 

Coming back to your question, you can't use these sequences to do what you want them to do. This is because they're poorly written. Instead of having one big loop inside the body() task of uvm_reg_single_access_seq, a better way would have been to write it like this:

class uvm_reg_single_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
  virtual task body();
    uvm_reg_map maps[$];

    // code that checks if register test is enabled
    // ...

    rg.get_maps(maps);

    foreach (maps[j]) begin
      if (skip_map(maps[j])
        continue;
      verify(maps[j]);
    end
  endtask


  virtual function bit skip_map(uvm_reg_map map);
    // code that checks if reg only has RO or undef fields in map
    // ...
  endfunction


  virtual task verify(uvm_reg_map map);
    uvm_status_e status;
    uvm_reg_data_t  v, exp;

    // code that was in the loop in the original file that does write and mirror
  endtask
endclass

This way, you could extend the skip_map(...) function to skip certain maps. You can still implement the code I showed you above in a sub-class of uvm_reg_single_access_seq that only handles a certain map:

class my_reg_single_access_seq extends uvm_reg_single_access_seq;
  uvm_reg_map map_to_test;

  // ... same code for body() and verify(...) as above

  virtual function bit skip_map(uvm_reg_map map);
    if (map != map_to_test)
      return 1;
    return super.skip(map);
  endtask
endclass

You could propagate this map_to_test field to the other sequences as well. You could then use the factory to override uvm_reg_single_access_seq with my_reg_single_access_seq. Using mid_do, you could make sure that the map_to_test field gets passed down hierarchically:

class my_reg_access_seq extends uvm_reg_access_seq;
  uvm_reg_map map_to_test;

  virtual function void mid_do (uvm_sequence_item this_item);
    my_reg_single_access_seq access_seq;
    if ($cast(access_seq, this_item)
      access_seq.map_to_test = this.map_to_test;
  endfunction

  task body();
    uvm_reg_single_access_seq::type_id::set_inst_override(
      my_reg_single_access_seq::get_type(), get_full_name());
    super.body();
    // ideally you should remove the override now, but it's only possible
    // in UVM 1.2 (I think)
  endtask
endclass

You'd need to do the same for bit bash and reset.

 

The code above might need some tweaks to get it to compile and really do what it's supposed to do, but it should be a good starting point for you.

Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...