Division of an integer by a real number using VHDL

G

genlock

Hi,

Is there a way to divide an integer by a real number(decimal number).

Can we simply use the operator '/' as follows:
eg: a <= 1234/ 1.36;
where we define 'a' as an integer.

Are there any specific libraries to be included for such a VHDL design
file.

If so, should these libraries be included in a particular order?

Thankyou
 
B

Brad Smallridge

Can you give us a hint? If this is for a testbench then you
can easily do the division using varaibles. If this is hardware
then we need to know how fast and how big the vectors are.
Lookup tables are fast if the numbers are small.
 
G

genlock

This is not for a testbench.

Its for hardware which has to be implemented on a FPGA.

This division is a part of another code

I am basically trying to divide a 24 bit vector by 1.36.(output result
eventually being a bit vector)

I am first converting this 24 bit vector to an integer.

Was wondering if we can simply use the operator '/' for then dividing
the integer by 1.36.

Does the '/' operator need specific IEEE libraries to be included in
the design file.

If so, is there any particular order?

Thankyou.
 
B

Brad Smallridge

That's tough. More like microprocessor work than FPGA.
Can't help you but I do know that there is no / operator in
VHDL that will do it on "real" signals. I suggest you do a
Google search on Xilinx (or whatever you are using) and
division and see what pops up. Perhaps other people in this
comp.fpga group can be more help.

b r a d @ a i v i s i o n . c o m
 
R

Ralf Hildebrandt

genlock wrote:

I am basically trying to divide a 24 bit vector by 1.36.(output result
eventually being a bit vector)

Don't divide by 1.36, but multiply by 1/1.36. Multiplication is much easier.

Am I right, that you have a constant factor? Then multiplication is very
easy. It becomes only a series of additions (and shifts).

The fractional number should not be used in floating point format but in
fixed point format with the accuracy you need. Remember that within some
bounds of accuracy a number can be given with:
2^n + ... + 2^1 + 2^0 + 2^(-1) + 2^(-2) + ... + 2^(-m)

Then your problem is nothing more than normal integer multiplication by
a constant value, which can be greatly optimized using even the normal
"*" Operator.

I am first converting this 24 bit vector to an integer.

No. A vector is much better (signed or unsigned is suitable). Extend
this vector by some zeros to the left to have a fractional part.
Use a constant with the same bitwidth (also signed or unsigned),
representing 1/1.36 with your desired accuracy using the above mentioned
fixed point scheme.



Addition: This multiplication will be represented by several additions.
Pipelining is possible, if needed for speed or lower area.

Ralf
 
M

Mohammed A khader

HI Ralf,
Extend this vector by some zeros to the left to have a fractional
part.

Suppose y is the integer variable which can be represented in 8 bit
as <8.0> format, and 1/1.36 = 0.73529 is represented in 16 bits as
<1.15> format. Then under such conditions multiplication can be done
between unsymmetrical formats i.e. format of <8.0> * <1.15> gives
<9.15>. I think there is no need to pad the integer to represent
fractional part. Correct me if I am going wrong.

Thanks a lot.

-- Mohammed A Khader.
 
R

Ralf Hildebrandt

Mohammed A khader wrote:

Suppose y is the integer variable which can be represented in 8 bit
as <8.0> format, and 1/1.36 = 0.73529 is represented in 16 bits as
<1.15> format. Then under such conditions multiplication can be done
between unsymmetrical formats i.e. format of <8.0> * <1.15> gives
<9.15>. I think there is no need to pad the integer to represent
fractional part. Correct me if I am going wrong.

Do you mean

result <= integer_signal * unsigned_constant;

while unsigned_constant is in <9.15> format? Well - seems to be a good
option (I have no simulator at hand to check ist). I was thinking of
something like

result <= unsigned_signal * unsigned_constant;

and there adding a (zero) fractional part is nessecary. But your
solution seems to be more elegant.

Ralf
 
M

Mohammed A khader

Hi Ralf,

I mean result <= unsigned_signal * unsigned_constant;

but no need to adjust the fixed point as it is needed in addition.
'unsigned_signal' should'nt be of same format as 'unsigned_constant'.

Even in ieee.numeric_std standard, ' * ' fucntion is defined to
handle
unsymetrical input vectors.

For result <= integer_signal * unsigned_constant;

if ' integer_signal' is defined with appropriate range limits then it
is equivalent to the other.

-- Mohammed A Khader.
 
D

Doug

Hal is spot on here.

