When attempting to compile the following code in a large environment I get the error message:
** Error: The function ‘count_1s’ is not a valid constant function
The code:
function automatic integer count_1s(input [32:0] in,integer count);
integer idx = 0;
begin
count_1s = '0;
repeat(count) begin
if(in[idx])
count_1s += 1;
idx++;
end
end
endfunction
When compiling standalone (small debug testbench) or with other simulators this code works fine. I have also tried changing the name of the function and the localparam to be very unique names and that does not resolve the issue - concern was regarding namespace collision but that does not appear to be the problem. Any suggestions?
If your code works in one simulator but not another, then you have a tool issue. Since this forum isn’t for tool issues, you need to contact your vendor support team for additional assistance.
It seems to me your function does meet the definition for a “constant function” as defined in the SystemVerilog spec. But I’m thinking there’s a bit of gray area here. After all there’s an implicit “loops must be unrollable at elaboration time” requirement for constant functions too.
I’m thinking your function would work if you removed the argument “count” as your repeat loop iterator, and just hardcoded 33 as your loop count?
Personally, I’ve not used repeat() statements, but have constant functions using fixed for loops doing very similar things to yours. All my tools accept such constructs as constant functions.
Edit - I’m wondering if the automatic tag is tripping the tool too. It’s not necessary is it?
Can you show a complete example? Maybe you’re missing something in the large design. It’s still possible there are tool specific features getting in the way (like parameter overrides), so you.may have to contact your tool vendor.
module top();
logic [2:0] in;
logic [2:0] out;
foo foo_i(
.*
);
endmodule
module foo (
input logic [2:0] in,
output reg [2:0] out
);
generate
if(1)
`include "foo.svh"
endgenerate
logic [32:0] wdata_all;
assign out = in - P;
always_comb begin
$display("P = 0x%x",P);
end
endmodule
function integer count_1s;
input [32:0] in;
input integer count;
integer idx;
begin
count_1s = 0;
for(idx = 0; idx<count; idx=idx+1)begin
if(in[idx])
count_1s = count_1s+1;
end
end
endfunction
notice that we were including the foo.svh inside a generate statement. This is where the problem lies. If we remove the generate statement it compiles just fine.
Edit: it helps to know that the function is located in foo.svh
Edit: it helps to know that the function is located in foo.svh
There’s your problem right there. You’re including the function declaration within a generate block.
From the standard, one of the requirements for a constant function:
Constant functions shall not be declared inside a generate block