【发布时间】:2014-06-21 09:28:49
【问题描述】:
我正在尝试基于其他对象来约束整个对象(不仅仅是对象的字段)。这是我的生产代码的精简版:
我有以下课程:
class some_class;
bit[7:0] some_field;
bit[3:0] some_other_field;
// this function would do some complex procedural
// operations on the fields of the object
function void do_some_op();
bit[3:0] tmp = some_field[3:0];
some_field[3:0] = some_other_field;
some_other_field = some_field[7:4];
some_field[7:4] = tmp;
endfunction
function some_class some_function(bit some_param);
some_function = new this;
$display("foo"); // this print here to see that method is executed
if (some_param)
some_function.do_some_op();
endfunction
function void print();
$display("some_field = %x", some_field);
$display("some_other_field = %x", some_other_field);
endfunction
endclass // some_class
这个类包含一些完整的字段。它还有一个方法可以在该类的字段上执行一些复杂的程序。在示例中,我对其进行了简化。我还有另一个类,它返回一个已对其执行操作的新对象。
我有另一个使用some_class 实例的类。根据 Dave 的输入,我已使其首先创建对象(因为 randomize() 不创建对象)。
class some_shuffler;
rand bit params[];
rand some_class objects[];
constraint size_c {
params.size() == objects.size() - 1;
params.size() <= 10;
};
constraint shuffle_c {
// not allowed by standard
// foreach (params[i])
// objects[i+1].some_field == objects[i].some_function(params[i]);
foreach (params[i])
objects[i+1].some_field ==
objects[i].some_function(params[i]).some_field &&
objects[i+1].some_other_field ==
objects[i].some_function(params[i]).some_other_field;
};
function new();
objects = new[10]; // create more objects than needed
foreach (objects[i])
objects[i] = new();
// initialize first object
objects[0].some_field = 8'hA5;
endfunction // new
function void post_randomize();
foreach (objects[i]) begin
$display("objects[%0d]:", i);
objects[i].print();
$display("");
end
endfunction
endclass
这个类有两个数组,一个是执行的操作,一个是中间状态。有一个初始对象。在这个上,some_function 被执行并产生下一个对象。
这就是我想要测试它的方式:
module top;
import some_pkg::*;
initial begin
static some_shuffler shuffler = new();
bit rand_ok;
rand_ok = shuffler.randomize() with {
params.size() == 1;
};
assert (rand_ok);
end
endmodule
当试图直接约束对象时,我立即得到约束违规。模拟器似乎试图使 2 个句柄相等。无论如何,这都是标准所禁止的,我不再这样做了(尽管编译失败会很好)。我已经按照 Dave 和 Greg 的建议解开了约束(我认为 some_function().some_field 是非标准的,但它可以在 Questa 中编译)。
即使是现在,foo 打印也不会出现在命令行上(some_function() 没有被执行)。我看到的是 objects[1] 包含初始值(两个字段全为 0)。
我不能只生成参数列表,然后在程序上随机化每次迭代的对象,因为我希望能够将最后一个对象约束为具有特定值 - 基本上是为约束求解器提供开始和结束点,让它找出到达那里的方法。
【问题讨论】:
-
这可能有助于解释显示您希望最终数据结构是什么样子的一些示例。然后你希望随机化如何在不尝试将其放入 SV 语法的情况下工作。
-
@dave_59 我正在尝试构建一个魔方求解器。我做了一个小例子,让问题更容易理解。这个想法是有一个动态的立方体状态数组和另一个移动数组。索引将代表时间步长。一个立方体在某个时间的状态取决于前一个立方体的移动和状态。我想看看约束求解器是否可以找到洗牌立方体的解决方案。
-
我已经通过在我的对象中使用
pack()和unpack()方法并使用比特流而不是对象来解决这个问题。类似于cube_stream[i+1] == turn_cube(cube_stream[i].pack, turn[i]),其中turn_cube()将使用unpack()创建一个立方体。 -
无论如何都没有用,因为就像你说的,求解器将方法的输入视为状态变量。最后,它基本上只是在做愚蠢的猜测。它甚至无法解决仅洗牌 3 次的立方体。
标签: system-verilog