Use of Unpacked Struct in solve...before Constraint

Hi,

Let’s say that I have an unpacked array declared as below.
And it seems perfectly okay according to LRM 18.4 (Random variables).

class my_class;
        
    typedef struct {
        rand int a;
        rand int b;
        rand int c;
    } unpacked_t;

    rand unpacked_t my_struct[];
    
endclass: my_class

But what if this unpacked array is used in solve…before constraint?
LRM 18.5.10 (Variable ordering) says, for variable ordering, “Only random variables are allowed, that is, they shall be rand”.
In the following example, is it okay to use the unpacked array in solve…before constraint?
In other words, can an unpacked array be considered rand?

class my_class;
    
    rand bit [3:0] n;
    
    typedef struct {
        rand int a;
        rand int b;
        rand int c;
    } unpacked_t;

    rand unpacked_t my_struct[];
    
    constraint c {
        solve n before my_struct; // is this okay?
        my_struct.size() == n;
    }
    
endclass: my_class

In case the above example is valid, here’s another example.
The only difference is that not all the variables in the struct are declared rand.
Is it also okay?

class my_class;
    
    rand bit [3:0] n;
    
    typedef struct {
        rand int a;
        rand int b;
        int c; // not rand
    } unpacked_t;

    rand unpacked_t my_struct[];
    
    constraint c {
        solve n before my_struct; // is this okay?
        my_struct.size() == n;
    }
    
endclass: my_class

The behaviors across the simulators differ and I’m not confident whether this complies with LRM or not.
Does LRM have the answer? Or is it just implementation-specific?

Best regards,
Jung Ik Moon

In reply to Jung Ik Moon:

It would help if you could share a complete runnable example and explained the differences you see.

I cannot think of a reason why a struct with at least one random member would have a problem with a solve before construct.

In any case, for the example you have shown, there is no need to have a solve before constraint on the size of my_struct array. A dynamic array gets sized before considering constraints on its elements, and the size becomes a state variable.

In reply to dave_59:

Hi Dave,

It would help if you could share a complete runnable example and explained the differences you see.

Actually, the code above itself is enough to see the problem as the simulator gives error while compiling the class.
But I’ve added some more codes below. (top module instantiating and randomizing the class)

The compile-time error I get from some simulators are as below.
https://edaplayground.com/x/bDAg (EDA Playground)

Error-[IVCB-SBUSTRUCT] Illegal use of solve before
top.sv, 14
$unit, "my_struct"
  The expression 'my_struct' is an unpacked structure and cannot be used in a 
  solve-before constraint.
  Remove the unpacked structure from the solve-before constraint and replace 
  it with a 'rand' variable.
ERROR VCP7875 "References to the 'this.my_struct' unpacked structure are not allowed in the 'solve...before' list." "testbench.sv" 14  33

In any case, for the example you have shown, there is no need to have a solve before constraint on the size of my_struct array. A dynamic array gets sized before considering constraints on its elements, and the size becomes a state variable.

You are right. Thanks for the information.
I’ve updated the constraints as well.

class my_class;
 
    rand bit [3:0] n;
 
    typedef struct {
        rand int a;
        int b; // not rand
        int c; // not rand
    } unpacked_t;
 
    rand unpacked_t my_struct;
 
    constraint c {
        solve n before my_struct; // is this okay?
        (n == 0) -> my_struct.a == 0;
    }
 
endclass: my_class

module top;

    my_class m_my_class;

    initial begin
        m_my_class = new();
        void'(m_my_class.randomize());
        $display("n = %1d", m_my_class.n);
        $display("my_struct = %p", m_my_class.my_struct);
    end 

endmodule: top

Best regards,
Jung Ik Moon

In reply to Jung Ik Moon:

The LRM says that the use of solve before is limited to variables with integral values. An unpacked struct is not an integral type, it is an aggregate.

In reply to dave_59:

Hi Dave,

Oh, I see. So it was about ‘integral’, not ‘rand’.
But when I tried the same with Mentor Questa, I got no error from it.
Does it mean that it depends on the vendor’s implementation of unpacked array?
Or is it simply not being checked?

Best regards,
Jung Ik Moon

In reply to Jung Ik Moon:

All tools seem to support
solve before
with an unpacked array of integral values, so I don’t know why there would be a limitation for unpacked structure of integral values.

However, this Mentor/Siemens EDA sponsored public forum is not for discussing tool specific usage or issues. Please read your tool’s user manual or contact your tool vendor directly for support.

In reply to dave_59:

Hi Dave,

Thanks for the answers.

Best regards,
Jung Ik Moon