--=====================================================
-- Проект 28. Прямой цифровой синтез (DDS)
-- Накопитель фазы адресует таблицу синуса:
-- частота задаётся приращением фазы.
--=====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity dds is
    generic (
        PHASE_W : integer := 24                         -- разрядность накопителя
    );
    port (
        clk       : in  std_logic;
        rst       : in  std_logic;
        phase_inc : in  std_logic_vector(PHASE_W-1 downto 0);   -- приращение
        wave      : out std_logic_vector(7 downto 0)            -- отсчёт синуса
    );
end entity dds;

architecture rtl of dds is
    signal phase : unsigned(PHASE_W-1 downto 0) := (others => '0');

    -- четверть периода синуса, 16 точек
    type lut_t is array (0 to 15) of integer range 0 to 127;
    constant QUARTER : lut_t := (
        0, 12, 24, 36, 48, 58, 68, 77,
        85, 92, 98, 103, 107, 110, 112, 113);

    signal idx : integer range 0 to 15;
    signal quad : std_logic_vector(1 downto 0);
    signal val  : integer range 0 to 127;
begin
    process (clk, rst)
    begin
        if rst = '1' then
            phase <= (others => '0');
        elsif rising_edge(clk) then
            phase <= phase + unsigned(phase_inc);       -- накопление фазы
        end if;
    end process;

    -- старшие биты фазы: номер четверти и индекс в таблице
    quad <= std_logic_vector(phase(PHASE_W-1 downto PHASE_W-2));
    idx  <= to_integer(phase(PHASE_W-3 downto PHASE_W-6));
    val  <= QUARTER(idx);

    -- симметрия синуса: одна четверть таблицы даёт весь период
    process (quad, val, idx)
    begin
        case quad is
            when "00"   => wave <= std_logic_vector(to_unsigned(128 + val, 8));
            when "01"   => wave <= std_logic_vector(to_unsigned(128 + QUARTER(15-idx), 8));
            when "10"   => wave <= std_logic_vector(to_unsigned(127 - val, 8));
            when others => wave <= std_logic_vector(to_unsigned(127 - QUARTER(15-idx), 8));
        end case;
    end process;
end architecture rtl;
