LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; entity cordic is generic (steps : Integer := 9); port ( clk : in std_logic; clr : in std_logic; validi : in std_logic; w : in std_logic_vector(6 downto 0); -- 0 to 90 deg valido : out std_logic; sin : out std_logic_vector(7 downto 0); -- 0 to 255 cos : out std_logic_vector(7 downto 0)); -- 0 to 255 end cordic; architecture a of cordic is type angle_arr is array (0 to 9) of Integer range 0 to 511; constant angles : angle_arr := (360, 213, 112, 57, 29, 14, 7, 4, 2, 1); constant x_ini : Integer := 620; subtype xy_type is Integer range -1024 to 1023; subtype w_type is Integer range -1024 to 1023; type xy_arr is array(0 to steps) of xy_type; type w_arr is array(0 to steps) of w_type; signal angle : w_arr; signal x, y : xy_arr; signal sin_i, cos_i : Integer range 0 to 255; signal valid : std_logic_vector(0 to steps); begin process(clk) begin if rising_edge(clk) then if clr='1' then for i in 0 to steps loop x(i) <= 0; y(i) <= 0; angle(i) <= 0; end loop; x(0) <= x_ini; valid <= (others => '0'); valido <= '0'; else angle(0) <= conv_integer('0' & w)*8; valid(0) <= validi; for i in 1 to steps loop valid(i) <= valid(i-1); if angle(i-1) > 0 then x(i) <= x(i-1) - y(i-1)/2**(i-1); y(i) <= y(i-1) + x(i-1)/2**(i-1); angle(i) <= angle(i-1) - angles(i-1); else x(i) <= x(i-1) + y(i-1)/2**(i-1); y(i) <= y(i-1) - x(i-1)/2**(i-1); angle(i) <= angle(i-1) + angles(i-1); end if; end loop; valido <= valid(steps); if x(steps) < 0 then cos_i <= 0; else cos_i <= x(steps)/4; end if; if y(steps) < 0 then sin_i <= 0; else sin_i <= y(steps)/4; end if; end if; end if; end process; cos <= conv_std_logic_vector(cos_i, cos'length); sin <= conv_std_logic_vector(sin_i, sin'length); end;