Reuse non-UVM classes in UVM environment

We have one of our VIP vendor that provides a configuration class to configure its VIP but the members are not ‘rand’ and we would like to randomize the configuration with a simple this.randomize() call.

Currently our poor-man solution to the problem is to create a wrapper class that has the same members but defined as rand, then copy the members over to the non-uvm class, something along the following lines:

class vip_cfg extends non_uvm_object_base;
  int var;
endclass: vip_cfg 

class vip_cfg_wrap extends uvm_object;
  // standard boiler-plate uvm code (new, utils, etc.)
  rand var;
endclass: vip_cfg_wrap 

class my_test extends uvm_test;
  vip_cfg cfg;
  vip_cfg_wrap uvm_cfg;
  abc_vip vip;

  // standard boiler-plate uvm code (new, utils, etc.)
  virtual function build_phase (uvm_phase phase);
    super.build_phase(phase);

    // build the vip config classes and pass the randomized variable
    cfg = new();
    uvm_cfg = vip_cfg_wrap::type_id::create("uvm_cfg");
    uvm_cfg.randomize();
    cfg.var = uvm_cfg.var;
    
    // now we can create the vip instance and pass the configuration object with the
    // vip API
    vip = new();
    vip.configure(cfg);

  endfunction: build_phase
endclass: my_test 

This approach is not only ugly, but it’s extremely painful to maintain, every time we want to randomize another member we need to modify the wrapper class and the test class (violating the ‘S’ in S.O.L.I.D).

Any suggestion? I’ve been looking around but haven’t found anything relevant.
Thanks a lot.

A typical approach is to have an environment configuration object which contains all of your agent configuration objects.

Using the following flow should make things easier:

  1. Add the variables you desire to randomize to the environment configuration object.
  2. In the post_randomize() function of your environment configuration object, assign the variables to the desired agent configuration.
  3. In the test, randomize your environment configuration object with any desired values.
  4. Pass the environment configuration object from the test to the environment.
  5. In the environment, get the environment configuration object, create the required agents and apply each agent configuration.

Ok, that would still require to ‘repeat’ the name of the variables in the ‘environment configuration object’ and then randomize it, but I guess it will be cleaner than having the test to do that.

Having the post_randomize() function dealing with assigning the variables to the correct object makes sense, although often the post_randomize() function is used to perform “error injection”, i.e. force values that violate the constrains of the object. Being the function not declared as virtual we are essentially giving up in extending the config class by overriding the post_randomize() call, unless we brutally copy/paste the assignments as well. I’m not saying it’s not a valid approach, just highlighting its shortcomings.

Do you confirm?

Tests are used to address specific functionalities for verification, i.e you should use a configuration object in the test, to configure your verification environment. From that you can pass your configuration variables downwards to the right place.

That is what I believe we are already doing. If you read through the snippet in my OP you’ll see how the test is creating an object, randomizing it and then passing it to the vip config object.

Then “cgales” suggested to use the post_randomization() function to perform the vip configuration and having the vip_cfg_wrap object include a vip_cfg object and take care of creating it and assigning the randomized variables.

I might have missed what you are suggesting that is different from what I’ve already mentioned in my OP.