Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

how to convert negative numbers in fixed point

Status
Not open for further replies.

DNA2683

Advanced Member level 4
Joined
Sep 3, 2012
Messages
106
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,296
Activity points
2,290
hi

i need to use a fixpoint in VHDL but i don't understand the principle...i have 32bit vector 16bit to fraction and 16 bit to integer

for example i need convert 2 numbers:
1. a positive number 266.7244 => what i did was converted the integer part to binary .and the fraction part to binary (i was multiplied the fraction by 2 and save the reminder ...)

for the integer i got "010A"(16) and for the fraction i got "00B9"(16) so i add the integer and the fraction and i got "010A00B9".


2. in the negative numbers i have a problem i'm trying to convert the number (-157.9295) so i used the same way as positive numbers i converted the integer part and got "FF63" and converted the fraction part an got "00ED" so i got "FF6300ED"(16) i know that i wrong....

how i calculate a negative number in fixed point?
do i calculate the positive numbers currectly?

thanks
 

To convert a real number to signed fixed point, you multiply it with the scaling factor (2^16 in your case) and convert it to signed:

sfix_16_16 := to_signed(to_integer(266.7244 * 2.0**16),32)

Or use IEEE fixed point package that does the conversions for you.
 

To convert a real number to signed fixed point, you multiply it with the scaling factor (2^16 in your case) and convert it to signed:

sfix_16_16 := to_signed(to_integer(266.7244 * 2.0**16),32)

Or use IEEE fixed point package that does the conversions for you.


can you please give me example how i calculate a real negative number to a fixed point number ?(-157.9295)
and how i go back from fix point to real?

thanks
 

Negative fixed point conversion can be done in the following step:
1. -157.9295 ==> (prescale to 16-bit integer) -157.9295 * 2 ** 16 = -10350068
2. convert it to 2-complementary = FF62120C (get absoutely value, flip-bit, and plus 1)
3. Reapply the scaling: FF62.120C

Going back for fixed to real is easy to. Just Convert the fixed to real without scaling and then divide by scaling factor.
For example: FF62120C = (minus 1 and flip to get abs of the 2-complementary) = -10350068, and divide 2^16.

Fixed type scaling is the key,

Cheers,
 
Last edited:

can you please give me example how i calculate a real negative number to a fixed point number ?(-157.9295)
In VHDL terms by putting -157.9295 into the given expression in post #2.
 

In the VHDL fixed point packages ('93 versions available from here: www.vhdl.org/fphdl for synthesis, newer versions of modelsim have the full 2008 support already) its very easy:

signal my_fixed : sfixed(15 downto -16)

my_signal <= to_sfixed(-157.9295, my_sfixed); --1st argument is value, second argument is for sizing).
 

Negative fixed point conversion can be done in the following step:
1. -157.9295 ==> (prescale to 16-bit integer) -157.9295 * 2 ** 16 = -10350068
2. convert it to 2-complementary = FF62120C (get absoutely value, flip-bit, and plus 1)
3. Reapply the scaling: FF62.120C

Going back for fixed to real is easy to. Just Convert the fixed to real without scaling and then divide by scaling factor.
For example: FF62120C = (minus 1 and flip to get abs of the 2-complementary) = -10350068, and divide 2^16.

Fixed type scaling is the key,

Cheers,

thanks

i think i understand the conversion :smile:

i asked about it because i need to write a code in VHDL that get a real number i have a 2 starting coordinates for example (X,Y)=(-157.9295,266.7244) -the integer part is 16 bit and the fraction part is 16 bit , that i add to them in eche clock (0.7071,-0.7071)

in pseudo code:

if x<648 then
X=X+0.7071
Y=Y+(-0.7071)

ench clock i'm getting my starting coordinates (X,Y)=(-157.9295,266.7244) increased by (0.7071,-0.7071)...

how can i do it in vhdl with fixed point?


thanks
 

For all variables with same scaling, I will just deal with 32-bit signed. And interpret the signal out the outer part.

X_in <= to_signed(-10350068, 32); -- -157.9295
step <= to_signed(46341, 32); -- 0.7071
X_out <= X_in+ step;
Ox <= std_logic_vector(X_out);

Y_in <= to_signed(17480050, 32); -- 266.7244
Y_out<= Y_in - step;
Oy <= std_logic_vector(Y_out);
 

For all variables with same scaling, I will just deal with 32-bit signed. And interpret the signal out the outer part.

X_in <= to_signed(-10350068, 32); -- -157.9295
step <= to_signed(46341, 32); -- 0.7071
X_out <= X_in+ step;
Ox <= std_logic_vector(X_out);

Y_in <= to_signed(17480050, 32); -- 266.7244
Y_out<= Y_in - step;
Oy <= std_logic_vector(Y_out);

Thanks:p


So i need to declare X_in ,X_out,Ox as std_logi_vector (31 downto 0)?
Also do I get an calculation error because that in fixed point some fractions are rounding numbers?


Thanks for the help
 

Thanks:p


So i need to declare X_in ,X_out,Ox as std_logi_vector (31 downto 0)?

Also do I get an calculation error because that in fixed point some fractions are rounding numbers?

Thanks for the help

Yes you have all std_logic_vector(31 downto 0);

You get quantization error, if that's what you meant. You can put boundary check logic for saturation protection if you want. I highly recommend you take a look at Mathworks Fixed-point designer for numeric analysis.
 

If you give the fixed point packages a go, you wont need all the complicated scaling, you can do it all in 1 step.
 

For all variables with same scaling, I will just deal with 32-bit signed. And interpret the signal out the outer part.

X_in <= to_signed(-10350068, 32); -- -157.9295
step <= to_signed(46341, 32); -- 0.7071
X_out <= X_in+ step;
Ox <= std_logic_vector(X_out);

Y_in <= to_signed(17480050, 32); -- 266.7244
Y_out<= Y_in - step;
Oy <= std_logic_vector(Y_out);


hi

i noticed that sometimes i get to my vhdl code different step for X and for Y ,also the step can be positive or negative....
do i need to change something in the code her?

for example i get a step for X_step=0.7071 and Y_step=(-0.7071)

so i was changed the line
Y_out<= Y_in - step;
to
Y_out<= Y_in + step;

but i don't get a correct answer ...
Y_in is the same 266.7244 =>17480050(fixed point) =>010AB972(hex)
Y_step = (-0.7071) => -46341(fixed point)=> 4AFB(2-complementary)
when i do Y_out<= Y_in + step;
i get : Y_out=010AB972+4AFB=10B046D

i take the 10B046D minus 1 and flip to get abs of the 2-complementar and get 1605518 divide it by 2^16 and i get 244.9827..and this is a wrong answer...(the right answer is 266.7244+(-0.7071)=266.0173)

what i'm doing wrong?


thanks for the help
 

You are really good in making simple things complicated.

In the present case, the problem is brought up by clipping the step value to 16 bit. The fractional part covers an interval of 1 (0..+1 in the two's complement), so it can hardly represent -0.7 without using one more bit.

As already said, IEEE fixed point is the best way to get rid of the low level two's complement operations, and IEEE.numeric_standard signed data type with respective conversion functions the second best.
 
- - - Updated - - -

In the VHDL fixed point packages ('93 versions available from here: www.vhdl.org/fphdl for synthesis, newer versions of modelsim have the full 2008 support already) its very easy:

signal my_fixed : sfixed(15 downto -16)

my_signal <= to_sfixed(-157.9295, my_sfixed); --1st argument is value, second argument is for sizing).

THANK you for your help..ill try it :razz:

can you tell me which package i need to use for " to_sfixed " function ?


thanks again
 

you need the fixed_pkg

hi

im trying to use a to _sfixed function but i dont understend somthing:

1.what type my input can be (X_in-the number that i want to convert to fixed point)?

2.After I finish the calculations I need to concatenate several outputs together with the oprator "&" but the compiler give me an error if im trying to do it for sfixed type(signal ) how can i solve it?

3.how i go back from fixed number to std_logic_vector 32bit(that have 16 bit for integer and 16 bit for fraction)?

thanks for the help
im new in the vhdl world and I can not imagine what I would do without the help here
 

1.what type my input can be (X_in-the number that i want to convert to fixed point)?
Any type(for tb and static objects), respectively any synthesizable type (for hardware)

2.After I finish the calculations I need to concatenate several outputs together with the oprator "&" but the compiler give me an error if im trying to do it for sfixed type(signal ) how can i solve it?
There's no meaningful purpose to do so, I suppose. What should be the mathematical meaning of this concatenation?

3.how i go back from fixed number to std_logic_vector 32bit(that have 16 bit for integer and 16 bit for fraction)?
the said sfixed(15 downto -16) type can be directly casted to this std_logic_vector
 

Any type(for tb and static objects), respectively any synthesizable type (for hardware)

If the number is constant, you can use a real type too: eg:

constant MY_CONSTANT : sfixed(15 downto -16) := to_sfixed(-1.234, 15, 16);

or:

my_singal <= some_input + to_sfixed(-1.234, 15, 16);

the said sfixed(15 downto -16) type can be directly casted to this std_logic_vector

Direct casting wont work, as slv doesnt allow -ve indeces. You need to use the to_std_logic_vector (or to_slv) function instead.

slv_op <= to_slv(some_sfixed);

and the other way round:

some_sfixed <= to_sfixed(slv_ip); --lengths must match, as the type of some_sfixed will contain the integer and fraction separation already.
 
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
If the number is constant, you can use a real type too: eg:

constant MY_CONSTANT : sfixed(15 downto -16) := to_sfixed(-1.234, 15, 16);

or:

my_singal <= some_input + to_sfixed(-1.234, 15, 16);



Direct casting wont work, as slv doesnt allow -ve indeces. You need to use the to_std_logic_vector (or to_slv) function instead.

slv_op <= to_slv(some_sfixed);

and the other way round:

some_sfixed <= to_sfixed(slv_ip); --lengths must match, as the type of some_sfixed will contain the integer and fraction separation already.



thank you for the help ...ill try to explain what i need to do:



i have a starting point coordinates (X,Y) (X_in and Y_in) that i get from a testbench (the cordenet can be positive or negative not a integer, i can choose the type (i want it to be 16 bit for integer and 16 bit for fraction 32 bit total).

also i get from the testbench 2 inputs X_step and Y_step (can be positive or negative, i can choose the type (i want it to be 16 bit for integer and 16 bit for fraction 32 bit total).


i need to add the step to starting point coordinates j times:

in pseudo code:

in pseudo code:

if j<648 then
U_res=X_in+X_step
V_res=Y_in+Y_step
out= U_res & V_res --the results out also 16 bit for integer and 16 bit for fraction ,32 bit total

can you tell me what is the vhdl code for it? (because the numbers can be positive or negative i need it in fixed point)


thanks for the help
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top