The question does not fully cover what is understood about fixed-point numbers, therefore will cover a little background which might not be relevant to the OP.
The decimal weighting of unsigned binary (base 2) numbers, 4bit for the example follows this rule:
2^3 2^2 2^1 2^0 (Base 2) 8 4 2 1
Just for reference the powers stay the same and the base is changed. For 4 hex it would be:
16^3 16^2 16^1 16^0 4096 256 16 1
Back to base 2, for twos complement signed number the MSB (Most Significant Bit) becomes negative.
-2^3 2^2 2^1 2^0 (Base 2, Twos complement) -8 4 2 1
When we insert a binary point or fractional bit the pattern continues. 4 Integer bits 4 fractional bits.
Base 2: Twos complement 4 integer, 4 bit frational -2^3 2^2 2^1 2^0 . 2^-1 2^-2 2^-3 2^-4 -8 4 2 1 . 0.5 0.25 0.125 0.0625
Unfortunately Verilog does not have a fixed-point format so the user has to keep track of the binary point and worked with scaled numbers. Decimal points
. can not be used in in verilog numbers stored as
logic as they are essentially integer formats. However verilog does ignore
_ when placed in number declarations, so it can be used as the binary point in numbers. Its use is only symbolic and has no meaning to the language.
In the above format 2.5 would be represented by
8'b0010_1000, the question has 16 fractional bits therefore you need to place 16 bits after the
_ to keep the binary point in the correct place.
Fixed-point Multiplication bit widths
If we have two numbers A and B the width of the result A*B will be:
Integer bits = A.integer_bits + B.integer_bits. Fractional bits = A.fractional_bits + B.fractional_bits.
Therefore [4 Int, 4 Frac] * [4 Int, 4 Frac] => [8 Int, 8 Frac]
reg [7:0] a = 0010_1000; reg [7:0] b = 0010_1000; reg [15:0] sum; always @* begin sum = a * b ; $displayb(sum); //Binary $display(sum); //Decimal end // sum == 00000110_01000000; //Decimal->6.25
Example on EDA Playground.
From this you should be able to change the depths to suit any type of fixed point number. and cast ing back to a 16 Int 16 fractional number can be done by part selecting the correct bits. Be careful if you need to saturate instead of overflowing.
There is a related Q&A that has 22 fractional bits.