-- WARNING: Do NOT edit the input and output ports in this file in a text
-- editor if you plan to continue editing the block that represents it in
-- the Block Editor! File corruption is VERY likely to occur.

-- Copyright (C) 1991-2003 Altera Corporation
-- Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
-- support information,  device programming or simulation file,  and any other
-- associated  documentation or information  provided by  Altera  or a partner
-- under  Altera's   Megafunction   Partnership   Program  may  be  used  only
-- to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
-- other  use  of such  megafunction  design,  netlist,  support  information,
-- device programming or simulation file,  or any other  related documentation
-- or information  is prohibited  for  any  other purpose,  including, but not
-- limited to  modification,  reverse engineering,  de-compiling, or use  with
-- any other  silicon devices,  unless such use is  explicitly  licensed under
-- a separate agreement with  Altera  or a megafunction partner.  Title to the
-- intellectual property,  including patents,  copyrights,  trademarks,  trade
-- secrets,  or maskworks,  embodied in any such megafunction design, netlist,
-- support  information,  device programming or simulation file,  or any other
-- related documentation or information provided by  Altera  or a megafunction
-- partner, remains with Altera, the megafunction partner, or their respective
-- licensors. No other licenses, including any licenses needed under any third
-- party's intellectual property, are provided herein.


-- Generated by Quartus II Version 2.2 (Build Build 191 03/31/2003)
-- Created on Wed Nov 19 12:02:12 2003

LIBRARY ieee;
USE ieee.std_logic_1164.all;


--  Entity Declaration

ENTITY hct4094 IS
	-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
	
	 GENERIC (
      data_len : integer := 24;
      glitch_capt : integer := 16
	 );
	
	PORT
	(
		clk : IN STD_LOGIC;
		clk_en : IN STD_LOGIC;
		reset : IN STD_LOGIC;
		data_in: IN STD_LOGIC_VECTOR(data_len-1 downto 0);
		test1 : OUT STD_LOGIC;
		test2 : OUT STD_LOGIC;
		test3 : OUT STD_LOGIC;
		test4 : OUT STD_LOGIC;
		str : OUT STD_LOGIC;
		data : OUT STD_LOGIC;
		sck : OUT STD_LOGIC
	);
	-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!
	
END hct4094;


--  Architecture Body

ARCHITECTURE a OF hct4094 IS

	TYPE STATE_TYPE IS (
	idle,
	sync_l,
	sync_h,
	data_l,
	data_h,
	data_end,
	next_tx			
	);
	
	
	
	
	
	SIGNAL state: STATE_TYPE;
    signal shift_count : integer range 2*data_len downto 0;
    signal shiftreg,data_shift : std_logic_vector (data_len-1 downto 0);
    signal  shift_enable,
		 	shifter_load,
			sck_temp,sck_buffer,
			str_temp,
		    shift_reset,
			data_temp,
		    stop_shift,
			str_del,
			reset_capt_logic : std_logic ;		
BEGIN
 

--***********************************************************************************************************************************************
--*******************************************	short pulse capture	*********************************************************************
--***********************************************************************************************************************************************

glitch_capture_logic:
FOR i IN 0 to glitch_capt-1 GENERATE
begin
	PROCESS (clk,reset)
		BEGIN
			IF reset = '1' THEN
				data_shift(i) <= '0';
			ELSIF clk'EVENT AND clk = '1' THEN
					if reset_capt_logic = '1' then 
						data_shift(i) <= '0';	
					elsif data_in(i) = '1' then 
						data_shift(i) <= '1'; 
					end if;					
			END IF;
	END PROCESS;
END GENERATE;


non_glitch_capture_logic:
FOR i IN glitch_capt to data_len-1 GENERATE
	data_shift(i) <= data_in(i); 				
END GENERATE;





--***********************************************************************************************************************************************
--*******************************************	data transfer state machine	*********************************************************************
--***********************************************************************************************************************************************

	PROCESS (clk,reset)
	BEGIN
		IF reset = '1' THEN
			state <= idle;
		ELSIF clk'EVENT AND clk = '1' THEN	
			if clk_en = '1' then
				CASE state IS
					WHEN idle =>
							state <=sync_l;
							
					when sync_l =>
							state<=sync_h;
							
					when sync_h =>	
							state<=data_l;
							
					when data_l =>  
						if stop_shift = '1' then
							state <= data_end;
						else	
							state<=data_h;
						end if;	
						
					when data_h =>
							state<=data_l; 
							
					when data_end =>
							state<=next_tx;
							
					when next_tx=>
							state<=idle;
							
					when others=>
							state<=idle;

				END CASE;
			end if;
		END IF;
	END PROCESS;

	WITH state SELECT
		shift_reset 	<=	'1' when idle,
							'1' when sync_l,
							'1' when sync_h,							
							'0' when data_l,
							'0' when data_h,
							'0' when data_end,
							'0' when next_tx;
							
							
	WITH state SELECT
		sck_temp        <=  '0' when idle,
							'0' when sync_l,
							'0' when sync_h,							
							'0' when data_l,
							'1' when data_h,
							'0' when data_end,
							'0' when next_tx;
		 
WITH state SELECT
		shift_enable    <=  '0' when idle,
							'0' when sync_l,
							'0' when sync_h,							
							'1' when data_l,
							'1' when data_h,
							'0' when data_end,
							'0' when next_tx;
							
	
							
	WITH state SELECT
	shifter_load        <=  '0' when idle,
							'1' when sync_l,
							'1' when sync_h,							
							'0' when data_l,
							'0' when data_h,
							'0' when data_end,
							'0' when next_tx;
							
	WITH state SELECT
	str_temp          <=    '0' when idle,
							'0' when sync_l,
							'0' when sync_h,							
							'0' when data_l,
							'0' when data_h,
							'1' when data_end,
							'1' when next_tx;
	
process(clk)
begin	
	if clk'event and clk='1' then
		if clk_en = '1' then
				if state = sync_h then
					reset_capt_logic  <=   '1';
				else 
					reset_capt_logic  <=   '0';
				end if;
		end if;
	end if;	
end process;
							

process(clk,shift_count)
begin
	if clk'event and clk='1' then
		if clk_en = '1' then
			if shift_reset='1' or reset = '1'  then
	            shift_count<=0;	
				stop_shift <= '0';
			elsif  stop_shift='0' then
					shift_count <=shift_count+1;		
			end if;
		end if;
	end if;
   	if shift_count = (2*data_len) then	
		stop_shift<='1';
	else
		stop_shift<='0';
	end if;
		end process;
		
		
		
							
process(clk)
begin
if clk'event and clk='0' then
	if clk_en = '1' then
		sck_buffer<=sck_temp;
		sck<=sck_buffer;
		str_del<=str_temp;
		str<=str_del;  
	end if;
end if;
end process;

	
process(clk)
begin
if clk'event and clk='1' then
	data<=data_temp; 

	end if;
end process;








Process (clk)
	begin
	if clk'event and clk='1' then
		if clk_en = '1' then
		 	if shifter_load = '1' then
				shiftreg <= data_shift;
			elsif sck_buffer='0' then
			   	if (shift_enable) = '1'  THEN
			    	shiftreg(data_len-1 downto 0) <=  shiftreg(data_len-2 downto 0) & '0';
					data_temp <=shiftreg(data_len-1);
				end if;
			end if;
		end if;
	end if;
end process;

	

test1<= shifter_load;
test2<=reset_capt_logic;
test3<=shift_reset;
test4<=shift_enable;








END a;




