# Functions in Verilog for combinational logic

I encountered something weird in a Verilog code, and I have doubts about it.

Someone used a function in Verilog in the following way:

Pipe #(.W(\$bits(Data))) MetaO (Clock, MyFunc(DataIn, I0, I1), DataOut);
function [DATA_SIZE-1:0] MyFunc (input [DATA_SIZE-1:0] DataIn, input I0, input I1);
MyFunc    = DataIn;
MyFunc[1] = X;
if(I0) begin
MyFunc[2]  = Y;
MyFunc[3]  = K;
MyFunc[4]  = I1;
end endfunction


So, what he tried to do here is to pipe DataIn to DataOut,
but to manipulate DataIn bits before the pipe, so he used function as the input to the Input port of the pipe.

My doubts are in the function itself.
He first of all kind of initialized MyFunc with DataIn,
and then in the following lines, assigns different values in the other bits depending on some stuff.

Because it's eventually combinatorial logic, I ask myself if it's a correct way to write Verilog.

Doesn't it create a race condition on some of these bits?
Can it make timing issues eventually?

What is another better way to write the same combinatorial logic?

Doesn't it create a race condition on some of these bits?

No, there is no race condition between the bits. As you mentioned, the function is used to model combinational logic. It correctly uses blocking assignments (=).

Can it make timing issues eventually?

No, there are no timing issues. The function explicitly sets 4 bits of MyFunc: 1-4. But, all bits of MyFunc are set by the initialization line, no matter how big DATA_SIZE is:

MyFunc    = DataIn;


Since there are assignments to all bits, this avoids inferring unintended latches.

What is another better way to write the same combinatorial logic?

Another way (not necessarily better) is:

always_comb begin
MyFunc    = DataIn;
MyFunc[1] = X;
if (I0) begin
MyFunc[2] = Y;
MyFunc[3] = K;
MyFunc[4] = I1;
end
end


You would replace MyFunc with another signal name.

One advantage of the function is that it can be called many times in the code without duplicating the 9 lines of code above and with a different set of input signals.

• so, the synthesizer in Verilog reads always_comb and function line by line from the first line and on? I imagined that all the lines inside the always_comb and function implemented in parallel. Commented Mar 6 at 12:57
• @MichaelRahav: The assignments all occur during the same time step in simulation, but they occur in the order that you wrote in the code since you use the blocking assignment operator (=). Commented Mar 6 at 13:02
• OK good to know, thanks! Commented Mar 6 at 13:22