Constraint to Generate Deck of 52 Cards

So, I am trying to generate a deck of 52 cards using constraint. The idea is to take a 52X2 matrix with 1st column representing suites and 2nd column representing ranks.
The constraints would be then each column1 element is within suites and column2 is from ranks. Apart from that, each suite should appear 13 times and each rank 4 times. But this constraint doesn’t seem to work for me as shown below. Can someone please tell where my approach is wrong.

class sample;
rand int x[52][2];
int suites[4] = '{0,1,2,3};
int ranks[13] = '{1,2,3,4,5,6,7,8,9,10,11,12,13};
  
  constraint x_a{
    foreach(x[i,j]){
            x[i][0] inside {suites};
            x[i][1] inside {ranks};
          }
        
            foreach(x[i,j]){
              
              (x.sum() with (x[i][0]==suites[i%4]))==13;
              (x.sum() with (x[i][1]==ranks[i%13]))==4;
            }
       
}
  
 
              endclass

Since I don’t understand your approach, I can’t tell you what is wrong.

However, if you are open to a different approach, consider the following.

You could create a new class named “card”, which would consist of 2 rand properties: suit and rank. Note: I think it is more common to use the word “suit” instead of “suite” for a deck of playing cards.

It might be more meaningful for the suit to be an enum: C, S, H, D (or spell out each word, like CLUB, etc.).

“rank” could still be an “int”, and you could constrain its range:
constraint ranks { rank inside {[1:13]}; }

Then, you can declare a variable “deck” as an array of cards:

rand card deck [52];

This is quite a hard problem to solve using constraints. A better approach is creating a ordered deck of cards, then shuffling them. (See Randomize deck of cards using constraints)

A problem with your approach is you are using the sum() method without referencing any iterated items. Another problem is you have to link the chosen suits with their ranks preventing duplicates.

Here is a different approach

module top;

typedef struct packed {
	int suit;
	int rank;
} TCard;

class TFoo;
	rand TCard cards[52];
	
	constraint c1 {
		foreach(cards[i]) {
			cards[i].suit inside { [0:3] };
			cards[i].rank inside { [1:13] };
		}
		unique { cards };
	}
endclass

TFoo f = new;
int status;

initial repeat(10)
	begin
		
		assert(f.randomize());
	   $display("%p",f.cards);
	   
	end

endmodule

I understand unique in context of 1D arrays. How does it work in the case of structs?

It is still a 1D unpacked array with each element being a packed struct.

1 Like