Constraint solver issue, while this constraint sometimes results in errors?

Question:
I have two credit array, a_credit have 2 instance and each have 4 pipes, b_credit have 1 instance and each have 8 pipes. the total 8 pipe of a_credit correspond to the 8 pipe of b_credit, acrdt[0].credit_num[0] corresponds to bcrdt[0].credit_num[0], acrdt[1].credit_num[3] corresponds to bcrdt[0].credit_num[7] and so on.

now i want to randomize one pipe of the 8 pipes, of which corresponding a_credit & b_credit are both greater than 1. So i write the constraint as following, but sometimes it will solve failed.



//----------------------------------------------------------------------
//  Copyright (c) 2018 by Doulos Ltd.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//----------------------------------------------------------------------


package my_package;

parameter A_CREDIT_WIDTH=4;
parameter B_CREDIT_WIDTH=8;

class a_credit;
  int credit_num[A_CREDIT_WIDTH];
endclass

class b_credit;
  int credit_num[B_CREDIT_WIDTH];
endclass
  

endpackage


program GRG_constraint;
  import my_package::*;
  
  a_credit acrdt[2];
  b_credit bcrdt[1];
  bit[2:0] pipe;

initial begin
  
  foreach(acrdt[i])begin
    acrdt[i] = new();
  end
    
  foreach(bcrdt[i])begin
    bcrdt[i] = new();
  end
  
  acrdt[0].credit_num[0] = 6;
  acrdt[0].credit_num[1] = 6;
  acrdt[0].credit_num[2] = 5;
  acrdt[0].credit_num[3] = 3;
  acrdt[1].credit_num[0] = 3;
  acrdt[1].credit_num[1] = 6;
  acrdt[1].credit_num[2] = 5;
  acrdt[1].credit_num[3] = 0;
  
  bcrdt[0].credit_num[0] = 1;
  bcrdt[0].credit_num[1] = 0;
  bcrdt[0].credit_num[2] = 0;
  bcrdt[0].credit_num[3] = 0;
  bcrdt[0].credit_num[4] = 0;
  bcrdt[0].credit_num[5] = 0;
  bcrdt[0].credit_num[6] = 0;
  bcrdt[0].credit_num[7] = 1;
  
  std::randomize(pipe) with {
    //-- pipe < B_CREDIT_WIDTH;
    acrdt[pipe/A_CREDIT_WIDTH].credit_num[pipe%A_CREDIT_WIDTH] > 0;
    bcrdt[0].credit_num[pipe] > 0;
    
  };
  $display("randomized result pipe = %0d", pipe);
  
end

endprogram



the vcs log is as following:

Warning-[LINX_KRNL] Unsupported Linux kernel
Linux kernel ‘5.4.0-153-generic’ is not supported.
Supported versions are 2.4* or 2.6*.

                     Chronologic VCS (TM)
        Version S-2021.09 -- Thu Nov  9 23:48:32 2023

                Copyright (c) 1991 - 2021 Synopsys, Inc.

This software and the associated documentation are proprietary to Synopsys,
Inc. This software may only be used in accordance with the terms and conditions
of a written license agreement with Synopsys, Inc. All other use, reproduction,
or distribution of this software is strictly prohibited. Licensed Products
communicate with Synopsys servers for the purpose of providing software
updates, detecting software piracy and verifying that customers are using
Licensed Products in conformity with the applicable License Key for such
Licensed Products. Synopsys will use information gathered in connection with
this process to deliver software updates and pursue software pirates and
infringers.

