Skip to content

Commit

Permalink
Fix solve_order's after argument when using lists
Browse files Browse the repository at this point in the history
Addresses #213
Adds a unit test for the various ways to call solve_order.
Update the solve_order docs with a snippet using lists.
  • Loading branch information
alwilson committed Jul 15, 2024
1 parent 35d3e55 commit 59c91c1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
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
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]))

0 comments on commit 59c91c1

Please sign in to comment.