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;

phuclv
  • 37,963
  • 15
  • 156
  • 475
Jack93
  • 21
  • 1
  • 4
  • 13
  • 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 – phuclv Mar 09 '15 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? – Jack93 Mar 09 '15 at 13:16
  • I think it would be useful for you to read these answers first http://stackoverflow.com/a/27765266/97073 http://stackoverflow.com/a/28170918/97073 They might answer your question or help you to revise it. up-votes on useful answers are welcome. – Morgan Mar 09 '15 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? – Jack93 Mar 10 '15 at 03: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. – Morgan Mar 10 '15 at 08:19
  • You are correct that, verilog does not have a fixed point data. As the second link shows you can 'conceptually' add fractional information by moving the binary point. Verilog will think it is an integer but we know it is fractional. for example you want to encode `2.5` in binary this is `10.1`. So multiply by 2**1 (1 fractional bit) in decimal it is `5` in binary it is `101` you should be able to notice this has the same bit set as the `2.5`. Now just perform Integer multiplication on the number. – Morgan Mar 10 '15 at 08:24
  • How are the fractional numbers getting into verilog. They need to be formatted correctly before they reach hardware. – Morgan Mar 10 '15 at 08:26
  • @Morgan, so does it mean that i need do personally convert the input of the numbers like Data A and B and redeem the output and reconvert it back again as verilog cannot support that right? – Jack93 Mar 10 '15 at 09:11
  • No, How do the numbers get to verilog? I am assuming this is for synthesis FPGA or ASIC, then the numbers some how have to get into the physical device. How are those numbers formatted? are they already fixed point? – Morgan Mar 10 '15 at 10:45
  • @Morgan, No the numbers are inputted from Matlab as shown in above (not fixed point), now i need to convert the numbers to the format the acceptable by verilog and then perform multiplication. Any idea on performing that? – Jack93 Mar 10 '15 at 12:59

3 Answers3

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

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • can descibe how I able to define the data A for value 0.01829052843325460 is it in signed? – Jack93 Mar 11 '15 at 08:19
  • 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 – phuclv Mar 11 '15 at 09:54
  • 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? – Jack93 Mar 11 '15 at 12:24
  • 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 – phuclv Mar 11 '15 at 15:38
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.

Community
  • 1
  • 1
Morgan
  • 19,934
  • 8
  • 58
  • 84
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.

Kiloman
  • 47
  • 6
  • 1
    I think the question is more about how to encode fractional information than how to implement an integer multiplication. – Morgan Mar 09 '15 at 15:39