Order and Constraint

I have two questions

  1. How to randomize the order of sequence item fields,

let’s say I have following fields in sequence item
1)[66:0]START
2)[66:0]DATA
3)[66:0]TERM
4)[66:0]SOS
5)[66:0]ECB
6)[66:0]IDLE

Now I want the order of sequence item like
START > DATA > TERM after that from (ILDE, SOS, ECB) any should come in any order and multiple times let’s say like,

START > DATA > TERM > IDLE > IDLE > ECB > SOS > ECB > SOS > SOS > IDLE
START > DATA > TERM > ECB > IDLE > SOS > SOS > ECB > ECB > IDLE

  1. Hi, I have an enum like this,
    typedef enum bit [65:0] {TERM0, TERM1, TERM2, TERM3, TERM4, TERM5, TERM6, TERM7} TERM;

now I want to add the constraint for all fields of TERM like

TERM0: {2’h2, 8’he1, 7’b?, 7’b0, 42’b?} (‘?’ indicates don’t care values)
TERM1: {2’h2, 8’h99, 8’b?, 6’b?, 7’b0, 35’b?}
TERM2: {2’h2, 8’h55, 16’b?, 5’b?, 7’b0, 28’b?}
TERM3: {2’h2, 8’h2d, 24’b?, 4’b?, 7’b0, 21’b?}
TERM4: {2’h2, 8’h33, 32’b?, 3’b?, 7’b0, 14’b?}
TERM5: {2’h2, 8’h4b, 40’b?, 2’b?, 7’b0, 7’b?}
TERM6: {2’h2, 8’h87, 48’b?, 1’b?, 7’b0}
TERM7: {2’h2, 8’hFF, 56’b?}

So how can I write a constraint for these fields and randomize don’t care fields

In reply to Jay Maradia:

Your question is not clear what you mean by “field”. Did you mean to say your sequence_item has a field that could take on the list of possible states: START, DATA, …, IDLE? And you need to send these items serially to your driver? Or did you need to create a dynamic array of fields, with the first element having the START value, then you send the array to the driver? Some code that showed what your sequence_item looks like would help.

It’s possible to have constraints that look at the previous value to constrain the new value, but it might be simpler to simple coerce the values directly.

Since constraints do not support don’t-care values, you have to use a bit mask to specify which bits are random and which bits need a specific value. For example suppose you had 16’h?A?B, then you need a constraint