Just multiply by K=0.7352941176. And how do you do that?

One way is to represent K by a 24 bit natural, let's call it Ki where
Ki = (2**24) * k = (2**24) / 1.36 = 12336188 (rounded off).

I will assume your 24 bit number is unsigned, let's call it G. You will
then end up with a 48 bit result for G.
R = G * Ki; -- R is 48 bits, G is 24 bits, and Ki is 24 bits.
G is a 24 bit integer with no fractional part.
Ki is a 24 bit fraction where 0xFFFFFF represents a value very
close to 1.0. Actually it ((2**24)-1)/(2**24) = 0.999999940395

The result, R, is a 48 bit number with 24 bit integer part and 24 bit
fractional part. You can drop the fractional part and retain the
24 MSBs and there you have it.


Doug
 
G

genlock

Thankyou everybody,

I think I have got all my questions answered. Am going to try the
methods suggested here and see how it works....
 
D

David Bishop

genlock said:
Hi,

Is there a way to divide an integer by a real number(decimal number).

Can we simply use the operator '/' as follows:
eg: a <= 1234/ 1.36;
where we define 'a' as an integer.

Are there any specific libraries to be included for such a VHDL design
file.

If so, should these libraries be included in a particular order?

The fixed point packages can deal with this.

http://www.eda.org/vhdl-200x/vhdl-200x-ft/packages/files.html
get "fixed_pkg.vhd" and "fixed_pkg_body.vhd".

Write it this way:

signal b : ufixed (15 downto 0);
signal c : ufixed (0 downto -10);
signal a : ufixed (26 downto -1);
begin
b <= to_ufixed (1234, b'high, b'low);
c <= to_ufixed (1.36, c'high, c'low);
a <= b / c;

Should synthesize OK of your tool can deal with an unsigned divide.
 
B

Bert Cuzeau

Who said arithmetic was difficut in an FPGA ;-)

It's just an example. It can be further optimized.
It's a parallel full speed solution...

-- Divide a 24 bits unsigned by 1.122
-- Author : Bert Cuzeau
-- not overly optimized (yet under 150 LCs of plain logic)

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

-- ---------------------------------------
Entity DIVBYR is -- Divide a 24 bits by 1.122
-- ---------------------------------------
Port ( Clk : In std_logic; -- Main System Clock
Rst : In std_logic; -- Asynchronous reset, active high
D : in unsigned (23 downto 0); -- use std_logic_vector !
Q : out unsigned (23 downto 0) -- use std_logic_vector !
); --
end;

-- ---------------------------------------
Architecture RTL of DIVBYR is
-- ---------------------------------------
begin

process (Rst,Clk)
begin
if Rst='1' then
Q <= (others=>'0');
elsif rising_edge (Clk) then
Q <= to_unsigned( (to_integer(D) * 7301 / 8192 ),24);
end if;
end process;

end RTL;
 
G

genlock

Thankyou very much for all the help regarding this topic....

Does anybody have any idea about dithering?

Thanks
 
G

genlock

Yes I am actually truncating a 48 bit value to 24 bits and hence am
losing the last 24 bits information of audio.....

So I would like to do dithering

Thankyou
 
P

Pete Fraser

genlock said:
Yes I am actually truncating a 48 bit value to 24 bits and hence am
losing the last 24 bits information of audio.....

So I would like to do dithering

I'm not an audio guy, but I would have thought
that 24 bits would have been fine.
Can you hear anything more?

Last time I was working on audio was 1976,
and 14 bits was the best we could do.

If you have a dedicated adder at the output
(say 48 bits but that's adding overkill to
overkill) and take the most significant 24 bits out
to go to your dac, you need to take the dropped
(least significant) 24 bits, delay them in a register,
and feed the output of the register, appropriately
sign extended, back to the input of the adder,
where it is summed with the full 48 bits of the
next sample. It will spectrally shape your noise
so it is less objectionable to those with super-human
hearing.
 
I

info_

genlock said:
Yes I am actually truncating a 48 bit value to 24 bits and hence am
losing the last 24 bits information of audio.....

24 bits is already 144 dB !
Are you sure you lose a lot of useful information ?
 
D

Dave Higton

In message <[email protected]>
genlock said:
Yes I am actually truncating a 48 bit value to 24 bits and hence am
losing the last 24 bits information of audio.....

So I would like to do dithering

Whatever ADC you use, or whatever analogue electronics you have in front
of the ADC, does all the dithering you will ever need.

Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top