How to generate a number with non-consecutive 1's

Hi,

I want to constraint a 32 bit number to have count 1’s ==12 and 1’s should be non-consecutive. I tried following but constraint solver failed.


rand bit[31:0]a;

constraint c1{
 $countones(a) == 12;
foreach(a[i])
  if(i) a[i-1] != a[i];
}




This is what the foreach constraint expanded to

((num[0]) != (num[1]));
   ((num[8]) != (num[9]));
   ((num[10]) != (num[11]));
   ((num[12]) != (num[13]));
   ((num[14]) != (num[15]));
   ((num[16]) != (num[17]));
   ((num[18]) != (num[19]));
   ((num[20]) != (num[21]));
   ((num[22]) != (num[23]));
   ((num[24]) != (num[25]));
   ((num[26]) != (num[27]));
   ((num[28]) != (num[29]));
   ((num[30]) != (num[31]));

Can anyone explain why it skipped num[2], num[3]… and why the constraint solver failed?
Thanks

In reply to UVM_SV_101:


class c; 
    /* I want to constraint a 32 bit number to have count 1's ==12 and 1's should be non-consecutive. 
    I tried following but constraint solver failed. */ 

   rand bit[31:0]a;
 
  constraint c1{
     $countones(a) == 12;
     foreach(a[i])
     if(i>0 && a[i]==1) a[i-1] != a[i];
     }
endclass

module top; 
    timeunit 1ns/100ps;
    `include "uvm_macros.svh"
     import uvm_pkg::*;
     bit clk;  
     bit[31:0] a1;
     c c1; 
      
     initial forever #10 clk=!clk;  
      
     always  @(posedge clk)  begin 
     end 
     
       initial begin 
        c1=new(); 
         repeat(200) begin 
             @(posedge clk);   
             if (!randomize(c1)) `uvm_error("MYERR", "This is a randomize error");
             a1=c1.a;
             ap_12: assert property(@ (posedge clk) $countones(a1) ==12);  
             $display("a1=%b", a1); 
         end 
        
         $finish; 
        end  
 endmodule    
 # a1=10100100010101010010010101000100
# a1=10100101010101010000001010000101
# a1=10010101001010101010010000010001
# a1=10010010100101001010100100010010
# a1=10010100100101010000101010010100
# a1=10010101010000010101001010001010
# a1=10100100101000101000100101010010
# a1=00010100101010100101010010010100
# a1=01001010010101010101010001000100
# a1=01010010101000010001001010010101
# a1=01000101010101000100010100101010
# a1=01010100010010101010101000101000
# a1=10100100000010010101010101001001
# a1=00010100010100010100101010101010
# a1=10101000010101010001010100000101
# a1=01010010010010100101001001001001
# a1=00100010001010010101010010100101
# a1=01010001010010101000101000100101
 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr

** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats | Verification Academy
  2. Free books: Component Design by Example FREE BOOK: Component Design by Example … A Step-by-Step Process Using VHDL with UART as Vehicle | Verification Academy
    Real Chip Design and Verification Using Verilog and VHDL($3) Amazon.com
  3. Papers:

In reply to ben@SystemVerilog.us:

Thanks Ben! That worked. Do you know why my constraint failed?


foreach(a[i])
  if(i) a[i-1] != a[i];

FYI - I am big fan of your assertion implementations. It is always a good learning!

In reply to UVM_SV_101:

Your constraint didn’t allow consecutive 0’s or 1’s, which meant there had to be exactly 16 1’s for that to work.

In reply to UVM_SV_101:
if(i) b[i-1] != b[i]; // i==1 for i==31 to i==1
This constraint forces one of 2 possible patterns:
10101010…0 // or
01010101…1 // See below
That means you are forcing 16 ONEs and 16 ZEROs
//
This constraint $countones(b) == 12;
asks that the vector has 12 ONES. This contradicts the if(i) b[i-1] != b[i][/b] constraint that forces 16 ONEs. Thus, you have a constraint error.


// consider this code
constraint cb{
        //$countones(b) == 12;
        foreach(b[i])
        if(i) b[i-1] != b[i];  // i==1 for i==31 to i==1
        }
        /* 
# b1=01010101010101010101010101010101
# b1=10101010101010101010101010101010
# b1=01010101010101010101010101010101
# b1=01010101010101010101010101010101
# b1=10101010101010101010101010101010
# b1=10101010101010101010101010101010
# b1=10101010101010101010101010101010
# b1=10101010101010101010101010101010
# b1=10101010101010101010101010101010
# b1=10101010101010101010101010101010
# b1=01010101010101010101010101010101
# b1=01010101010101010101010101010101
# b1=10101010101010101010101010101010 */ 

Ben SystemVerilog.us

An alternate solution which works too


  rand bit [31:0] a ;

  constraint ONES { 
  ( a  & (  a << 1 )  ) == 0 ;
   $countones( a )  == 12 ;
                   }