Inclusivity & Diversity - Visit SolvNetPlus to read the “Synopsys Statement on
Inclusivity and Diversity” (Refer to article 000036315 at
https://solvnetplus.synopsys.com)

Parsing design file ‘design.sv’
Parsing design file ‘testbench.sv’
Top Level Modules:
GRG_constraint
TimeScale is 1 ns / 1 ns
Starting vcs inline pass…

2 modules and 0 UDP read.
recompiling package my_package
recompiling module GRG_constraint
Both modules done.
rm -f cuarc*.so csrc*.so pre_vcsobj*.so share_vcsobj*.so
if [ -x …/simv ]; then chmod a-x …/simv; fi
g++ -o …/simv -m32 -m32 -rdynamic -Wl,-rpath=‘$ORIGIN’/simv.daidir -Wl,-rpath=./simv.daidir -Wl,-rpath=/apps/vcsmx/vcs/S-2021.09/linux/lib -L/apps/vcsmx/vcs/S-2021.09/linux/lib -Wl,-rpath-link=./ -Wl,–no-as-needed objs/amcQw_d.o _321_archive_1.so SIM_l.o rmapats_mop.o rmapats.o rmar.o rmar_nd.o rmar_llvm_0_1.o rmar_llvm_0_0.o -lvirsim -lerrorinf -lsnpsmalloc -lvfs -lvcsnew -lsimprofile -luclinative /apps/vcsmx/vcs/S-2021.09/linux/lib/vcs_tls.o -Wl,-whole-archive -lvcsucli -Wl,-no-whole-archive /apps/vcsmx/vcs/S-2021.09/linux/lib/vcs_save_restore_new.o /apps/vcsmx/vcs/S-2021.09/linux/lib/ctype-stubs_32.a -ldl -lc -lm -lpthread -ldl
…/simv up to date
CPU time: .277 seconds to compile + .328 seconds to elab + .306 seconds to link
Chronologic VCS simulator copyright 1991-2021
Contains Synopsys proprietary information.
Compiler version S-2021.09; Runtime version S-2021.09; Nov 9 23:48 2023
a = 4, b = 9, c = 29, parity_ok = 1, size = SMALL, len = 20, i = 3, aa = 11, bb = 10
a = 4, b = 9, c = 12, parity_ok = 1, size = SMALL, len = 12, i = 3, aa = 11, bb = 10
a = 4, b = 16, c = 22, parity_ok = 1, size = SMALL, len = 28, i = 2, aa = 01, bb = 00
a = 4, b = 30, c = 13, parity_ok = 1, size = SMALL, len = 18, i = 3, aa = 01, bb = 00
a = 4, b = 18, c = 27, parity_ok = 1, size = SMALL, len = 9, i = 3, aa = 11, bb = 10
a = 4, b = 19, c = 20, parity_ok = 1, size = MEDIUM, len = 15, i = 3, aa = 11, bb = 00
addr0 = 1
addr1 = 2

=======================================================

Solver failed when solving following set of constraints

integer acrdt[1].credit_num[3] = 0;

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(acrdt[1].credit_num[3] > 0);
}

=======================================================

Note-[CNST-SATE] Standalone test extracted
A standalone test-case for this failure has automatically been extracted
from randomize serial 8 partition 2.
To reproduce the error using the extracted testcase, please use the
following command:
cd /home/runner/./simv.cst/testcases;
vcs -sverilog extracted_r_8_p_2_inconsistent_constraints.sv -R
To reproduce the error using the original design and verbose logging, re-run
simulation using:
simv +ntb_solver_debug=trace +ntb_solver_debug_filter=8
To reproduce the error using the original design and debug the error with
Verdi/DVE:

  1. re-compile the original design with -debug_access+all, if not already
    done so
    % vcs -debug_access+all
  2. re-run the simulation interactively with -gui/-verdi
    % simv -gui/-verdi
  3. enter the following commands to begin interactive constraint
    inconsistency debug within Verdi/DVE
    I. set the breakpoint: verdi/dve> stop -solver -serial 8
    II. run the simulation till it stops: verdi/dve> run
    III. step in the constraint solver: verdi/dve> step -solver

Error-[CNST-CIF] Constraints inconsistency failure
testbench.sv, 106
Constraints are inconsistent and cannot be solved.
Please check the inconsistent constraints being printed above and rewrite
them.

pipe = 0
$finish at simulation time 60
V C S S i m u l a t i o n R e p o r t
Time: 60 ns
CPU Time: 0.580 seconds; Data structure size: 0.0Mb
Thu Nov 9 23:48:33 2023

accord to the vcs hint of failure, i add the simulation options, “+ntb_solver_debug=trace +ntb_solver_debug_filter=8”

now i get the following log with the detailed process of solving,

