Jack93
Jack93

Reputation: 21

16-bit fixed point arithmetic multiplication

I have 2 data values (A = 0.00537667139546100 and B = -0.0182905843325460) and I want to multiply them using 16-bit fixed point arithmetic by using round off method.

How should I do that? How should I define the both data? Is it reg or signed? Is the multiplication like Output = A*B;

Upvotes: 0

Views: 11246

Answers (3)

phuclv
phuclv

Reputation: 41794

A binary pattern stored as a 16-bit value x in Q2.14 format represents the value x/214, therefore if we have A and B then

\frac{A}{2^{14}}\times\frac{B}{2^{14}} = \frac{A \times B}{2^{14}}\times \frac{1}{2^{14}}

So if you directly multiply the patterns A and B, you need to divide the result by 214 to get it back into the form x/214 like this

Output = A*B >> 14;

A rounding step is needed to get the nearest value. You can find the way to do it in Q number format#Math operations. The simplest way to round to nearest is just add back the bit that was last shifted out (i.e. the first fractional bit) like this

AxB = (int32_t)A*B;
AxB = (AxB >> 14) + ((AxB >> 13) & 1);

You might also want to read these

One important note is that 16-bit fixed-point values can only hold about 4.8 digits of precision, you can't store such long values like 0.0182905843325460. The nearest value is about 0.018310546875

Upvotes: 3

Morgan
Morgan

Reputation: 20514

If I understand the problem Stimulus is being generated by Matlab of the form (Floating Point):

0.00537667139546100
-0.0182905843325460

Where you want to apply a fixed point multiplication in verilog on those numbers.

My first step here would be to round the data in Matlab I have a function called roundn2 which I use to round to a fixed point precision use -15 for 15 fractional bits.

I would then multiply that number by 2^15 in matlab to turn it into an integer.

Then the problem in Verilog is easy as a*b, remembering to keep track of the decimal (binary) point, and shift the data back to interpret as a fractional.

More information regarding multiplication in verilog can be found here and here.

Upvotes: 1

Kiloman
Kiloman

Reputation: 47

If you just use the "*" symbol, when you synthesize, your synthesis tool will use whichever kind of multiplier it internally decides to use. You won't necessarily get the kind of round-off behavior that you want. You will need to design the logic for it yourself.

Since at least one of your inputs is signed, you will want to use signed reg for both inputs A and B, as well as for the output.

Upvotes: 0

Related Questions