fvutils / pyvsc Goto Github PK
View Code? Open in Web Editor NEWPython packages providing a library for Verification Stimulus and Coverage
Home Page: https://fvutils.github.io/pyvsc
License: Apache License 2.0
Python packages providing a library for Verification Stimulus and Coverage
Home Page: https://fvutils.github.io/pyvsc
License: Apache License 2.0
It seems like the first entry in the post_randomize() method doesn't work well for all the cases.
I am trying to get the value in the post_randomize() method after each randomization call and trying to append that in post_randomize() method only like this.
Logically, If I'm calling randomize() function for 5 times then I must get 5 elements in the self.temp list but I am getting only four values in the list after the randomization.
As you can see, I have an empty list in the post_randomize() even after appending the first random enum elements into it.
Maybe I am missing something.
Can you help me out with this issue?
Hi Matthew,
1- Assume that I have a standalone a = vsc.bit_t(32, 1024)
. Is there a way to partially select and check variable a? For example, does PyVSC provide a mechanism to directly check the lower 16 bits of variable a? I know that it's provided in the constraint programming side of PyVSC, so I was curious if it's doable for standalone variables as well. Anyhow, this is not an essential needed feature as we can use the a.get_val()
which returns an integer
object and then manipulate it.
2- It seems like the get_val()/set_val() issue that was fixed in #22 still exists for the enum type standalone variables (say if I have a = vsc.enum_t(my_e), I can't call set/get value for a).
Thanks,
Hodjat
Your blog posts in http://bitsbytesgates.blogspot.com/search/label/PyVSC would form a nice chapter with background info, or some parts could be a tutorial, but for now I would just add that link to the introduction.
https://py-vsc.readthedocs.io/en/latest/reference.html#vsc.attrs.rand_attr and other places have
Created on Jul 23, 2019
@author: ballance
which looks strange.
Hi @mballance
I was trying to implement an example for the randomization process like this
import vsc
from enum import Enum, auto
class Numbers(Enum):
Zero = 0
One = auto()
Two = auto()
Three = auto()
class more_numbers(Enum):
Eight = 8
Nine = auto()
@vsc.randobj
class parent_0:
def __init__(self):
self.count = vsc.rand_enum_t(Numbers)
@vsc.randobj
class parent_1():
def __init__(self):
self.list_count = vsc.randsz_list_t(vsc.enum_t(Numbers))
@vsc.randobj
class child_0(parent_0):
def __init__(self):
super().__init__()
self.name = vsc.rand_enum_t(more_numbers)
@vsc.randobj
class child_1(parent_1):
def __init__(self):
super().__init__()
self.child_0_ins = []
self.length = vsc.uint8_t(10)
def pre_randomize(self):
#self.list_count = [None] * self.length
pass
def post_randomize(self):
self.child_0_ins = [None] * 4
for i in range(3):
print=("PS: list_count", self.list_count)
self.child_0_ins[i] = child_0()
self.child_0_ins[i].count = self.list_count[i]
@vsc.constraint
def list_count_size(self):
self.list_count.size == 10
child_1_ins = child_1()
child_1_ins.randomize()
print("List_Count ", child_1_ins.list_count)
After experimenting with every possibility, I am getting an attribute error as
I am trying to call the randomize() with the child_1 class instance to update the count variable of parent_0 class with a parent_1 list_count element.
I might be missing something here.
Can you help me with this issue?
Hi @mballance
I came across a situation where I am not able to use the list_field.size
inside the constraint block.
I am attaching a test case for you for a better understanding of this issue.
import vsc
from enum import IntEnum, auto
class reg_t(IntEnum):
A = 0
B = auto()
C = auto()
D = auto()
E = auto()
F = auto()
G = auto()
@vsc.randobj
class my_c:
def __init__(self):
self.offset = vsc.randsz_list_t(vsc.int32_t())
self.reg = vsc.randsz_list_t(vsc.enum_t(reg_t))
self.num_of_regs = vsc.rand_uint32_t()
self.reserved_regs = vsc.randsz_list_t(vsc.enum_t(reg_t))
self.max_offset = vsc.rand_uint32_t()
@vsc.constraint
def num_of_reg_c(self):
self.num_of_regs == 2
self.reserved_regs.size == 3
@vsc.constraint
def reg_c(self):
vsc.solve_order(self.num_of_regs, self.reg)
self.reg.size == 2 # self.num_of_regs
self.offset.size == 2 # self.num_of_regs
with vsc.foreach(self.reg, idx=True) as i:
self.reg[i].not_inside(vsc.rangelist(self.reserved_regs, reg_t.A))
vsc.unique(self.reg)
@vsc.constraint
def offset_c(self):
with vsc.foreach(self.offset, idx=True) as i:
self.offset[i] in vsc.rangelist(vsc.rng(0, self.max_offset - 1))
obj = my_c()
for i in range(20):
obj.randomize()
print(obj.reg)
print(obj.num_of_regs)
print(obj.offset)
As you can see in constraint reg_c, I am not able to constraint the reg list size using self.num_of_regs
.
With Direct values, It's working but that is not I am expecting at all.
With these two statements
self.reg.size == self.num_of_regs
self.offset.size == self.num_of_regs
the error is something like this
Also, I am assuming this line is redundant.
Line 369 in 5c2aff0
Please have a look at this.
Thanks and regards,
Anil
Hi Matt,
I have this small test and have a few questions regarding it:
@vsc.covergroup
class my_cg(object):
def __init__(self):
self.with_sample(dict(
a=vsc.uint8_t(),
b=vsc.uint8_t()))
self.a_cp = vsc.coverpoint(self.a, bins=dict(
a_bins=vsc.bin_array([4], [0, 16])
))
my_cg_1 = my_cg()
my_cg_2 = my_cg()
for i in range(8):
my_cg_1.sample(i, 0)
for i in range(16):
my_cg_2.sample(i, 0)
str_report = vsc.get_coverage_report(details=True)
print("Report:\n" + str_report)
If I run this, it gives me below results:
Report:
TYPE my_cg : 50.000000%
CVP a_cp : 50.000000%
Bins:
a_bins : 4
a_bins : 20
a_bins : 0
a_bins : 0
INST my_cg : 50.000000%
CVP a_cp : 50.000000%
Bins:
a_bins : 4
a_bins : 4
a_bins : 0
a_bins : 0
INST my_cg_1 : 100.000000%
CVP a_cp : 100.000000%
Bins:
a_bins : 4
a_bins : 4
a_bins : 4
a_bins : 4
1- Results for the two instances make sense (just a minor comment, it doesn't seem to print correct names for the two instances (my_cg and my_cg1 instead of my_cg1 and my_cg2), same issue exists when multiple covergroups (TYPEs)). However, what I am concerned about is the "overall" results for the TYPE (first few lines in the above results). Especially, that "20" doesn't make sense for the second partition.
2- Say that we have multiple covergroups (each with multiple coverpoints). Is there a way to get an overall coverage report? I can see reports for individual covergroups/instances, but I'm wondering if there is a way to get the aggregated report.
Thanks,
Hodjat
Hi Matthew,
Perhaps I'm missing something here, but I was trying to use get/set_val
methods for a scalar attribute. Is this small piece of code valid?:
import vsc
x = vsc.int_t(8, 0xff)
print(x.__dir__()) # set_val() and get_val() are in the list
print("{}\n".format(x.get_val()))
Error: AttributeError: 'NoneType' object has no attribute 'get_val'
However, I can change the value of the object with x.val
attribute.
Thanks,
Hodjat
Covergroup instances are currently named , _1, etc. A mechanism should be provided that would allow a user to specify a more-meaningful instance name
Hello, this is more an issue of the 'pyboolector' dependency. (And after a superficial search 'pyvsc' in the only package which directly relies on 'pyboolector'.)
Not actually sure, but guessing that the package is coming from this github repo which as an fork does not allow issues I thought this might the best place to report the issue.
Starting with Python 3.9 I get the following error message:
STEP 4: RUN pip install --no-cache-dir -r requirements.txt
Collecting pyvsc
Downloading pyvsc-0.2.8.20201222.1-py2.py3-none-any.whl (240 kB)
|████████████████████████████████| 240 kB 1.5 MB/s
Collecting pyboolector
Downloading PyBoolector-3.2.1.20201201.2.tar.gz (20 kB)
ERROR: Command errored out with exit status 1:
command: /usr/local/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-5bcujxdm/pyboolector_9a7ddce85e0e4e36a3cc1d856fc8cffd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-5bcujxdm/pyboolector_9a7ddce85e0e4e36a3cc1d856fc8cffd/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-5o0zmkn8
cwd: /tmp/pip-install-5bcujxdm/pyboolector_9a7ddce85e0e4e36a3cc1d856fc8cffd/
Complete output (5 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-install-5bcujxdm/pyboolector_9a7ddce85e0e4e36a3cc1d856fc8cffd/setup.py", line 15, in <module>
with open(cmakelists_txt, "r") as f:
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-install-5bcujxdm/CMakeLists.txt'
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
Please let me know if more information is required. Thanks!
Hi,
System Verilog has a rand case property, that specifies the probability of any case statement to be selected. We tried some workaround but haven't found the solution. So, can we have support for the same in pyvsc or some other way to do it?
Thanks & Regards,
Ishita
Hi,
I have written pyvsc coverage for adder, I have seen pyvsc documentation. but not sure about to coverage data that i am getting while running tests .
i have installed the pyucis-viewer and pyucis but not sure how to open cov.xml in pyucis-viewer.
test link: https://github.com/Divyanirankari/cocotb_tests/blob/master/pyvsc_tests/adder/tests/test_adder.py
log file:
a.log
Hi @mballance ,
I am trying to use following code for randomize_with().
import vsc
@vsc.randobj
class my_sub_s(object):
def __init__(self):
self.has_rs1 = 1
self.has_rs2 = 1
self.has_rd = 1
self.avail_regs = vsc.rand_list_t(vsc.uint8_t(0), 10)
self.reserved_rd = vsc.rand_list_t(vsc.uint8_t(0), 10)
self.reserved_regs = vsc.rand_list_t(vsc.uint8_t(0), 10)
self.rd = vsc.rand_uint8_t(0)
self.rs1 = vsc.rand_uint8_t(0)
self.rs2 = vsc.rand_uint8_t(0)
self.format = 2
obj = my_sub_s()
with obj.randomize_with() as it:
with vsc.if_then(obj.avail_regs.size > 0):
with vsc.if_then(obj.has_rs1):
obj.rs1.inside(vsc.rangelist(obj.avail_regs))
with vsc.if_then(obj.has_rs2):
obj.rs2.inside(vsc.rangelist(obj.avail_regs))
with vsc.if_then(obj.has_rd):
obj.rd.inside(vsc.rangelist(obj.avail_regs))
with vsc.foreach(obj.reserved_rd, idx = True) as i:
with vsc.if_then(obj.has_rd):
obj.rd != obj.reserved_rd[i]
with vsc.if_then(obj.format == 2):
obj.rs1 != obj.reserved_rd[i]
with vsc.foreach(obj.reserved_regs, idx = True) as i:
with vsc.if_then(obj.has_rd):
obj.rd != obj.reserved_regs[i]
with vsc.if_then(obj.format == 2):
obj.rs1 != obj.reserved_regs[i]
And it is giving an error like following:
File "9usecase.py", line 30, in <module>
with vsc.if_then(obj.format == 2):
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/constraints.py", line 146, in __init__
to_expr(e)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/types.py", line 236, in to_expr
raise Exception("Element \"" + str(t) + "\" isn't recognized, and doesn't provide to_expr")
Exception: Element "True" isn't recognized, and doesn't provide to_expr
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "9usecase.py", line 36, in <module>
obj.rs1 != obj.reserved_regs[i]
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/rand_obj.py", line 186, in __exit__
Randomizer.do_randomize([model], [c])
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/model/randomizer.py", line 694, in do_randomize
constraint_l.extend(ArrayConstraintBuilder.build(
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/visitors/array_constraint_builder.py", line 45, in build
m.accept(builder)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/model/constraint_block_model.py", line 42, in accept
v.visit_constraint_block(self)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/visitors/constraint_copy_builder.py", line 85, in visit_constraint_block
super().visit_constraint_block(c)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/model/model_visitor.py", line 102, in visit_constraint_block
self.visit_constraint_scope(c)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/visitors/constraint_override_visitor.py", line 26, in visit_constraint_scope
cc.accept(self)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/model/constraint_foreach_model.py", line 47, in accept
v.visit_constraint_foreach(self)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/visitors/array_constraint_builder.py", line 61, in visit_constraint_foreach
self.override_constraint(scope)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/visitors/constraint_override_visitor.py", line 37, in override_constraint
self.scope_s[-1].constraint_l[self.scope_i],
IndexError: list index out of range
I am not able to understand what is the cause, can you please take a look into this?
Thanks & Regards,
Shraddha Devaiya.
Hi @mballance
As we know System Verilog has solve before constraint property, to specify the order of constraint solving. We tried to found some alternatives, but haven't found the solution. So, can we have support for the same in pyvsc or some other way to do it?
Thanks & Regards,
Yash
I was trying to access the parent class variable in child class constraints as in the test example below.
import vsc
@vsc.randobj
class parent:
def __init__(self):
self.num = 0
self.temp = []
def pre_randomize(self):
for i in range(10):
self.temp.append(i**2)
self.num = len(self.temp)
print("num = ", self.num)
@vsc.randobj
class child(parent):
def __init__(self):
super().__init__()
self.data = vsc.rand_uint32_t()
@vsc.constraint
def data_c(self):
print("Inside data_c")
print("Inside data_c num = ", self.num)
self.data < self.num
def pre_randomize(self):
super().pre_randomize()
child_ins = child()
print("Before calling randomize()")
child_ins.randomize()
print("After calling randomize()")
print("Data ", child_ins.data)
I found that the constraint of child class being called after the creation of the child class object. Is this expected?
Ideally, the constraint should be checked only after we call the randomize() method.
Hi @mballance,
I was trying to use range in weighted distribution with Enum type values, because if we have many values in Enum class, then it seems little impractical to add every values between certain range in weighted distribution constraint. So, I was trying following code :
import vsc
from enum import Enum,auto
class my_e(Enum):
A = 0
B = auto()
C = auto()
D = auto()
@vsc.randobj
class my_c(object):
def __init__(self):
self.a = vsc.rand_enum_t(my_e)
#self.a = vsc.rand_list_t(vsc.bit_t(7),15)
#self.a = vsc.rand_uint8_t()
@vsc.constraint
def dist_a(self):
#with vsc.foreach(self.a, idx=True) as i:
vsc.dist(self.a, [ vsc.weight(vsc.rng(my_e.A, my_e.C),10) vsc.weight(my_e.D, 20)])
my = my_c()
# Randomize
for i in range(10):
my.randomize()
print("MY ITEM : ",i+1)
print(my.a)
But for this rightnow we are getting syntax error. So, can you please take a look into this?
Thanks & Regards,
Shraddha Devaiya.
Hi Matthew,
I need to define some coverpoints with enum/list type, but I guess build_coverpoint()
method doesn't work properly if cp_t=enum type
or cp_t=list type
. It throws a ZeroDivisionError due to not properly detecting the coverItems
.
Thanks,
Hodjat
Hi @mballance ,
I was trying this code, but it is giving an error for constraint failure.
import vsc
@vsc.randobj
class my_s(object):
def __init__(self):
super().__init__()
self.num_of_nested_loop = vsc.rand_bit_t(8)
self.loop_init_val = vsc.rand_list_t(vsc.uint8_t())
@vsc.constraint
def ab_con(self):
self.num_of_nested_loop.inside(vsc.rangelist(1,2))
self.loop_init_val.size == self.num_of_nested_loop;
item = my_s()
for i in range(5):
item.randomize()
print("A = ",item.num_of_nested_loop,", B = ",item.loop_init_val)
and this is giving an error like following :
Failed constraints:
[1]: num_of_nested_loop in [2, 1];
[1]: num_of_nested_loop in [2, 1];
[2]: (size == num_of_nested_loop);
[2]: (0 == num_of_nested_loop);
Solve failure
Traceback (most recent call last):
File "usecase.py", line 22, in <module>
item.randomize()
File "/home/shraddha/.local/lib/python3.6/site-packages/vsc/rand_obj.py", line 107, in randomize
Randomizer.do_randomize([model])
File "/home/shraddha/.local/lib/python3.6/site-packages/vsc/model/randomizer.py", line 855, in do_randomize
r.randomize(ri, bounds_v.bound_m)
File "/home/shraddha/.local/lib/python3.6/site-packages/vsc/model/randomizer.py", line 160, in randomize
raise Exception("solve failure")
Exception: solve failure
I think for this we need solve before constraint . Can you please take a look into it?
Hi @mballance , I am trying to use not_inside feature with list declared random variable. Following is the code for it :
import vsc
@vsc.randobj
class my_s(object):
def __init__(self):
self.temp = vsc.randsz_list_t(vsc.uint8_t(8))
self.a = [1,2,3,5,6,7,8]
@vsc.constraint
def ls(self):
with vsc.foreach(self.temp, idx = True) as i:
self.temp[i].not_inside(vsc.rangelist(self.a))
io = my_s()
io.randomize()
print(io.temp)
And for this, it is giving an error like following:
Exception while processing constraint: 'expr' object has no attribute 'not_inside'
Traceback (most recent call last):
File "unique_list.py", line 16, in <module>
io = my_s()
File "/home/shraddha/.local/lib/python3.6/site-packages/vsc/rand_obj.py", line 61, in __init__
self.build_field_model(None)
File "/home/shraddha/.local/lib/python3.6/site-packages/vsc/rand_obj.py", line 134, in build_field_model
raise e
File "/home/shraddha/.local/lib/python3.6/site-packages/vsc/rand_obj.py", line 131, in build_field_model
fo.c(self)
File "unique_list.py", line 13, in ls
self.temp[i].not_inside(vsc.rangelist(self.a))
AttributeError: 'expr' object has no attribute 'not_inside'
With this error, it seems that it is not supported for rand_list_t and randsz_list_t declared variables.
Can you please take a look at this?
Hello, Follwing is the code that I am running for else_then statement :
It is giving an error like following :
image
Can you please help me in this and suggest some solution for this?
Hi Matthew,
I'm showing two testcases here, I believe the issue for both originates from the same place. Say that I have these three covergroups where two of them are extending the first one:
@vsc.covergroup
class main_cg(object):
def __init__(self, it):
super().__init__()
self.cp1 = vsc.coverpoint(it, bins={
"a": vsc.bin(5)
})
@vsc.covergroup
class first_extended_cg(main_cg):
def __init__(self, it):
super().__init__(it)
self.cp2 = vsc.coverpoint(it, bins={
"a": vsc.bin(7)
})
@vsc.covergroup
class second_extended_cg(main_cg):
def __init__(self, it):
super().__init__(it)
self.cp3 = vsc.coverpoint(it, bins={
"a": vsc.bin(9)
})
a = 5
cg1 = first_extended_cg(lambda: a)
cg1.sample()
b = 8
cg2 = second_extended_cg(lambda: b)
cg2.sample()
report = vsc.get_coverage_report()
print("Report:\n" + report)
The issue is with the TYPE names: It seems like the inherited covergroups TYPE first_extended_cg
and TYPE second_extended_cg
are mistakenly get their names and are mapped to TYPE main_cg
: So in the below results you see TYPE main_cg
and TYPE main_cg2
:
TYPE main_cg : 50.000000%
CVP cp1 : 100.000000%
CVP cp2 : 0.000000%
INST main_cg : 50.000000%
CVP cp1 : 100.000000%
CVP cp2 : 0.000000%
TYPE main_cg_2 : 0.000000%
CVP cp1 : 0.000000%
CVP cp3 : 0.000000%
INST main_cg_1 : 0.000000%
CVP cp1 : 0.000000%
CVP cp3 : 0.000000%
This could be really problematic in the final coverage results.
Here is another testcase (as I said, I think it originates from the same naming issue discussed above):
@vsc.covergroup
class main_cg(object):
def __init__(self, it):
super().__init__()
self.cp1 = vsc.coverpoint(it, bins={
"a": vsc.bin(5)
})
@vsc.covergroup
class first_extended_cg(main_cg):
def __init__(self, it):
super().__init__(it)
@vsc.covergroup
class second_extended_cg(main_cg):
def __init__(self, it):
super().__init__(it)
a = 5
cg1 = first_extended_cg(lambda: a)
cg1.sample()
b = 8
cg2 = second_extended_cg(lambda: b)
cg2.sample()
report = vsc.get_coverage_report()
print("Report:\n" + report)
It's very similar to the previous example with one small difference: first_extended_cg
and second_extended_cg
just inherit from the main_cg
without adding additional coverpoints. As you can see in the results below, both types are considered as two instances to a single TYPE main_cg
while they should actually be two different TYPEs (TYPE first_extended_cg
and second_extended_cg
):
Report:
TYPE main_cg : 100.000000%
CVP cp1 : 100.000000%
INST main_cg : 100.000000%
CVP cp1 : 100.000000%
INST main_cg_1 : 0.000000%
CVP cp1 : 0.000000%
Thanks beforehand for fixing this!
Best,
Hodjat
Hi @mballance , I have tried to apply constraint on Enum type value. Following is the code for it:
and the output for this is like following :
As you can see in this, it is just assigning first value from given constraint. We have one usecase of this, so can you please take a look at this?
Hi Matthew,
Say that I have something like this:
class my_e(IntEnum):
A = auto()
B = auto()
class my_c:
def __init__(self):
self.a = 5
self.b = my_e.A
@vsc.covergroup
class my_cg(object):
def __init__(self, input):
super().__init__()
self.cp1 = vsc.coverpoint(input.a,
bins=dict(
a=vsc.bin_array([], [1, 15])
))
self.cp2 = vsc.coverpoint(input.b, cp_t=vsc.enum_t(my_e))
inst = my_c()
cg = my_cg(lambda: inst)
cg.sample()
vsc.report_coverage(details=True)
I get this error when I try to run it:
self.cp1 = vsc.coverpoint(input.a,
AttributeError: 'function' object has no attribute a
I can actually pass all individual attributes at the instantiation time : cg = my_cg(lambda: inst.a, lambda: inst.b)
and change the __init__
of my_cg
accordingly, but I was wondering if there is a possibility to pass an object as a whole at the time of instantiation. The reason that I need it is because inst
is a riscv_instruction
object with lots of attributes, and I want to define several coverpoints
for each of those attributes, so it's easier to pass the whole object rather than passing too many arguments at the instantiation time.
Thanks,
Hodjat
Hi Matthew,
I have this small test program:
class my_e(IntEnum):
A = auto()
B = auto()
@vsc.covergroup
class my_cg(object):
def __init__(self, a, b):
super().__init__()
self.cp1 = vsc.coverpoint(a,
bins=dict(
a=vsc.bin_array([], [1, 15])
))
self.cp2 = vsc.coverpoint(b, cp_t=vsc.enum_t(my_e))
a = 1
b = my_e.A
cg = my_cg(lambda: a, lambda: b)
cg.sample()
vsc.report_coverage(details=True)
1- Although b = my_e.A
in the above example, results show a hit for the second bin of cp2:
CVP cp2 : 50.000000%
Bins:
my_e.B : 0
my_e.B : 1
To confirm this issue, if I change it to b = my_e.B
in the example, I get 0% coverage (it's probably due to something like a delayed append to the list).
2- It works for IntEnum
types and I get 50% coverage for the cp2. However, it doesn't work for Enum
types: if I change my_e(IntEnum)
to my_e(Enum)
, I'll get 0% coverage for cp2 which is not correct.
3- When the coverage report shows the individual bins for cp2, the key for all individual bins is the last member of Enum (my_e.B
in this example):
CVP cp2 : 0.000000%
Bins:
my_e.B : 0
my_e.B : 0
Thanks,
Hodjat
Hi @mballance
Thanks for the new release which is working well for randcase and std::randomization().
I am facing some issue with inline randomization in the new release.
Previously I have implemented inline randomization like this and it was working well with the previous release i.e 0.2.3.20201006.1.
The above particular code is working in a random fashion in the new release.
Here is the console message for the failure case.
I tried to debug with the pyvsc source files and provided the positional argument level value as 0.
but this doesn't solve the issue, Instead of a level issue, there was a multiple constraint failure.
I am assuming this is not the expected solution to this problem.
I am in a confusion whether the new release alters the behaviour of inline randomization or there is some issue with my implemented code.
Can you give me some pointer on this?
Regards,
Anil
Hi @mballance
While checking the working of #38, I came across another issue where the solve order is not working.
I have created a test case to give you a better understanding of the issue.
import vsc
from enum import IntEnum, auto
@vsc.randobj
class mem_region_t:
def __init__(self, name = "", size_in_bytes = 0, xwr = 0):
self.name = name
self.size_in_bytes = vsc.uint32_t(i = size_in_bytes)
self.xwr = vsc.uint8_t(i = xwr)
@vsc.randobj
class classA:
def __init__(self):
self.base = vsc.rand_int32_t()
self.max_load_store_offset = vsc.rand_int32_t()
self.max_data_page_id = vsc.int32_t()
self.data_page = vsc.list_t(mem_region_t())
self.data_page_id = vsc.rand_uint32_t()
self.mem_region = vsc.list_t(mem_region_t())
self.mem_region.extend([mem_region_t(name = "region_0", size_in_bytes = 4096, xwr = 8),
mem_region_t(name = "region_1", size_in_bytes = 4096, xwr = 8)])
def pre_randomize(self):
print("[Pre] max_load_store_offset: ", self.max_load_store_offset)
print("[Pre] Base: ", self.base)
self.data_page.clear()
self.data_page.extend(self.mem_region)
self.max_data_page_id = len(self.data_page)
def post_randomize(self):
print("[Post] max_load_store_offset: ", self.max_load_store_offset)
print("[Post] Base: ", self.base)
@vsc.constraint
def addr_c(self):
vsc.solve_order(self.data_page_id, self.max_load_store_offset)
vsc.solve_order(self.max_load_store_offset, self.base)
self.data_page_id < self.max_data_page_id
with vsc.foreach(self.data_page, idx = True) as i:
with vsc.if_then(i == self.data_page_id):
self.max_load_store_offset == self.data_page[i].size_in_bytes
self.base in vsc.rangelist(vsc.rng(0, self.max_load_store_offset - 1))
obj = classA()
obj.randomize()
In the above test case the self.base
is giving a large value instead of value between in vsc.rng(0,4095)
My output:-
-- push_constraint_stmt
-- push_constraint_stmt
[Pre] max_load_store_offset: 0
[Pre] Base: 0
[Post] max_load_store_offset: 4096
[Post] Base: 2494113924
Please let me know If I have missed something.
Regards,
Anil
Hi,
I was trying to run the below example
import vsc
@vsc.randobj
class ex:
def __init__(self):
self.a = 0
self.rs1 = vsc.rand_uint8_t()
self.rd = vsc.rand_uint8_t()
@vsc.randobj
class riscv_lr_sc_instr_stream:
def __init__(self):
self.lr_instr = ex()
self.sc_instr = ex()
self.num_amo = vsc.rand_uint8_t()
self.num_mixed_instr = vsc.rand_uint8_t()
self.isa = "RV32A"
self.reserved_regs = vsc.rand_list_t(vsc.uint8_t(), 4) #[1, 2, 3, 4]
self.reserved_rd = vsc.rand_list_t(vsc.uint8_t(), 4) # [1, 2, 3, 4]
self.rs1_reg = vsc.rand_list_t(vsc.uint8_t(), 1)
@vsc.constraint
def legal_c(self):
self.num_amo == 1
self.num_mixed_instr in (vsc.rangelist(vsc.rng(0, 15)))
@vsc.constraint
def lr_con(self):
self.lr_instr.rs1 == self.rs1_reg[0]
self.lr_instr.rd.not_inside(vsc.rangelist(self.reserved_rd))
self.lr_instr.rd.not_inside(vsc.rangelist(self.reserved_regs))
self.lr_instr.rd != self.rs1_reg[0]
@vsc.constraint
def sc_con(self):
self.sc_instr.rs1 == self.rs1_reg[0]
self.sc_instr.rd.not_inside(vsc.rangelist(self.reserved_rd))
self.sc_instr.rd.not_inside(vsc.rangelist(self.reserved_regs))
self.sc_instr.rd != self.rs1_reg[0]
def post_randomize(self):
print("RS1_REG = ",self.rs1_reg)
pri_obj = ex()
pri_obj.randomize()
obj = riscv_lr_sc_instr_stream()
obj.randomize()
For this, I getting the following error,
Problem Constraints:
Constraint 1:
(rd(0) != [0][0]);
(rd != rs1_reg[0]);
Constraint 2:
(rd(0) != [0][0]);
(rd != rs1_reg[0]);
Traceback (most recent call last):
File "../example_lr_sc.py", line 47, in <module>
obj.randomize()
File "/home/ishita/.local/lib/python3.6/site-packages/vsc/rand_obj.py", line 112, in randomize
raise e
File "/home/ishita/.local/lib/python3.6/site-packages/vsc/rand_obj.py", line 109, in randomize
Randomizer.do_randomize([model])
File "/home/ishita/.local/lib/python3.6/site-packages/vsc/model/randomizer.py", line 565, in do_randomize
r.randomize(ri, bounds_v.bound_m)
File "/home/ishita/.local/lib/python3.6/site-packages/vsc/model/randomizer.py", line 204, in randomize
self.create_diagnostics(active_randsets))
vsc.model.solve_failure.SolveFailure: solve failure
Can you help me with this?
Regards,
Ishita
Hello,
I'm trying to randomize an enum-type attribute (it's been mentioned in the manual that Enum and IntEnum are supported by PyVSC). When I try this example from the manual:
class my_e(Enum):
A = auto()
B = auto()
@vsc.randobj
class my_s(object):
def __init__(self):
self.a = vsc.rand_enum_t(my_e)
self.b = vsc.enum_t(my_e)
inst = my_s()
Then this error happens in the last line: TypeError: int() argument must be a string, a bytes-like object or a number, not 'my_e'.
However, with IntEnum (instead of Enum), it works but seems like doesn't actually do the randomization, below code doesn't randomize the enum (inst.a), but it does randomize the uint8 attribute:
from enum import *
import vsc
class my_e(IntEnum):
A = auto()
B = auto()
@vsc.randobj
class my_s(object):
def __init__(self):
self.a = vsc.rand_enum_t(my_e)
self.b = vsc.enum_t(my_e)
self.c = vsc.rand_uint8_t()
inst = my_s()
inst.randomize()
print('{}{}{}'.format(inst.a, inst.b, inst.c))
I think I'm missing something here... Could someone please explain this behavior?
Thanks,
Hodjat
Hi Matthew,
I believe that there is an issue with installing PyVSC on windows machines (mine is Windows 10). Initially I tried to install it from a virtual environment in PyCharm (tried different python/pip versions), then also tried to install it from the command line but no success. Here is the error (probably with the pyboolector library?):
'C:\Users\Hodja\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Hodja\\AppData\\Local\\Temp\\pycharm-packaging\\pyboolector\\setup.py'"'"'; __file__='"'"'C:\\Users\\Hodja\\AppData\\Local\\Temp\\pycharm-packaging\\pyboolector\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\Public\Documents\Wondershare\CreatorTemp\pip-pip-egg-info-c10zy0vp'
cwd: C:\Users\Hodja\AppData\Local\Temp\pycharm-packaging\pyboolector\
Complete output (5 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\Hodja\AppData\Local\Temp\pycharm-packaging\pyboolector\setup.py", line 14, in <module>
with open(cmakelists_txt, "r") as f:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Hodja\\AppData\\Local\\Temp\\pycharm-packaging\\CMakeLists.txt'
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
It works for same versions of Python/Pip on various linux machines though.
Thanks,
Hodjat
Hi,
Thanks for this great library, I just discovered. Really useful.
I've been performing some tests on the outcomes one may get out of this just to check I understand the documentation correctly. You may see it here.
As you can see, it's just creating random data and histogramming it. From the results
here, I observe that constraining the variables makes the histogram weird. What am I doing wrong ?
Thanks !
Currently, I am experiencing some issues/errors in a random fashion. Mostly constraint failure when running regressions.
It would be really great If you can provide a method/switch to use the seed.
It helps me to debug the issue efficiently and precisely.
Regards,
Anil
Hi Matthew,
I have a couple of questions regarding this small test:
@vsc.covergroup
class my_cg(object):
def __init__(self, a, b):
super().__init__()
self.cp1 = vsc.coverpoint(a, bins={
"a": vsc.bin_array([], [1, 10])
})
self.cp2 = vsc.coverpoint(b, bins={
"b": vsc.bin_array([], [1, 10])
})
self.cp1X2 = vsc.cross([self.cp1, self.cp2])
a = 6
b = 8
cg = my_cg(lambda: a, lambda: b)
for i in range(50):
cg.sample()
vsc.report_coverage(details=True)
print("Coverage: " + str(cg.get_coverage()))
1- When getting the coverage report using vsc.report_coverage(details=True)
, I can only see the coverage report (10%) for the first two coverpoints (cp1 and cp2), and not the coverpoint cross cp1X2 (I believe the coverage for cp1X2 should be 1%)
2- It seems like the result of vsc.report_coverage(details=True)
and cg.get_coverage()
do not match: I get 10% and 7, respectively. Is this a normal behavior?
Thanks,
Hodjat
Hi,
i have generated multiple coverage xml files using vsc.write_coverage_db("cov.xml")
. How to merge multiple xml files. is there any method to merge multiple xml files?
Hi Matthew,
I am new to pyvsc and curious to know that are you going to provide support for SystemVerilog assertions and fork-join,join_any, join_none statements in the future?
Thanks for your contributions until now.
Hi Matthew,
I believe there is a small bug with respect to PyVSC partial selection (please let me know if I'm missing something here): it looks like the part select in PyVSC isn't inclusive in both ends, please look at the below example:
import vsc
imm = vsc.rand_bit_t(4)
imm.set_val(2)
print("imm val is: {}\n".format(imm[1:0]))
This prints 0 instead of 2 (apparently it only prints imm[0]
).
Cheers,
Hodjat
Hi @mballance ,
As we know in SystemVerilog with weighted distribution constraint, value with the more weight will get allocated more often to a random variable. We tried to implement it but couldn't find the way. We have one use case of it, so can we please have support of weighted distribution for randomization in pyvsc or some way to achieve it?
Hello, I am trying to compute sum of list elements with for loop. Following is the code for it :
But in this it is giving an error like following :
As you can see, at line 15 it is working properly, but in for loop, range method it is giving an error. So can we have sum() function like in SV or solution to this issue , so that we can get sum of the elements of list ?
In this we need support for "list" type value for range with "in" and "not in" feature with your tool. Currently these two things, for compilation it is working good , but it is not randomizing the value, as @mballance said in issue #7 .
Hi @mballance
We have done some experiments on different APIs from pyvsc. Some Model APIs are provided, and we have tried one from them that is, set_constraint_enabled(en). We are expecting the output same as constraint_mode(). Don't know the actual use of Model APIs.
Can you provide some examples related to that? So that we can know how to use and where to use.
Thanks & Regards,
Yash Patel
I think object.randomize() should return True (1) or False(0) on successful and unsuccessfull randomization respectively.
Such that we can call the randomize() function with the class instance by checking it in the if ... else
condition to check the possible randomization failure.
Hi @mballance ,
I was trying to use implies constraint. But sometimes, it is giving wrong values. Following is the code for it :
import vsc
@vsc.randobj
class my_s(object):
def __init__(self):
super().__init__()
self.a = vsc.rand_bit_t(2)
self.b = vsc.rand_bit_t(2)
@vsc.constraint
def ab_con(self):
with vsc.implies(self.a == 1):
self.b == 1
item = my_s()
for i in range(10):
item.randomize()
print("A = ",item.a,", B = ",item.b)
And following is the output for this :
A = 2 , B = 3
A = 3 , B = 3
A = 2 , B = 0
A = 0 , B = 2
A = 3 , B = 2
A = 1 , B = 2
A = 0 , B = 2
A = 1 , B = 2
A = 1 , B = 3
A = 2 , B = 1
As we can see, for A=1 there are different values of B, which is not correct according to our example code.
Can you please take a look at this?
Hi @mballance,
I am getting constraint failure error for following use-case:
@vsc.randobj
class my_s(object):
def __init__(self):
self.a_list = vsc.rand_list_t(vsc.uint8_t(),7)
self.temp_list = vsc.rand_list_t(vsc.uint8_t(),7)
self.c = 0
@vsc.constraint
def ab_c(self):
with vsc.foreach(self.a_list, idx=True) as i:
if self.c:
self.a_list[i] in vsc.rangelist(5,6,7,8)
else:
self.a_list[i] in vsc.rangelist(10,11,12,13)
with vsc.foreach(self.temp_list, idx=True) as i:
if self.a_list[i] in [6,7]:
self.temp_list[i] == 0
else:
self.temp_list[i] == 1
my = my_s()
my.randomize()
And it is giving an error like this :
Failed constraints:
[1]: (temp_list.<unknown>[0] == 0);
[1]: (temp_list.<unknown>[0] == 0);
[2]: (temp_list.<unknown>[1] == 0);
[2]: (temp_list.<unknown>[1] == 0);
[3]: (temp_list.<unknown>[2] == 0);
[3]: (temp_list.<unknown>[2] == 0);
[4]: a_list.<unknown>[0] in [13, 12, 11, 10];
[4]: a_list.<unknown>[0] in [13, 12, 11, 10];
[5]: (a_list.<unknown>[0] == 6);
[5]: (a_list.<unknown>[0] == 6);
[6]: a_list.<unknown>[1] in [13, 12, 11, 10];
[6]: a_list.<unknown>[1] in [13, 12, 11, 10];
[7]: (a_list.<unknown>[1] == 6);
[7]: (a_list.<unknown>[1] == 6);
[8]: (a_list.<unknown>[2] == 6);
[8]: (a_list.<unknown>[2] == 6);
[9]: a_list.<unknown>[2] in [13, 12, 11, 10];
[9]: a_list.<unknown>[2] in [13, 12, 11, 10];
Traceback (most recent call last):
File "2usecase.py", line 27, in <module>
my.randomize()
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/rand_obj.py", line 107, in randomize
Randomizer.do_randomize([model])
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/model/randomizer.py", line 861, in do_randomize
r.randomize(ri, bounds_v.bound_m)
File "/home/adduser/.local/lib/python3.8/site-packages/vsc/model/randomizer.py", line 160, in randomize
raise Exception("solve failure")
Exception: solve failure
I think if self.a_list[i] in [6,7]
this condition, it is interpreting as constraint on self.a_list variable, but here I want to use as checking condition. So how can I resolve this ? Can you please help ?
Thanks & Regards,
Shraddha Devaiya.
I have an enum class my_enum of 5 elements. Is there any way to randomly pick 3 elements of enum class in a class variable for each randomization? Such that I can use the variable by slicing elsewhere in the code.
The intention is to create a list of random enum elements of a fixed size.
I have tried with variable_name = vsc.randsz_list(vsc.rand_enum_t(enum_class)) but it doesn't works well.
import vsc
from enum import Enum, auto
class my_enum(Enum):
a = auto()
b = auto()
c = auto()
d = auto()
e = auto()
@vsc.randobj
class my_class(object):
def __init__(self):
self.variable = vsc.rand_enum_t(my_enum)
@vsc.constraint
def variable_c(self):
self.variable.not_inside(vsc.rangelist(my_enum.a, my_enum.c))
inst = my_class()
inst.randomize()
print("Result = {}".format(inst.variable))
The above code snippet gives me a single enum element.
I want to make the self.variable as a list of a particular size, especially for enumerated types.
Please correct me if I'm missing something here.
Apart from the above issue
import vsc
from enum import Enum, auto
class my_enum(Enum):
a = auto()
b = auto()
c = auto()
d = auto()
e = auto()
@vsc.randobj
class my_class(object):
def __init__(self):
self.variable1 = vsc.rand_enum_t(my_enum)
self.variable2 = vsc.rand_enum_t(my_enum)
self.variable3 = vsc.rand_enum_t(my_enum)
@vsc.constraint
def variable_c(self):
# Situation 1
self.variable1.not_inside(vsc.rangelist(self.variable2, self.variable3))
# Situation 2
self.variable1.not_inside(vsc.rangelist(self.variable2, self.variable3, my_enum.a))
inst = my_class()
inst.randomize()
print("Result = {}".format(inst.variable1))
For Situation 1
I am getting the same result even after iterating the randomize() method more than once.
The result is always the first element of enum class i.e a
For Situation 2
I am getting an key error
I think the key error is because of self,var1, and self.var2 which are of vsc.rand_enum_t type otherwise my_enum.b, my_enum.a, my_enum.c
works well.
The Intention is to use the randomly generated enum values inside the vsc.rangelist clause with my_enum.a for self.variable1 constraint.
Let me know if I am missing something here.
Thanks!
Hi,
I think there is an "out of range IndexError" in the "bin_array" class inside coverage.py
file: line 278:
self.nbins = -1 if len(nbins) == 0 else nbins[1]
I believe it should be nbins[0]
. Please correct me if I'm missing something here.
Thanks
Hi @mballance , I have tried this "not in" feature with pyvsc. Following is the code for it :
and following is the output for this code :
As you can see, self.b value is falling in the given list range, which is not correct. So can you please check this ?
Hi @mballance
I can see that we have support for constraint_mode() for the current version release.
Can we have support for the rand_mode() as well?
Thanks!
Hi
I have experimented and try to achieve the same but it didn't works for me.
Is it achievable by doing some workaround with the current updates?
If not then Can we have support for std::randomize() of System Verilog?
Thanks and Regards,
Anil
Hello @mballance ,
I am using solve_order for our following use-case, but with this it is not randomizing value of num_of_nested_loop variable.
import vsc
from enum import Enum,auto
@vsc.randobj
class riscv_instr:
def __init__(self):
self.temp = vsc.rand_uint8_t()
class my_e(Enum):
A = 0
B = auto()
C = auto()
D = auto()
E = auto()
F = auto()
G = auto()
@vsc.randobj
class riscv_loop_instr:
def __init__(self):
self.loop_cnt_reg = vsc.randsz_list_t(vsc.enum_t(my_e))
self.loop_limit_reg = vsc.randsz_list_t(vsc.enum_t(my_e))
self.loop_init_val = vsc.randsz_list_t(vsc.uint32_t())
self.loop_step_val = vsc.randsz_list_t(vsc.uint32_t())
self.loop_limit_val = vsc.randsz_list_t(vsc.uint32_t())
self.num_of_nested_loop = vsc.rand_bit_t(3)
self.num_of_instr_in_loop = vsc.rand_uint32_t()
self.branch_type = vsc.randsz_list_t(vsc.enum_t(my_e))
@vsc.constraint
def legal_loop_regs_c(self):
vsc.solve_order(self.num_of_nested_loop, self.loop_init_val)
vsc.solve_order(self.num_of_nested_loop, self.loop_step_val)
vsc.solve_order(self.num_of_nested_loop, self.loop_limit_val)
vsc.solve_order(self.loop_limit_val, self.loop_limit_reg)
vsc.solve_order(self.branch_type, self.loop_init_val)
vsc.solve_order(self.branch_type, self.loop_step_val)
vsc.solve_order(self.branch_type, self.loop_limit_val)
self.num_of_instr_in_loop.inside(vsc.rangelist((1, 25)))
self.num_of_nested_loop.inside(vsc.rangelist(1, 2))
self.loop_init_val.size == self.num_of_nested_loop
self.loop_step_val.size == self.num_of_nested_loop
self.loop_limit_val.size == self.num_of_nested_loop
self.loop_init_val.size == self.num_of_nested_loop
self.branch_type.size == self.num_of_nested_loop
self.loop_step_val.size == self.num_of_nested_loop
self.loop_limit_val.size == self.num_of_nested_loop
self.branch_type.size == self.num_of_nested_loop
@vsc.constraint
def loop_c(self):
vsc.solve_order(self.num_of_nested_loop, self.loop_cnt_reg)
vsc.solve_order(self.num_of_nested_loop, self.loop_limit_reg)
self.loop_cnt_reg.size == self.num_of_nested_loop
self.loop_limit_reg.size == self.num_of_nested_loop
obj = riscv_loop_instr()
for i in range(5):
obj.randomize()
print(obj.num_of_nested_loop)
For this code, it is giving an output like following:
-- push_constraint_stmt
-- push_constraint_stmt
-- push_constraint_stmt
-- push_constraint_stmt
-- push_constraint_stmt
-- push_constraint_stmt
-- push_constraint_stmt
-- push_constraint_stmt
0
0
0
0
0
As we can see, it is giving num_of_nested_loop = 0 every time. Can you please help, if I missed something in this?
And if I comment following lines:
vsc.solve_order(self.num_of_nested_loop, self.loop_init_val)
vsc.solve_order(self.num_of_nested_loop, self.loop_step_val)
vsc.solve_order(self.num_of_nested_loop, self.loop_limit_val)
vsc.solve_order(self.num_of_nested_loop, self.loop_cnt_reg)
vsc.solve_order(self.num_of_nested_loop, self.loop_limit_reg)
then it is randomizing value of num_of_nested_loop.
Can you please take a look into this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.