- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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:
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
can I get it work in interface?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You still have typos. This works for me after replacing end with endinterface.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
automatic package pkg;
// ... dummy codes...
endpackage
I'm not familly enough for the SystemVerilog syntax, and not sure if it is right. Would you like tell me more details ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Let's say you have this
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
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 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 2
When you declare a package or module as automatic, then all named blocks, tasks, and functions declared in that package become implicitly automatic package 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It has no impact on typedefs. It only affects the lifetimes of variables declared inside named blocks, functions or tasks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page