Forum Discussion
modelsim compiling error:external function 'xxxxx' may not be used in a constant expr
Consider the following code:
package pkg;
function bit bitgen(int bit1idx);
automatic bit res = '0;
if (bit1idx >= 0 && bit1idx < 16)
res = 1'b1;
return res;
endfunction
function bit bit2test(bit bits2test);
if ((bits2test&bitgen(2)) != 0)
return 1'b1;
return 1'b0;
endfunction
endpackage
module mod2test# (
parameter para2test = 16'h000F
);
import pkg::*;
localparam bit2set_flag = bit2test(para2test);
initial begin
if (bit2set_flag == 0)
$error("bit2 of para2test is not set!);
end
endmodule
When compiling these code in modelsim, it reports some error message, one of them is: External function 'bit2test' may not be used in a constant expression. My purpose is: by defining a function to test the instantiate parameter of module , to obtain some state of instantiating of module and to make some special processing for it, the defined function should be used in many different module, for the testing work in them is same. But if the function defined in package can not be used in constant expression, how can I realize my purpose in design?10 Replies
- Altera_Forum
Honored Contributor
This worked for me going back a number of releases. You have a few typos. Make sure what you posed is exactly what you are compiling.
- Altera_Forum
Honored Contributor
--- Quote Start --- This worked for me going back a number of releases. You have a few typos. Make sure what you posed is exactly what you are compiling. --- Quote End --- Hi, Mr.dave_59. thanks for replying. I'm sorry that I had not made enough tests. After testing the code I found it worked in module, but not in an interface:
can I get it work in interface?package pkg; function bit bitgen(int bit1idx); automatic bit res = '0; if (bit1idx >= 0 && bit1idx < 16) res = 1'b1; return res; endfunction function bit bit2test(bit bits2test); if ((bits2test&bitgen(2)) != 0) return 1'b1; return 1'b0; endfunction endpackage interface iftest# ( parameter para2test = 15 ); import pkg::*; localparam bit2set_flag = bit2test(para2test); // modelsim reports compiling error here! initial begin if (bit2set_flag == 0) $error("bit2 of para2test is not set!"); end end module mod2test# ( parameter para2test = 15 ); import pkg::*; localparam bit2set_flag = bit2test(para2test); // the code here passed modelsim's compiling initial begin if (bit2set_flag == 0) $error("bit2 of para2test is not set!"); end endmodule - Altera_Forum
Honored Contributor
You still have typos. This works for me after replacing end with endinterface.
- Altera_Forum
Honored Contributor
--- Quote Start --- You still have typos. This works for me after replacing end with endinterface. --- Quote End --- Thank you for your patiently replying, At last I found the reason why it didn't work in my design is: one of the functions in the package had declared a local variable without "static" or "automatic" prefix word. But the error message is suppressable for modelsim and is not reported with red color. So this key error message is covered by the following less important red color messages and ignored by me. Now After add a "automatic" prefix for that local variable, the problem has been solved. Thank you for your patient replying again! - Altera_Forum
Honored Contributor
Yes, without the static or automatic keyword, it is difficult to know if the local variable gets initialized once at time 0, or each time the function gets called. I think its best to declare your package as automatic, then all the functions are automatic, and all the local variables inside the functions are automatic. Then, only declare local variables as 'static' when they need to be.
- Altera_Forum
Honored Contributor
--- Quote Start --- Yes, without the static or automatic keyword, it is difficult to know if the local variable gets initialized once at time 0, or each time the function gets called. I think its best to declare your package as automatic, then all the functions are automatic, and all the local variables inside the functions are automatic. Then, only declare local variables as 'static' when they need to be. --- Quote End --- Did you mean I should declare the package like the following code?
I'm not familly enough for the SystemVerilog syntax, and not sure if it is right. Would you like tell me more details ?automatic package pkg; // ... dummy codes... endpackage - Altera_Forum
Honored Contributor
Let's say you have this
Those results are because gacc, add, in, and fout are all static variables initialized once at time 0. You can make a function automatic, which makes all arguments, return values, and local variables implicitly automatic (initialized upon each entry to the function)package pkg; int gacc; function int fout(input int in); int acc; if (in !=0) begin acc += in; fout = acc+ gacc; gacc = acc; end endfunction endpackage // in some code you have $display(fout(1)); // prints 1 $display(fout(0)); // prints 1 - returns last value assigned to fout $display(fout(1)); // prints 3
When you declare a package or module as automatic, then all named blocks, tasks, and functions declared in that package become implicitly automaticpackage pkg; int gacc; function automatic int fout(input int in); int acc; // implicitly automatic if (in !=0) begin acc += in; fout = acc+ gacc; gacc = acc; end endfunction endpackage // in some code you have $display(fout(1)); // prints 1 $display(fout(0)); // prints 0 // no value assigned to fout $display(fout(1)); // prints 2package automatic pkg; int gacc; // always static - not inside any block function int fout(input int in); // implicitly automatic int acc; // implicitly automatic if (in !=0) begin acc += in; fout = acc+ gacc; gacc = acc; end endfunction endpackage // in some code you have $display(fout(1)); // prints 1 $display(fout(0)); // prints 0 $display(fout(1)); // prints 2 - Altera_Forum
Honored Contributor
Wow, it seems that the automatic package is just the feature what I want!. will it damage or impact the type definition in package?
well... I mean if I define a type in an automatic package, will the type be deferent to non-automatic package?package automatic pkg1; typedef enum { t1 = 0, t2 = 1 } type_t; endpackage package pkg2; typedef enum { t1 = 0, t2 = 1 } type_t; endpackage - Altera_Forum
Honored Contributor
It has no impact on typedefs. It only affects the lifetimes of variables declared inside named blocks, functions or tasks.
- Altera_Forum
Honored Contributor
--- Quote Start --- It has no impact on typedefs. It only affects the lifetimes of variables declared inside named blocks, functions or tasks. --- Quote End --- OK! Thank you! I've learned so much form your patient replying! Thank you very much!