----------------------------------------------------------------
-- Projet : rst_module1.ise   19Jan2008-Sat-crater
-- File   : rst_module1.vhd / .ise
----------------------------------------------------------------
-- This module provides RESET_PULSE - 0 for RESETing the system
--                                    1 for NORMAL WORKING

-- This module provides RESET_ONCE  - 1 for RESETing the system
--                                    0 for NORMAL WORKING
----- This happens ONLY ONCE -----------------------------------

-- There will be 1 counter which will take the RESET from the INIT
-- based 16 bit shift register.
--  gk, 17Jan2008
----------------------------------------------------------------
-- Company: RAMAN RESEARCH INSTITUTE
-- Engineer: gk
 
-- Create Date:    19:40:52 01/17/2008 
-- Design Name:  
-- Module Name:    rst_module1 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity rst_module1 is
    Port ( 
      	  clk_in    : in  STD_LOGIC;
--			  ext_rst_in    : in std_logic;
			  usb_data_in		: in std_logic_vector(31 downto 0);
			  usb_load			: in std_logic;
--			  counter_out : out std_logic_vector(15 downto 0);
	        ms6a_out  : out std_logic; 
			  reset_out : out std_logic);
end rst_module1;

architecture Behavioral of rst_module1 is

signal counter1 : std_logic_vector(15 downto 0) := X"0000";
signal reset1,reset2,ext_rst1,s_ext_rst : std_logic := '0';
signal ms1: std_logic;
signal reset_once : std_logic := '1';

signal Q15 ,ext_rst_in,ext_rst_internal: std_logic ;
signal a0 : std_logic := '1';
signal a1 : std_logic := '1';
signal a2 : std_logic := '1';
signal a3 : std_logic := '1';
signal check_ld_low,usb_load_int,valid_load: std_logic := '0';
signal reset_reg : std_logic_vector(31 downto 0):=(OTHERS => '0');
signal ext_rst_internal_ctr : std_logic_vector(2 downto 0):=(others => '0');

begin
--usb valid load
process(clk_in)
begin
  if clk_in'event and clk_in= '1' then 
		usb_load_int <= usb_load;
  	if usb_load_int = '1' and check_ld_low = '0' then
		  valid_load <= '1';
		  check_ld_low <= '1';
	elsif usb_load_int = '1' and check_ld_low = '1' then 	  
		  valid_load <= valid_load ;
		  check_ld_low <= check_ld_low;
	elsif usb_load_int = '0' and check_ld_low = '1' then
		  check_ld_low<= '0';
		  valid_load <= valid_load;
	elsif usb_load_int = '0' and check_ld_low = '0' then		
		  valid_load <= valid_load ;
		  check_ld_low<= '0';--check_ld_low;
	end if;	  
   if valid_load = '1' then
	    valid_load <= '0';
	end if;	 
end if;
end process;

process(clk_in,valid_load)
begin
  if clk_in'event and clk_in = '1' then 
    if ext_rst_in = '1' then
	 		reset_reg  <= (others => '0');
	 elsif valid_load = '1' then 
			reset_reg <= usb_data_in;
	 else
			reset_reg <= reset_reg;
	 end if;	
	 
	 if ext_rst_internal = '1' then
	    ext_rst_in <= '1';
	 else
	 	 ext_rst_in <= '0';
	 end if; 
	 if ext_rst_in = '1' then 
		ext_rst_internal_ctr <= ext_rst_internal_ctr + '1' ;
--		ext_rst_in <= '1';
		if  ext_rst_internal_ctr = 10  then
			ext_rst_in <= '0';
      	ext_rst_internal_ctr <=(others => '0');
      end if;		
	end if;	
 end if;	
end process;
ext_rst_internal <= reset_reg(0);



------------ External RESET Input double synchronization ---------
--------------- Single INIT Register with 0 ----------------------
 FDCE_inst1 : FDCE
   generic map (
      INIT => '0') -- Initial value of register ('0' or '1')  
