Constraint to generate a pattern

Write a constraint to generate a pattern 10110011100011110000…
I have tried this with constraint but i am not getting the output

1 Like

could you please add wha you tried that did not work.

class pattern;
  rand int intA[$];
  constraint intA_c{
    intA.size()==55;
  }
  
  function void pre_randomize();
    for (int i=0;i<10;i++)begin
      for (int j=0;j<i+1;j++)begin
        intA.push_back(1);
      end
      
      for(int j=0;j<i+1;j++)begin
        intA.push_back(0);
      end
    end
    $display("intA=%0p",intA);
    
    
  endfunction 
  
endclass

module top;
  pattern c_h = new();
  initial begin
    
    c_h.randomize();
    //$display("Pattern = %0p",c_h);
    
  end
  
  
endmodule

I have tried this with pre-randomization i am getting the result but how to do by using constraint i am not getting that logic…

module check;
  class p;
    rand bit a = 1; 
    bit [31:0] b = 2;  // this holds the count of sub-patterns'10'->(2),'1100'-> (4),'111000'-> (6) etc. Increment by 2 					   // once count matches b value which means sub-pattern is done 
    bit [31:0] count = 0; // Every time pattern matches reset the count to '0'
    constraint a_size { if(count == b) a == 1;
                        else if(count == b/2) a == 0;
                        else a == const'(a);   }
    
    function void post_randomize();

      if(count == b) begin 
        b += 2; 
        count = 0; 
      end
      count += 1;
    endfunction
    
  endclass
   
  initial begin
    p p1 = new;
    repeat(30) begin 
      void'(p1.randomize());
      $display(" a value : %0b",p1.a);
    end
  end
endmodule
//output : 

# run -all
#  a value : 1
#  a value : 0
#  a value : 1
#  a value : 1
#  a value : 0
#  a value : 0
#  a value : 1
#  a value : 1
#  a value : 1
#  a value : 0
#  a value : 0
#  a value : 0
#  a value : 1
#  a value : 1
#  a value : 1
#  a value : 1
#  a value : 0
#  a value : 0
#  a value : 0
#  a value : 0
#  a value : 1
#  a value : 1
#  a value : 1
#  a value : 1
#  a value : 1
#  a value : 0
#  a value : 0
#  a value : 0
#  a value : 0
#  a value : 0
# exit

hope this helps.

1 Like

that’s not working for me,actually. Could you simulate and let me know whether it’s working or not?

Interesting sequence. I tinkered with it a bit, noted its “square-root-ness”, but didn’t find the closed form. So, I looked it up on https://oeis.org/.

module top;
  // Write a constraint to generate a pattern
  //    1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, ....
  // ref: https://oeis.org/A118175
  class A118175;
    int unsigned n;
    rand bit value;

    function void post_randomize();
      value = $floor($sqrt(n + 1) + 0.5) - $floor($sqrt(n));
      ++n;
    endfunction
    
    function void print();
      $display("%0d", value);
    endfunction
  endclass

  A118175 gen = new;
  initial begin
    repeat(20) begin
      gen.randomize();
      gen.print();
    end
  end
endmodule
1 Like

It’s one of the alternate solution which I have posted above but we have to solve this by using constraint…

Very fewer chances that we might make it only with constraints. For now i see this pattern requires randomize callback hooks. Will update if any with only constraints.

Its working for me. Try with siemens simulator.
Some simulators might give you the error for const’() as most simulators do not implement this from constraints point of view i feel.

ok sure…

It’s working for seimens…

Here is one way to do it without pre_randomize(), post_randomize(), const’() cast.

package learning;
 
 import uvm_pkg::*;
`include "uvm_macros.svh"

class packet extends uvm_object;
  `uvm_object_utils(packet)
  
  function new(string name = "packet");
    super.new(name);
  endfunction 
  
  rand bit temp[][];
  rand bit arr[];



constraint seq {
    temp.size() inside {[2:10]};
    foreach (temp[i]) { 
      temp[i].size() == (i+1)*2;
      foreach (temp[i][j]) {
        (j <= i) -> temp[i][j] == 1; 
        (j >  i) -> temp[i][j] == 0; 
       }
    }
   
    arr.size() == (temp.size()) * (temp.size()+1); 
      foreach (temp[i,j]) {
          arr[(i*(i+1)) + j] == temp[i][j];
      }
  }
      

  virtual function void printInfo();
      `uvm_info(get_type_name, $sformatf("%p", arr), UVM_LOW)
  endfunction 
endclass


class test extends uvm_test; 
  `uvm_component_utils(test)
  rand packet pkt; 
  function new (string name = "test", uvm_component parent);
    super.new(name, parent);
  endfunction 
  
  task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    super.run_phase(phase);
    
    begin
      pkt = packet::type_id::create("pkt");
      repeat (30) begin
        pkt.randomize(); 
        pkt.printInfo();
      end
    end
    
    phase.drop_objection(this);
  endtask

endclass

endpackage : learning
      
      
      
module top();
  import uvm_pkg::*;
  `include "uvm_macros.svh"
  import learning::*;
  
  initial begin
    run_test("test");
  end
endmodule
1 Like

Good solution!

I have tried this solution. Seems to be working.

Code:

module tb;

class test;

rand int a[];
int x=0,i=0;

constraint c {a.size==20;}

function void post_randomize();
  
  while(i<$size(a))
    begin
      for(int j=0; j<=x; j++)
        begin
        	a[i]=1;
          	i++;
        end
          
      
      for(int j=0; j<=x; j++)
        begin
        	a[i]=0;
          	i++;
        end
      
      x++;
    end
  endfunction

endclass

test h;

initial
begin
h=new;
h.randomize;
$display(“a=%p”,h.a);
end
endmodule

Output:

a='{1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}

1 Like

I have tried it using 2 dimensional dynamic array. -->10110011100011110000…

class packet;
   rand bit arr[ ][ ];
   constraint c1{arr.size==5;}
   
   constraint c2{foreach(arr[i]){
     arr[i].size==(2+(i*2));
     foreach(arr[i,j])if(j<=i)arr[i][j]==1;
                      else arr[i][j]==0;}}
                               
 endclass
module gen_pattern;
  packet p;
  initial begin
    p=new();
    p.randomize();
    foreach(p.arr[i,j])$write("%0d ",p.arr[i][j]);
  end
endmodule