VHDL, how to convert sensor data to Q15

Guest
Sensor data length is 16 bit data, value is from -32768 to 32767,i think data format represented as one highest is sign and others are integers, who can help how to convert it to Q15 data format in VHDL?

Q15 like https://en.wikipedia.org/wiki/Q_(number_format) one sigh and others are fractional from -1 to 1

Sensor is ADC output is 16 bit format, one sign and other integer

so it need only divide ? ADC output to 32768 ??
 
Den lørdag den 21. januar 2017 kl. 17.38.01 UTC+1 skrev Tim Wescott:
On Sat, 21 Jan 2017 07:58:02 -0800, abirov wrote:

Sensor data length is 16 bit data, value is from -32768 to 32767,i think
data format represented as one highest is sign and others are integers,
who can help how to convert it to Q15 data format in VHDL?

Q15 like https://en.wikipedia.org/wiki/Q_(number_format) one sigh and
others are fractional from -1 to 1

Sensor is ADC output is 16 bit format, one sign and other integer

so it need only divide ? ADC output to 32768 ??

OK. First, in an FPGA, if you're going to start with 16 bits and end up
with 16 bits and divide by 32768, what do you need to do other than
relabel the bits?

Second, review your number formats very carefully. I strongly suspect
that everything is in 2's compliment where, indeed, the MSB is the sign
bit, but things are more complicated than that. As far as I know, if
it's called Q15, it's just 2's compliment integer shifted down by 15 bits..

Third, verify what the ADC is putting out. Some put out 2's compliment,
some put out straight binary, and it's up to you to invert the first bit
to get 2's compliment.

yes it is just a relabeling until you start multiplying.

1.15 * 1.15 results in 2.30 to get back to 1.15 you need skip an msb and use the upper bits (and keep in mind the -1*-1 results in overflow)

-Lasse
 
On Sat, 21 Jan 2017 07:58:02 -0800, abirov wrote:

Sensor data length is 16 bit data, value is from -32768 to 32767,i think
data format represented as one highest is sign and others are integers,
who can help how to convert it to Q15 data format in VHDL?

Q15 like https://en.wikipedia.org/wiki/Q_(number_format) one sigh and
others are fractional from -1 to 1

Sensor is ADC output is 16 bit format, one sign and other integer

so it need only divide ? ADC output to 32768 ??

OK. First, in an FPGA, if you're going to start with 16 bits and end up
with 16 bits and divide by 32768, what do you need to do other than
relabel the bits?

Second, review your number formats very carefully. I strongly suspect
that everything is in 2's compliment where, indeed, the MSB is the sign
bit, but things are more complicated than that. As far as I know, if
it's called Q15, it's just 2's compliment integer shifted down by 15 bits.

Third, verify what the ADC is putting out. Some put out 2's compliment,
some put out straight binary, and it's up to you to invert the first bit
to get 2's compliment.

--
Tim Wescott
Control systems, embedded software and circuit design
I'm looking for work! See my website if you're interested
http://www.wescottdesign.com
 
On Sat, 21 Jan 2017 09:14:18 -0800, lasselangwadtchristensen wrote:

Den lørdag den 21. januar 2017 kl. 17.38.01 UTC+1 skrev Tim Wescott:
On Sat, 21 Jan 2017 07:58:02 -0800, abirov wrote:

Sensor data length is 16 bit data, value is from -32768 to 32767,i
think data format represented as one highest is sign and others are
integers, who can help how to convert it to Q15 data format in VHDL?

Q15 like https://en.wikipedia.org/wiki/Q_(number_format) one sigh and
others are fractional from -1 to 1

Sensor is ADC output is 16 bit format, one sign and other integer

so it need only divide ? ADC output to 32768 ??

OK. First, in an FPGA, if you're going to start with 16 bits and end
up with 16 bits and divide by 32768, what do you need to do other than
relabel the bits?

Second, review your number formats very carefully. I strongly suspect
that everything is in 2's compliment where, indeed, the MSB is the sign
bit, but things are more complicated than that. As far as I know, if
it's called Q15, it's just 2's compliment integer shifted down by 15
bits.

