Constraint for most recent four numbers are unique out of stream of random number

could you please let me know how to write constraint for the following

stream of random numbers are getting generated. how to write constraints to make sure most recent four numbers are unique.

In reply to srbeeram:
Create a queue of recent numbers and use the unique constraint

class A;
 typedef bit [9:0] number_t;
 rand number_t number;
 number_t recent_numbers[$];
 constraint uniq_recent { unique {number, recent_numbers}; }

 function void post_randomize;
   recent_numbers.push_front(number);
   if (recent_numbers.size() > 4)
      void'(recent_numbers.pop_back());
  endfunction
endclass

In reply to dave_59:

Hi Dave,
I have follow up question on this post. Do simulators remember the last time randomized number? or is unique cyclic in nature? even if unique is cyclic everytime we randomize, how is it really remembering the old values and producing different values in the next randomization? Basically I wanted to know how exactly below code is working, and generating unique numbers to push in queue.

I used your code snippet as below mentioned CHANGE.

class A;
 typedef bit [2:0] number_t;
 rand number_t number;
 rand number_t recent_numbers[$];            //CHANGE: added rand and queue here
 constraint uniq_recent { unique {number, recent_numbers}; }
 
 function void post_randomize;
   recent_numbers.push_front(number);
   if (recent_numbers.size() > 4)
      void'(recent_numbers.pop_back());
  endfunction
endclass

module top();
  A a = new();
  initial begin
    repeat(20) begin
    if(!a.randomize()) $display("Please look into randomization issue");
    $display("recent_numbers = %p",a.recent_numbers);
    end
  end

endmodule : top

Below are the output results,
recent_numbers = '{'h1}
recent_numbers = '{'h3, 'h1}
recent_numbers = '{'h4, 'h7, 'h0}
recent_numbers = '{'h1, 'h2, 'h5, 'h6}
recent_numbers = '{'h3, 'h5, 'h7, 'h4}
recent_numbers = '{'h5, 'h6, 'h7, 'h0}
recent_numbers = '{'h7, 'h4, 'h2, 'h5}
recent_numbers = '{'h1, 'h0, 'h6, 'h3}
recent_numbers = '{'h6, 'h3, 'h0, 'h4}
recent_numbers = '{'h5, 'h1, 'h6, 'h0}
recent_numbers = '{'h7, 'h3, 'h0, 'h5}
recent_numbers = '{'h0, 'h4, 'h3, 'h2}
recent_numbers = '{'h1, 'h5, 'h0, 'h4}
recent_numbers = '{'h1, 'h7, 'h4, 'h6}
recent_numbers = '{'h7, 'h1, 'h3, 'h0}
recent_numbers = '{'h3, 'h4, 'h6, 'h1}
recent_numbers = '{'h4, 'h6, 'h1, 'h7}
recent_numbers = '{'h0, 'h4, 'h2, 'h5}
recent_numbers = '{'h6, 'h4, 'h2, 'h5}
recent_numbers = '{'h0, 'h7, 'h6, 'h5}

Thank you,
Mega

In reply to megamind:
Sorry, I had a typo in my example, recent_numbers was meant to be declared as a queue with [$].

But even though you added the rand keyword, the size of the recent_numbers queue is not random unless there is a constraint on its size. Only post_randomize is changing the size of the queue, and after pushing 4 elements the size remains the same.

As far as each solution looking unique, that is governed by statistics. Since you have 4 3-bit numbers, there is only a 1/4096=0.0002= 0.02% chance that two consecutive solutions would be the same. And that will happen if you change the repeat loop to a larger value.

In reply to dave_59:

Thank you Dave. I often get confused with constraints, as it has many directions, for example inheritance, bidirection, statistical calculations etc. Do you have some best video or paper which covers or summarizes all facets of constraints in one single place, if not do you have some two/three papers which covers everything.

In reply to megamind:

https://verificationacademy.com/sessions/verilog-basics-for-systemverilog-constrained-random-verification

http://www.testandverification.com/wp-content/uploads/2018//DVClub_Europe/John_Dickol.pdf

In reply to dave_59:

Thank you Dave, I watched the useful video link you shared. I have got some follow up questions from your video.

Under the title “Signed Expressions” you have explained how below code will work,
bit signed [2:0] A = -1;
bit [3:0] B = 14;
A + B < 14

First question : why expression will get evaluated in 32 bit context, as I thought it should be evaluated to the highest variable bits in the expression, i.e 4 bit (from previous explanation in the video, please correct me if required)
Second question : I understand the if there is one unsigned value in the expression, whole expression will turn unsigned, my question is for the value, how 3 bit signed value (which is shown as -1) will become unsigned 32’d7 , how did you converted from -1 to 7 ?

In reply to megamind:

Another question is from the slide title as “Distribution Example”

op dist {READ := 20 , WRITE := 15 , NOP := 5};
And you said READ = 50% , WRITE = 40% and NOP = 20%
How do you calculate % value from the distribution numbers ?
May be I am missing something fundamental, it will be a great help if you can quick explain or share the relevant information, so I can understand this topic completely.

Thank you.
Mega

In reply to megamind:

  • 1st Q: The literal 14 is a signed 32-bit decimal number, the largest type in the expression.
  • 2nd Q: A has a 3-bit value 3’sb111. That gets 0-extended to 32’b00000000000000000000000000000111
  • 3rd Q: Percentage = 100 * individual_weight / total_of_all_weights

In reply to dave_59:

Thank you very much Dave :) love you for always providing easy to understand great solutions .

In reply to dave_59:

Hi Dave,
Today I was going through the old post, and found that the calculation is not matching here!

–AS YOU SAID–>>> “3rd Q: Percentage = 100 * individual_weight / total_of_all_weights”

For this distribution :- op dist {READ := 20 , WRITE := 15 , NOP := 5};
In video you mentioned READ = 50% , WRITE = 40% and NOP = 20%

From equation, I was able to calculate as READ = 50% WRITE = 37.5% and NOP = 12.5%
Probably you might have showed round figures.

Thank you,
Mega