I’m trying to constrain a scatter gather list as shown below.
But the C_SET_LENGTH_FIELD constraint causes this error in VCS.
Error-[CNST-NAE] Constraint null array error
The constraint solver failed when accessing a null array
sgl__vcs_type[5].idx.
Please make sure array sgl__vcs_type[5].idx is allocated properly.
The number of elements gets randomized to 5 (0 to 4), but the solver wants to looks at the non-existent element 5 to satisfy the constraint which fails.
How can I create a guard to prevent this?
Regards,
Dale.
class cmd_item extends uvm_sequence_item;
// UVM automation macro
`uvm_object_utils(cmd_item)
rand byte sgl[][][16];
constraint C_NUM_ELEMENTS {sgl.size inside { [5:7] }; }
constraint C_NUM_DESCRIPTORS_PER_ELEMENT {
foreach (sgl[i,,]) {
sgl[i].size inside { [1:10] };
}
}
constraint C_SET_LENGTH_FIELD {
foreach (sgl[i,j,]) {
sgl[i][j][8] == sgl[i+1].size;
}
}
function string sprint();
string s;
s = {s, $psprintf("\n[There are this many elements := %0d]\n", sgl.size())};
foreach (sgl[i,])
s = {s, $psprintf("[Segement %0d has this many descriptors := %0d]\n", i, sgl[i].size)};
foreach (sgl[i,j])
s = {s, $psprintf("[Segment := %0d, Descriptor := %0d, Length := %0d]\n", i,j, sgl[i][j][8])};
return s;
endfunction
endclass
module top;
cmd_item c=new();
initial repeat(1) begin
assert(c.randomize());
uvm_report_info("cmd_item", c.sprint());
end
endmodule
Issue is when I == 4,I + 1 you’ve on last constraint goes out of range. So VCS is right here. What would you want the value to be for last iteration? Once you decide that you can use an implication as guard as in:
i < sgl.size → …
Can you share the standalone test that VCS creates in such case? I don’t recall if it is by default or under +ntb_solver something (please look in VCS -doc if needed)
Because, solver is getting two opposite choices, i) because of implication, ii) there is no restriction for second choice.
When there is no implication solver will consider it always. In your case which is contradictory with implication.
A solution:
constraint C_SET_LENGTH_FIELD {
foreach (sgl[i,j,]) {
(i <= sgl.size-2) -> (sgl[i][j][8] == sgl[i+1].size);
(i ==sgl.size-1) -> (sgl[i][j][8] == 0); // This is application only for last element.
}
constraint C_NUM_DESCRIPTORS_PER_ELEMENT {
foreach (sgl[i,]) { sgl[i].size inside { [1:10] }; // #1_1 it is non-zero size…
}
}
constraint C_SET_LENGTH_FIELD {
foreach (sgl[i,j,]) { (i <= sgl.size-2) → (sgl[i][j][8] == sgl[i+1].size);// #1_2 it is non-zero size
(sgl[i][j][8] == 0) // #2_1 it tries to set ‘zero’
}
}
because of these two sets of constraints
#1_1, #1_2 // which tries to set sgl[i][j][8] to a non-zero value #2_1 // which tries to set sgl[i][j][8] to ‘zero’.
Thanks, I tried your suggestion as below, but it results in my original error which was a “Constraint null error array”
class cmd_item extends uvm_sequence_item;
// UVM automation macro
`uvm_object_utils(cmd_item)
rand byte unsigned sgl[][][16];
constraint C_NUM_ELEMENTS {sgl.size inside { [5:5] }; }
constraint C_NUM_DESCRIPTORS_PER_ELEMENT {
foreach (sgl[i,,]) {
sgl[i].size inside { [5:10] };
}
}
constraint C_SET_LENGTH_FIELD {
foreach (sgl[i,j,]) {
(i <= sgl.size-2) -> (sgl[i][j][8] == sgl[i+1].size);
(i == sgl.size-1) -> (sgl[i][j][8] == 5); // This is application only for last element.
}
}
function string sprint();
string s;
s = {s, $psprintf("\n[There are this many elements := %0d]\n", sgl.size())};
foreach (sgl[i,])
s = {s, $psprintf("[Segement %0d has this many descriptors := %0d]\n", i, sgl[i].size)};
foreach (sgl[i,j])
s = {s, $psprintf("[Segment := %0d, Descriptor := %0d, Length := %0d]\n", i,j, sgl[i][j][8])};
return s;
endfunction
endclass
module top;
cmd_item c=new();
initial repeat(1) begin
assert(c.randomize());
uvm_report_info("cmd_item", c.sprint());
end
endmodule
Error-[CNST-NAE] Constraint null array error
…/tb/for_va_question.sv, 61
The constraint solver failed when accessing a null array
sgl__vcs_type[5].idx.
Please make sure array sgl__vcs_type[5].idx is allocated properly.
“…/tb/for_va_question.sv”, 61: top.unnamed$$_1: started at 0ps failed at 0ps
Offending ‘c.randomize()’
UVM_INFO @ 0: reporter [cmd_item]
[There are this many elements := 5]
[Segement 0 has this many descriptors := 5]
[Segement 1 has this many descriptors := 9]
[Segement 2 has this many descriptors := 10]
[Segement 3 has this many descriptors := 8]
[Segement 4 has this many descriptors := 10]
[i]In reply to
Hi,
Thanks, I tried your suggestion as below, but it results in my original error which was a “Constraint null error array”
class cmd_item extends uvm_sequence_item;
// UVM automation macro
`uvm_object_utils(cmd_item)
rand byte unsigned sgl[][][16];
constraint C_NUM_ELEMENTS {sgl.size inside { [5:5] }; }
constraint C_NUM_DESCRIPTORS_PER_ELEMENT {
foreach (sgl[i,,]) {
sgl[i].size inside { [5:10] };
}
}
constraint C_SET_LENGTH_FIELD {
foreach (sgl[i,j,]) {
(i <= sgl.size-2) -> (sgl[i][j][8] == sgl[i+1].size);
(i == sgl.size-1) -> (sgl[i][j][8] == 5); // This is application only for last element.
}
}
function string sprint();
string s;
s = {s, $psprintf("\n[There are this many elements := %0d]\n", sgl.size())};
foreach (sgl[i,])
s = {s, $psprintf("[Segement %0d has this many descriptors := %0d]\n", i, sgl[i].size)};
foreach (sgl[i,j])
s = {s, $psprintf("[Segment := %0d, Descriptor := %0d, Length := %0d]\n", i,j, sgl[i][j][8])};
return s;
endfunction
endclass
module top;
cmd_item c=new();
initial repeat(1) begin
assert(c.randomize());
uvm_report_info("cmd_item", c.sprint());
end
endmodule
The above code looks fine and runs fine on other tools as well. Can you double check VCS result? If problem still persists, time to contact your vendor!