Third, verify what the ADC is putting out. Some put out 2's
compliment, some put out straight binary, and it's up to you to invert
the first bit to get 2's compliment.


yes it is just a relabeling until you start multiplying.

1.15 * 1.15 results in 2.30 to get back to 1.15 you need skip an msb and
use the upper bits (and keep in mind the -1*-1 results in overflow)

-Lasse

I wrote my own set of Q15 and Q31 code (software, not HDL) that travels
around with me. Even though it takes a few clock ticks on every
operation, I simply forbid 0x80..0 -- it makes life ever so much simpler.

Dunno how hard it'd be with an FPGA, but it might be worthwhile.

--
Tim Wescott
Control systems, embedded software and circuit design
I'm looking for work! See my website if you're interested
http://www.wescottdesign.com
 
On 1/21/2017 10:58 AM, abirov@gmail.com wrote:
Sensor data length is 16 bit data, value is from -32768 to 32767,i think data format represented as one highest is sign and others are integers, who can help how to convert it to Q15 data format in VHDL?

Q15 like https://en.wikipedia.org/wiki/Q_(number_format) one sigh and others are fractional from -1 to 1

Sensor is ADC output is 16 bit format, one sign and other integer

so it need only divide ? ADC output to 32768 ??

As others have indicated, there is no logic required to convert between
the two formats. Here are some links for the proposed IEEE fixed point
arithmetic package.

http://wayback.archive.org/web/20151124101646/http://www.vhdl.org/fphdl/Fixed_ug.pdf

http://wayback.archive.org/web/20151130082614/http://vhdl.org/fphdl/fixed_pkg_c.vhdl

--

Rick C
 
On 1/21/2017 5:25 PM, rickman wrote:
On 1/21/2017 10:58 AM, abirov@gmail.com wrote:
Sensor data length is 16 bit data, value is from -32768 to 32767,i
think data format represented as one highest is sign and others are
integers, who can help how to convert it to Q15 data format in VHDL?

Q15 like https://en.wikipedia.org/wiki/Q_(number_format) one sigh and
others are fractional from -1 to 1

Sensor is ADC output is 16 bit format, one sign and other integer

so it need only divide ? ADC output to 32768 ??

As others have indicated, there is no logic required to convert between
the two formats. Here are some links for the proposed IEEE fixed point
arithmetic package.

http://wayback.archive.org/web/20151124101646/http://www.vhdl.org/fphdl/Fixed_ug.pdf


http://wayback.archive.org/web/20151130082614/http://vhdl.org/fphdl/fixed_pkg_c.vhdl

And you might need this one too.

http://wayback.archive.org/web/20160129055142/http://www.vhdl.org/fphdl/fixed_float_types_c.vhdl

--

Rick C
 
On 21/01/2017 22:26, rickman wrote:
On 1/21/2017 5:25 PM, rickman wrote:
...

As others have indicated, there is no logic required to convert between
the two formats. Here are some links for the proposed IEEE fixed point
arithmetic package.

http://wayback.archive.org/web/20151124101646/http://www.vhdl.org/fphdl/Fixed_ug.pdf



http://wayback.archive.org/web/20151130082614/http://vhdl.org/fphdl/fixed_pkg_c.vhdl


And you might need this one too.

http://wayback.archive.org/web/20160129055142/http://www.vhdl.org/fphdl/fixed_float_types_c.vhdl
Bit of extra info, I would not compile these packages yourself but use
the ones supplied with your simulator as they are most likely tuned for
some extra performance.

In Modelsim you can find the precompiled library in
<install_dir>\floatfixlib and the source files in
<install_dir>\vhdl_src\floatfixlib.

Good luck,

Hans
www.ht-lab.com
 
It is too complicated to understand to me,I just want to divide range of numbers from -32767 to +32767 and get according data from -1 to +1. To get this i must divide by 32767.

For this purpose i use Xilinx divider generator.So i use signed core, reminder type both fractional and reminder too.

It is OK when results must be 1 or more,but when it less then 1 thats sad.
When result must be more then 1 quotient show right results in two's compliment digits (according to datasheet) . But !!! fractional part is mad, cannot use two's compliment digit conversion. when i divide any digit to 32767 (0111111111111111) and in fractional result is always dividend. I tryed fractional part 32-bit width but no result/

Why it doesnot work ? Does anyone meet this problem ?
 
On Fri, 03 Feb 2017 07:32:52 -0800, abirov wrote:

It is too complicated to understand to me,I just want to divide range of
numbers from -32767 to +32767 and get according data from -1 to +1. To
get this i must divide by 32767.

For this purpose i use Xilinx divider generator.So i use signed core,
reminder type both fractional and reminder too.

It is OK when results must be 1 or more,but when it less then 1 thats
sad.
When result must be more then 1 quotient show right results in two's
compliment digits (according to datasheet) . But !!! fractional part is
mad, cannot use two's compliment digit conversion. when i divide any
digit to 32767 (0111111111111111) and in fractional result is always
dividend. I tryed fractional part 32-bit width but no result/

Why it doesnot work ? Does anyone meet this problem ?

Explain how it is "mad".

And please, please, please, stop for a moment and think on how sensible
it is to use up a whole bunch of resources to do a divide by 32767 when a
divide by 32768 is just a matter of shifting down by 16 bits -- which, on
an FPGA, is simply a matter of relabeling your wires.

If you're absolutely bound and determined to divide by 32767, then use
the following rule, which shouldn't take too much logic, because if you
think about it you'll only be paying attention to the top two bits:

* If the input number has an absolute value less than 0x4000, shift down
by 16

* If the input number has an absolute value 0x4000 or greater, shift down
by 16 and add (or subtract) 1 to (from) it, depending on whether it's
positive or negative.

* Unless, of course, the input is 32767, in which case you need to shift
down by 16 and _don't_ add 1, because if you do the result will be -1,
which is a lot different from 1 - 1/32768.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

I'm looking for work -- see my website!
 
Shifting down by 15 means what? My english very poor sorry.
You mean shifting down like following vhdl code :

Ding(15) is sign bit.
Dout <= std_logic_vector(unsigned(Din(14 downto 1)) sll 14); ?
 
On Friday, February 3, 2017 at 11:36:36 PM UTC+6, Tim Wescott wrote:
On Fri, 03 Feb 2017 07:32:52 -0800, abirov wrote:

It is too complicated to understand to me,I just want to divide range of
numbers from -32767 to +32767 and get according data from -1 to +1. To
get this i must divide by 32767.

For this purpose i use Xilinx divider generator.So i use signed core,
reminder type both fractional and reminder too.

It is OK when results must be 1 or more,but when it less then 1 thats
sad.
When result must be more then 1 quotient show right results in two's
compliment digits (according to datasheet) . But !!! fractional part is
mad, cannot use two's compliment digit conversion. when i divide any
digit to 32767 (0111111111111111) and in fractional result is always
dividend. I tryed fractional part 32-bit width but no result/

Why it doesnot work ? Does anyone meet this problem ?

Explain how it is "mad".

And please, please, please, stop for a moment and think on how sensible
it is to use up a whole bunch of resources to do a divide by 32767 when a
divide by 32768 is just a matter of shifting down by 16 bits -- which, on
an FPGA, is simply a matter of relabeling your wires.

If you're absolutely bound and determined to divide by 32767, then use
the following rule, which shouldn't take too much logic, because if you
think about it you'll only be paying attention to the top two bits:

* If the input number has an absolute value less than 0x4000, shift down
by 16

* If the input number has an absolute value 0x4000 or greater, shift down
by 16 and add (or subtract) 1 to (from) it, depending on whether it's
positive or negative.

* Unless, of course, the input is 32767, in which case you need to shift
down by 16 and _don't_ add 1, because if you do the result will be -1,
which is a lot different from 1 - 1/32768.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

I'm looking for work -- see my website!

I got it, and finish this problem, Very thanx everything is OK now.
 
On 2/6/2017 8:26 AM, abirov@gmail.com wrote:
Shifting down by 15 means what? My english very poor sorry.
You mean shifting down like following vhdl code :

Ding(15) is sign bit.
Dout <= std_logic_vector(unsigned(Din(14 downto 1)) sll 14); ?

Shifting down mean a right shift. "Down" because the value of the
number is less. The assumption is that the input value is an integer.
So logically to divide by 32768 (2^15) would be the same as a right
shift by 15 bits. Your integer has no fractional part so this would
require using a fixed point 31 bit number 16.15 which means 16 bits to
the left of the binary point and 15 bits to the right. This will
prevent loss of data when shifting. However...

Shifting can also be done by moving the binary point while keeping the
data in place. In other words, treat the data Ding(15 downto 0) as a
1.15 fixed point number rather than a 16 bit integer.

I hope this is more clear.

--

Rick C
 
On Mon, 06 Feb 2017 14:24:59 -0500, rickman wrote:

On 2/6/2017 8:26 AM, abirov@gmail.com wrote:
Shifting down by 15 means what? My english very poor sorry. You mean
shifting down like following vhdl code :

Ding(15) is sign bit.
Dout <= std_logic_vector(unsigned(Din(14 downto 1)) sll 14); ?

Shifting down mean a right shift. "Down" because the value of the
number is less. The assumption is that the input value is an integer.
So logically to divide by 32768 (2^15) would be the same as a right
shift by 15 bits. Your integer has no fractional part so this would
require using a fixed point 31 bit number 16.15 which means 16 bits to
the left of the binary point and 15 bits to the right. This will
prevent loss of data when shifting. However...

Shifting can also be done by moving the binary point while keeping the
data in place. In other words, treat the data Ding(15 downto 0) as a
1.15 fixed point number rather than a 16 bit integer.

I hope this is more clear.

That's what I said! Only Rick's version makes sense.

Yes -- perform a right shift. Except, as Rick says, you're not really
moving anything, you're just re-labeling the wires. Your 16-bit integer
had a wire with weight 1, a wire with weight 2, etc., all the way up to a
wire with weight 32768. You "shift" that by relabeling your wires as
having weight 1/32768, 1/16384, ... 1/2, 1.

Note that there is no physical operation whatsoever inside your chip to
perform this shift -- you're just _thinking differently_ about the number
for all operations except multiplications.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

I'm looking for work -- see my website!
 
On 02/06/2017 12:23 PM, Tim Wescott wrote:
On Mon, 06 Feb 2017 14:24:59 -0500, rickman wrote:

On 2/6/2017 8:26 AM, abirov@gmail.com wrote:
Shifting down by 15 means what? My english very poor sorry. You mean
shifting down like following vhdl code :

Ding(15) is sign bit.
Dout <= std_logic_vector(unsigned(Din(14 downto 1)) sll 14); ?

Shifting down mean a right shift. "Down" because the value of the
number is less. The assumption is that the input value is an integer.
So logically to divide by 32768 (2^15) would be the same as a right
shift by 15 bits. Your integer has no fractional part so this would
require using a fixed point 31 bit number 16.15 which means 16 bits to
the left of the binary point and 15 bits to the right. This will
prevent loss of data when shifting. However...

Shifting can also be done by moving the binary point while keeping the
data in place. In other words, treat the data Ding(15 downto 0) as a
1.15 fixed point number rather than a 16 bit integer.

I hope this is more clear.

That's what I said! Only Rick's version makes sense.

Yes -- perform a right shift. Except, as Rick says, you're not really
moving anything, you're just re-labeling the wires. Your 16-bit integer
had a wire with weight 1, a wire with weight 2, etc., all the way up to a
wire with weight 32768. You "shift" that by relabeling your wires as
having weight 1/32768, 1/16384, ... 1/2, 1.

Note that there is no physical operation whatsoever inside your chip to
perform this shift -- you're just _thinking differently_ about the number
for all operations except multiplications.

The bundle of wires doesn't care whether you think it has a decimal
point in it or not.


--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 

Welcome to EDABoard.com

Sponsor

Back
Top