fvutils / pyvsc

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

Key error of ordinary for loop and TypeError of list indices in vsc.foreach #216

Open kangshuo1 opened 5 months ago

kangshuo1 commented 5 months ago

Hi! I encountered the problem of reporting keyerror in the for loop but i don't know why. Here is an exampel.

import vsc

@vsc.randobj
class my_s(object):
    def __init__(self) -> None:
        self.a = [i for i in range(10)]
        self.b = vsc.rand_list_t(vsc.int_t(8), 10)

    @vsc.constraint
    def ab_c1(self):
        for i in range(6):
            if i == 0:
                self.b[i] == self.a[i]
            else:
                self.b[i] == self.b[i-1] + self.a[i]

if __name__ == "__main__":
    random1 = my_s()
    random1.randomize()

Output:

kangshuo@oa-wssong1:~/work/f1_constraint$ python3 ./test.py 
Traceback (most recent call last):
  File "./test1.py", line 20, in <module>
    random1.randomize()
  File "/home/kangshuo/work/pyvsc/src/vsc/rand_obj.py", line 162, in randomize
    Randomizer.do_randomize(
  File "/home/kangshuo/work/pyvsc/src/vsc/model/randomizer.py", line 593, in do_randomize
    ri = RandInfoBuilder.build(field_model_l, constraint_l, Randomizer._rng)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/rand_info_builder.py", line 116, in build
    fm.accept(builder)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/field_composite_model.py", line 154, in accept
    v.visit_composite_field(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/rand_info_builder.py", line 429, in visit_composite_field
    super().visit_composite_field(f)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/model_visitor.py", line 68, in visit_composite_field
    c.accept(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/constraint_block_model.py", line 42, in accept
    v.visit_constraint_block(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/rand_info_builder.py", line 176, in visit_constraint_block
    super().visit_constraint_block(c)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/model_visitor.py", line 107, in visit_constraint_block
    self.visit_constraint_scope(c)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/model_visitor.py", line 147, in visit_constraint_scope
    cc.accept(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/constraint_expr_model.py", line 40, in accept
    visitor.visit_constraint_expr(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/rand_info_builder.py", line 227, in visit_constraint_expr
    super().visit_constraint_expr(c)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/model_visitor.py", line 115, in visit_constraint_expr
    c.e.accept(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/expr_bin_model.py", line 178, in accept
    visitor.visit_expr_bin(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/model_visitor.py", line 166, in visit_expr_bin
    e.rhs.accept(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/expr_bin_model.py", line 178, in accept
    visitor.visit_expr_bin(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/model_visitor.py", line 165, in visit_expr_bin
    e.lhs.accept(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/expr_array_subscript_model.py", line 58, in accept
    v.visit_expr_array_subscript(self)
  File "/home/kangshuo/work/pyvsc/src/vsc/model/rand_info_builder.py", line 314, in visit_expr_array_subscript
    self._randset_m.pop(idx)
KeyError: 1

I found that this error does not occur when using vsc.foreach and vsc.if_then.

import vsc

@vsc.randobj
class my_s(object):
    def __init__(self) -> None:
        self.a = [i for i in range(10)]
        self.b = vsc.rand_list_t(vsc.int_t(8), 10)

    @vsc.constraint
    def ab_c1(self):
        with vsc.foreach(self.b, idx=True) as i:
            with vsc.if_then(i == 0):
                self.b[i] == self.a[i]
            with vsc.else_then:
                self.b[i] == self.b[i-1] + self.a[i]

if __name__ == "__main__":
    random1 = my_s()
    random1.randomize()

However, the list indices type of vsc.foreach does not support access to ordinary integer lists (self.a)

Exception while processing constraint: list indices must be integers or slices, not idx_term_c
Traceback (most recent call last):
  File "./test1.py", line 19, in <module>
    random1 = my_s()
  File "/home/kangshuo/work/pyvsc/src/vsc/rand_obj.py", line 82, in __init__
    self.build_field_model(None)
  File "/home/kangshuo/work/pyvsc/src/vsc/rand_obj.py", line 211, in build_field_model
    raise e
  File "/home/kangshuo/work/pyvsc/src/vsc/rand_obj.py", line 208, in build_field_model
    fo.c(self)
  File "./test1.py", line 13, in ab_c1
    self.b[i] == self.a[i]
TypeError: list indices must be integers or slices, not idx_term_c

Do you have any good suggestions to solve this problem? Looking forward to your reply

alwilson commented 2 months ago

I think you need to wrap up self.a as a list_t, which is non-random by default. Then you can append values to it and you'll end up with a list of constant non-random int_t.

import vsc

@vsc.randobj
class my_s(object):
    def __init__(self) -> None:
        self.a = vsc.list_t(vsc.int_t(8))
        for i in range(10):
            self.a.append(i)
        self.b = vsc.rand_list_t(vsc.rand_int_t(8), 10)

    @vsc.constraint
    def ab_c1(self):
        with vsc.foreach(self.b, idx=True) as i:
            with vsc.if_then(i == 0):
                self.b[i] == self.a[i]
            with vsc.else_then:
                self.b[i] == self.b[i-1] + self.a[i]

if __name__ == "__main__":
    random1 = my_s()
    random1.randomize(debug=False)
    print(random1.a)
    print(random1.b)