我们假设有一个1920 x 1080的2d像素矩阵。我想约束矩阵,以便在关闭像素(0)附近只有打开像素(1-255)。对于较小的5x4矩阵,模式应为以下形式:
x x x x x 0 x 0 x x x x x 0 x 0 x x x x
假设我不使用如下所述的foreach循环,将是解决此约束的更好方法:
foreach(mat[i][j]){
mat[i][i] = 0;
}
foreach(mat[i][j]){
if(mat[i][j] == 0) begin
mat[i-1][j] = $urandom_range(1,255);
mat[i][j-1] = $urandom_range(1,255);
mat[i-1][j-1] = $urandom_range(1,255);
..etc
end
}
答案 0 :(得分:0)
首先,如果要进行约束随机化,则不能使用$urandom(...)
。您需要使用类和randomize()
函数。
将像素放在matrix
类中:
class matrix;
parameter WIDTH = 10;
parameter HEIGHT = 5;
rand bit pixels[HEIGHT][WIDTH];
// ...
endclass
我使用bit
而不是bit [7:0]
,因为我们想随机化像素是打开还是关闭。可以使用bit [7:0]
,但是像素处于关闭状态的可能性很小。稍后会对此进行更多介绍。
我们对约束条件进行建模,该约束条件指出在所有其他像素均位于关闭像素旁边:
class matrix;
// ...
constraint on_next_to_off {
foreach (pixels[i,j]) {
if (pixels[i][j] == 0) {
pixels[i-1][j-1] != 0;
pixels[i-1][j] != 0;
pixels[i-1][j+1] != 0;
pixels[i][j-1] != 0;
pixels[i][j+1] != 0;
pixels[i+1][j-1] != 0;
pixels[i+1][j] != 0;
pixels[i+1][j+1] != 0;
}
}
}
endclass
我们可以尝试运行它,但是它将失败。这是因为我们没有处理极端情况。如果像素在最上一行,则上方没有像素要约束,因此引用i-1
的约束没有意义,需要排除这种情况。最下一行以及最左和最右列也是如此。我们必须为所有这些情况添加警卫:
class matrix;
// ...
constraint on_next_to_off {
foreach (pixels[i,j]) {
if (pixels[i][j] == 0) {
if (i > 1) {
if (j > 1)
pixels[i-1][j-1] != 0;
pixels[i-1][j] != 0;
if (j < WIDTH-1)
pixels[i-1][j+1] != 0;
}
if (j > 1)
pixels[i][j-1] != 0;
if (j < WIDTH-1)
pixels[i][j+1] != 0;
if (i < HEIGHT-1) {
if (j > 1)
pixels[i+1][j-1] != 0;
pixels[i+1][j] != 0;
if (j < WIDTH-1)
pixels[i+1][j+1] != 0;
}
}
}
}
endclass
要对此进行调试,我们可以向print()
添加matrix
函数:
class matrix;
// ...
function void print();
foreach (pixels[i]) begin
string line;
foreach (pixels[,j])
line = $sformatf("%s %d", line, pixels[i][j]);
$display(line);
end
endfunction
endclass
我们可以使用以下代码进行尝试:
module test;
initial begin
matrix m = new();
if (!m.randomize())
$fatal(0, "randerr");
m.print();
end
endmodule
如果您想使用bit [7:0]
而不是bit
,约束将仍然有效。如上所述,求解器不太可能选择0
作为像素值,因为它有255种其他选择。为了使这种可能性更大,您可以添加一个额外的约束条件,规定像素以相等的概率打开或关闭:
class matrix;
// ...
constraint on_or_off_equal {
foreach (pixels[i,j]) {
pixels[i][j] == 0 dist {
0 := 1,
1 := 1
};
}
}
endclass