Grace90
Grace90

Reputation: 227

Constraint for square sub matrices in a matrix

I have a 9x9 matrix as follows M[9][9] Each A,B,C etc below are sub square matrices of 3x3 so that its a total of 9x9 matrix.

                  A B C

           M  =   D E F

                  G H I

I need to write a constraint for following conditions : Condition 1 : Any given 3x3 sub square matrices A,B etc above should have a unique max value e g

          1 1 1               5 6 6  

     A =  3 2 1          B =  6 9 6 

          3 6 8               6 6 6

Amax = 8 , Bmax = 9.

Condition 2 : Amax != Bmax

Condition 3 : Amax != Dmax

For having a max element for one sub square matrix, follo. code works but I dont know how to make it work for all the sub square matrces,

         class max;  
         bit[4:0] sub_mat[3][3];
         rand bit[4:0] max;

           constraint c3 {
               sub_mat.sum(item1) with (item1.sum(item2) with (int'(item2==max))) ==1;
                   
                         foreach (mat[i,j]){
                            sub_mat[i][j] <= max;
                               }
                           }    
         endclass

Please provide inputs for how to do it for all A,B,C etc sub matrices in bigger matrix M

Upvotes: -1

Views: 246

Answers (2)

Greg
Greg

Reputation: 19112

If I understand correctly, you want M to be a 3x3 where each entry itself is a 3x3, and the max value for each sub 3x3 is unique.

This is achievable if you make sub_mat a rand type in your max class. Then you can define the parent matrix as:

class matrix;
  rand max sub_mat[3][3];
  rand bit[4:0] sub_max [3][3];
  function new();
    string sub_matrix_name;
    foreach(sub_mat[i,j]) begin
      sub_matrix_name = string'( 65 + (3*i)+j ); // "A", "B", "C", etc
      sub_mat[i][j] = new( sub_matrix_name );
    end
  endfunction
  virtual function void pprint();
    foreach(sub_mat[i,j]) begin
      sub_mat[i][j].pprint();
    end
  endfunction
  constraint c1 {
    unique {sub_max};
    foreach(sub_mat[i,j]) {
      sub_mat[i][j].max == sub_max[i][j];
    }
  }
endclass

When randomized and printed, it will provided an output like:

A 22 '{'{0, 18, 3}, '{10, 10, 6}, '{14, 10, 22}}
B 10 '{'{1, 10, 8}, '{1, 6, 4}, '{3, 1, 8}}
C 28 '{'{15, 25, 7}, '{2, 27, 10}, '{28, 2, 0}}
D 19 '{'{8, 4, 2}, '{4, 19, 18}, '{6, 3, 8}}
E  3 '{'{1, 2, 2}, '{0, 1, 1}, '{0, 1, 3}}
F 11 '{'{6, 5, 4}, '{10, 2, 5}, '{1, 10, 11}}
G  6 '{'{5, 0, 1}, '{1, 5, 2}, '{0, 6, 4}}
H 17 '{'{4, 16, 14}, '{16, 16, 0}, '{16, 17, 16}}
I 31 '{'{1, 2, 12}, '{6, 25, 3}, '{2, 26, 31}}

Notes: For readability and debugging, I added new(input string name) and pprint() to your max class. I also had to add some workaround logic because the version of Aldec Riviera on EDAplayground did not like the nested .sum().

Full code: https://www.edaplayground.com/x/rjej

Upvotes: 0

EEliaz
EEliaz

Reputation: 359

I don't follow what are conditions 2 and 3 for, as they are already contained in condition 1.

But if I understand your question correctly, you want to guarantee that each sub matrix has a unique max value. I think the next class will work:

class MyClass;
  bit[4:0] matrix[9][9]; 
  rand bit[4:0] sub_mat[9][3][3];

    // Ensure unique maximum values in sub-matrices
    constraint unique_max_value {
      foreach (sub_mat[i]) {
        bit[4:0] max_val = sub_mat[i].max();
        foreach (sub_mat[j]) {
          if (i != j) {
            max_val != sub_mat[j].max();
          }
        }
      }
    }

     function void post_randomize();
          // Assign sub-matrices into the 9x9 matrix
          for (int i = 0; i < 9; i++) begin
                for (int j = 0; j < 9; j++) begin
                      matrix[i][j] = sub_mat[(i/3)*3+(j/3)][i%3][j%3];
                end
          end
     endfunction
endclass

Note: I didn't check it compiles or works, and it has been a while since I wrote UVM, so take it with a grain of salt.

Upvotes: -1

Related Questions