[2023-11-10 05:01:47 UTC] vcs -licqueue ‘-timescale=1ns/1ns’ ‘+vcs+flush+all’ ‘+warn=all’ ‘-sverilog’ design.sv testbench.sv && ./simv +vcs+lic+wait ‘+ntb_solver_debug=trace’ ‘+ntb_solver_debug_filter=8’

Warning-[LINX_KRNL] Unsupported Linux kernel
Linux kernel ‘5.4.0-153-generic’ is not supported.
Supported versions are 2.4* or 2.6*.

                     Chronologic VCS (TM)
        Version S-2021.09 -- Fri Nov 10 00:01:48 2023

                Copyright (c) 1991 - 2021 Synopsys, Inc.

This software and the associated documentation are proprietary to Synopsys,
Inc. This software may only be used in accordance with the terms and conditions
of a written license agreement with Synopsys, Inc. All other use, reproduction,
or distribution of this software is strictly prohibited. Licensed Products
communicate with Synopsys servers for the purpose of providing software
updates, detecting software piracy and verifying that customers are using
Licensed Products in conformity with the applicable License Key for such
Licensed Products. Synopsys will use information gathered in connection with
this process to deliver software updates and pursue software pirates and
infringers.

Inclusivity & Diversity - Visit SolvNetPlus to read the “Synopsys Statement on
Inclusivity and Diversity” (Refer to article 000036315 at
https://solvnetplus.synopsys.com)

Parsing design file ‘design.sv’
Parsing design file ‘testbench.sv’
Top Level Modules:
GRG_constraint
TimeScale is 1 ns / 1 ns
Starting vcs inline pass…

2 modules and 0 UDP read.
recompiling package my_package
recompiling module GRG_constraint
Both modules done.
rm -f cuarc*.so csrc*.so pre_vcsobj*.so share_vcsobj*.so
if [ -x …/simv ]; then chmod a-x …/simv; fi
g++ -o …/simv -m32 -m32 -rdynamic -Wl,-rpath=‘$ORIGIN’/simv.daidir -Wl,-rpath=./simv.daidir -Wl,-rpath=/apps/vcsmx/vcs/S-2021.09/linux/lib -L/apps/vcsmx/vcs/S-2021.09/linux/lib -Wl,-rpath-link=./ -Wl,–no-as-needed objs/amcQw_d.o _321_archive_1.so SIM_l.o rmapats_mop.o rmapats.o rmar.o rmar_nd.o rmar_llvm_0_1.o rmar_llvm_0_0.o -lvirsim -lerrorinf -lsnpsmalloc -lvfs -lvcsnew -lsimprofile -luclinative /apps/vcsmx/vcs/S-2021.09/linux/lib/vcs_tls.o -Wl,-whole-archive -lvcsucli -Wl,-no-whole-archive /apps/vcsmx/vcs/S-2021.09/linux/lib/vcs_save_restore_new.o /apps/vcsmx/vcs/S-2021.09/linux/lib/ctype-stubs_32.a -ldl -lc -lm -lpthread -ldl
…/simv up to date
CPU time: .261 seconds to compile + .352 seconds to elab + .326 seconds to link
Chronologic VCS simulator copyright 1991-2021
Contains Synopsys proprietary information.
Compiler version S-2021.09; Runtime version S-2021.09; Nov 10 00:01 2023
a = 4, b = 9, c = 29, parity_ok = 1, size = SMALL, len = 20, i = 3, aa = 11, bb = 10
a = 4, b = 9, c = 12, parity_ok = 1, size = SMALL, len = 12, i = 3, aa = 11, bb = 10
a = 4, b = 16, c = 22, parity_ok = 1, size = SMALL, len = 28, i = 2, aa = 01, bb = 00
a = 4, b = 30, c = 13, parity_ok = 1, size = SMALL, len = 18, i = 3, aa = 01, bb = 00
a = 4, b = 18, c = 27, parity_ok = 1, size = SMALL, len = 9, i = 3, aa = 11, bb = 10
a = 4, b = 19, c = 20, parity_ok = 1, size = MEDIUM, len = 15, i = 3, aa = 11, bb = 00
addr0 = 1
addr1 = 2

=======================================================
SOLVING constraints
At file testbench.sv, line 106, serial 8

Rng state is: 0x1zzx00x1xzz011001zzzz1x011z000zzzzzxzzxxzxxxxzzxzzzxzzxxzxzzxz
std::randomize


Filtered constraint problem in allocation phase 0

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(acrdt[(pipe / 4)].credit_num[(pipe % 4)] > 0);
(bcrdt[0].credit_num[pipe] > 0);
}



