The following code for constraint for sum of products results in error:
class c;
rand logic [7:0] dataq1 [];
rand logic [7:0] dataq2 [];
constraint data_size {dataq1.size() == 10; dataq2.size() == 10; }
constraint data_items {
foreach(dataq1[i]) dataq1[i] < 100;
foreach(dataq2[i]) dataq2[i] < 50;
}
constraint sum_c {
dataq1.sum() with (int'(item)) < 1000;
dataq2.sum() with (int'(item)) < 1000;
}
constraint sum_product_c {sum_pro() < 100000; }
function longint sum_pro();
sum_pro = 0;
foreach(dataq1[i])
sum_pro += dataq1[i] * dataq2[i];
endfunction
endclass
module test;
initial begin
c c1 = new();
void'(c1.randomize());
foreach(c1.dataq1[i])
$display("%0d %0d", c1.dataq1[i], c1.dataq2[i]);
end // initial begin
endmodule // test
Errors:
Error-[CSTR-UMC] Constraint: unsupported method call
ex04/mycode/sum_of_products.sv, 15
$unit, “this.sum_pro()”
Method c::sum_pro contains a construct not supported in constraint
functions: reference to a rand variable ‘dataq1’ at line 19 of
ex04/mycode/sum_of_products.sv.
Rewrite the method to avoid unsupported constructs.
Error-[CSTR-UMC] Constraint: unsupported method call
ex04/mycode/sum_of_products.sv, 15
$unit, “this.sum_pro()”
Method c::sum_pro contains a construct not supported in constraint
functions: reference to a rand variable ‘dataq1’ at line 20 of
ex04/mycode/sum_of_products.sv.
Rewrite the method to avoid unsupported constructs.
Error-[CSTR-UMC] Constraint: unsupported method call
ex04/mycode/sum_of_products.sv, 15
$unit, “this.sum_pro()”
Method c::sum_pro contains a construct not supported in constraint
functions: reference to a rand variable ‘dataq2’ at line 20 of
ex04/mycode/sum_of_products.sv.
Rewrite the method to avoid unsupported constructs.
Normally the keyword unsupported is due to the tool limitation for that you need to contact your tool’s vendor, as I tried your code and it compiled, and ran without errors, or do as the log file is telling you “Rewrite the method to avoid unsupported constructs.”
Also you can check the LRM section 18.5.12 Functions in constraints to see what are the restrictions about calling functions in constraints, as they can change the order on how constraints are solved
This would not work even if your tool did support the function. The function is not pure, meaning its return value is not solely determined by its inputs—it does not have any.
You can write this as
constraint sum_product_c {dataq1.sum(q1) with (int'(q1)*int'(dataq2(q1.index))) < 100000; }
While reading the LRM in the section I mentioned I don’t see any reference to “pure functions”, is this the part regarding to functions with no side effects or am I missing something here?
btw I know this not a tool specific forum, but will this yield in a randomisation failure or not, as per the LRM? as Questa and other simulator did not report any on checking the result of the randomize() call
ncelab: *W,DSEMEL: This SystemVerilog design will be simulated as per IEEE 1800-2009 SystemVerilog simulation semantics. Use -disable_sem2009 option for turning off SV 2009 simulation semantics.
constraint sum_product_c {dataq1.sum(q1) with (int’(q1)*int’(dataq2[q1.index])) < 100000; }
|
ncelab: *E,CUVUNF (./testbench.sv,25|77): Hierarchical name component lookup failed at ‘index’.
Yes, no side effects is part of the general software concept of a pure function call. (not to be confused with a pure virtual method declaration in SystemVerilog). Since the function call used in a constraint has no input arguments, there is no way to figure out the random variable ordering. So the function could be called before values have been placed in the dataq and meet the constraint.
In reply to csivas@gmail.com:
Please use code tags making your code easier to read. I have added them for you.