SystemVerilog 中 class 中 class 对象的随机化
Randomization of a class object inside a class in SystemVerilog
class c2;
rand bit[1:0] a;
rand bit[1:0] b;
function void my_print();
$display("a = %b", a);
$display("b = %b", b);
endfunction
endclass
class c1;
rand bit[1:0] i;
rand bit[1:0] j;
rand c2 o2;
function new();
o2 = new();
endfunction
function void my_print();
$display("i = %b", i);
$display("j = %b", j);
endfunction
endclass
program p1;
c1 o1 = new;
c2 o2_local = new;
initial begin
if (o1.randomize() with {o2 == o2_local;}) begin
o1.my_print();
o2.my_print();
end
endprogram
在此程序中,o1.randomize() 的随机化失败。如果我为 o2 使用单独的变量并使用内联约束(比如 o2.a == o2_local.a),那么它就可以工作。
有没有其他方法可以进行这种类型的随机化,因为我原来的 class 包含将近 38 个变量,单独分配会很麻烦。
如果c2中的所有变量class需要随机化"with"没有太大影响,因为"with"仅用于约束某些值,一个简单的方法就可以了所有变量随机化,我怀疑因为这个原因 LRM 并没有过多谈论嵌套 classes
的内联约束
initial begin
if (o1.randomize()) begin
if (o2_local.randomize()) begin
o1.my_print();
o2_local.my_print();
end
end
else $fatal ("Randomize failed");
end
endprogram
正如您已经了解如何约束每个变量,如果仅内联约束特定值,这将有所帮助。
==
运算符在应用于对象时并不像您认为的那样。它只比较句柄。求解器失败,因为它发现 o1.o2
和 o2_local
是不同的对象,因此不是 "equal".
如果 o2_local
不应被随机化改变,那么您可以执行以下操作:
o1.o2 = o2_local;
o1.o2.rand_mode(0);
if (o1.randomize()) begin
o1.print();
o1.o2.print();
end
o1.o2.rand_mode(1);
通过这种方式,您已将 o2_local
分配给 o2
,如果您有任何引用 o2
和 o1
字段的约束,它们将得到解决.
对象等价性问题是所有 OOP 语言的症状。您需要一个函数来考虑对象的所有字段以确定两个对象是否相等:
class c2;
// ...
function bit equals(c2 obj);
return a == obj.a && b == obj.b;
endfunction
endclass
此函数在过程代码中运行良好,但它不会帮助您进行随机化,因为在约束中使用函数比较棘手。
一个丑陋的解决方案也是声明一个扩展到 equals(...)
函数主体的宏,因为展开 ==
语句将在约束中起作用。
class c2;
rand bit[1:0] a;
rand bit[1:0] b;
function void my_print();
$display("a = %b", a);
$display("b = %b", b);
endfunction
endclass
class c1;
rand bit[1:0] i;
rand bit[1:0] j;
rand c2 o2;
function new();
o2 = new();
endfunction
function void my_print();
$display("i = %b", i);
$display("j = %b", j);
endfunction
endclass
program p1;
c1 o1 = new;
c2 o2_local = new;
initial begin
if (o1.randomize() with {o2 == o2_local;}) begin
o1.my_print();
o2.my_print();
end
endprogram
在此程序中,o1.randomize() 的随机化失败。如果我为 o2 使用单独的变量并使用内联约束(比如 o2.a == o2_local.a),那么它就可以工作。
有没有其他方法可以进行这种类型的随机化,因为我原来的 class 包含将近 38 个变量,单独分配会很麻烦。
如果c2中的所有变量class需要随机化"with"没有太大影响,因为"with"仅用于约束某些值,一个简单的方法就可以了所有变量随机化,我怀疑因为这个原因 LRM 并没有过多谈论嵌套 classes
的内联约束 initial begin
if (o1.randomize()) begin
if (o2_local.randomize()) begin
o1.my_print();
o2_local.my_print();
end
end
else $fatal ("Randomize failed");
end
endprogram
正如您已经了解如何约束每个变量,如果仅内联约束特定值,这将有所帮助。
==
运算符在应用于对象时并不像您认为的那样。它只比较句柄。求解器失败,因为它发现 o1.o2
和 o2_local
是不同的对象,因此不是 "equal".
如果 o2_local
不应被随机化改变,那么您可以执行以下操作:
o1.o2 = o2_local;
o1.o2.rand_mode(0);
if (o1.randomize()) begin
o1.print();
o1.o2.print();
end
o1.o2.rand_mode(1);
通过这种方式,您已将 o2_local
分配给 o2
,如果您有任何引用 o2
和 o1
字段的约束,它们将得到解决.
对象等价性问题是所有 OOP 语言的症状。您需要一个函数来考虑对象的所有字段以确定两个对象是否相等:
class c2;
// ...
function bit equals(c2 obj);
return a == obj.a && b == obj.b;
endfunction
endclass
此函数在过程代码中运行良好,但它不会帮助您进行随机化,因为在约束中使用函数比较棘手。
一个丑陋的解决方案也是声明一个扩展到 equals(...)
函数主体的宏,因为展开 ==
语句将在约束中起作用。