46 lines
1.3 KiB
VHDL
46 lines
1.3 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use ieee.math_real.all;
|
|
|
|
package cordic_pkg is
|
|
type cordic_mode is (cordic_rotate, cordic_vector);
|
|
|
|
function cordic_gain(Iterations : positive) return real;
|
|
|
|
procedure adjust_angle(x, y, z : in signed; signal xa, ya, za : out signed);
|
|
end package cordic_pkg;
|
|
|
|
package body cordic_pkg is
|
|
function cordic_gain(iterations : positive) return real is
|
|
variable g : real := 1.0;
|
|
begin
|
|
for i in 0 to iterations-1 loop
|
|
g := g * sqrt(1.0 + 2.0**(-2*i));
|
|
end loop;
|
|
return g;
|
|
end function;
|
|
|
|
procedure adjust_angle(x, y, z : in signed; signal xa, ya, za : out signed) is
|
|
variable quad : unsigned(1 downto 0);
|
|
variable zp : signed(z'length-1 downto 0) := z;
|
|
variable yp : signed(y'length-1 downto 0) := y;
|
|
variable xp : signed(x'length-1 downto 0) := x;
|
|
begin
|
|
|
|
-- 0-based quadrant number of angle
|
|
quad := unsigned(zp(zp'high downto zp'high-1));
|
|
|
|
if quad = 1 or quad = 2 then -- Rotate into quadrant 0 and 3 (right half of plane)
|
|
xp := -xp;
|
|
yp := -yp;
|
|
-- Add 180 degrees (flip the sign bit)
|
|
zp := (not zp(zp'left)) & zp(zp'left-1 downto 0);
|
|
end if;
|
|
|
|
xa <= xp;
|
|
ya <= yp;
|
|
za <= zp;
|
|
end procedure;
|
|
end package body cordic_pkg;
|