Vous êtes sur la page 1sur 2

library ieee;

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- This is for the fixed point libraries


use work.std_logic_1164_additions.all;
use work.numeric_std_additions.all;
use work.math_utility_pkg.all;
use work.fixed_pkg.all;

entity cordic_trig is

port (rads : in sfixed (5 downto -15);


clk : in std_logic;
aclr : in std_logic;
sine, cosine : out sfixed(0 downto -15)
);
end entity cordic_trig;

architecture rtl of cordic_trig is

-- Build a 2-D array type for the RoM


subtype word_t is sfixed(0 downto -15);
type memory_t is array(15 downto 0) of word_t;

function create_atan_tbl
return memory_t is
variable tmp : memory_t := (others => (others => '0'));
begin
tmp(0) := to_sfixed(0.785398163397, tmp(0));
tmp(1) := to_sfixed(0.463647609001, tmp(0));
tmp(2) := to_sfixed(0.244978663127, tmp(0));
tmp(3) := to_sfixed(0.124354994547, tmp(0));
tmp(4) := to_sfixed(0.062418809996, tmp(0));
tmp(5) := to_sfixed(0.0312398334303, tmp(0));
tmp(6) := to_sfixed(0.0156237286205, tmp(0));
tmp(7) := to_sfixed(0.0078123410601, tmp(0));
tmp(8) := to_sfixed(0.00390623013197, tmp(0));
tmp(9) := to_sfixed(0.00195312251648, tmp(0));
tmp(10) := to_sfixed(0.000976562189559, tmp(0));
tmp(11) := to_sfixed(0.000488281211195, tmp(0));
tmp(12) := to_sfixed(0.000244140620149, tmp(0));
-- tmp(13) := to_sfixed(0.000122070311894, tmp(0));
-- tmp(14) := to_sfixed(6.10351561742e-005, tmp(0));
-- tmp(15) := to_sfixed(3.05175781155e-005, tmp(0));
return tmp;
end create_atan_tbl;

-- Declare the ROM signal and specify a default value. Quartus II


-- will create a memory initialization file (.mif) based on the
-- default value.
signal atan_tbl : memory_t := create_atan_tbl;

begin

process (clk,aclr)
-- Too many variables?
variable tmp_x, tmp_y : sfixed(cosine'high+1 downto cosine'low);
variable tmp_rad : sfixed(rads'high+1 downto rads'low);

variable x : sfixed(cosine'high downto cosine'low)


:= to_sfixed(0.60725, cosine'high, cosine'low);
variable y : sfixed(sine'high downto sine'low)
:= to_sfixed(0, sine'high, sine'low);

-- atan_values to be looked up
variable a : sfixed(0 downto -15);

begin
if aclr = '0' then
sine <= (others=>'0');
cosine <= (others=>'0');
elsif rising_edge(clk) then

for i in 0 to 10 loop
tmp_x := resize(x sra i, tmp_x);
tmp_y := resize(y sra i, tmp_y);
a := atan_tbl(i);

if (tmp_rad >= 0) then


x := resize(x-tmp_y, x);
a := resize(-a, a);
y := resize(y+tmp_x, y);
else
x := resize(x+tmp_y, x);
y := resize(y-tmp_x, y);
end if;

tmp_rad := resize(tmp_rad + a, tmp_rad);


end loop;

cosine <= x;
sine <= y;
end if;
end process;

end architecture rtl;