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

[Medium] Enums with nested classes #87

Closed ShreyanJabade closed 3 years ago

ShreyanJabade commented 3 years ago

Hello, Using constraints involving enums inside nested classes does not honor the constraints. Further, the enum equality constraint (self.c1[0].a[0].enum_test == level_e.level_1) also may honor the condition at times, but it does not work always.

I request you to look into this aspect. Thank you

import vsc 
from vsc import *

level_list = [('level_'+str(level), auto()) for level in range(3)]
level_e = Enum('level', dict(level_list))

@vsc.randobj
class Parent:
    def __init__(self):
        self.id = 0
        self.c1 = vsc.rand_list_t(vsc.attr(Child1()))
        for i in range(10):    
            self.c1.append(vsc.attr(Child1()))

        self.c2 = vsc.rand_list_t(vsc.attr(Child2()))
        for i in range(10):
            self.c2.append(vsc.attr(Child2()))

        self.val = vsc.rand_uint16_t(5)

    @vsc.constraint
    def enum_inter_class(self):
        # Does not work
        self.c1[0].a[0].enum_test == level_e.level_1

        with vsc.if_then(self.c1[0].a[0].enum_test == level_e.level_0):
            self.c2[0].x[0].value == 0

        with vsc.else_if(self.c1[0].a[0].enum_test == level_e.level_1):
            self.c2[0].x[0].value == 1

        with vsc.else_then:
            self.c2[0].x[0].value == 2

@vsc.randobj
class Field():
    def __init__(self, name, def_value):
        self.name = name
        self.enum_test = vsc.rand_enum_t(level_e)
        self.value = vsc.rand_uint8_t(def_value)

@vsc.randobj
class Child1:
    def __init__(self):
        self.a = vsc.rand_list_t(vsc.attr(Field('a', 10)))
        for i in range(5):    
            self.a.append(vsc.attr(Field('a', 10)))

        self.b = vsc.rand_list_t(vsc.attr(Field('b', 10)))
        for i in range(5):    
            self.b.append(vsc.attr(Field('b', 10)))

        #self.enum_test = vsc.rand_enum_t(level_e)

    @vsc.constraint
    def test_c(self):
        self.a[0].value < self.a[1].value

@vsc.randobj
class Child2:
    def __init__(self):
        self.x = vsc.rand_list_t(vsc.attr(Field('x', 10)))
        for i in range(5):    
            self.x.append(vsc.attr(Field('x', 10)))

        self.y = vsc.rand_list_t(vsc.attr(Field('y', 10)))
        for i in range(5):    
            self.y.append(vsc.attr(Field('y', 10)))

    @vsc.constraint
    def test_c(self):
        self.x[0].value < self.x[1].value

inst=Parent()
inst.randomize()

for i in range(10):
    inst.randomize()
    print(inst.c1[0].a[0].enum_test)
    print(inst.c2[0].x[0].value)
    print()

Output is:

level.level_0
0

level.level_1
0

level.level_0
0

level.level_2
0

level.level_0
0

level.level_0
0

level.level_1
0

level.level_0
0

level.level_0
0

level.level_1
1
mballance commented 3 years ago

Really good find here. This has been corrected in 0.4.4.