Lösung des ESY6/A Praktikums "signal_processing".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cordic.vhd 3.1KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use ieee.math_real.all;
  5. library work;
  6. use work.cordic_pkg.all;
  7. entity cordic is
  8. generic (
  9. SIZE : positive;
  10. ITERATIONS : positive;
  11. RESET_ACTIVE_LEVEL : std_ulogic := '1'
  12. );
  13. port (
  14. Clock : in std_ulogic;
  15. Reset : in std_ulogic;
  16. Data_valid : in std_ulogic; --# Load new input data
  17. Busy : out std_ulogic; --# Generating new result
  18. Result_valid : out std_ulogic; --# Flag when result is valid
  19. Mode : in cordic_mode; --# Rotation or vector mode selection
  20. X : in signed(SIZE-1 downto 0);
  21. Y : in signed(SIZE-1 downto 0);
  22. Z : in signed(SIZE-1 downto 0);
  23. X_result : out signed(SIZE-1 downto 0);
  24. Y_result : out signed(SIZE-1 downto 0);
  25. Z_result : out signed(SIZE-1 downto 0)
  26. );
  27. end entity;
  28. architecture rtl of cordic is
  29. type signed_array is array (natural range <>) of signed(SIZE-1 downto 0);
  30. function gen_atan_table(s : positive) return signed_array is
  31. variable table : signed_array(0 to ITERATIONS-1);
  32. begin
  33. for i in table'range loop
  34. table(i) := to_signed(integer(arctan(2.0**(-i)) * 2.0**s / MATH_2_PI), s);
  35. end loop;
  36. return table;
  37. end function;
  38. constant ATAN_TABLE : signed_array(0 to ITERATIONS-1) := gen_atan_table(SIZE);
  39. signal xr : signed(X'range);
  40. signal yr : signed(Y'range);
  41. signal zr : signed(Z'range);
  42. signal x_shift : signed(X'range);
  43. signal y_shift : signed(Y'range);
  44. subtype iter_count is integer range 0 to ITERATIONS;
  45. signal cur_iter : iter_count;
  46. begin
  47. p_cordic: process(Clock, Reset) is
  48. variable negative : boolean;
  49. begin
  50. if Reset = RESET_ACTIVE_LEVEL then
  51. xr <= (others => '0');
  52. yr <= (others => '0');
  53. zr <= (others => '0');
  54. cur_iter <= 0;
  55. Result_valid <= '0';
  56. Busy <= '0';
  57. elsif rising_edge(Clock) then
  58. if Data_valid = '1' then
  59. xr <= X;
  60. yr <= Y;
  61. zr <= Z;
  62. cur_iter <= 0;
  63. Result_valid <= '0';
  64. Busy <= '1';
  65. else
  66. if cur_iter /= ITERATIONS then
  67. --if cur_iter(ITERATIONS) /= '1' then
  68. if Mode = cordic_rotate then
  69. negative := zr(z'high) = '1';
  70. else
  71. negative := yr(y'high) = '0';
  72. end if;
  73. --if zr(z'high) = '1' then -- z or y is negative
  74. if negative then
  75. xr <= xr + y_shift; --(yr / 2**(cur_iter));
  76. yr <= yr - x_shift; --(xr / 2**(cur_iter));
  77. zr <= zr + ATAN_TABLE(cur_iter);
  78. else -- z or y is positive
  79. xr <= xr - y_shift; --(yr / 2**(cur_iter));
  80. yr <= yr + x_shift; --(xr / 2**(cur_iter));
  81. zr <= zr - ATAN_TABLE(cur_iter);
  82. end if;
  83. cur_iter <= cur_iter + 1;
  84. --cur_iter <= '0' & cur_iter(0 to ITERATIONS-1);
  85. end if;
  86. if cur_iter = ITERATIONS-1 then
  87. Result_valid <= '1';
  88. Busy <= '0';
  89. end if;
  90. end if;
  91. end if;
  92. end process;
  93. x_shift <= shift_right(xr, cur_iter);
  94. y_shift <= shift_right(yr, cur_iter);
  95. X_result <= xr;
  96. Y_result <= yr;
  97. Z_result <= zr;
  98. end architecture;