Filtered constraint problem in allocation phase 0 elaboration phase 1

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(acrdt[(pipe / 4)].credit_num[(pipe % 4)] > 0);
(bcrdt[0].credit_num[pipe] > 0);
}


integer bcrdt[0].credit_num[0] = 1;
integer bcrdt[0].credit_num[1] = 0;
integer bcrdt[0].credit_num[2] = 0;
integer bcrdt[0].credit_num[3] = 0;
integer bcrdt[0].credit_num[4] = 0;
integer bcrdt[0].credit_num[5] = 0;
integer bcrdt[0].credit_num[6] = 0;
integer bcrdt[0].credit_num[7] = 1;
rand bit[2:0] pipe; // rand_mode = ON

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(bcrdt[0].credit_num[pipe] > 0);
}

Solving Partition 1 (mode = 2)

Rng state is: 00001zzx0x0zxxxxx10x0100z11xxxxxzxzzzxzzzxzxxzzxzxzxzzzzzzxxzzzz

integer bcrdt[0].credit_num[0] = 1;
integer bcrdt[0].credit_num[1] = 0;
integer bcrdt[0].credit_num[2] = 0;
integer bcrdt[0].credit_num[3] = 0;
integer bcrdt[0].credit_num[4] = 0;
integer bcrdt[0].credit_num[5] = 0;
integer bcrdt[0].credit_num[6] = 0;
integer bcrdt[0].credit_num[7] = 1;
rand bit[2:0] pipe; // rand_mode = ON

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(bcrdt[0].credit_num[pipe] > 0);
}


pipe = 3’h7


Filtered constraint problem in allocation phase 0 elaboration phase 2

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(acrdt[1].credit_num[3] > 0);
}


integer acrdt[1].credit_num[3] = 0;

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(acrdt[1].credit_num[3] > 0);
}

Solving Partition 2 (mode = FAST)

Rng state is: x0x1xxzx10z0x0xxx0zz010x01z10z01zxxzzzxxzxxzzzxzxzxxxzxzxxxxxxzx

integer acrdt[1].credit_num[3] = 0;

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(acrdt[1].credit_num[3] > 0);
}

=======================================================

Solver failed when solving following set of constraints

integer acrdt[1].credit_num[3] = 0;

constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (testbench.sv:106)
{
(acrdt[1].credit_num[3] > 0);
}

=======================================================

Note-[CNST-SATE] Standalone test extracted
A standalone test-case for this failure has automatically been extracted
from randomize serial 8 partition 2.
To reproduce the error using the extracted testcase, please use the
following command:
cd /home/runner/./simv.cst/testcases;
vcs -sverilog extracted_r_8_p_2_inconsistent_constraints.sv -R
To reproduce the error using the original design and verbose logging, re-run
simulation using:
simv +ntb_solver_debug=trace +ntb_solver_debug_filter=8
To reproduce the error using the original design and debug the error with
Verdi/DVE:

  1. re-compile the original design with -debug_access+all, if not already
    done so
    % vcs -debug_access+all
  2. re-run the simulation interactively with -gui/-verdi
    % simv -gui/-verdi
  3. enter the following commands to begin interactive constraint
    inconsistency debug within Verdi/DVE
    I. set the breakpoint: verdi/dve> stop -solver -serial 8
    II. run the simulation till it stops: verdi/dve> run
    III. step in the constraint solver: verdi/dve> step -solver

Error-[CNST-CIF] Constraints inconsistency failure
testbench.sv, 106
Constraints are inconsistent and cannot be solved.
Please check the inconsistent constraints being printed above and rewrite
them.

=======================================================
pipe = 0
$finish at simulation time 60
V C S S i m u l a t i o n R e p o r t
Time: 60 ns
CPU Time: 0.620 seconds; Data structure size: 0.0Mb
Fri Nov 10 00:01:49 2023
Done

