LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity sin_lut is
generic(Na : Integer := 8;
Nd : Integer := 9);
port(
raddr : in std_logic_vector(Na-1 downto 0);
rdata : out std_logic_vector(Nd-1 downto 0));
end sin_lut;
architecture a of sin_lut is
component sin_lut90 is
generic(Na : Integer range 4 to 6 := 4;
Nd : Integer := 8);
port(
raddr : in std_logic_vector(Na-1 downto 0);
rdata : out std_logic_vector(Nd-1 downto 0));
end component;
constant sub0 : std_logic_vector(Na-3 downto 0) := (others => '0');
signal suba, suba2lut : std_logic_vector(Na-3 downto 0);
signal rdata_lut : std_logic_vector(Nd-2 downto 0);
signal sel : std_logic_vector(2 downto 0);
begin
lut0to90: sin_lut90 -- table for 0 to 90 deg
generic map(Na => Na-2, Nd => Nd-1)
port map(raddr => suba2lut, rdata => rdata_lut);
suba <= raddr(Na-3 downto 0);
suba2lut <= suba when raddr(Na-2) = '0' else (not suba) + 1; -- suba or -suba
-- suba2lut <= sub0 + suba when raddr(Na-2) = '0' else sub0 - suba; -- suba or -suba
sel <= '1' & raddr(Na-1 downto Na-2) when suba = sub0 else '0' & raddr(Na-1 downto Na-2);
process(sel, rdata_lut)
begin
rdata <= (others => '0'); -- used in "100", "110", partly in "111"
case sel is
when "101" => rdata <= (others => '1'); -- 90 deg
rdata(Nd-1) <= '0'; -- +(2**Nd-1)
when "111" => rdata(Nd-1) <= '1'; -- 270 deg
rdata(0) <= '1'; -- -(2**Nd-1)
when "000"|"001" => rdata <= '0' & rdata_lut; -- LUT
when "010"|"011" => rdata <= '1' & ((not rdata_lut) + 1); -- -LUT
when others => NULL;
end case;
end process;
end;