Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions