Skip to content

[Bug] Solver failure when comparing rand_bit_t field against boolean expression using == #278

@Balajimcr

Description

@Balajimcr

Environment
Python: 3.11
PyVSC: 0.9.4.22122858116

PyVSC fails with a solver error when a rand_bit_t field is compared against a boolean expression using equality (==).

The equivalent SystemVerilog constraint works correctly in SV simulators.

Interestingly, replacing == with != makes the constraint pass in PyVSC.

This appears related to boolean vs bitvector coercion/typing during SMT lowering.

PyVSC Passing Example (!= works)

import vsc


@vsc.randobj
class RgbpRandItem:

  def __init__(self):
    self.AB = vsc.rand_int_t(32)
    self.CD = vsc.rand_int_t(32)
    self.boolean_multi_10 = vsc.rand_bit_t(32)

  @vsc.constraint
  def parameter_range(self):
    self.AB.inside(vsc.rangelist(vsc.rng(-255, 255)))
    self.CD.inside(vsc.rangelist(vsc.rng(-255, 255)))
    self.boolean_multi_10.inside(vsc.rangelist(vsc.rng(0, 1)))

  @vsc.constraint
  def cr0(self):
    self.AB == self.CD
    self.AB != 0

  @vsc.constraint
  def cr1(self):
    self.CD != 0

  @vsc.constraint
  def cr2(self):
    self.boolean_multi_10 != (
        (self.AB >= 0) |
        (self.CD <= 90)
    )


obj = RgbpRandItem()

obj.randomize(solve_fail_debug=1)

print("Randomization PASSED")
print(f"AB                = {obj.AB}")
print(f"CD                = {obj.CD}")
print(f"boolean_multi_10  = {obj.boolean_multi_10}")

PyVSC Failing Example (== fails)

import vsc


@vsc.randobj
class RgbpRandItem:

  def __init__(self):
    self.AB = vsc.rand_int_t(32)
    self.CD = vsc.rand_int_t(32)
    self.boolean_multi_10 = vsc.rand_bit_t(32)

  @vsc.constraint
  def parameter_range(self):
    self.AB.inside(vsc.rangelist(vsc.rng(-255, 255)))
    self.CD.inside(vsc.rangelist(vsc.rng(-255, 255)))
    self.boolean_multi_10.inside(vsc.rangelist(vsc.rng(0, 1)))

  @vsc.constraint
  def cr0(self):
    self.AB == self.CD
    self.AB != 0

  @vsc.constraint
  def cr1(self):
    self.CD != 0

  @vsc.constraint
  def cr2(self):
    self.boolean_multi_10 == (
        (self.AB >= 0) |
        (self.CD <= 90)
    )


obj = RgbpRandItem()

obj.randomize(solve_fail_debug=1)

print("Randomization PASSED")
print(f"AB                = {obj.AB}")
print(f"CD                = {obj.CD}")
print(f"boolean_multi_10  = {obj.boolean_multi_10}")

Failure Output

Problem Set: 3 constraints
  <unknown>:
    (AB == CD);

  <unknown>:
    (boolean_multi_10 == ((AB >= 0) | (CD <= 90)));

  <unknown>:
    boolean_multi_10 in [0..1];

[DEBUG] SolveFailure captured during debug re-run.

solve failure

Observation

The following constraint PASSES successfully in PyVSC:

@vsc.constraint
def cr2(self):
    self.boolean_multi_10 != ((self.AB >= 0) | (self.CD <= 90))

Only the equality (==) version fails.

Why This Appears Valid

The RHS expression:

(self.AB >= 0) | (self.CD <= 90)

is logically boolean.

The LHS:

self.boolean_multi_10

is constrained to:

0 or 1

which mirrors standard SV boolean/integral coercion behaviour.

SystemVerilog handles this correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions