SystemVerilog中类内类对象的随机化

SystemVerilog中类内类对象的随机化,verilog,system-verilog,Verilog,System Verilog,在此程序中,o1的随机化失败。随机化()。如果我为o2取单个变量并使用内联约束(比如o2.a==o2_local.a),那么它就可以工作了 有没有其他方法可以进行这种类型的随机化,因为我的原始类包含几乎38个变量,而且单个赋值会很麻烦。如果c2类中的所有变量都需要随机化,“with”没有太大影响,因为“with”仅用于约束某些值,一个简单的方法可以完成所有变量的随机化,我对此表示怀疑,因为这个原因,LRM没有太多地讨论嵌套类的内联约束 class c2; rand bit[1:0] a;

在此程序中,o1的随机化失败。随机化()。如果我为o2取单个变量并使用内联约束(比如o2.a==o2_local.a),那么它就可以工作了


有没有其他方法可以进行这种类型的随机化,因为我的原始类包含几乎38个变量,而且单个赋值会很麻烦。

如果c2类中的所有变量都需要随机化,“with”没有太大影响,因为“with”仅用于约束某些值,一个简单的方法可以完成所有变量的随机化,我对此表示怀疑,因为这个原因,LRM没有太多地讨论嵌套类的内联约束

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

正如您已经了解了如何约束每个变量一样,这将有助于仅内联约束特定值。

如果c2类中的所有变量都需要随机化“with”没有太大影响,因为“with”仅用于约束某些值,那么一个简单的方法将执行所有变量随机化,我怀疑是因为这个原因,LRM没有太多地讨论嵌套类的内联约束

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.o2
o2\u local
是不同的对象,因此不“相等”

如果随机化不应改变
o2\u local
,则您可以执行以下操作:

 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
通过这种方式,您已将
o2\u local
分配给
o2
,如果您有任何引用
o2
o1
字段的约束,它们将得到解决

对象等价性问题是所有OOP语言的症状。您需要一个考虑对象所有字段的函数来确定两个对象是否相等:

o1.o2 = o2_local;
o1.o2.rand_mode(0);
if (o1.randomize()) begin
  o1.print();
  o1.o2.print();
end
o1.o2.rand_mode(1);
这个函数在过程代码中工作得很好,但它对随机化没有帮助,因为在约束中使用函数更复杂


另一个丑陋的解决方案是声明一个宏,该宏扩展到
equals(…)
函数的主体,因为展开
==
语句将在约束中工作。

应用于对象时
==
操作符不会执行您认为它会执行的操作。它只比较句柄。解算器失败,因为它看到
o1.o2
o2\u local
是不同的对象,因此不“相等”

如果随机化不应改变
o2\u local
,则您可以执行以下操作:

 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
通过这种方式,您已将
o2\u local
分配给
o2
,如果您有任何引用
o2
o1
字段的约束,它们将得到解决

对象等价性问题是所有OOP语言的症状。您需要一个考虑对象所有字段的函数来确定两个对象是否相等:

o1.o2 = o2_local;
o1.o2.rand_mode(0);
if (o1.randomize()) begin
  o1.print();
  o1.o2.print();
end
o1.o2.rand_mode(1);
这个函数在过程代码中工作得很好,但它对随机化没有帮助,因为在约束中使用函数更复杂


另一个丑陋的解决方案是声明一个扩展到
equals(…)
函数体的宏,因为展开
==
语句将在约束中工作。

这里的“嵌套类”不是合适的术语。嵌套类是在另一个类中定义的类。您拥有的是另一个类的对象成员。“嵌套类”在这里不是合适的术语。嵌套类是在另一个类中定义的类。这里有另一个类的对象成员。@Emam:我希望o1的o2有o2_local的值,因为原始数据在o2中,而o2_local只是给o2提供数据。所以我不能用你的代码,因为它不能做o2=o2_local@Emmam:我希望o1的o2具有o2_local的值,因为原始数据在o2中,而o2_local只是将数据提供给o2。所以我不能使用您的代码,因为它不会执行o2=o2\u local是的,我尝试过这个解决方案,但有一个问题是,在执行o1.o2.rand\u模式(0)之后,它不会随机化o2。但如果c2类中存在任何约束,那么这些约束也不会得到解决。这正是我所说的。但是为什么你也要随机化
o2
?从您给出的示例来看,您似乎有一个类型为
c2
的外部随机对象,您只希望
o2
字段包含相同的值。是的,这似乎令人信服。非常感谢您的回答。是的,我尝试过这个解决方案,但有一个问题是,在执行o1.o2.rand_模式(0)之后,它不会随机化o2。但如果c2类中存在任何约束,那么这些约束也不会得到解决。这正是我所说的。但是为什么你也要随机化
o2
?从您给出的示例来看,您似乎有一个类型为
c2
的外部随机对象,您只希望
o2
字段包含相同的值。是的,这似乎令人信服。谢谢你的回答。