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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions