0

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;

10
  • What's that data? Fixed point? In which format? You can't simply multiply 2 values like that, just write down the math and you'll see Commented Mar 9, 2015 at 12:52
  • @LưuVĩnhPhúc, the data is the Data A and B, and yes I am using Fixed Point Arithmetic maybe in Q2.14. Any idea on how to multiply the both data? Commented Mar 9, 2015 at 13:16
  • I think it would be useful for you to read these answers first stackoverflow.com/a/27765266/97073 stackoverflow.com/a/28170918/97073 They might answer your question or help you to revise it. up-votes on useful answers are welcome. Commented Mar 9, 2015 at 13:24
  • @Morgan, Thanks for the link, it was helpful but since verilog does not have any fix point format support, how does i able to program the system to read the incoming data and change it to base 2 fix point with 16 bit (bit 16= signed bit, bit 15 = integer and bit 14-0 is the fractional bit) and do calculations? Because now I dealing with thousands of input data, it is quite impossible for me to manually convert 1 by 1 from decimal numbers like above to its respective fix point. Any guidance or ways to do so? Commented Mar 10, 2015 at 3:13
  • All numbers in a computer are binary, Hexadecimal, decimal and binary are just ways of displaying the underlying binary data. Signed and unsigned are just ways of interpreting that data. Commented Mar 10, 2015 at 8:19

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

4 Comments

can descibe how I able to define the data A for value 0.01829052843325460 is it in signed?
If you want to store to 17 decimal digits + 1 more digit for int part like in 0.01829052843325460 (or 2 bits like in your format) then you need at least 60 bits for unsigned type and 61 bits for signed type
so means if i want to use 16 bit then i must round off until it can support 14 bit of fractional bit right? But still as mention above after getting the result in this way i need to convert it back to its original value as in 16 bit, it is shown in binary right?
I don't know what you mean by "support" here. You must shift and round off after doing the 16x16→32 multiplication to make it back 16-bit Q2.14
1

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.

Comments

0

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.

1 Comment

I think the question is more about how to encode fractional information than how to implement an integer multiplication.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.