Generic Sudoku Using Randomization

Here is one method using unique. If you do not want to use unique, you can just replace unique with an equivalent constraint.

The solution below is not scalable for other sudoku sizes. A 9x9 size sudoku is assumed.




class sudoku;

parameter ROWS =9;
parameter COLS =9;

//mat is the final sudoku 9X9 matrix
rand int mat[ROWS][COLS];
//trans_mat is the transpose of the final sudoku
rand int trans_mat[COLS][ROWS];
// boxes has 9 rows. Each row has the elements of the 3X3 grid in sudoku
// that have unique numbers
rand int boxes[COLS][ROWS];

constraint sudoku {
    //make the numbers in the 3X3 grid unique
    foreach(boxes[i])
        unique {boxes[i]};
    //This effectively makes the cols in the sudoku unique
    foreach( trans_mat[i]) {
          unique {trans_mat[i]};
    }
    //make the rows in the sudoku unique
    foreach( mat[i]) {
          unique {mat[i]};
    }
    //This is essentially saying that the 3X3 boxes are rows in boxes array
    foreach(mat[i,j]) {
        boxes[(3*(i/3)) + (j/3)][(3*(i%3))+(j%3)] == mat[i][j];
    }
    //Constrain for the numbers to be used in the sudoku
    foreach(mat[i,j]) {
      mat[i][j] >0;
      mat[i][j] <=9; 
    }
    //Constrain for mat and trans_mat to be transpose of each other
    foreach(mat[k,j]) {
      mat[k][j] == trans_mat[j][k];
    }
}

//Display each element of matrix
function string display_elem(int k);
    return($psprintf("%0d",k));
endfunction:display_elem

//Display each row matrix
function string display_row(input int row[COLS]);
    string disp_string;
    foreach(row[i])
    begin
      disp_string = {disp_string, "\t",  display_elem(row[i])};
    end
    return disp_string;
endfunction:display_row

//Display each matrix
function display_mat(ref int mat[ROWS][COLS]);
    foreach(mat[i])
    begin
        $display(display_row(mat[i]));
    end
    $display("=====================================");
endfunction:display_mat
//Display all matrices for debug
function display_all_mats();
    display_sudoku();
    display_mat(trans_mat);
    display_mat(boxes);
endfunction:display_all_mats

function display_sudoku();
    display_mat(mat);
endfunction:display_sudoku
endclass

module sudoku_tb();

   sudoku sudoku_h;
   
initial
begin
    sudoku_h = new();
    sudoku_h.randomize();
    sudoku_h.display_sudoku();
    sudoku_h.randomize();
    sudoku_h.display_sudoku();
end
endmodule