是否有任何方法可以知道成员在SV中的类中是否被声明为随机

时间:2015-07-15 18:26:59

标签: system-verilog uvm

// 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

因此在函数abc中,根据rand成员值是否与引用类中该成员的值匹配或不匹配,该rand声明了类x的成员,应该是活动的或非活动的。

目的 - 我需要检查rand变量是否与引用类值匹配,然后才应该随机化,否则不是。

我想概括方法abc,对于所有可能的未来变化(所以我不需要修改它,如上例所示),并且我不知道,当一个班级成员可能成为rand或nonrand成员,是否有任何内置方法可以知道,该类成员是否在该类中被声明为rand?

2 个答案:

答案 0 :(得分:2)

您可以稍微改变您对问题的看法。而不是试图为声明为rand的字段禁用随机化,为什么不说当它们被随机化时,它们应该保留它们的值?

根据这个不错的post,SV 2012中有一个新的构造,const'(...)在这种情况下会起作用。不幸的是,我不认为很多供应商都支持它。您的randomize()电话看起来像这样:

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

让我们剖析一下这段代码。在进行任何类型的随机化之前,const(a)将对a的值进行采样。如果随机化之前a的值不等于参考值,那么我们有约束的第二部分,即a应保持其值。我已经在两个模拟器上尝试过这个代码,但它们都不支持(尽管它应该是合法的SV 2012语法)。也许你很幸运有一个支持它的供应商。

你甚至可以为状态变量编写这样的约束,因为它们仍然存在。

如果您无法在模拟器中使用const语法,那么相同的post会显示如何解决此问题。您可以在随机化之前将值存储在对象内,并使用约束中的值:

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

当您想要随机化时,您需要添加以下约束:

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");

您可以在EDAPlayground上找到完整的示例。

您提到您执行随机化的函数是在对象之外定义的。因此,pre_rand_*字段不能是本地/受保护的,这不是很好。您应该考虑将该函数作为类成员并将引用对象传递给它,以便您可以强制执行适当的封装。

答案 1 :(得分:0)

这是不可能的,因为SystemVerilog不提供任何反射功能。您可以使用VPI来解决这个问题,但我不确定VPI的实现对于类的完整程度。

根据你想要做的事情,我会说无论如何实施这样的查询只是为了将来证明你的代码,以防某些字段有一天变为rand。就像将rand修饰符添加到字段中一样,您也可以将其添加到应禁用随机化的字段列表中。两个代码位置都位于同一个文件中,因此很难错过。

当询问状态变量-1时,某个模拟器将返回rand_mode(),但这是非标准的。 LRM明确指出在非随机字段上调用rand_mode()是一个编译错误。