constraint C { (random_variable & 16'h0F0F) == 16'h0A0B; }

The bits are masked out with 0 become don’t cares.

Here is what I came up with based on the information you gave

module top;
class A;
   rand bit [65:0] field;
   typedef enum bit [65:0] {START=66'h1234, DATA=66'h4567, TERM=66'h0,SOS=66'hABCD, ECB=66'hBEEF, IDLE=66'hDEAD} command_t;
   typedef enum bit [65:0] {TERM0, TERM1, TERM2, TERM3, TERM4, TERM5, TERM6, TERM7} term_t;
   rand command_t command;
   rand term_t term;

   const bit [65:0] pattern_mask[term_t] = '{
				       TERM0: {2'h3, 8'hFF, { 7{1'b0}},            7'h3F, {42{1'b0}}},
				       TERM1: {2'h3, 8'hFF, { 8{1'b0}}, {6{1'b0}}, 7'h3F, {35{1'b0}}},
				       TERM2: {2'h3, 8'hFF, {16{1'b0}}, {5{1'b0}}, 7'h3F, {28{1'b0}}},
				       TERM3: {2'h3, 8'hFF, {24{1'b0}}, {4{1'b0}}, 7'h3F, {21{1'b0}}},
				       TERM4: {2'h3, 8'hFF, {32{1'b0}}, {3{1'b0}}, 7'h3F, {14{1'b0}}},
				       TERM5: {2'h3, 8'hFF, {40{1'b0}}, {2{1'b0}}, 7'h3F, {7{1'b0}}},
				       TERM6: {2'h3, 8'hFF, {48{1'b0}}, {1{1'b0}}, 7'h3F},
				       TERM7: {2'h3, 8'hFF, {56{1'b0}}} };
   const bit [65:0] pattern_data[term_t] = '{
				       TERM0: {2'h2, 8'he1, { 7{1'b0}},            7'b0, {42{1'b0}}},
				       TERM1: {2'h2, 8'h99, { 8{1'b0}}, {6{1'b0}}, 7'b0, {35{1'b0}}},
				       TERM2: {2'h2, 8'h55, {16{1'b0}}, {5{1'b0}}, 7'b0, {28{1'b0}}},
				       TERM3: {2'h2, 8'h2d, {24{1'b0}}, {4{1'b0}}, 7'b0, {21{1'b0}}},
				       TERM4: {2'h2, 8'h33, {32{1'b0}}, {3{1'b0}}, 7'b0, {14{1'b0}}},
				       TERM5: {2'h2, 8'h4b, {40{1'b0}}, {2{1'b0}}, 7'b0, {7{1'b0}}},
				       TERM6: {2'h2, 8'h87, {48{1'b0}}, {1{1'b0}}, 7'b0},
				       TERM7: {2'h2, 8'hFF, {56{1'b0}}} };

   constraint c { 
      command != TERM -> field == command;
      command == TERM -> (field & pattern_mask[term]) == pattern_data[term];
      solve command, term before field; } // improve distribution
endclass
   A a = new;
   initial repeat (50) begin
      assert (a.randomize);
      $displayh(a.field,, a.command.name,,a.term.name);
   end
endmodule

Thanks for your help and efforts.

So as you suggested I have tried the code for question 2 which I asked

  1. Hi, I have an enum like this,
    typedef enum bit [65:0] {TERM0, TERM1, TERM2, TERM3, TERM4, TERM5, TERM6, TERM7} TERM;

now I want to add the constraint for all fields of TERM like

TERM0: {2’h2, 8’he1, 7’b?, 7’b0, 42’b?} (‘?’ indicates don’t care values)
TERM1: {2’h2, 8’h99, 8’b?, 6’b?, 7’b0, 35’b?}
TERM2: {2’h2, 8’h55, 16’b?, 5’b?, 7’b0, 28’b?}
TERM3: {2’h2, 8’h2d, 24’b?, 4’b?, 7’b0, 21’b?}
TERM4: {2’h2, 8’h33, 32’b?, 3’b?, 7’b0, 14’b?}
TERM5: {2’h2, 8’h4b, 40’b?, 2’b?, 7’b0, 7’b?}
TERM6: {2’h2, 8’h87, 48’b?, 1’b?, 7’b0}
TERM7: {2’h2, 8’hFF, 56’b?}

So how can I write a constraint for these fields and randomize don’t care fields

but still, the value of the term is generating as follows,
TERM0 - 66’h00000000000000000
TERM1 - 66’h00000000000000001
TERM2 - 66’h00000000000000002
TERM3 - 66’h00000000000000003
TERM4 - 66’h00000000000000004
TERM5 - 66’h00000000000000005
TERM6 - 66’h00000000000000006
TERM7 - 66’h00000000000000007

not what I want like some should be fixed and some bits are randomized

So can I do that with enum or I have to use struct

please help me.

In reply to J_M:
There was no “struct” in my code.

Since constraint can only handle 2-state values, you have to create two sets of values. The pattern_mask has a mode for each bit: 1 means fixed, 0 means random. The pattern_data has the value for each fixed bit and is 0 for each random bit.

I know that you haven’t mentioned struct,

but I am asking will it solve my problem or not, and if yes then how?

As you have taken 2 enums but I only want enum for TERM so constraint c want work for me because both fields are different, so I only want constraint for TERM

it should not depend on other fields.

only this enum as shown below

typedef enum bit [65:0] {TERM0, TERM1, TERM2, TERM3, TERM4, TERM5, TERM6, TERM7} TERM;

TERM0: {2’h2, 8’he1, 7’b?, 7’b0, 42’b?} (‘?’ indicates don’t care values)
TERM1: {2’h2, 8’h99, 8’b?, 6’b?, 7’b0, 35’b?}
TERM2: {2’h2, 8’h55, 16’b?, 5’b?, 7’b0, 28’b?}
TERM3: {2’h2, 8’h2d, 24’b?, 4’b?, 7’b0, 21’b?}
TERM4: {2’h2, 8’h33, 32’b?, 3’b?, 7’b0, 14’b?}
TERM5: {2’h2, 8’h4b, 40’b?, 2’b?, 7’b0, 7’b?}
TERM6: {2’h2, 8’h87, 48’b?, 1’b?, 7’b0}
TERM7: {2’h2, 8’hFF, 56’b?}

Just let field to be random and just contrain what the bits you care.
Modify the example code a bit for your to try.

module top;
class A;
   rand bit [65:0] field;

   typedef enum {START, DATA, TERM,SOS, ECB, IDLE} command_t;
   typedef enum {TERM0, TERM1, TERM2, TERM3, TERM4, TERM5, TERM6, TERM7} term_t;
   rand command_t command;
   rand term_t term;

   constraint commnad_c { 
      solve command before term; 
      solve command before field; 
      solve term before field; 
      field[65:64] == 2'h2; 
      //add other command constraints here 


      if(command == TERM) {
         //not follow your spec, just for example 
         (term == TERM0) -> (field[63:56] == 8'he1 && field[15:8] == 8'h0); 
         (term == TERM1) -> (field[63:56] == 8'he2 && field[15:8] == 8'h1); 
         (term == TERM2) -> (field[63:56] == 8'he3 && field[15:8] == 8'h2); 
         (term == TERM3) -> (field[63:56] == 8'he4 && field[15:8] == 8'h3); 
         (term == TERM4) -> (field[63:56] == 8'he5 && field[15:8] == 8'h4); 
         (term == TERM5) -> (field[63:56] == 8'he6 && field[15:8] == 8'h5); 
         (term == TERM6) -> (field[63:56] == 8'he7 && field[15:8] == 8'h6); 
         (term == TERM7) -> (field[63:56] == 8'he8 && field[15:8] == 8'h7); 
      }
   }

endclass
   A a = new;
   initial repeat (50) begin
      assert (a.randomize with {command == TERM;});
      $displayh(a.field,, a.command.name,,a.term.name);
   end
endmodule

Thanks for the reply, I will definitely try the same.