fvutils / pyvsc

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

Distributions have higher priority than soft constraints #191

Closed alwilson closed 1 year ago

alwilson commented 1 year ago

While looking back into constraint caching I noticed that distributions result in the final model having a very high priority soft constraint to ensure that the winning value take higher priority than any soft constraints. But the swizzler randomization also looks out for these distributions and will try to obey the weights. I wanted to see what purpose it had so I commented it out and found that the test_soft_dist_priority fails.

https://github.com/fvutils/pyvsc/blob/32f01e686d8b2aadff25f073cd67f72928be9dcd/ve/unit/test_constraint_soft.py#L72-L105

That got me thinking what it did in SV, so looking at the SystemVerilog LRM - 1800-2017 the Distribution section (18.5.4) seems to indicate that satisfying constraints, even soft constraints, comes before satisfying distribution weights. With the exception of the zero weight case. PyVSC adds a hard constraint for the zero weight case and an IN constraint for the possible values, which I think is correct, but I don't think it should cause non-zero weights to take priority over soft constraints.

If there are constraints on some expressions that cause the distribution weights on these expressions to be not satisfiable, implementations are only required to satisfy the constraints. An exception to this rule is a weight of zero, which is treated as a constraint.

I wrote up an SV testcase and tried it out, and it only randomizes a to 8, which seems to match up with the LRM:

class test_class;
    rand logic[7:0] a;
    rand logic[7:0] b;

    constraint addr_c {
        a < b;
        soft a > 5;
        a dist {
            0 :/ 10,
            1 :/ 10,
            2 :/ 10,
            4 :/ 10,
            8 :/ 10
        };
    };
endclass

module top;
    initial begin
        int mybins[];

        test_class test0;
        test0 = new();

        mybins = new[9];

        for (int j = 0; j < 100; j++) begin
            void'(test0.randomize());
            mybins[test0.a] += 1;
        end
        $display("%p", mybins);
    end
endmodule

Output:

'{0, 0, 0, 0, 0, 0, 0, 0, 100} 

Is this a specification bug? If so it seems like an easy fix and I think it would make constraint caching easier since the soft constraints wouldn't have to be regenerated and re-solved on each call, potentially.

mballance commented 1 year ago

Fixed with PR #194