约束在2d像素矩阵中

时间:2019-07-01 00:08:38

标签: system-verilog

我们假设有一个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
}

1 个答案:

答案 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