fvutils / pyvsc

Python packages providing a library for Verification Stimulus and Coverage
https://fvutils.github.io/pyvsc
Apache License 2.0
113 stars 26 forks source link

vsc.if_then Constraint Not Support AND/OR Operation #226

Open hcube123 opened 3 days ago

hcube123 commented 3 days ago

Problem Description

The vsc.if_then constraint do not support and/or operation in the expression.

import vsc

@vsc.randobj
class my_s:
    def __init__(self):
        self.op = vsc.rand_bit_t(1)
        self.sz = vsc.rand_bit_t(1)

    @vsc.constraint
    def s_cons(self):
        with vsc.if_then(self.op == 0 or self.op == 1):
            self.sz in vsc.rangelist([1])

s = my_s()
s.randomize(solve_fail_debug=1)
print(f"op={s.op}, sz={s.sz}")

The output of the above code may be:

op=1, sz=0

Version

pyvsc 0.9.3.10985030023

alwilson commented 3 days ago

In python and, or, and not are more like keywords or short-circuit flow controls than operators that you can override, so they aren't available to pyvsc to override. In the case of that or I don't think the python interpreter even lets pyvsc see the 2nd self.op == 1 expression b/c it short-circuited.

This is what I see when I run with randomize(debug=True):

Initial Model:
  <anonymous> {
    rand unsigned [1] op
    rand unsigned [1] sz
    constraint s_cons {
        if ((op == 0)) {
            sz in [1];
        }
    }
}

You can use &, |, and ~ instead. That said, when playing with ~ I'm not sure how to actually use it. I get is_signed unimplemented exceptions unless I use it on an expression.

List of implemented pyvsc features and operators: https://fvutils.github.io/pyvsc/features.html Pyvsc unit tests using the various operators to know what's regularly tested: https://github.com/fvutils/pyvsc/blob/master/ve/unit/test_constraint_expr.py

Example using some of those bit-wise operators:

import vsc

@vsc.randobj
class my_item_c:
    def __init__(self):
        self.a = vsc.rand_bit_t()
        self.b = vsc.rand_bit_t()
        self.c = vsc.rand_bit_t()
        self.d = vsc.rand_bit_t()

    @vsc.constraint
    def ab_c(self):
        self.a & self.b | self.c
        ~self.d

i = my_item_c()
i.randomize(debug=True)
print(i.a, i.b, i.c, i.d)