--      INIT => '1') -- Initial value of register ('0' or '1')  
   port map (
      Q => ext_rst1,      -- Data output
      C => clk_in,      -- Clock input
      CE => '1',    -- Clock enable input
      CLR => '0',  -- RESET_IN,  -- Asynchronous clear input
      D => ext_rst_in      -- Data input
   );
------------- Single INIT Register with 0 ----------------------
 FDCE_inst2 : FDCE
   generic map (
      INIT => '0') -- Initial value of register ('0' or '1')  
--      INIT => '1') -- Initial value of register ('0' or '1')  
   port map (
      Q => s_ext_rst,      -- Data output
      C => clk_in,      -- Clock input
      CE => '1',    -- Clock enable input
      CLR => '0',  -- RESET_IN,  -- Asynchronous clear input
      D => ext_rst1      -- Data input
   );
----------------------------------------------------------------
------------------ 16 bit shift register -----------------------
   SRLC16E_inst : SRLC16E
   generic map (
      INIT => X"FFFF")
   port map (
      Q => reset1,       -- SRL data output
--      Q15 => DATA_OUT0,   -- Carry output (connect to next SRL)
      Q15 => Q15,   -- Carry output (connect to next SRL)
      A0 => A0,     -- Select[0] input
      A1 => A1,     -- Select[1] input
      A2 => A2,     -- Select[2] input
      A3 => A3,     -- Select[3] input
--      CE => CE,     -- Clock enable input
      CE => '1',     -- Clock enable input
      CLK => clk_in,   -- Clock input
      D => '0'         -- SRL data input
--      D => D        -- SRL data input
   );

------------- Single INIT Register with 0 ----------------------
 FDCE_inst3 : FDCE
   generic map (
      INIT => '1') -- Initial value of register ('0' or '1')  -- Anish Feb 23, 2008 
--      INIT => '1') -- Initial value of register ('0' or '1')  
   port map (
      Q => reset2,      -- Data output
      C => clk_in,      -- Clock input
      CE => '1',    -- Clock enable input
      CLR => '0',  -- RESET_IN,  -- Asynchronous clear input
      D => reset1      -- Data input
   );
----------------------------------------------------------------
-- 16-bit counter1 - UP COUNTER --------------------------------
-- and reset pulse generation 
process(clk_in)
begin
 if(clk_in'event and clk_in = '1') then
--  if( (reset1 = '1') or (s_ext_rst='1') ) then  ---- *** ----
  if( (reset2 = '1') or (s_ext_rst='1') ) then  ---- *** ----
    counter1 <= x"0000";
	 ms1 <= '1';
--  elsif(counter1 = X"FFFE") then  --for simulation this value is reduced to 28F
--  elsif(counter1 = X"028F") then
  elsif(counter1 = X"008F") then

    ms1 <= '0';
    counter1 <= counter1 + 1;
  else  
    ms1 <= '1';
    counter1 <= counter1 + 1;
  end if;	 
 else
  counter1 <= counter1; 
 end if; 
end process;
------------- Single INIT Register with 1 ----------------------
 FDCE_inst : FDCE
   generic map (
--      INIT => '0') -- Initial value of register ('0' or '1')  
      INIT => '1') -- Initial value of register ('0' or '1')  
   port map (
      Q => reset_out,      -- Data output
      C => clk_in,      -- Clock input
      CE => '1',    -- Clock enable input
      CLR => '0',  -- RESET_IN,  -- Asynchronous clear input
      D => reset_once      -- Data input
   );
----------------------------------------------------------------



--init_anded  <= reset_once and ms1;
--rst_control <= init_anded or reset2 or s_ext_rst ;

ms6a_out <= ms1;

process(clk_in)
begin
 if(clk_in'event and clk_in = '1') then
		reset_once <= (reset_once and ms1) or reset2 or s_ext_rst ;
 end if;
end process;
 
end Behavioral;

----------- end of file : rst_module1.vhd -----------------------
