| Author |
Division of an integer by a real number using VHDL
|
|
| genlock 2005-03-29, 9:01 pm |
| 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
| |
| Brad Smallridge 2005-03-29, 9:01 pm |
| 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.
| |
| genlock 2005-03-29, 9:01 pm |
| 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.
| |
| dutchgoldtony 2005-03-29, 9:01 pm |
| Are you assuming the imput vector is going to be a multiple of 1.36?
| |
| Brad Smallridge 2005-03-30, 4:04 am |
| 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
| |
| Hal Murray 2005-03-30, 4:04 am |
| >I am basically trying to divide a 24 bit vector by 1.36.(output result
>eventually being a bit vector)
One trick is to multiply by the inverse.
--
The suespammers.org mail server is located in California. So are all my
other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited
commercial e-mail to my suespammers.org address or any of my other addresses.
These are my opinions, not necessarily my employer's. I hate spam.
| |
| Ralf Hildebrandt 2005-03-30, 4:04 am |
| 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
| |
| Mohammed A khader 2005-03-30, 9:03 am |
| 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.
| |
| Ralf Hildebrandt 2005-03-30, 9:03 am |
| Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Trace: individual.net ghsjN+0Yjg9G6qBavQvUPwkQOOw+NFPZxUPRbOY1
eDGVsFdg==
User-Agent: Mozilla Thunderbird 1.0.2 (Windows/20050317) Hamster/2.0.6.0
X-Accept-Language: en-us, en
In-Reply-To: <1112174376.767707.179180@l41g2000cwc.googlegroups.com>
Xref: number1.nntp.dca.giganews.com comp.lang.vhdl:53682
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
| |
| Mohammed A khader 2005-03-30, 9:03 am |
| 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.
| |
|
| 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
"Hal Murray" <hmurray@suespammers.org> wrote in message
news:LqWdnQIR1vJFgdffRVn-pw@megapath.net...
>
> One trick is to multiply by the inverse.
>
> --
> The suespammers.org mail server is located in California. So are all my
> other mailboxes. Please do not send unsolicited bulk e-mail or
unsolicited
> commercial e-mail to my suespammers.org address or any of my other
addresses.
> These are my opinions, not necessarily my employer's. I hate spam.
>
| |
| genlock 2005-03-31, 4:04 pm |
| Thankyou everybody,
I think I have got all my questions answered. Am going to try the
methods suggested here and see how it works....
| |
| David Bishop 2005-04-01, 8:59 am |
| genlock wrote:
> 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-2...ages/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.
| |
| Bert Cuzeau 2005-04-01, 8:59 am |
| 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;
| |
| genlock 2005-04-01, 9:00 pm |
| Thankyou very much for all the help regarding this topic....
Does anybody have any idea about dithering?
Thanks
|
|
|
|