Parameter passing to functions

J

John Apostol

Guest
Is there a means in Verilog to create a generic function that can be
reused in the same manner as a parameterized module? e.g. for modules
we have

module xyz_generic (a,b,...);

parameter SIZE = 32;

input [SIZE-1:0] a;
....

endmodule

module top (...);
....


xyz_generic #(.SIZE(16)) xyz_16 ( .a(...), ...);
xyz_generic #(.SIZE(64)) xyz_64 ( ...);


Simularly can I somehow define a function e.g.

function [SIZE-1:0] abc_generic;

input [SIZE-1:0] a;
input [SIZE-1:0] b;
....

abc_generic = ...

endfunction

?

Thanks
 
Hi,
In Verilog, functions have to be inside a module, hence they can
reuse parameters from their modules - isn't that enough? are you
looking for "global functions" that can be used across modules? If so,
SystemVerilog has them via packages (similar to VHDL).
Ajeetha
http://www.noveldv.com
 
Well, I do have other questions, but for the momemnt lets just say that
I want a function ie. defined in its module that can be called multiple
times but with different parameters e.g. (made up code to mimic the
way parameter passing is done with modules)

y_32 <= foo_generic #(.SIZE(32)) ( a=> a_32 , b => b_32 );
z_16 <= foo_generic #(.SIZE(16)) ( a=> w_16 , b => x[16:0]);
... ie. call foo_generic with arguments of varying bus size
within this module ...

-john


Ajeetha wrote:
Hi,
In Verilog, functions have to be inside a module, hence they can
reuse parameters from their modules - isn't that enough? are you
looking for "global functions" that can be used across modules? If so,
SystemVerilog has them via packages (similar to VHDL).
Ajeetha
http://www.noveldv.com
 
John Apostol wrote:
Is there a means in Verilog to create a generic function that can be
reused in the same manner as a parameterized module? e.g. for modules
we have

module xyz_generic (a,b,...);

parameter SIZE = 32;

input [SIZE-1:0] a;
...

endmodule

module top (...);
...


xyz_generic #(.SIZE(16)) xyz_16 ( .a(...), ...);
xyz_generic #(.SIZE(64)) xyz_64 ( ...);


Simularly can I somehow define a function e.g.

function [SIZE-1:0] abc_generic;

input [SIZE-1:0] a;
input [SIZE-1:0] b;
...

abc_generic = ...

endfunction

?

Thanks
If all you need is flexible range for the input/output ports, verilog
2001 allows integer/real type input/output ports for functions. I'm not
sure if it will synthesize, but it might be worth a try.

-jz
 
In Verilog, the granularity of parameterized instantiation is at
the module level.

Another approach would be to recognize that your function
is intended to represent a piece of combinational logic,
which you could also represent with a module. Just put
your function into a module with ports matching the function
arguments, and add a continuous assignment that computes
the output by calling the function on the inputs. In the
module where you wanted to call the function, instantiate
the module with appropriate parameterization, and connect
the inputs and an output. In the procedural block where you
would have called the function, just read the output. Unlike
making a hierarchical function call, this _will_ synthesize.
You have just done some of what the synthesis tool would
have had to do anyway.
 
No, not directly.

A function call does not instantiate a function. It calls a function
that was already instantiated with the module, with a particular
set of parameter values (e.g. widths).

You have a couple of choices. If all you are changing is widths,
you can just define the function with the maximum width you
need, and rely on implicit conversions when you call it with
values that are narrower.

Or you can put the function in its own parameterized module,
instantiate the module multiple times with different parameter
values to instantiate the function variants you need, and then
call the particular instance of the function you want by using
a hierarchical path to it. I don't know whether synthesis will
handle this though.

It would be nice if you could use Verilog-2001 for-generates
to generate multiple instances of a function with a range of
different widths. Unfortunately, Verilog-2001 disallows task
and function declarations in for-generates (probably due to
an erroneous belief that they would always be identical and
thus useless). Verilog-2005 is expected to correct this.
 
This was my fear. The objective was to have an overloadable function
from a bus width scaling perspective ie. in the same manner as the
language allows you to overload parametrized modules. But I wanted
the function call, not a module.

Thanks.

sharp@cadence.com wrote:
No, not directly.

A function call does not instantiate a function. It calls a function
that was already instantiated with the module, with a particular
set of parameter values (e.g. widths).

You have a couple of choices. If all you are changing is widths,
you can just define the function with the maximum width you
need, and rely on implicit conversions when you call it with
values that are narrower.

Or you can put the function in its own parameterized module,
instantiate the module multiple times with different parameter
values to instantiate the function variants you need, and then
call the particular instance of the function you want by using
a hierarchical path to it. I don't know whether synthesis will
handle this though.

It would be nice if you could use Verilog-2001 for-generates
to generate multiple instances of a function with a range of
different widths. Unfortunately, Verilog-2001 disallows task
and function declarations in for-generates (probably due to
an erroneous belief that they would always be identical and
thus useless). Verilog-2005 is expected to correct this.
 

Welcome to EDABoard.com

Sponsor

Back
Top