Dividing a 24 bit std_logic_vector by a decimal number

Hi, Is there anywayz a 24 bit std_logic_vector can be divided by a decimal number (eg: 1.36)using VHDL.

The quotient needs to be a 24 bit std_logic_vector as well.

I am currently using Xilinx ISE for implementing this division.

Any help is appreciated.

Thanks

Reply to
genlock
Loading thread data ...

First of all, is the decimal number constant? If so, think multiplication. Embedded multipliers are quick and easy while dividers are much more work.

Do you need a new result every 200 MHz clock or do you need to know the once every 3 microseconds?

Reply to
John_H

Yes the decimal number is a constant value.

What do you mean by embedded multipliers?

Is there a VHDL code available for that or how do we go about coding one.

I dont need a clock for this one.

Thankyou

Reply to
genlock

I'm a Verilog guy and your question is for VHDL - it would be great if a VHDL guy gould give the proper code snippets. The question is addressed in general:

For the example of division by 1.36, multiplying by (2^24/1.36) and taking the 24 MSbits of the result, you get an "effective" division. If you generate the "reciprical integer multiplier" from real literals and do a type conversion to std_logic_vector, the multiply would follow as a simple multiply. Then just shift or select the upper bits and you have your result.

The modern FPGAs tend to have multipliers as part of the logic fabric. You're using ISE so my expectation is you're using a Virtex(-E)Virtex-II(Pro), Virtex-4, Spartan-II(E), or Spartan-3/3L/3E. These should all have multipliers if memory serves me right. Check the data sheets.

I'd like to see someone on this newsgroup provide you a snippet to do (roughly) what I suggest. If you wanted Verilog, it'd be something like result[23:0]

Reply to
John_H

Can you explain this logic that you have mentioned in more detail?

I am using Xilinx ISE and when I try doing any division or multiplication, it keeps showing an error as follows:

/ can not have such operands in this context. ERROR: XST failed

a)What I am trying to do is first convert the 24 bit vector to an integer.

b)Then figure out a method to divide this integer by 1.36 that gives the result as an integer

c)This integer is converted back to a 24 bit vector

Any idea about how this division (b)can be performed?

Thankyou

Reply to
genlock

Why not just use the explicit number 12336188, with a comment that it's the nearest integer to 2^24/1.36?

Tom

Reply to
Thomas Womack

If you're using ISE you can always have a look into the Language=20 Templates (the icon with the light bulb on it).

The following code will do the trick:

signal product : std_logic_vector(47 downto 0); signal mult_in : std_logic_vector(23 downto 0); constant const_val : std_logic_vector(23 downto 0) :=3D X"the divisor";

--snip-- process (clk) begin if rising_edge(clk) then product

Reply to
Johan Bernspång

Comments inline below... Basic summary is you need to think more like hardware and less like software.

genlock ( snipped-for-privacy@gmail.com) wrote: : Can you explain this logic that you have mentioned in more detail?

: I am using Xilinx ISE and when I try doing any division or : multiplication, it keeps showing an error as follows:

: / can not have such operands in this context. : ERROR: XST failed

: a)What I am trying to do is first convert the 24 bit vector to an : integer.

: b)Then figure out a method to divide this integer by 1.36 that gives : the result as an integer

: c)This integer is converted back to a 24 bit vector

Synthesis tools (ISE's XST etc.) use typecodes (and hence typecode conversions) as a queue to how to implement something (e.g. signed or unsigned multiply.) XST doesn't implement divides (other than by powers of 2:-) full stop, so converting to a type where it's obvious to you won't help the syn tool produce hardware. (It might work in simulation though.)

Remember inside the FPGA you are working with signals made of bits, and only bits, so something like 1.36 is a bit meaningless. As others have said just multiply by the reciprocal of the divisor. Below is an untested code snippet to demonstrate how to do this in VHDL.

signal input : std_logic_vector(23 downto 0); signal recip : std_logic_vector(23 downto 0); signal mult_res: std_logic_vector(47 downto 0); signal div_res : std_logic_vector(23 downto 0);

recip

Reply to
c d saunter

What do u mean by an explicit number and how did you arrive at this value?

Reply to
genlock

How did you arrive at the value 47 ( 2F hex) for the value 1.36.....

What if the number is 1.122 instead?....

Is there a technique to do that..

Thankyou

Reply to
genlock

Thankyou Chris, Instead of 2^24, we need to plug in the deicmal equivalent of the 24 bit input we have.

Is that right

And also,

recip

Reply to
genlock

Because 64/47 is nearly 1.36, so multiplying by 47 and dividing by 64 is about the same as dividing by 1.36

1.122 is nearly 64/57, so multiplying by 57 and dividing by 64 is about the same as dividing by 1.122

Given X, for example 1.122, work out w = 2^k / X for k from 1 to some conveniently big number, and use the [k,w] pair that makes w nearest to a whole number.

eg 1.5678, you try lots of k and find that 2^18 / 1.5678 is almost exactly 167205.

This general technique is called fixed-point arithmetic.

Tom

Reply to
Thomas Womack

Tom,

Thankyou.

Reply to
genlock

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.