123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
- use ieee.math_real.all;
-
- library work;
- use work.cordic_pkg.all;
-
- entity cordic is
- generic (
- SIZE : positive;
- ITERATIONS : positive;
- RESET_ACTIVE_LEVEL : std_ulogic := '1'
- );
- port (
- Clock : in std_ulogic;
- Reset : in std_ulogic;
-
- Data_valid : in std_ulogic; --# Load new input data
- Busy : out std_ulogic; --# Generating new result
- Result_valid : out std_ulogic; --# Flag when result is valid
- Mode : in cordic_mode; --# Rotation or vector mode selection
-
- X : in signed(SIZE-1 downto 0);
- Y : in signed(SIZE-1 downto 0);
- Z : in signed(SIZE-1 downto 0);
-
- X_result : out signed(SIZE-1 downto 0);
- Y_result : out signed(SIZE-1 downto 0);
- Z_result : out signed(SIZE-1 downto 0)
- );
- end entity;
-
- architecture rtl of cordic is
- type signed_array is array (natural range <>) of signed(SIZE-1 downto 0);
-
- function gen_atan_table(s : positive) return signed_array is
- variable table : signed_array(0 to ITERATIONS-1);
- begin
- for i in table'range loop
- table(i) := to_signed(integer(arctan(2.0**(-i)) * 2.0**s / MATH_2_PI), s);
- end loop;
-
- return table;
- end function;
-
- constant ATAN_TABLE : signed_array(0 to ITERATIONS-1) := gen_atan_table(SIZE);
-
- signal xr : signed(X'range);
- signal yr : signed(Y'range);
- signal zr : signed(Z'range);
-
- signal x_shift : signed(X'range);
- signal y_shift : signed(Y'range);
-
- subtype iter_count is integer range 0 to ITERATIONS;
-
- signal cur_iter : iter_count;
- begin
-
- p_cordic: process(Clock, Reset) is
- variable negative : boolean;
- begin
- if Reset = RESET_ACTIVE_LEVEL then
- xr <= (others => '0');
- yr <= (others => '0');
- zr <= (others => '0');
- cur_iter <= 0;
- Result_valid <= '0';
- Busy <= '0';
- elsif rising_edge(Clock) then
- if Data_valid = '1' then
- xr <= X;
- yr <= Y;
- zr <= Z;
- cur_iter <= 0;
- Result_valid <= '0';
- Busy <= '1';
- else
- if cur_iter /= ITERATIONS then
- --if cur_iter(ITERATIONS) /= '1' then
- if Mode = cordic_rotate then
- negative := zr(z'high) = '1';
- else
- negative := yr(y'high) = '0';
- end if;
-
- --if zr(z'high) = '1' then -- z or y is negative
- if negative then
- xr <= xr + y_shift; --(yr / 2**(cur_iter));
- yr <= yr - x_shift; --(xr / 2**(cur_iter));
- zr <= zr + ATAN_TABLE(cur_iter);
- else -- z or y is positive
- xr <= xr - y_shift; --(yr / 2**(cur_iter));
- yr <= yr + x_shift; --(xr / 2**(cur_iter));
- zr <= zr - ATAN_TABLE(cur_iter);
- end if;
-
- cur_iter <= cur_iter + 1;
- --cur_iter <= '0' & cur_iter(0 to ITERATIONS-1);
- end if;
-
- if cur_iter = ITERATIONS-1 then
- Result_valid <= '1';
- Busy <= '0';
- end if;
- end if;
-
- end if;
- end process;
-
- x_shift <= shift_right(xr, cur_iter);
- y_shift <= shift_right(yr, cur_iter);
-
-
- X_result <= xr;
- Y_result <= yr;
- Z_result <= zr;
-
- end architecture;
|