1
// Current Class
class x;
  rand int a;
  int b; // b is nonrandom as of now

  function new();
  endfunction

  function abc;
    // if a != ref.a, where ref is reference object of class x, declared somewhere else
       a.rand_mode(0);
  endfunciton

// Future Possible Class
class x;
  rand int a;
  rand int b; // b is also a random variable now

  function new();
  endfunction

  function abc;
    // if a != ref.a, where ref is reference object of class x, declared somewhere else
       a.rand_mode(0);
    // if b != ref.b, where ref is reference object of class x, declared somewhere else
       b.rand_mode(0);
  endfunciton

So in function abc, depending upon whether a rand member value matches or doesn't match with the value of that member in reference class, that rand declared members of class x, should be active or inactive accordinly.

Purpose - I need to check if a rand variable matches with reference class value then only it should be randomized, otherwise not.

I want to generalize method abc, for all possible future variations (So I don't need to modify it, as done in the above example), and as I don't know, when a class member may become rand or nonrand member, Is there any inbuilt method to know, whether a member of a class is declared as rand or not in that class?

Karan Shah
  • 1,912
  • 1
  • 29
  • 42

2 Answers2

2

You could change your perspective on the problem slightly. Instead of trying to disable randomization for fields that are declared rand, why not say that when they get randomized, they should keep their value?

According to this nice post, there's a new construct in SV 2012, const'(...) that would work in this case. Unfortunately I don't think many vendors support it. Your randomize() call would look like this:

if (!rand_obj.randomize() with {
  const'(a) != ref_obj.a -> a == const'(a);
})
  $fatal(0, "rand error");

Let's dissect this code. const(a) will sample the value of a prior to doing any sort of randomization. If the value of a before randomization is not equal to the reference value, then we have the second part of the constraint that says a should keep its value. I've tried this code on two simulators but it wasn't supported by either (though it should be legal SV 2012 syntax). Maybe you're lucky enough to have a vendor that supports it.

You can write such constraints even for state variables, as they will still hold.

If you can't get the const syntax to work in your simulator, then the same post shows how you could work around the issue. You could store the values prior to randomization inside the object and use those in the constraint:

class some_class;
  rand bit [2:0] a;
  bit [2:0] b;

  bit [2:0] pre_rand_a;
  bit [2:0] pre_rand_b;

  function void pre_randomize();
    pre_rand_a = a;
    pre_rand_b = b;
  endfunction
endclass

When you want to randomize, you'd add the following constraints:

if (!rand_obj.randomize() with {
  pre_rand_a != ref_obj.a -> a == pre_rand_a;
  pre_rand_b != ref_obj.b -> b == pre_rand_b;
})
  $fatal(0, "rand error");

You can find a full example on EDAPlayground.

You mention that your function that does randomization is defined outside of the object. Because of that, the pre_rand_* fields can't be local/protected, which isn't very nice. You should consider making the function a class member and pass the reference object to it, so that you can enforce proper encapsulation.

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53
  • Ok, this works fine. But here b is nonrand variable, and you have randomized it. I have seen in EDA also that it works, but does it not violate LRM? Means is it not like that only rand variable can be used in inline constraints?? – Karan Shah Jul 17 '15 at 07:15
  • @MaheshShah All class fields can be used in any constraint, regardless if they're `rand` or not. You could potentially get constraint violations because the solver isn't allowed to change the value of that variable. That's why we wrote the constraint in such a way that it will never fail for `b` (non-rand). – Tudor Timi Jul 17 '15 at 11:18
  • Yes, b == pre_rand_b constraint will always hold true. Thanks a lot for answer. – Karan Shah Jul 17 '15 at 12:59
0

This isn't possible as SystemVerilog doesn't provide any reflection capabilities. You could probably figure this out using the VPI, but I'm not sure how complete the implementation of the VPI is for classes.

Based on what you want to do, I'd say it anyway doesn't make sense to implement such a query just to future proof your code in case some fields will one day become rand. Just as how you add the rand modifier to the field, you can also add it to the list of fields for which randomization should be disabled. Both code locations reside in the same file, so it's difficult to miss.

One certain simulator will return -1 when interrogating a state variable's rand_mode(), but this is non-standard. The LRM explicitly states that it's a compile error to call rand_mode() on non-random fields.

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53
  • Yes indeed, I am getting compile error for that in QuestaSIM. And another thing is that, this is just an example, actually in my case, function abc, is in another directory, in another file, which will operate on object of class x. So it is not an internal method. Adding that field later on in the list is always possible, but you are talking about some VPI. As I don't know about it, can you please elaborate it, which may help me? – Karan Shah Jul 16 '15 at 03:08
  • @MaheshShah VPI means Verilog Programming Interface. It allows you to write C code that can interrogate the structure of your SystemVerilog code. It's pretty difficult to use and I don't think you'll find support for the full object model. Have a look at the 'Programming Interfaces' chapter of the LRM for more info. – Tudor Timi Jul 16 '15 at 07:09
  • @MaheshShah I don't know what your `abc` function looks like, but wouldn't it be enough to just set `rand_mode(0)` on the whole object? Also, why do you need to disable randomization for all fields and then call randomize on the object? If you want to treat all fields as state variables (i.e. non-random) for a randomization call, just do `obj.randomize(null)`. If you post more detail to your question we might be able to help you find an alternate way. – Tudor Timi Jul 16 '15 at 07:13
  • Thanks for giving info on VPI. I have modified the question and added my purpose & exact conditions in it. Please have a look at it. – Karan Shah Jul 16 '15 at 07:39