Suppose I have a multiplier code like this,
module multiply(
output [63:0] result,
input [31:0] a,
input [31:0] b
);
assign result = a * b;
endmodule
This produces a lot of gates.
What preferable method should be used to implement combinatorial multiplier?
Hardware multipliers are big, you just have to live with it!
Multipliers will get bigger as its input bit widths get bigger. So if you don't need the full 32 bits on one of you operands, then reducing this size to the minimum will reduce the size of the resulting hardware.
If you're multiplying by a fixed number, I think the compiler can make some optimizations to limit the size of the hardware too. Or you can use different encoding schemes for the fixed number such as CSD that will reduce the number of adders in the multiplier, further reducing its area.
If you need loads of multipliers and have a fast clock, maybe you can reuse a single hardware multiplier for many calculations. This means writing some control/pipelining logic to schedule your multiplies, and you might need some memory, but it can save you area overall. You'd be designing a mini-DSP datapath in this case.