Skip to content

[BUG] PyVSC Solver Failure with Mixed Signed/Unsigned Arithmetic #280

@Balajimcr

Description

@Balajimcr

Environment
Python: 3.11
PyVSC: 0.9.4.22122858116

PyVSC reports a solve failure for a satisfiable constraint set involving:

two unsigned 32-bit variables (rand_bit_t(32))
one signed 32-bit variable (rand_int_t(32))
multiplication by a negative constant (-2)
a bounded signed result variable

The equivalent SystemVerilog constraint randomises successfully in commercial simulators.

The issue appears to be related to arithmetic type promotion and/or signedness handling when evaluating:

self.C >= ((-2 * self.A * self.B) / 1024)

PyVSC Failing Example (Failing)

import vsc

@vsc.randobj
class Item:

    def __init__(self):
        self.A = vsc.rand_bit_t(32)
        self.B = vsc.rand_bit_t(32)
        self.C = vsc.rand_int_t(32)

    @vsc.constraint
    def c(self):
        self.A.inside(vsc.rangelist(vsc.rng(32, 12288)))
        self.B.inside(vsc.rangelist(vsc.rng(1, 32767)))
        self.C.inside(vsc.rangelist(vsc.rng(-32767, 32767)))

        vsc.solve_order(self.A, self.C)
        vsc.solve_order(self.B, self.C)

       self.C >= ((-2 * self.A * self.B) / 1024)
       self.C <= ((self.A * self.B) / 1024)


obj = Item()
obj.randomize()

print(f"A={obj.A} B={obj.B} C={obj.C}")

PyVSC reports:

Problem Set: 4 constraints

(C >= (((A * B) * -2) / 1024));
(C <= ((A * B) / 1024));
A in [32..12288];
B in [1..32767];

solve failure

Randomisation fails consistently.

Additional Observation: Equivalent Mathematical Expression Solves Successfully

self.C >= -1 * ((2 * self.A * self.B) / 1024)

PyVSC Failing Example (Working)

import vsc

@vsc.randobj
class Item:

    def __init__(self):
        self.A = vsc.rand_bit_t(32)
        self.B = vsc.rand_bit_t(32)
        self.C = vsc.rand_int_t(32)

    @vsc.constraint
    def c(self):
        self.A.inside(vsc.rangelist(vsc.rng(32, 12288)))
        self.B.inside(vsc.rangelist(vsc.rng(1, 32767)))
        self.C.inside(vsc.rangelist(vsc.rng(-32767, 32767)))

        vsc.solve_order(self.A, self.C)
        vsc.solve_order(self.B, self.C)

        self.C >= -1 * ((2 * self.A * self.B) / 1024)
        self.C <= ((self.A * self.B) / 1024)


obj = Item()
obj.randomize()

print(f"A={obj.A} B={obj.B} C={obj.C}")

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