FPGARelated.com
Forums

Dividing a 24 bit std_logic_vector by a decimal number

Started by genlock March 29, 2005
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

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?


"genlock" <genlocks@gmail.com> wrote in message
news:1112125409.443564.224970@z14g2000cwz.googlegroups.com...
> 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
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

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:

"genlock" <genlocks@gmail.com> wrote in message
news:1112131201.352597.22410@g14g2000cwa.googlegroups.com...
> Yes the decimal number is a constant value.
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.
> What do you mean by embedded multipliers?
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.
> Is there a VHDL code available for that or how do we go about coding > one.
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] <= In[23:0] * ((1<<24)/1.36 + 0.5) >> 24; but I haven't used real variables in my code much if at all. I think this would synthesize.
> I dont need a clock for this one. > > Thankyou
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

In article <1112136150.388063.56450@g14g2000cwa.googlegroups.com>,
genlock <genlocks@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.
Why not just use the explicit number 12336188, with a comment that it's the nearest integer to 2^24/1.36? Tom
genlock wrote:

> Can you explain this logic that you have mentioned in more detail? >=20 > I am using Xilinx ISE and when I try doing any division or > multiplication, it keeps showing an error as follows: >=20 > / can not have such operands in this context. > ERROR: XST failed >=20 > a)What I am trying to do is first convert the 24 bit vector to an > integer. >=20 > b)Then figure out a method to divide this integer by 1.36 that gives > the result as an integer >=20 > c)This integer is converted back to a 24 bit vector >=20 > Any idea about how this division (b)can be performed? >=20 > Thankyou >=20
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 <=3D mult_in * const_val; end if; end process; To make sure you're inferring hardware multipliers you have to set the=20 correct synthesize properties for that. The value of the perfect constant could probably be a discussion in=20 itself but I would probably multiply by 47 (i.e. 2F hex) and then do a 6 = bit right shift after the multiplication: prod_out <=3D product(41 downto 18); This method does not divide exactly by 1.36, but pretty close: 1.362. Correct me if I'm totally wrong... --=20 ----------------------------------------------- Johan Bernsp=E5ng, xjohbex@xfoix.se Research engineer Swedish Defence Research Agency - FOI Division of Command & Control Systems Department of Electronic Warfare Systems www.foi.se Please remove the x's in the email address if replying to me personally. -----------------------------------------------
Comments inline below...  Basic summary is you need to think more like 
hardware and less like software.

genlock (genlocks@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 <= conv_std_logic(2^24 * 1 / 1.36) -- not sure this is the right
                                         -- conv_blah function
                                         -- Note that the calculation is
                                         -- evaluated at synthesis time
                                         
                                         
mult_res <= input * recip                -- assuming unsigned input
div_res  <= mult_res(47 downto 24)       -- there's a .5 bit rounding
                                         -- error here for some results
Cheers,
	Chris

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

: Thankyou

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

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