Need help in writing constarints

Hi,

I have to write a constraint to generate random number to enable while sending the data.

Q) write a constraint to generate a random value such that it always has 10 bits as 1 and no two bits next to each other should be 1.

randc bit [31:0] Byte_Enable;
constraint byte_en_max_10 {
$countones(Byte_Enable) == 10;
}

How to write constarint for this point , “no two bits next to each other should be 1

Any inputs would be helpful, my idea is to add a for loop and compare in post_randomize() which is not an effective coding style.

-Regards,
-Raja.

In reply to sraja:



constraint SUM {    
                      foreach(b[i])
                   {
                          if ( i < 31 ) // Else Error :: " Constraint solver out of bound error "
                     soft int'( b[i] + b[i+1] ) == 2'd1 ; 

	            }


               }




This would work .

EDIT :: Curious to see other possible solutions without soft constraint

In reply to MICRO_91:

Hi MICRO_91,

The above condition will not work in my case.I have to generate only 10-1’s out of 32 bit value.In some bit positions i can have consecutive 0’s.

randc bit [31:0] Byte_Enable;

STEP 1) constraint byte_en_max_10 {
$countones(Byte_Enable) == 10;
}

STEP 2) constraint SUM {
foreach(b[i])
{
if ( i < 31 ) // Else Error :: " Constraint solver out of bound error "
( b[i] && b[i+1] ) == 'b0 ; //Making it simple
}
}

STEP 3) solve byte_en_max_10 before SUM.

-Regards,
-Sravan

In reply to sraja:

Did you try my code ?

The solution I gave gives the following results :

01010101010101010101000000 .
00000010101010101010101010

This does have consecutive zeroes as you wish to have .

Also solve byte_en_max_10 before SUM isn’t correct .

**solve a before b is used when a and b are random variables and not constraint Names .
**
I don’t get your statement " .I have to generate only 10-1’s out of 32 bit value "

Hi Micro_91,

Did you try my code ?
No i haven’t used the code. another way which is working but not a good coding style.I am using for loop instead of for each.

First of all its my mistake for the following statement, my intent was different.
Also solve byte_en_max_10 before SUM isn’t correct

I don’t get your statement " .I have to generate only 10-1’s out of 32 bit value "

  • I want to generate a random number which has 10 one’s(1) and rest all other bits zero(0).

-Regards,
-Sravan.

randc bit [31:0] Byte_Enable;
constraint byte_en_max_10 {
$countones(Byte_Enable) == 10;
}
constraint byte_en_next{
foreach (Byte_Enable[i]) a[i] !=a[i+1];
}

In reply to sraja:

So $countones(b) == 10 ( which you mentioned in the original post ) satisfies the 10 ones that you wish .

In reply to n347:
It seems even you didn’t run it before posting here .

This has 2 issues :

(1) For index 31 , it will try to access index 32 due [i+1] which will give Error .
Solution is to use ::


         foreach(b[i])
	 if ( i < 31 )
	 b[i] != b[i+1] ;

(2) Even if you write if condition there is another issue due to conflict between ::
$countones(b) == 10 && b[i] != b[i+1]; .

If out of 32 bits you would have 10 ones , there will be sequence of continous zeroes which contradicts your 2nd constarint

In reply to sraja:


// The below code will help you
class A;
	rand bit [31:0] b;
	bit [31:0] bQ[$:10];
constraint SUM {    
                      foreach(b[i])
                          if ( i < 31 ) // Else Error :: " Constraint solver out of bound error "
                     		soft int'( b[i] + b[i+1] ) == 2'd1 ; 
               }

constraint max_10 {
			$countones(b) == 10;
			unique{b,bQ};
		}

function void post_randomize();
	bQ.push_back(b);
endfunction

endclass

module top;
 A a=new;
 initial begin
	 for(int i=0;i<9;i++)begin
	 	a.randomize();
	 	$display("value of a = %b",a.b);
 	end
 end
endmodule

In reply to MICRO_91:

In reply to sraja:


constraint SUM {    
foreach(b[i])
{
if ( i < 31 ) // Else Error :: " Constraint solver out of bound error "
soft int'( b[i] + b[i+1] ) == 2'd1 ; 
}
}

This would work .
EDIT :: Curious to see other possible solutions without soft constraint

THIS ALSO WORKS FINE.

Hi,
module random_number;
class gen_random;
rand bit [31:0] junk_number;

constraint j_nu {
  $countones(junk_number) == 10;
  
  foreach(junk_number[i])
  {
    (junk_number[i] ==1'b1) -> (junk_number[i+1] == 1'b0);
  }
}

endclass

    initial
      begin
        gen_random g_h;
        g_h = new();
        if(!g_h.randomize())
          $display("FAILED To RANDOMIZE");
        else
          $display("Random Number %0b",g_h.junk_number);
      end

endmodule

This code is not giving any out of bound errors. It directly generates the required random number.

In reply to avpchandra:

Well, I tried running the above code. And, it gives the output as FAILED TO RANDOMIZE. Since, for last i=31, i+1 is out of bounds.

In reply to chiranjeevsinghal:

No need for soft constraint or additional array or post randomize logic.


class A;
  rand bit [31:0] b;
  constraint cnt{
    $countones(b) == 10;
    foreach(b[i]){
      if(i>0) (b[i] & b[i-1]) == 0 ;
    }
  }
endclass
 
module top;
 A a=new;
 initial begin
	 for(int i=0;i<9;i++)begin
	 	a.randomize();
	 	$display("value of a = %b",a.b);
 	end
 end
endmodule