You can write recursive modules using a generate block:
module unary_and
#(parameter WIDTH = 32)
(input [WIDTH-1:0] in_and,
output out_and)
generate
if(WIDTH == 1) begin
assign out_and = in_and;
end
else if(WIDTH == 2) begin
assign out_and = in_and[0] & in_and[1];
end
else begin
unary_and #(.WIDTH (WIDTH/2))
unary_and_low
(.in_and (in_and[WIDTH/2-1:0]),
.out_and (out_and_low));
unary_and #(.WIDTH (WIDTH - WIDTH/2))
unary_and_high
(.in_and (in_and[WIDTH-1:WIDTH/2]),
.out_and (out_and_high));
assign out_and = out_and_low & out_and_high;
end
endgenerate
endmodule
This is from Recursive and Iterative designs in Verilog where you can find other solutions as well. You can check out Recursive Modules too.
Maybe you should also take a look at these questions and answers:
Could we have generate inside an always block?
Verilog generate/genvar in an always block