Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solve-order fixes #223

Merged
merged 2 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion doc/source/constraints.rst
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,19 @@ statement corresponds to the SystemVerilog `solve a before b` statement.
with vsc.else_then:
self.b != 4

In the example above, te `solve_order` statement causes `b` to
In the example above, the `solve_order` statement causes `b` to
have values evenly distributed between the value sets [4] and
[0..3,5..255].

Use lists of variables to create multiple solve-order constraints.
The example below solves `a` and `b` before `c` and `d`.

.. code-block:: python3

@vsc.constraint
def abcd_c(self):
vsc.solve_order([self.a, self.b], [self.c, self.d])

unique
------
The `unique` constraint ensures that all variables in the specified list have
Expand Down
2 changes: 1 addition & 1 deletion src/vsc/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ def solve_order(before, after):
a_e = pop_expr()
if not isinstance(a_e, ExprFieldRefModel):
raise Exception("Parameter " + str(a) + " is not a field reference")
before_l.append(a_e.fm)
after_l.append(a_e.fm)
else:
to_expr(after)
after_e = pop_expr()
Expand Down
8 changes: 6 additions & 2 deletions src/vsc/model/rand_info_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,15 @@ def build(

builder = RandInfoBuilder(rng)

# First, collect all the fields
# First, collect all fields and ordering from constraints
builder._pass = 0
for fm in field_model_l:
fm.accept(builder)


# Collect all fields and ordering from standalone constraints passed to the function
for c in constraint_l:
c.accept(builder)

builder._randset_m.clear()
builder._randset_l.clear()
builder._randset_field_m.clear()
Expand Down
42 changes: 42 additions & 0 deletions ve/unit/test_constraint_solve_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,45 @@ def a_and_lists_c(self):
self.assertEqual(first.a, repeat.a, "Mismatch on a")
self.assertListEqual(list(first.list_0), list(repeat.list_0), "Mismatch on list_0")
self.assertListEqual(list(first.list_1), list(repeat.list_1), "Mismatch on list_1")

def test_before_and_after_lists(self):

@vsc.randobj
class my_c(object):

def __init__(self):
self.a = vsc.rand_bit_t(64)
self.b = vsc.rand_bit_t(64)
self.c = vsc.rand_bit_t(1)

@vsc.constraint
def abc_c(self):
# If a or b is solved first then it's extremely likley
# that all variables will be non-zero
with vsc.implies(self.c == 0):
self.a == 0
self.b == 0

def test_solve_order(order):
a_hist = [0]*2
b_hist = [0]*2
c_hist = [0]*2
samples = 100

for _ in range(samples):
with i.randomize_with():
order()
a_hist[i.a > 0] += 1
b_hist[i.b > 0] += 1
c_hist[i.c > 0] += 1
self.assertEqual(a_hist[1], samples)
self.assertEqual(b_hist[1], samples)
self.assertEqual(c_hist[1], samples)

i = my_c()

# Test various combinations of before and after arguments
test_solve_order(lambda: vsc.solve_order( i.a , i.c ))
test_solve_order(lambda: vsc.solve_order( i.a , [i.c]))
test_solve_order(lambda: vsc.solve_order([i.a, i.b], i.c ))
test_solve_order(lambda: vsc.solve_order([i.a, i.b], [i.c]))
Loading