[SV]SystemVerilog二維數組的初始化和約束

            SystemVerilog 2d array initialization & randomize

 

       前言:二维数组是数组的数组。二维数组被组织成矩阵,矩阵可以表示为行和列的集合。

 

一、SystemVerilog二維數組語法

 

 1.1、SystemVerilog二維數組聲明

data_type     array_name [rows][columns];
int array [2:0][3:0];
  • 二维数组中的数据以表格形式存储,如下图所示。

         

 

 1.2、SystemVerilog二維數組初始化

array = '{ '{0,1,2,3}, '{4,5,6,7}, '{8,9,10,11}};

 

 1.3、SystemVerilog二維數組實例

module two_d_array;
  //declaration of array’s
  int array[2:0][3:0];        //2 dimension array
  
  initial begin
    //array initialization
    array = '{'{0,1,2,3},'{4,5,6,7},'{8,9,10,11}};
  
    //displaying array elements
    $display("-------displaying 2d array-------");
    foreach(array[i,j]) $display("\t array[%0d][%0d] = %0d",i,j,array[i][j]);
  end
endmodule
  • Simulation Output
-------displaying 2d array-------
array3[2][3] = 0
array3[2][2] = 1
array3[2][1] = 2
array3[2][0] = 3
array3[1][3] = 4
array3[1][2] = 5
array3[1][1] = 6
array3[1][0] = 7
array3[0][3] = 8
array3[0][2] = 9
array3[0][1] = 10
array3[0][0] = 11

 

二、SystemVerilog --- Solving Sudoku

       在SystemVerilog中解决数独问题只不过是指定带有约束的规则。有五个限制条件。

 

 2.1、箱(Box)约束

       每个框的值必须在1和N之间,其中N是M*M。m的定义见上图。对于典型的9×9数独,N = 9。

 

 2.2、行(Row)约束

       同一行的方框必须具有唯一的值。

 

 2.3、列(Column)约束

       同一列上的方框必须具有唯一的值。

 

 2.4、块(Block)的约束

       同一个MxM块中的框必须具有唯一的值。

 

 2.5、拼图(Puzzle)的约束

       NxN数组给出了一个需要解决的数独难题。如果指定了该值,则该框必须具有与拼图相同的值(零表示空白框)。如果字谜数组的值都为零,则不存在字谜约束。在本例中,将创建一个新的数独谜题。

 

三、Sudoku class

       以下是数独类的完整列表。查看如何在类中定义这五个约束。solve_this(第64行;说明:solve是SystemVerilog的一个关键字)是主要的解算函数。-简单地随机化这个类将会给我们一个解决方案(如果它存在的话)。打印函数将对解决方案进行美化打印。

class sudoku#( int M = 3 ); // M >= 1
  localparam N = M * M;
  local int unsigned puzzle[N][N];
  rand  int unsigned box   [N][N];
 
  // The value of each box must be between 1 and N.
 
  constraint box_con {
    foreach ( box[row, col] ) {
      box[row][col] inside { [ 1 : N ] };
    }
  }
 
  // The boxes on the same row must have unique values.
 
  constraint row_con {
    foreach   ( box[row, colA] ) {
      foreach ( box[   , colB] ) {
        if ( colA != colB ) { 
          box[row][colA] != box[row][colB];
        }
      }
    }
  }
 
  // The boxes on the same column must have unique values.
 
  constraint column_con {
    foreach   ( box[rowA, col] ) {
      foreach ( box[rowB,    ] ) {
        if ( rowA != rowB ) {
          box[rowA][col] != box[rowB][col];
        }
      }
    }
  }
 
  // The boxes in the same MxM block must have unique values.
 
  constraint block_con {
    foreach   ( box[rowA, colA] ) {
      foreach ( box[rowB, colB] ) {
        if ( rowA / M == rowB / M && 
             colA / M == colB / M && 
             ! ( rowA == rowB && colA == colB ) ) {
          box[rowA][colA] != box[rowB][colB];
        }
      }
    }
  }
 
  // The box must have the same value as the puzzle's if specified (!=0).
 
  constraint puzzle_con {
    foreach ( puzzle[row, col] ) {
      if ( puzzle[row][col] != 0 ) {
        box[row][col] == puzzle[row][col];
      }
    }
  }
 
  // Sudoku solver
 
  function int solve_this( int unsigned puzzle[N][N] );
    this.puzzle = puzzle;
    return this.randomize();
  endfunction: solve_this
 
  // Print the solution.
 
  function void print();
    for ( int i = 0; i < N; i++ ) begin
      if ( i % M == 0 ) $write( "\n" );
      for ( int j = 0; j < N; j++ ) begin
        if ( j % M == 0 ) $write( " " );
        $write( "%3d", box[i][j] );
      end
      $write( "\n" );
    end
  endfunction: print
 
endclass: sudoku