Questions about disabling random variables with rand_mode()

Hello VA,

In the 1800-2017 LRM section 18.8 Disabling random variables with rand_mode() the following description is found:

syntax for the rand_mode() method is as follows:

task object[.random_variable]::rand_mode( bit on_off );
function int object.random_variable::rand_mode();

The object is any expression that yields the object handle in which the random variable is defined.
The random_variable is the name of the random variable to which the operation is applied. If it is not
specified (only allowed when called as a task), the action is applied to all random variables within the
specified object.

It seems a weird choice of delegating two different behaviours for this method (a setter as task and a getter as function) instead of having a set_rand_mode(), get_rand_mode(), but in any case I have the following questions:

  1. Is there any restriction about pre_randomize() and post_randomize() changing the rand_mode of a variable? I did not find any comment in the LRM at first glance, so assume it is allowed, all 3 major simulators seem to accept it.
  2. Is it allowed w.r.t the LRM for a function to call rand_mode() as a task (or any other system task like $fclose)? I understand that section 13.4.4 Background processes spawned by function calls does not explicitly prohibits functions calling tasks only methods that attempt to consume time, so I’d assume an implementation should be smart enough such that during parsing is able to detect if a method will attempt to consume time, again all simulators seem to accept it but, my question is about the LRM not about the tools current behaviour.


In reply to rgarcia07:

There are no restrictions on setting the rand_mode() inside pre/post_randomize, but there could be some complications if you try changing the mode of a nested rand class object and the ordering of it calling the pre/post_randomize methods of those nested object. Probably not a good idea.

The current SystemVerilog LRM has some terminology problems left over from the Verilog, further complicated by features inherited from Vera.

In Verilog, a function must return a value as part of an expression, must have input arguments, cannot have any delays, and cannot be used as a bare statement. Tasks cannot return a value and can only be used as a bare statement. Vera, where much of the testbench features of SystemVerilog came from, did not really make any distinction between tasks or functions; they were just routines. Vera did take advantage of whether a routine had an argument or not to alter its behavior. That’s something that carried into SystemVerilog, but SystemVerilog has no mechanism for the user to write such behavior.

Verilog uses the term “System task” to define what are now called void functions in SystemVerilog, and sometimes uses the terminology “called as a task” also to mean called as a void function. The LRM has to fix all these enigmas, but will take some time. 0002027: calling system tasks from functions - Accellera Mantis