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

entity nn2_div is
    port (
        vcoin      : in  std_logic;                     -- clock input
        select_bit : in  std_logic;                     -- 0 = fixed n, 1 = alternate n / n+2
        count_val  : in  std_logic_vector(7 downto 0);  -- 0..255 → n = count_val (lower 8 bits of 10-bit)
        out_pulse  : out std_logic                      -- 1-cycle pulse when limit reached
    );
end entity nn2_div;

architecture rtl of nn2_div is
    signal counter       : unsigned(9 downto 0) := (others => '0');  -- 10-bit counter
    signal toggle        : std_logic := '0';
    signal current_mode  : std_logic := '0';
    signal current_base_n : unsigned(9 downto 0) := (others => '0');  -- registered base_n
    signal current_limit : unsigned(9 downto 0);
begin

    process(vcoin)
        variable next_base_n : unsigned(9 downto 0);
        variable next_mode   : std_logic;
        variable next_counter : unsigned(9 downto 0);
    begin
        if rising_edge(vcoin) then
            out_pulse <= '0';

            -- Sample inputs at current clock (but apply at cycle end)
            next_base_n := ("00" & unsigned(count_val))-1;  -- n = count_val (padded high bits 0)
            next_mode   := select_bit;

            -- Select limit based on CURRENT values
            if current_mode = '0' then
                current_limit <= current_base_n;  -- fixed n
            else
                if toggle = '0' then
                    current_limit <= current_base_n;
                else
                    current_limit <= current_base_n + 4;
                end if;
            end if;

            -- Next counter
            next_counter := counter + 1;

            -- Pulse when next reaches the limit (divide by current_limit exactly)
            if next_counter = current_limit then
                out_pulse <= '1';
                counter   <= (others => '0');

                -- Update registered values only at end of cycle
                current_base_n <= next_base_n;
                current_mode   <= next_mode;

                -- Toggle only if alternating mode
                if current_mode = '1' then
                    toggle <= not toggle;
                end if;
            else
                counter <= next_counter;
            end if;
        end if;
    end process;

end architecture rtl;