Skip to content

Commit

Permalink
Merge pull request #223 from alwilson/solve_order_fix_213
Browse files Browse the repository at this point in the history
Solve-order fixes
  • Loading branch information
mballance authored Jul 15, 2024
2 parents 117a8bb + 59c91c1 commit 0269856
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 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
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]))

0 comments on commit 0269856

Please sign in to comment.