Constraint for two dimensional array

Two dimensional array need to allocate size and values like below

byte array[i][j];

i and j should be same value i.e square matrix. i and j values should be any number

  1. diagonal matrix left side values should be increment from starting( i=0 and j=0)
  2. diagonal matrix right side should be decrement value from diagonal (Ex in second row i=1 j=3)

Ex:
1 2 4 5 6
2 4 5 6 4
4 5 6 5 3
1 6 4 2 1
6 5 3 2 1

can you elaborate more on this? didn’t get question.

In reply to Juhi_Patel:

  1. In array rows and columns should equal

  2. diagonal value should be same like i=0 j=max_col-1; arr[i]([j=max_col-1-i]== arr[i+1][j-max_col-1-i]) for understanding purpose look at matrix example or you can search in google for diagnoal matrix.

  3. In each row before(left side) diagonal value(column) value should be increment like arr[i][j-1] <arr[i][j].

    1. In each row after(right side) diagonal value(column) value should be decrement like arr[i][j-1] > arr[i][j]

This is an interview Question, interviewer not explained properly to me, its took time to understand question properly.

In reply to Subbi Reddy:
I googled a diagonal matrix and from what I was able to comprehend, except the diagonal elements none of the other values with unidentical index values store zero. And if indeed that is what you are looking for, here is the code:

class packet;

	rand int array [] []; //two dimensional array size randomization
	
	randc int size_i,size_j;

	constraint size_set {size_i > 2 ; size_i < 7; size_j > 2; size_j < 7;}
	
	constraint fixing_size {
		
				array.size == size_i;
								
				foreach(array[size_i]) {
								
							array[size_i].size == size_j;
									
							}
															
				}
	
	constraint array_elements_limit {
	
					foreach(array[size_i,size_j]) {
																		
					if(size_i == size_j) {
																		
					array[size_i][size_j] == 1;
																								
					}
																								
					if(size_i != size_j) {
																				
							array[size_i][size_j] == 0;				
																				
							     }
															
				        }
												
											
					}
	
	constraint rows_equals_columns {size_i == size_j;}

endclass


module diagonal_array;

	initial
	
		begin
		
			packet pkt = new();
			
			repeat (5)
			
				begin
			
					pkt.randomize();
			
					$display("\ni = %0d \t j = %0d",pkt.size_i,pkt.size_j);
						
					$display("\narray : %0p",pkt.array);
					
					$display("\n------------------------------------------------ END OF RANDOMIZATION -----------------------------------------------------");

				end
			
		end

endmodule

In reply to Shashank Gurijala:

your code partially correct:
1. diagonal should be right to left and not left to right
2. diagonal value should be range between 1 to 100 any number i.e [i][j] == [i-1][j+1]
3. you forget before diagonal increment and after diagonal decrement in a row
4. please observe above matrix example and read my comments to get clarity.

In reply to Subbi Reddy:

So instead of zero, every element has to be i-1 and j+1 or is it just the diagonal elements that follow the fashion?

In reply to Subbi Reddy:

And for the diagonal to initiate from the left, you can use a for loop instead of a foreach loop

In reply to Shashank Gurijala:

Diagonal should follow like below from right to left
1 3 1 6
1 4 6 1
1 6 4 3
6 1 1 3

whole output should be

1 2 3 4 6
2 3 4 6 1
2 4 6 3 2
1 6 5 4 3
6 4 3 2 1
Note:

  1. diagonal matrix left side values should be increment from starting
  2. diagonal matrix right side should be decrement value from diagonal
    Ex: row=3 or i=2
    2 and 4 incremented before 6
    3 and 2 decremented after 6

In reply to Subbi Reddy:

I just don’t understand the increment from left and decrement from the right in your question! If it’s increasing from right, it is obv going to be in a decreasing order from the right, right?

In reply to Shashank Gurijala:

Ex: increment happen from left upto reaches to 6 diagonal value position and value decrement happen after or from 6 position

In reply to Subbi Reddy:

I tried my best to understand from you tried to convey. See if the logic is right. If it isn’t, please be more clear with what you need.

