Division of an integer by a real number using VHDL

Discussion in 'VHDL' started by genlock, Mar 29, 2005.

  1. genlock

    genlock Guest


    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

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

    genlock, Mar 29, 2005
    1. Advertisements

  2. 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.
    Brad Smallridge, Mar 29, 2005
    1. Advertisements

  3. genlock

    genlock Guest

    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?

    genlock, Mar 29, 2005
  4. Are you assuming the imput vector is going to be a multiple of 1.36?
    dutchgoldtony, Mar 30, 2005
  5. 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
    Brad Smallridge, Mar 30, 2005
  6. genlock

    Hal Murray Guest

    I am basically trying to divide a 24 bit vector by 1.36.(output result
    One trick is to multiply by the inverse.
    Hal Murray, Mar 30, 2005
  7. genlock wrote:

    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.

    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 Hildebrandt, Mar 30, 2005
  8. HI Ralf,

    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.
    Mohammed A khader, Mar 30, 2005
  9. Mohammed A khader wrote:

    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 Hildebrandt, Mar 30, 2005
  10. 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
    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.
    Mohammed A khader, Mar 30, 2005
  11. genlock

    Doug Guest

    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, Mar 31, 2005
  12. genlock

    genlock Guest

    Thankyou everybody,

    I think I have got all my questions answered. Am going to try the
    methods suggested here and see how it works....
    genlock, Mar 31, 2005
  13. genlock

    David Bishop Guest

    The fixed point packages can deal with this.

    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);
    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.
    David Bishop, Apr 1, 2005
  14. genlock

    Bert Cuzeau Guest

    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 !
    ); --

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

    process (Rst,Clk)
    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;
    Bert Cuzeau, Apr 1, 2005
  15. genlock

    genlock Guest

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

    Does anybody have any idea about dithering?

    genlock, Apr 1, 2005
  16. genlock

    Pete Fraser Guest

    Pete Fraser, Apr 2, 2005
  17. genlock

    genlock Guest

    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

    genlock, Apr 2, 2005
  18. genlock

    Pete Fraser Guest

    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
    Pete Fraser, Apr 2, 2005
  19. genlock

    info_ Guest

    24 bits is already 144 dB !
    Are you sure you lose a lot of useful information ?
    info_, Apr 2, 2005
  20. genlock

    Dave Higton Guest

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

    Dave Higton, Apr 2, 2005
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.