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
ben2
November 23, 2020, 9:46pm
2
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
…
SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats | Verification Academy
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
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!
dave_59
November 23, 2020, 11:10pm
4
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.
ben2
November 23, 2020, 11:15pm
5
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 ;
}