Function
Function can be declared by function keyword.
Arguments are placed in () and return type is placed after ->.
If function doesn’t have a return value, -> can be omitted.
module ModuleA {
let a: logic<10> = 1;
var b: logic<10>;
function FunctionA (
a: input logic<10>,
) -> logic<10> {
return a + 1;
}
function FunctionB (
a: input logic<10>,
) {}
assign b = FunctionA(a);
initial {
FunctionB(a);
}
}
Interface modports can be used as type of arguments. The given interface modports will be expanded into each Verilog ports when emitting SystemVerilog RTL.
interface InterfaceA::<W: u32> {
var ready: logic ;
var valid: logic ;
var data : logic<W>;
modport master {
ready: input ,
valid: output,
data : output,
}
modport slave {
..converse(master)
}
}
module ModuleA {
inst a_if: InterfaceA::<8>;
inst b_if: InterfaceA::<8>;
function FunctionA (
a_if: modport InterfaceA::<8>::slave ,
b_if: modport InterfaceA::<8>::master,
) {
a_if <> b_if;
}
always_comb {
FunctionA(a_if, b_if);
}
}
Global function
Functions defined at the project namespace level (outside of module, interface, and package) are called global functions.
When a global function is called from a module, it is emitted into the caller module’s namespace in the generated SystemVerilog.
Global functions can be generic and can be published with pub for cross-project use.
pub function add::<W: u32> (
a: input logic<W>,
b: input logic<W>,
) -> logic<W> {
return a + b;
}
module ModuleA #(
param WIDTH: u32 = 8,
) (
i_a: input logic<WIDTH>,
i_b: input logic<WIDTH>,
o_c: output logic<WIDTH>,
) {
assign o_c = add::<WIDTH>(i_a, i_b);
}