class packet;

	rand int array [5] [5];
	
	constraint elements_range_fix {
	
			foreach(array[i,j]) {
								
				array[i][j] inside {[1:5]};
	
							}
	
					}
							 
	constraint element_pattern_fix {
	
	     foreach(array[i,j]) {
										
	         if(i == 0) {
																								
		   foreach(array[j]) {
																													
			if(j == 0 || j < 4) {
																													
				array[i][j] < array[i][j + 1];
																			
							}
																			
			                   }
																																
				   }
																					 
		if(i == 1) {
																	
		   foreach(array[j]) {
																						
			if(j == 0 || j <= 2 ) {
																													
			    array[i][j] < array[i][j + 1];
				  
                                                         }
																	
		       else if(j == 3 || j < 4) {
																													
			    array[i][j] > array[i][j + 1];
																													
				                           }
																																	 
		                            }
																												 
		               }
																					 
		if(i == 2) {
																	
		  foreach(array[j]) {
																						
		     if(j == 0 || j <= 1 ) {
																													
			 array[i][j] < array[i][j + 1];
						
                                                      }
																	
		     else if(j == 2 || j < 4) {
																													
			array[i][j] > array[i][j + 1];
																													
					                  }
																																	 
                                          }
																												 
			       }
																	
	        if(i == 3) {
																	
		   foreach(array[j]) {
																						
		       if(j == 0 || j < 1 ) {
																													
				array[i][j] < array[i][j + 1];
						
                                                       }
																	
		       else if(j == 1 || j < 4) {
																													
			        array[i][j] > array[i][j + 1];
																													
							  }
																																	 
					}
																												 
			   }
																					 
	        if(i == 4) {
																	
		   foreach(array[j]) {
																						
			if(j == 0 || j < 4) {
																													
				array[i][j] > array[i][j + 1];
																																		
							}
																																	 
					    }
																												 
		                 }
										
																 
                         }	  

                }
							 						 
endclass

module diagonal_array;

	initial 
	
		begin
		
			packet pkt = new();
			
			pkt.randomize();
			
			$display("\narray : %0p",pkt.array);
			
		end
		
endmodule

In reply to Shashank Gurijala:

You understand the problem correctly.

i got it output as above code
array : ‘{’{1, 2, 3, 4, 5} , '{1, 2, 3, 4, 2} , '{1, 2, 5, 3, 2} , '{3, 5, 4, 3, 1} , '{5, 4, 3, 2, 1} }

Expected output:
1 2 3 4 5
1 2 3 5 2 ( At 2nd row 5 value is not generated, please check it from your side )
1 2 5 3 2
3 5 4 3 1
5 4 3 2 1

In reply to Subbi Reddy:

add a constraint in your class as shown to make sure all the values you generate are unique values

constraint unique_elements_in_each {
	
			foreach(array[size_j]) {
												
				unique {array[size_j]};
																		
						}
												
						     }

In reply to Subbi Reddy:

The question was to generate increasing and decreasing values as per given conditions.

It was only an eg that you gave. Is it necessary to generate the largest value in every row even if the condition holds?

In reply to Shashank Gurijala:

No Need to generate the largest value in every row, please check result of second row diagonal value generated or not from your side that’s it i added comment above.

class matrix#(parameter size=3);
  
  rand int arr[size][size];
  //helper variable to fix daigonal element
  rand int x;
  constraint c0 {x inside {[1:100]};}
  //if diagonal element then it should be x
  constraint c1 {foreach(arr[i,j]) if(i+j==size-1)  arr[i][j]==x;}
  //if not a diagonal element 
  constraint c2 {foreach(arr[i,j]) if(i+j!=size-1) arr[i][j]==x+((i+j)-size+1);}
  
endclass

module top();
  
  matrix#(5) m1;
  
  initial begin
    m1=new();
    repeat(5) begin
    	m1.randomize();
    	foreach(m1.arr[i])
      		$display("%p",m1.arr[i]);
      $display("///////////////////");
    end
  end
  
endmodule

In reply to Subbi Reddy:

Hi, Please take a look at this approach as well:


class A;
  rand int max_col;
  rand int x[][];
  rand int max_val;
 
  constraint c1{   
    max_col inside {[2:15]};
    (x.size() == max_col);
    foreach(x[i]){
      (x[i].size() == max_col);
    }   
   (max_val inside {[5 : 40]});  
  }
  
  constraint c2 {      
      foreach(x[i,j]) {
        x[i][j] inside {[1:35]};
      } 
  }
  
  constraint c3 {  
    foreach(x[i,j]) {      
      if(i+j == (max_col-1)) {
        (x[i][j] == max_val);
      }
      else {
        if (i+j < (max_col -1)){
          ((x[i][j+1] > x[i][j]));       
        }
        else if (i+j > (max_col -1)){
          ((x[i][j] < x[i][j-1]));
        }  
      }          
    }
  }
endclass

module diagonal_constraint;
  
  A a;
  initial begin
    a = new();
    a.randomize();            
    foreach(a.x[i,j]) begin  
      $display("element of x[%d][%d] = %d ",i,j, a.x[i][j]);
    end
  end
endmodule