+ Post New Thread
Results 1 to 8 of 8

13th March 2018, 10:33 #1
 Join Date
 Sep 2017
 Posts
 7
 Helped
 0 / 0
 Points
 150
 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
 12,292
 Helped
 2845 / 2845
 Points
 60,133
 Level
 59
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. No friend requests. Thank you.

13th March 2018, 11:03 #3
 Join Date
 Jun 2010
 Posts
 6,589
 Helped
 1924 / 1924
 Points
 36,062
 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
 114
 Helped
 24 / 24
 Points
 775
 Level
 6
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
 7
 Helped
 0 / 0
 Points
 150
 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,094
 Helped
 244 / 244
 Points
 7,451
 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
 42,502
 Helped
 12950 / 12950
 Points
 244,657
 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

21st March 2018, 19:32 #8
 Join Date
 Aug 2011
 Posts
 2,503
 Helped
 288 / 288
 Points
 12,360
 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