Alternative of `uvm_do_with macro

hi…
uvm_do_with is working well with random items in my data class, but in data class, i have few items which are not random variables. So to set their values also, what should i do? Is there any alternative of uvm_do_with which can also set non random items to our desired value?

We do not recommend using the `uvm_do_* macros to give you more flexibility in how you assigned and randomize members of a class. I just showed this example in a previous post

my_transaction tx;
task body;
    tx = my_transaction::type_id::create("tx");
    start_item(tx);
    tx.array = {8'h11, 8'h22, 8'h33, 8'h44 };
    tx.array.rand_mode(0);    // need these next 2 lines if there 
    assert( tx.randomize() ); //    are other fields to randomize
    finish_item(tx);
  end
endtask: body

Instead of using array.rand_mode(0) to make array a non-rand variable, you can also call tx.randomize(list_of_rand_variables) and only the variables in the list will be randomized. Another option is to call randomize() first, and then overwrite the variables you want to assign. If you want to check that the constraints are still met, you can call tx.randomize(null) and that will check the constraints using the current values of all variables.

If you still want to use the `uvm_do_* macros, you will have to do this for each variable you want to treat as a non-random variable

  1. declare a temporary non-random variable
  2. assign the temp variable the value you want to use
  3. add a constraint to the with argument of the uvm_do_with macro that constrains the temporary variable to be equal to the random variable

In reply to dave_59:

You shouldn’t be enclosing required logic in an assertion. The user should always be able to run a working test with assertions turned off. That is why assert(foo.randomize()) style calls were replaced in the OVM code (although they keep sneaking back in). The `uvm_do_on() macros do it correctly.

The randomize portion should look like this:


if (!tx.randomize()) begin
  `uvm_warning("RNDFLD", "Randomization failed for tx")
end

In reply to hackonteur:

It is unfortunate that some vendors choose to disable evaluation of immediate assertions. The many reason people disable assertions is for performance and false warning in their DUT from concurrent assertions. I would recommend that people disable assertions selectivly to their DUT and not globally in any case.

In reply to dave_59:

It is unfortunate that some vendors choose to disable evaluation of immediate assertions.

Even Mentor allows disabling assertions. It is perfectly reasonable to disable assertions, but doing so should not disrupt the normal execution of the testbench. This is common practice in Computer Science.

Never put required logic in assertions.

In reply to hackonteur:

A question on why we cant use something like below:
uvm_create(tx) tx.randomize(); std::randomize(list_of_var) with (constraint_list); tx.randomize(null); // Checks for valid values. uvm_send(tx)

list_of_var can have variable accessed through “tx.var_name”.

Wont this be a easier option. Is there any negatives of using this?

Thank you

I have many sequences that use the `uvm_do_with macro. In order to keep them consistent, I used the mid_do function in some sequence classes to randomize the non-random values. This allows you to set the values after randomization of the item.


my_transaction tx;
task body;
    `uvm_do_with(tx, {array inside{'h11, 'h22};} );
  end
endtask: body

// Customize item before sending
virtual function void mid_do(uvm_sequence_item this_item); 
  tx.configure = $urandom_range(2);
endfunction

In reply to mike.russell.lsi:

My recommendation is to declare all data fields of an transaction/sequence item as rand/randc.
The effort to hold some of the data fields on deterministic values is smaller than assigning random values to non-rand data fileds.