----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    10:53:48 07/19/2012 
-- Design Name: 
-- Module Name:    serialpatternrx - 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;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

library WORK;
use WORK.common.ALL;

entity serialpatternrx is
	Port (
		i 		: in t_serialpatternrx_i;
		o 		: out t_serialpatternrx_o;
		clk40 	: in std_logic
		);
end serialpatternrx;

architecture Behavioral of serialpatternrx is

	constant random_c : std_logic_vector (359 downto 0):= "111000101010011000001011010100110011001100101000100111100110100100011110001101100000101111110100101000111010100110000010000010001000111100101101111010100000101110011100010101100110110000001100111011100111101011011010111111010110001111111100010001010010010000010110000001001001110111100101000111100001011011010011100001000001101011100010010110100111111000001101";

	signal error_flag : std_logic;
	signal realign_flag : std_logic;

begin

	o.error_flag <= error_flag;
	o.realign_flag <= realign_flag;

	process (clk40)
		variable substate : integer range 19 downto 0 := 0;
		constant realigning_max : integer := 3;
		variable realigning : integer range realigning_max downto 0 := 0;
		constant unaligning_max : integer := 10;
		variable unaligning : integer range unaligning_max downto 0 := 0;
		variable dummy : std_logic;
	begin
		if rising_edge(clk40) then
			if i.deser_lock = '1' then
				if realigning = realigning_max then --está alineado
					if i.word(18 downto 1) /= random_c(substate*18+17 downto substate*18) then
						error_flag <= not error_flag;
						if unaligning = unaligning_max then	realigning := 0;
						else unaligning := unaligning + 1;
						end if;
					elsif unaligning > 0 then 
						unaligning := unaligning -1;
					end if;
					
					if substate = 19 then substate := 0;
					else substate := substate + 1;
					end if;
				else 
					realign_flag <= not realign_flag;
					if i.word(18 downto 1) = random_c(realigning*18+17 downto realigning*18) then
						realigning := realigning + 1;
						substate := realigning;
					else
						realigning := 0;
					end if;
				end if;
			end if;
		end if;
	end process;


end Behavioral;