it seems that the solver solve the constrint two steps, and the on second step, it just verify if the result of first step satisfy the second constraint.

so i change the constraint to another style, as following, now it becoms right.



//----------------------------------------------------------------------
//  Copyright (c) 2018 by Doulos Ltd.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//----------------------------------------------------------------------


package my_package;

parameter A_CREDIT_WIDTH=4;
parameter B_CREDIT_WIDTH=8;


class a_credit;
  int credit_num[A_CREDIT_WIDTH];
endclass

class b_credit;
  int credit_num[B_CREDIT_WIDTH];
endclass
  

endpackage


program GRG_constraint;
  import my_package::*;
  
  a_credit acrdt[2];
  b_credit bcrdt[1];
  bit[2:0] pipe;

initial begin

  foreach(acrdt[i])begin
    acrdt[i] = new();
  end
    
  foreach(bcrdt[i])begin
    bcrdt[i] = new();
  end
  
  acrdt[0].credit_num[0] = 6;
  acrdt[0].credit_num[1] = 6;
  acrdt[0].credit_num[2] = 5;
  acrdt[0].credit_num[3] = 3;
  acrdt[1].credit_num[0] = 3;
  acrdt[1].credit_num[1] = 6;
  acrdt[1].credit_num[2] = 5;
  acrdt[1].credit_num[3] = 0;
  
  bcrdt[0].credit_num[0] = 1;
  bcrdt[0].credit_num[1] = 0;
  bcrdt[0].credit_num[2] = 0;
  bcrdt[0].credit_num[3] = 0;
  bcrdt[0].credit_num[4] = 0;
  bcrdt[0].credit_num[5] = 0;
  bcrdt[0].credit_num[6] = 0;
  bcrdt[0].credit_num[7] = 1;
  
  std::randomize(pipe) with {
    //-- pipe < B_CREDIT_WIDTH;
    //-- acrdt[pipe/A_CREDIT_WIDTH].credit_num[pipe%A_CREDIT_WIDTH] > 0;
    //-- bcrdt[0].credit_num[pipe] > 0;
    
    foreach(bcrdt[0].credit_num[i]) {
    	(acrdt[i/A_CREDIT_WIDTH].credit_num[i%A_CREDIT_WIDTH] <= 0 || bcrdt[0].credit_num[i] <=0) -> pipe != i;
    }
    
  };
  $display("pipe = %0d", pipe);
  
  
end

endprogram



so, does anyone know the reason? thanks

the code on edaplayground:

constraint problem try demo…

In reply to Yesire-Lincoln:

The issue with your initial approach is related to the fact that SystemVerilog’s constraint solver is not always able to find a valid solution for certain constraints. The constraints you provided are complex, and the solver has difficulty finding a solution that satisfies all of them simultaneously. This is a common challenge in random testing and constraint-based randomization.

In the modified approach, you’ve simplified the constraints, and the solver can now find a solution more easily. This simplification makes the problem more tractable for the solver.

Here are some observations and suggestions:

Complexity of Constraints: The complexity of constraints, including dependencies and relationships between variables, can impact the solver’s ability to find a solution. Simplifying constraints or breaking them down into smaller, more manageable parts can improve solver performance.

Randomization Priority: You’ve used the soft constraint to set priorities (aa and bb). Setting priorities can guide the solver to focus on certain constraints before others. This can be helpful when dealing with conflicting constraints.

Partitioning Constraints: Your modified approach includes a foreach loop to iterate over the elements of bcrdt[0].credit_num. This helps in partitioning the constraints and simplifying the solving process.

Alternative Approaches: If you encounter difficulty in solving constraints, you might consider alternative approaches such as using multiple randomize calls with different constraints or breaking down complex constraints into simpler ones.

Remember that constraint solving is a complex task, and the effectiveness of the solver can depend on the specific constraints, their interdependencies, and the characteristics of the random variables involved. If a solution cannot be found, simplification of constraints and exploring alternative approaches are reasonable strategies.


Rahulvala@gmail.com
Verificaion engineer

In reply to Rahulvala:

OK,I see, thanks very much for your reply and guideline!!!