library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.std_logic_signed.all;

library fact_fad_lib;
use fact_fad_lib.fad_definitions.all;


ENTITY drs_pulser is
     port (
         CLK : in std_logic;
        
         start_endless_mode : in std_logic;
         start_read_stop_pos_mode : in std_logic;

         SROUT_in_0 : in std_logic;
         SROUT_in_1 : in std_logic;
         SROUT_in_2 : in std_logic;
         SROUT_in_3 : in std_logic;

         stop_pos : out drs_s_cell_array_type;
         stop_pos_valid : out std_logic := '0';

         start_srin_write_8b : in std_logic;
         srin_write_ready : out std_logic := '0';
         srin_write_ack : out std_logic := '0';
         srin_data : in std_logic_vector (7 downto 0);
         SRIN_out : out std_logic := '0';

         RSRLOAD : out std_logic := '0';
         SRCLK : out std_logic := '0'
     );
end drs_pulser;


ARCHITECTURE behavior of drs_pulser IS

type state_main_type is (MAIN, SRIN_WRITE_8B, SRIN_WRITE_END, READ_STOP_POS, ENDLESS_MODE);
signal state_main : state_main_type := MAIN;
signal stop_pos_cntr, wait_cntr : integer range 0 to 31 := 0;

signal stop_pos_int : drs_s_cell_array_type;
signal RSRLOAD_EN, SRCLK_EN : std_logic := '0';

signal srin_cntr : integer range 0 to 7 := 1;

begin
  
  
  main_proc: process (clk) begin

    RSRLOAD <= (clk and RSRLOAD_EN);
    SRCLK <= (clk and SRCLK_EN);

    if rising_edge(clk) then
      case state_main is
        when MAIN =>
          if (start_srin_write_8b = '1') then
            srin_write_ready <= '0';
            srin_write_ack <= '1';
            srin_cntr <= 0;
            --SRCLK_EN <= '1';
            state_main <= SRIN_WRITE_8B;
          end if;
          if (start_read_stop_pos_mode = '1') then
            RSRLOAD_EN <= '1';
            stop_pos_valid <= '0';
            state_main <= READ_STOP_POS;
          end if;
          if (start_endless_mode = '1') then
            RSRLOAD_EN <= '1';
            state_main <= ENDLESS_MODE;
          end if;
        
        when SRIN_WRITE_8B =>
          SRCLK_EN <= '1';
          srin_out <= srin_data (7 - srin_cntr);
          if (srin_cntr = 7) then
            --SRCLK_EN <= '0';
            state_main <= SRIN_WRITE_END;
          else
            srin_cntr <= srin_cntr + 1;
          end if;
        when SRIN_WRITE_END =>
          SRCLK_EN <= '0';
          srin_out <= '0';
          srin_write_ready <= '1';
          srin_write_ack <= '0';
          state_main <= MAIN;
          
          
        when ENDLESS_MODE =>
          RSRLOAD_EN <= '0';
          if (wait_cntr = 3) then
            SRCLK_EN <= '1';
          else
            wait_cntr <= wait_cntr + 1;
          end if;
          if (start_endless_mode = '0') then
            SRCLK_EN <= '0';
            wait_cntr <= 0;
            state_main <= MAIN;
          end if;
         
        when READ_STOP_POS =>
          RSRLOAD_EN <= '0';
          if (stop_pos_cntr = 10) then
            stop_pos (0) <= stop_pos_int (0);
            stop_pos (1) <= stop_pos_int (1);
            stop_pos (2) <= stop_pos_int (2);
            stop_pos (3) <= stop_pos_int (3);
            stop_pos_valid <= '1';
            stop_pos_cntr <= 0;
            SRCLK_EN <= '0';
            state_main <= MAIN;
          else
            SRCLK_EN <= '1';
            stop_pos_int (0) <= stop_pos_int (0) (8 downto 0) & SROUT_in_0;
            stop_pos_int (1) <= stop_pos_int (1) (8 downto 0) & SROUT_in_1;
            stop_pos_int (2) <= stop_pos_int (2) (8 downto 0) & SROUT_in_2;
            stop_pos_int (3) <= stop_pos_int (3) (8 downto 0) & SROUT_in_3;
            stop_pos_cntr <= stop_pos_cntr + 1;
          end if;
            
      end case; -- state_main
    end if;

  end process main_proc;

end behavior;
