// 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?
答案 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()
是一个编译错误。