Constraint Pattern problem

I am trying to solve the below constraint but unable to get the right idea. So just randomizing the queue size in constraint block and solving in the post_randomize method the only solution? I even tried to replicate procedural solution in declarative way in constraint block but it is not working. I request someone to shed light on this and educate me with tips and tricks to solve these kind of problems in constraint blocks.

Constraint problem:
Write a constraint to generate a pattern {1,2,2,3,3,3,4,4,4,4}.

Solution using post_randomize method:

class prac;
  rand int arr[];

  
  constraint c1{arr.size == 10;}
  
  function void post_randomize();
    int k = 0;
    for(int i=1;i<10;i++)begin
      for(int j=1;j<=i;j++)begin
        arr[k] = i;
        k++;
      end
  	end
    
  endfunction
 
  
endclass

module tb;
  prac p;
  initial begin
    p = new;
    p.randomize;
    $display("arr=%0p",p.arr);
  end
endmodule

Result:
############ Questa Sim ############
run -all
arr=1 2 2 3 3 3 4 4 4 4
############Synopsys VCS##########
arr='{1, 2, 2, 3, 3, 3, 4, 4, 4, 4}
##################################

1 Like
1 Like

Dear Dave,
This approach gives output as '{1, 22, 333, 4444, 55555, 666666}. My requirement was '{1,2,2,3,3,3,4,4,4,4}. Also simulators like Synopsys VCS are saying “**” operator is illegal to use in constraints. So the code is not portable too. My goal is not to use “post_randomize” because I believe we don’t need many constraint constructs if we can directly use post_randomize method as it can be procedural. Could you please check and guide me.

1 Like

That was meant to give you a hint to the approach.

Generating a non-random series of numbers becomes trivial if you have a function that computes the kth element of the series.

class A;
  function int series(int k);
    int n = 1;
    int t = 1;
    while (t < k) begin
      n++;
      t += n;
    end
    return n;
  endfunction
  rand int arr[15];
  constraint c {
    foreach(arr[i]) arr[i] == series(i+1);
  }
endclass
module top;
  A h = new;
  initial begin
    assert(h.randomize());
    $display("%0p",h.arr);
  end
endmodule
2 Likes

Dear Dave,
Thanks for the solution.I should have put more effort into understanding your previous message. It is really a good idea to use a function in constraint when complex(this actually can help in solving many of my problems). But one question still bothers me is the usage of post_randomize. I really want to understand , is it alright to use post_randomize whenever I want to solve a complex constraint ? or else it is not recommended for any reason? Kindly educate me.

Constraint solving is most effective when all constraints can be applied simultaneously during randomization. Once values are generated in the post_randomize() function, they become unusable with the constraints. While this may not be necessary in every scenario, once values are set in post_randomize(), you are stuck with that.

If you have non-random values to generate, it might be better to push that to pre_randomize() or before calling randomize(). This way, you can use the full language for generating those values, instead of being limited by constraints.

2 Likes