+ Post New Thread
Results 1 to 8 of 8

13th March 2018, 10:33 #1
 Join Date
 Sep 2017
 Posts
 4
 Helped
 0 / 0
 Points
 123
 Level
 1
How to "ARCTAN" Function in VHDL
I am a student and doing my final project. I need to find θ = atan (Y/X) in VHDL.
I found a link https://standards.ieee.org/downloads...math_real.vhdl
in this they give different Math functions. Can any one tell me how can I write a code to find the phase value θ.

13th March 2018, 10:33

13th March 2018, 10:51 #2
Awards:
 Join Date
 Apr 2014
 Posts
 11,404
 Helped
 2654 / 2654
 Points
 56,177
 Level
 57
Re: How to "ARCTAN" Function in VHDL
Hi,
I don´t know the VHDL solution.
Often with atan one like to get the direction of a vector. 0...360°.
But atan repeats every 180°. You may need additional logic to get full 360° information.
KlausPlease don´t contact me via PM, because there is no time to respond to them. Thank you.

13th March 2018, 10:51

13th March 2018, 11:03 #3
 Join Date
 Jun 2010
 Posts
 6,538
 Helped
 1907 / 1907
 Points
 35,732
 Level
 46
Re: How to "ARCTAN" Function in VHDL
That package you posted is part of the VHDL standard, but it is not synthesisable (ie, you cannot use it on a chip). You can use it to calculate constants/generics in your VHDL design at elaboration time.
For trigonometric functions, most people look into using a CORDIC function, or build a look up table (you can use math_real to calculate this).

13th March 2018, 11:03

13th March 2018, 11:12 #4
 Join Date
 Apr 2017
 Posts
 91
 Helped
 16 / 16
 Points
 602
 Level
 5
Re: How to "ARCTAN" Function in VHDL
You have to write your own 'code' to calculate atan(x) value. Another possibility is to use vendor specific IP core:
https://www.altera.com/en_US/pdfs/li...altfp_mfug.pdf
You may want to convert signed/unsigned value into ieee754 format, calculate atan(x) and then again do a conversion from ieee754 into signed/unsigned.

15th March 2018, 12:13 #5
 Join Date
 Sep 2017
 Posts
 4
 Helped
 0 / 0
 Points
 123
 Level
 1
Re: How to "ARCTAN" Function in VHDL
Thanks all for replying
I try to apply your given solutions but problem accrue in look up table as well as in CORDIC is there is less space remaning in FPGA board. So I have to cancle that idea.
If am no wrong I can write a code using Taylor Series which is
arctan(x)=xx^3/3+x^5/5x^7/7+ ...
I am trying to write code but error accrue here, below code is given. It says that Type of aout is incompatible with type of 'conversion to unsigned'
Code C  [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; entity atan_try is port( xin : in std_logic_vector(31 downto 0); aout : out std_logic_vector(31 downto 0) ); end atan_try; architecture Behavioral of atan_try is begin aout <= unsigned (signed(xin)  ((signed(xin)*signed(xin)*signed(xin))/3) + ((signed(xin)*signed(xin)*signed(xin)*signed(xin)*signed(xin))/5)  ((signed(xin)*signed(xin)*signed(xin)*signed(xin)*signed(xin)*signed(xin)*signed(xin))/7)); end Behavioral;
Last edited by BradtheRad; 15th March 2018 at 13:03. Reason: Added code formatted window

15th March 2018, 13:46 #6
 Join Date
 Jan 2008
 Location
 Germay
 Posts
 1,060
 Helped
 235 / 235
 Points
 7,228
 Level
 20
 Blog Entries
 1
Re: How to "ARCTAN" Function in VHDL
Without looking into the internal calc....
Yes, because aout is of type std_logic_vector and you are type casting the entire calc to unsigned.
Try this:
aout <= std_logic_vector( unsigned (signed(xin)  ((signed(xin)*signed(xin)*signed(xin))/3) + ((signed(xin)*signed(xin)*signed(xin)*signed(xin)* signed(xin))/5)  ((signed(xin)*signed(xin)*signed(xin)*signed(xin)* signed(xin)*signed(xin)*signed(xin))/7)) );.....yes, I do this for fun!

15th March 2018, 18:23 #7
 Join Date
 Jan 2008
 Location
 Bochum, Germany
 Posts
 41,708
 Helped
 12709 / 12709
 Points
 240,499
 Level
 100
Re: How to "ARCTAN" Function in VHDL
Besides using incompatible types, there are problems with data width and result scaling. It's also inappropriate to use division operations for the Fourier parameter scaling.
The result of a simple chained multiply of 7 32bit numbers has a width of 7*32 bits. You'll define a fixed point interpretation of the 32 bit input number and get a 32 bit result by respective rounding and truncation.
Division should be replaced by a multiply with fixed point constant.
Instead of chained asynchronous multiply, you better perform sequential multiply with x˛ in a clocked process.

15th March 2018, 18:23

Today, 19:32 #8
 Join Date
 Aug 2011
 Posts
 2,485
 Helped
 286 / 286
 Points
 12,241
 Level
 26
Re: How to "ARCTAN" Function in VHDL
This is a generic synthesize tan(x) LUT I designed once.
You can try to do the same with arctan.
Code:library ieee ; use ieee.std_logic_1164.all ; use ieee.numeric_std.all ; use ieee.math_real.all ; entity tan_lut is generic ( WIDTH_FRACTION_ANGLE : natural := 4 ;  4 is 1/16 WIDTH_FRACTION_RESULT : natural := 10 ) ; port ( IN_ANGLE : in std_logic_vector ( 7 + WIDTH_FRACTION_ANGLE  1 downto 0 ) ;  90 is 1011010 ( 7 bits ). A sign bit isn't needed ( the user shall exploit the tan symmetry ). IN_CLOCK : in std_logic ; OUT_RESULT : out std_logic_vector ( WIDTH_FRACTION_RESULT downto 0 )  One integer bit + WIDTH_FRACTION_RESULT ) ; end entity tan_lut ; architecture rtl_tan_lut of tan_lut is type type_lut_tan_real is array ( 0 to 2 ** ( IN_ANGLE ' length )  1 ) of real ; type type_lut_tan_slv is array ( 0 to 2 ** ( IN_ANGLE ' length )  1 ) of std_logic_vector ( OUT_RESULT ' range ) ; signal lut_tan_slv : type_lut_tan_slv ; signal integer_part_of_in_angle : unsigned ( 6 downto 0 ) ; begin integer_part_of_in_angle <= unsigned ( IN_ANGLE ( IN_ANGLE ' high downto IN_ANGLE ' high  6 ) ) ; generate_tan_lut : for index in 0 to 2 ** ( IN_ANGLE ' length )  1 generate lut_tan_slv ( index ) <= std_logic_vector ( to_unsigned ( integer ( ( cos ( real ( index ) * ( MATH_PI / 180.0 ) / ( real ( 2 ** WIDTH_FRACTION_ANGLE ) ) ) ) * ( real ( 2 ** WIDTH_FRACTION_RESULT ) ) ) , OUT_RESULT ' length ) ) ; end generate ; reading_from_memory : process ( IN_CLOCK ) is begin if rising_edge ( IN_CLOCK ) then OUT_RESULT <= lut_tan_slv ( to_integer ( unsigned ( IN_ANGLE ) ) ) ; end if ; end process reading_from_memory ; end architecture rtl_tan_lut ;
+ Post New Thread
Please login