1
\$\begingroup\$

I am working on a vhdl/fpga project using the vga module. I am trying to make an object fall with an acceleration (gravity). I found an answer on another problem, and it suggest to implement something similar to these equations:

Position_next <= Position_reg + timestep*Velocity_reg ;

Velocity_next <= Velocity_reg + timestep*Acceleration ;

Where timesetp in my case is the frame time, which is 1/60fps. The acceleration(gravity) is going to be a constant number. The result of the two equations are a floating point. Which is a problem, since the minimum step my object can take is 1 pixel per frame. Any idea how to solve this problem.

\$\endgroup\$
  • 1
    \$\begingroup\$ You need to explain why you think that may be a problem. \$\endgroup\$ – Andy aka Dec 1 '16 at 8:24
  • \$\begingroup\$ @Andyaka Since timestep is 1/60fps=0.016. when we multiply timestep*Acceleration the result is a float not a decimal. Therefore Velocity_next is a float too. Multiplying again by timestep and adding it to Position_reg, we will end up with a fraction of pixels. And you know that the minimum object step is 1 pixel, it can't be 1.5 for example. \$\endgroup\$ – atarief Dec 1 '16 at 8:30
  • 2
    \$\begingroup\$ I don't feel your pain dude. Ever heard of keeping the main calculations in floats and creating a new integer value from that float when you need it? \$\endgroup\$ – Andy aka Dec 1 '16 at 8:33
  • \$\begingroup\$ No never heard of it. Can you give an example. Thanks \$\endgroup\$ – atarief Dec 1 '16 at 8:40
  • 1
    \$\begingroup\$ Try looking up "converting a floating point number to an integer". \$\endgroup\$ – Andy aka Dec 1 '16 at 8:43
2
\$\begingroup\$

Between floats (difficult to implement, resource-hungry) and integers (not enough precision), there's an intermediate: it's called fixed point math. Fixed point isn't much more difficult than integers to work with. And it is sufficient in your case.

The basic idea is that you represent each value by an integer number. The correspondance between both is done simply by multiplying or dividing by a fixed value (usually a power of two, to make it easier). For example if you set the ratio to 256, that means the 1.5 value will be represented by the 16#180# number. Because 180 in hex (=384 in dec) divided by 256 makes 1.5. Another way to see it is that the stored number represents an integral number of 1/256th units.

This means that implementation of addition and subtraction does not change compared to the usual integer implementation. Multiplication is very similar to the classic integer multiplication, you just have to divide by your ratio after (or just shifting the correct number of bits if it is a power of two).

The only choice to make, then, is to choose the ratio appropriately so that you can accurately represent the values you need in your specific case.

\$\endgroup\$
  • \$\begingroup\$ The difference between a shift and a divide after each multiplication means that you nearly always want to choose a power of 2 as your ratio (at least if you support multiplication). \$\endgroup\$ – Jerry Coffin Dec 2 '16 at 16:20
1
\$\begingroup\$

FPGA distributors often provide IP Cores that can do floating point operations. For example, Intel/Altera provides a bunch of floating-point IP Cores:

https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_altfp_mfug.pdf

I can say they work as I have done a real time fractals calculator with those.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.