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 ;