OpenCores
URL https://opencores.org/ocsvn/rio/rio/trunk

Subversion Repositories rio

[/] [rio/] [trunk/] [rtl/] [vhdl/] [srio_pcs_struct.vhd] - Rev 45

Go to most recent revision | Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--
-- File name:    ccs_timer.vhd
-- Rev:          0.0
-- Description:  This entity watches the CCS (clock compensation sequence) 
--               insertion according to RIO Sepec. Part-6, subchapter 4.7.1
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use work.rio_common.all;
 
entity ccs_timer is
  generic (
    TCQ         : time      := 100 ps
  );
  port ( 
    rst_n               : in  std_logic;
    UCLK                : in  std_logic;
 
    send_ccs            : out std_logic;    
    ccs_timer_rst       : in  std_logic
  );
end ccs_timer;
 
architecture RTL of ccs_timer is
--------------------------------------------------------------------------------------
signal   ccs_counter            : std_logic_vector(11 downto 0) := (others => '0');
constant CCS_INTERVAL           : std_logic_vector(11 downto 0) := x"7FF";  -- = 4096 chars
 
--------------------------------------------------------------------------------------
begin
 
-- CCS counter process
process(rst_n, UCLK)
    begin    
    if rst_n = '0'  then    
        ccs_counter     <= CCS_INTERVAL; 
        send_ccs        <= '0';
    elsif rising_edge(UCLK) then 
        if ccs_timer_rst = '0' then  
            if ccs_counter = CCS_INTERVAL then
                send_ccs    <= '1';
            else
                send_ccs    <= '0';
                ccs_counter <= ccs_counter + '1';
            end if;   
        else
            send_ccs    <= '0';
            ccs_counter <= (others => '0');  
        end if;   
    end if;
end process;
 
end RTL;
---------------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--
-- File name:    idle_generator.vhd
-- Rev:          0.0
-- Description:  This entity generates IDLE1 sequence for SRIO PHY 
--               RIO Sepec. Part-6, subchapter 4.7.2
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use work.rio_common.all;
 
entity idle_generator is
  generic (
            lfsr_init   : std_logic_vector(7 downto 0) := x"01";
            TCQ         : time      := 100 ps
  );
  port ( 
    UCLK                : in  std_logic;
    rst_n               : in  std_logic;
 
    send_idle           : in  std_logic;
 
    send_K              : out std_logic;
    send_A              : out std_logic;
    send_R              : out std_logic
  );
end idle_generator;
 
architecture RTL of idle_generator is
-------------------------------------------------------------------------------------------------------------------------------------------
signal q_pseudo_random_number  : std_logic_vector(7 downto 0) := (others => '0');
signal pseudo_random_bit       : std_logic                    := '0';
 
signal down_counter_load_value : std_logic_vector(4 downto 0) := (others => '0');
signal down_counter            : std_logic_vector(4 downto 0) := (others => '0');
signal Acntr_eq_zero           : std_logic                    := '0';
signal send_idle_q             : std_logic                    := '0';
-- 
 
COMPONENT pseudo_random_number_generator    
GENERIC (
         lfsr_init   : std_logic_vector(7 downto 0)
        );
PORT(
	clk     : IN std_logic;
	rst_n   : IN std_logic;          
	q       : OUT std_logic_vector(7 downto 0)
	);
END COMPONENT;
 
-------------------------------------------------------------------------------------------------------------------------------------------
begin
 
inst_prng: pseudo_random_number_generator GENERIC MAP(
        lfsr_init => lfsr_init  --x"01"
	)
    PORT MAP(
        clk     => UCLK,
		rst_n   => rst_n,
		q       => q_pseudo_random_number
	);
 
pseudo_random_bit       <= q_pseudo_random_number(0);
 
down_counter_load_value <= '1' & q_pseudo_random_number(6) & q_pseudo_random_number(4) & q_pseudo_random_number(3) & q_pseudo_random_number(1);
 
-- down counter process
process(rst_n, UCLK)
    begin    
    if rst_n = '0'  then    
        down_counter      <= (others => '0');       
    elsif rising_edge(UCLK) then    
        if Acntr_eq_zero = '1' then
            down_counter <= down_counter_load_value;
        else
            down_counter <= down_counter - '1';
        end if;   
    end if;
end process;
 
Acntr_eq_zero <= '1' when down_counter = "00000" else '0';
 
-- send_idle delay process
process(rst_n, UCLK)
    begin    
    if rst_n = '0'  then    
        send_idle_q     <= '0';       
    elsif rising_edge(UCLK) then    
        send_idle_q     <= send_idle;
    end if;
end process;
 
send_K <= send_idle and (not(send_idle_q) or (send_idle_q and not(Acntr_eq_zero) and pseudo_random_bit)); 
send_A <= send_idle and send_idle_q and Acntr_eq_zero;
send_R <= send_idle and send_idle_q and not(Acntr_eq_zero) and not(pseudo_random_bit);
 
end RTL;
-------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--
-- File name:    idle_generator_dual.vhd
-- Rev:          0.0
-- Description:  This entity generates IDLE1 sequence for SRIO PHY 
--               RIO Sepec. Part-6, subchapter 4.7.2
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use work.rio_common.all;
 
entity idle_generator_dual is
  generic (
            TCQ         : time      := 100 ps
  );
  port ( 
    UCLK                : in  std_logic;
    rst_n               : in  std_logic;
 
    send_idle           : in  std_logic_vector(1 downto 0);
 
    send_K              : out std_logic_vector(1 downto 0);
    send_A              : out std_logic_vector(1 downto 0);
    send_R              : out std_logic_vector(1 downto 0)
  );
end idle_generator_dual;
 
architecture RTL of idle_generator_dual is
-------------------------------------------------------------------------------------------------------------------------------------------
 
COMPONENT idle_generator
  generic (
            lfsr_init   : std_logic_vector(7 downto 0);
            TCQ         : time 
  );
PORT(
	UCLK        : IN  std_logic;
	rst_n       : IN  std_logic;
	send_idle   : IN  std_logic;          
	send_K      : OUT std_logic;
	send_A      : OUT std_logic;
	send_R      : OUT std_logic
	);
END COMPONENT;
 
-------------------------------------------------------------------------------------------------------------------------------------------
begin
 
	Inst_idle_generator_0: idle_generator GENERIC MAP(
        TCQ         => 100 ps,
        lfsr_init   => x"0F"
    )
        PORT MAP(
		UCLK        => UCLK,
		rst_n       => rst_n,
		send_idle   => send_idle(0),
		send_K      => send_K(0),
		send_A      => send_A(0),
		send_R      => send_R(0)
	);
 
	Inst_idle_generator_1: idle_generator GENERIC MAP(
        TCQ         => 100 ps,
        lfsr_init => x"F0"
    )
        PORT MAP(
		UCLK        => UCLK,
		rst_n       => rst_n,
		send_idle   => send_idle(1),
		send_K      => send_K(1),
		send_A      => send_A(1),
		send_R      => send_R(1)
	);
 
end RTL;
-------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--
-- File name:    pcs_rx_controller.vhd
-- Rev:          0.0
-- Description:  This entity controls the RX stream 
--               
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use work.rio_common.all;
 
entity pcs_rx_controller is
  generic (
    TCQ                     : time  := 100 ps
  );
  port ( 
    rst_n                   : in  std_logic;
    rio_clk                 : in  std_logic;  -- ~150 MHz
    UCLK_x2                 : in  std_logic;  --  312,5 MHz
    UCLK                    : in  std_logic;  --  156,25 MHz 
    UCLK_x2_DV2             : in  std_logic;  --  312,5 MHz @ x4 mode / 78,125 @ x1 (fallback mode) 
    UCLK_or_DV4             : in  std_logic;  --  156,25 MHz @ x4 mode / 39,0625 @ x1 (fallback mode)
    -- UCLK_DV4                : in  std_logic;  --  39,0625
    --
    -- Interface to the RioSerial
    inboundRead_i           : in  std_logic;
    inboundEmpty_o          : out std_logic;
    inboundSymbol_o         : out std_logic_vector(33 downto 0);    
    --
    -- Interface to the GTX transceivers
    RXDATA_i                : in  std_logic_vector(63 downto 0);  -- N = 4
    RXCHARISK_i             : in  std_logic_vector(7 downto 0);
    RXCHARISvalid_i         : in  std_logic_vector(7 downto 0);
    --
    -- Interface to the port init
    port_initalized_i       : in  std_logic;
    mode_sel_i              : in  std_logic;
    mode_0_lane_sel_i       : in  std_logic
 
  );
end pcs_rx_controller;
 
architecture RTL of pcs_rx_controller is
 
-------------------------------------------------------------------------------
COMPONENT pcs_rx_boudary_32b_out_64b_in
    PORT (
    rst             : IN STD_LOGIC;
    wr_clk          : IN STD_LOGIC;
    rd_clk          : IN STD_LOGIC;
    din             : IN STD_LOGIC_VECTOR(67 DOWNTO 0);
    wr_en           : IN STD_LOGIC;
    rd_en           : IN STD_LOGIC;
    dout            : OUT STD_LOGIC_VECTOR(33 DOWNTO 0);
    full            : OUT STD_LOGIC;
    almost_full     : OUT STD_LOGIC;
    empty           : OUT STD_LOGIC;
    almost_empty    : OUT STD_LOGIC;
    valid           : OUT STD_LOGIC
  );
END COMPONENT;    
-------------------------------------------------------------------------------
signal rst                  : std_logic:= '0';
 
signal RXDATA_swap          : std_logic_vector(63 downto 0) := (others => '0'); 
signal RXCHARISK_swap       : std_logic_vector(7  downto 0) := (others => '0');
signal RXCHARISvalid_swap   : std_logic_vector(7  downto 0) := (others => '0');
 
signal RXDATA_u             : std_logic_vector(31 downto 0) := (others => '0'); 
signal RXCHARISK_u          : std_logic_vector(3  downto 0) := (others => '0');
signal RXDATA_l             : std_logic_vector(31 downto 0) := (others => '0'); 
signal RXCHARISK_l          : std_logic_vector(3  downto 0) := (others => '0');
signal RXCHARISvalid_u      : std_logic_vector(3  downto 0) := (others => '0');
signal RXCHARISvalid_l      : std_logic_vector(3  downto 0) := (others => '0');
 
signal inboundValid           : std_logic:= '0';
signal rx_fifo_wr_en          : std_logic:= '0';
signal rx_fifo_wr_en_q        : std_logic:= '0';
signal rx_fifo_full           : std_logic:= '0';
signal rx_fifo_almost_full    : std_logic:= '0';
signal rx_fifo_almost_empty   : std_logic:= '0';
 
signal rx_fifo_data_in        : std_logic_vector(67 downto 0) := (others => '0');
signal rx_fifo_data_in_q      : std_logic_vector(67 downto 0) := (others => '0');
signal rx_fifo_data_swapped   : std_logic_vector(67 downto 0) := (others => '0');
signal rx_fifo_full_p         : std_logic:= '0';
 
signal port_initalized      : std_logic:= '0'; 
signal mode_sel             : std_logic:= '0'; 
signal mode_0_lane_sel      : std_logic:= '0';    
 
signal port_state           : std_logic_vector(2 downto 0) := (others => '0');
 
signal upper_symbol_type    : std_logic_vector(1  downto 0) := (others => '0');
signal lower_symbol_type    : std_logic_vector(1  downto 0) := (others => '0');
 
signal upper_symbol_not_idle  : std_logic:= '0'; 
signal lower_symbol_not_idle  : std_logic:= '0'; 
signal upper_symbol_valid     : std_logic:= '0'; 
signal lower_symbol_valid     : std_logic:= '0'; 
signal upper_symbol_not_error : std_logic:= '0'; 
signal lower_symbol_not_error : std_logic:= '0'; 
 
-- signal RXDATA_sr              : std_logic_vector(63 downto 0) := (others => '0'); 
-- signal RXCHARISK_sr           : std_logic_vector(7  downto 0) := (others => '0');
-- signal RXCHARISvalid_sr       : std_logic_vector(7  downto 0) := (others => '0'); 
 
signal RXDATA_sr_done         : std_logic_vector(63 downto 0) := (others => '0'); 
signal RXCHARISK_sr_done      : std_logic_vector(7  downto 0) := (others => '0');
signal RXCHARISvalid_sr_done  : std_logic_vector(7  downto 0) := (others => '0');   
 
signal RXDATA_sr              : std_logic_vector(71 downto 0) := (others => '0'); 
signal RXCHARISK_sr           : std_logic_vector(8  downto 0) := (others => '0');
signal RXCHARISvalid_sr       : std_logic_vector(8  downto 0) := (others => '0');   
 
signal RXDATA_R_lane          : std_logic_vector(15 downto 0) := (others => '0'); 
signal RXCHARISK_R_lane       : std_logic_vector(1  downto 0) := (others => '0');
signal RXCHARISvalid_R_lane   : std_logic_vector(1  downto 0) := (others => '0');    
 
signal valid_byte_cntr        : std_logic_vector(2  downto 0) := (others => '0');
signal irregular_stream       : std_logic:= '0';
signal done_cntr              : std_logic_vector(1  downto 0) := (others => '0');
signal rx_done                : std_logic:= '0';
 
signal u_l_switch             : std_logic:= '0';
 
-- signal sr_symbol_not_idle     : std_logic:= '0'; 
-- signal sr_symbol_not_idle_q   : std_logic:= '0'; 
-- signal sr_symbol_not_error    : std_logic:= '0'; 
-- signal sr_symbol_not_error_q  : std_logic:= '0'; 
-- signal RXDATA_sr              : std_logic_vector(31 downto 0) := (others => '0'); 
-- signal RXCHARISK_sr           : std_logic_vector(3  downto 0) := (others => '0');
-- signal RXCHARISvalid_sr       : std_logic_vector(3  downto 0) := (others => '0');                              
-- signal sr_symbol_type         : std_logic_vector(1  downto 0) := (others => '0');
 
signal sr_u_symbol_not_idle     : std_logic:= '0'; 
signal sr_u_symbol_not_idle_q   : std_logic:= '0'; 
signal sr_u_symbol_not_error    : std_logic:= '0'; 
signal sr_u_symbol_not_error_q  : std_logic:= '0'; 
signal RXDATA_u_sr              : std_logic_vector(31 downto 0) := (others => '0'); 
signal RXCHARISK_u_sr           : std_logic_vector(3  downto 0) := (others => '0');
signal RXCHARISvalid_u_sr       : std_logic_vector(3  downto 0) := (others => '0');                              
signal sr_u_symbol_type         : std_logic_vector(1  downto 0) := (others => '0');
 
signal sr_l_symbol_not_idle     : std_logic:= '0'; 
signal sr_l_symbol_not_idle_q   : std_logic:= '0'; 
signal sr_l_symbol_not_error    : std_logic:= '0'; 
signal sr_l_symbol_not_error_q  : std_logic:= '0'; 
signal RXDATA_sr_l              : std_logic_vector(31 downto 0) := (others => '0'); 
signal RXCHARISK_sr_l           : std_logic_vector(3  downto 0) := (others => '0');
signal RXCHARISvalid_sr_l       : std_logic_vector(3  downto 0) := (others => '0');                              
signal sr_l_symbol_type         : std_logic_vector(1  downto 0) := (others => '0');
 
 
signal started_once           : std_logic:= '0'; 
signal word_switch            : std_logic:= '0';
signal shift_cntr             : std_logic_vector(1  downto 0) := (others => '0');
 
 
----------------------------------------------------------------------------------
begin  
rst                  <= not(rst_n);
 
rx_boundary_fifo : pcs_rx_boudary_32b_out_64b_in   -- FWFT FIFO
  PORT MAP (
    rst            => rst,    
    rd_clk         => rio_clk,
    rd_en          => inboundRead_i,
    dout           => inboundSymbol_o,
    valid          => inboundValid,
    empty          => inboundEmpty_o,
    almost_empty   => rx_fifo_almost_empty,
 
    wr_clk         => UCLK_or_DV4,
    wr_en          => rx_fifo_wr_en_q,      -- rx_fifo_wr_en,        -- rx_fifo_wr_en_q,         --
    din            => rx_fifo_data_in_q,    -- rx_fifo_data_in,      -- rx_fifo_data_in_q,       --
    full           => rx_fifo_full,         -- rx_fifo_full    
    almost_full    => rx_fifo_almost_full   -- rx_fifo_full    
  ); 
 
-- Pipelining RX write
process(UCLK_or_DV4)  
    begin  
    if rising_edge(UCLK_or_DV4) then            
        rx_fifo_wr_en_q   <= rx_fifo_wr_en; 
        rx_fifo_data_in_q <= rx_fifo_data_in;        
    end if;
end process;  
 
 
-- rx_fifo_data_swapped <= rx_fifo_data_in(33 downto 32) 
--                         & rx_fifo_data_in(7 downto 0) & rx_fifo_data_in(15 downto 8) & rx_fifo_data_in(23 downto 16) & rx_fifo_data_in(31 downto 24); 
 
port_initalized  <= port_initalized_i; 
mode_sel         <= mode_sel_i;         
mode_0_lane_sel  <= mode_0_lane_sel_i;  
 
port_state <= port_initalized & mode_sel & mode_0_lane_sel;
 
-- RX management / FIFO write process  
process(rst_n, UCLK)  -- _x2
    begin      
    if rst_n = '0'  then                
 
        rx_fifo_wr_en    <= '0';
        word_switch      <= '0';
        started_once     <= '0';
        rx_fifo_data_in  <= (others => '0');    
        -- RXDATA_sr        <= (others => '0');    
        -- RXCHARISK_sr     <= (others => '1');    
        -- RXCHARISvalid_sr <= (others => '0');
        shift_cntr       <= (others => '0');
 
    elsif rising_edge(UCLK) then   
        -- Alternative If-Else Statement 
        if port_initalized = '0' then   -- Port has not been initialized yet
            rx_fifo_wr_en   <= '0';
            rx_fifo_data_in <= (others => '0');            
        else                            -- Port has been initialized            
            -- if mode_sel = '1' then      -- x4 mode is active
                if upper_symbol_valid = '1' and lower_symbol_valid = '1' then
                    rx_fifo_data_in <= upper_symbol_type & RXDATA_u & lower_symbol_type & RXDATA_l;                        
                    rx_fifo_wr_en   <= not(rx_fifo_almost_full);
                elsif upper_symbol_valid = '1' then
                    rx_fifo_data_in <= upper_symbol_type & RXDATA_u & SYMBOL_IDLE & x"00000000";                        
                    rx_fifo_wr_en   <= not(rx_fifo_almost_full);       
                elsif lower_symbol_valid = '1' then
                    rx_fifo_data_in <= SYMBOL_IDLE & x"00000000" & lower_symbol_type & RXDATA_l;                        
                    rx_fifo_wr_en   <= not(rx_fifo_almost_full);
                else                  
                    rx_fifo_wr_en   <= '0';                    
                end if;  
            -- else -- x1 fallback mode is active    
            --     if upper_symbol_valid = '1' and lower_symbol_valid = '1' then
            --         rx_fifo_data_in <= upper_symbol_type & RXDATA_u & lower_symbol_type & RXDATA_l;                        
            --         rx_fifo_wr_en   <= not(rx_fifo_full);
            --     elsif upper_symbol_valid = '1' then
            --         rx_fifo_data_in <= upper_symbol_type & RXDATA_u & SYMBOL_IDLE & RXDATA_l;                        
            --         rx_fifo_wr_en   <= not(rx_fifo_full);       
            --     elsif lower_symbol_valid = '1' then
            --         rx_fifo_data_in <= SYMBOL_IDLE & RXDATA_u & lower_symbol_type & RXDATA_l;                        
            --         rx_fifo_wr_en   <= not(rx_fifo_full);
            --     else                  
            --         rx_fifo_wr_en   <= '0';                    
            --     end if;                  
            -- end if;        
        end if;
    end if;
end process;  
-------------------------------------------------------------------------------------------------------------------------------------------------------
 
-- -- Pipelining RX stream
-- process(UCLK)  
--     begin  
--     if rising_edge(UCLK) then   
--         RXDATA_swap         <= RXDATA_i(15 downto 0)   & RXDATA_i(31 downto 16)  & RXDATA_i(47 downto 32)  & RXDATA_i(63 downto 48);
--         RXCHARISK_swap      <= RXCHARISK_i(1 downto 0) & RXCHARISK_i(3 downto 2) & RXCHARISK_i(5 downto 4) & RXCHARISK_i(7 downto 6);
--         RXCHARISvalid_swap  <= RXCHARISvalid_i(1 downto 0) & RXCHARISvalid_i(3 downto 2) & RXCHARISvalid_i(5 downto 4) & RXCHARISvalid_i(7 downto 6);
--     end if;
-- end process;  
 
-- Pipelining RX stream
process(UCLK)  
    begin  
    if rising_edge(UCLK) then   
 
        RXDATA_swap         <= RXDATA_i(15 downto 0)   & RXDATA_i(31 downto 16)  & RXDATA_i(47 downto 32)  & RXDATA_i(63 downto 48);
        RXCHARISK_swap      <= RXCHARISK_i(1 downto 0) & RXCHARISK_i(3 downto 2) & RXCHARISK_i(5 downto 4) & RXCHARISK_i(7 downto 6);
        RXCHARISvalid_swap  <= RXCHARISvalid_i(1 downto 0) & RXCHARISvalid_i(3 downto 2) & RXCHARISvalid_i(5 downto 4) & RXCHARISvalid_i(7 downto 6);        
 
        -- if mode_sel = '1' then      -- x4 mode is active               
 
        -- else                        -- x1 fallback mode is active  
        --     
        --     RXDATA_swap         <= RXDATA_sr_done        ;
        --     RXCHARISK_swap      <= RXCHARISK_sr_done     ;
        --     RXCHARISvalid_swap  <= RXCHARISvalid_sr_done ;
        --     
        -- end if;  
    end if;
end process;  
---                      Lane 0 active                                                  Lane 2 active
RXDATA_R_lane         <= RXDATA_i(15 downto 0)          when mode_0_lane_sel = '0' else RXDATA_i(47 downto 32)       ;  
RXCHARISK_R_lane      <= RXCHARISK_i(1 downto 0)        when mode_0_lane_sel = '0' else RXCHARISK_i(5 downto 4)      ;
RXCHARISvalid_R_lane  <= RXCHARISvalid_i(1 downto 0)    when mode_0_lane_sel = '0' else RXCHARISvalid_i(5 downto 4)  ; 
 
-- RXDATA shifting process for x1 mode
process(UCLK)  -- _x2  rst_n, 
    begin      
    -- if rst_n = '0'  then                
    -- 
    --     RXDATA_sr              <= (others => '0');    
    --     RXCHARISK_sr           <= (others => '1');    
    --     RXCHARISvalid_sr       <= (others => '0');
    --     valid_byte_cntr        <= (others => '0');
    --     
    --     RXDATA_sr_done         <= (others => '0');
    --     RXCHARISK_sr_done      <= (others => '1');
    --     RXCHARISvalid_sr_done  <= (others => '0');
    --     
    --     done_cntr              <= (others => '0');
    --     rx_done                <= '0';
    --     
    -- els
    if rising_edge(UCLK) then           
 
        if port_initalized = '0' then   -- Port has not been initialized yet
 
            RXDATA_sr              <= (others => '0');    
            RXCHARISK_sr           <= (others => '1');    
            RXCHARISvalid_sr       <= (others => '0');
            valid_byte_cntr        <= (others => '0');
 
            RXDATA_sr_done         <= (others => '0');
            RXCHARISK_sr_done      <= (others => '1');
            RXCHARISvalid_sr_done  <= (others => '0');
 
            done_cntr              <= (others => '0');
            rx_done                <= '0';
 
        else               
            done_cntr <= done_cntr + rx_done;            
            if RXCHARISvalid_R_lane(0) = '1' and (RXCHARISK_R_lane(0) = '0' or (RXCHARISK_R_lane(0) = '1' and (RXDATA_R_lane(7 downto 0) = SC or RXDATA_R_lane(7 downto 0) = PD))) then
                if RXCHARISvalid_R_lane(1) = '1' and (RXCHARISK_R_lane(1) = '0' or (RXCHARISK_R_lane(1) = '1' and (RXDATA_R_lane(15 downto 8) = SC or RXDATA_R_lane(15 downto 8) = PD))) then
                --- [VVVV] It may appear anytime
                    valid_byte_cntr    <= valid_byte_cntr + "10";                    
                    RXDATA_sr          <= RXDATA_sr(55 downto 0)   & RXDATA_R_lane(15 downto 0);
                    RXCHARISK_sr       <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1 downto 0);       
                    RXCHARISvalid_sr   <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1 downto 0);  
                    if valid_byte_cntr = "110" then
                        irregular_stream        <= '0';
                        rx_done                 <= '1';
                        done_cntr               <= (others => '0');
                        RXDATA_sr_done          <= RXDATA_sr(47 downto 0)   & RXDATA_R_lane(15 downto 0);
                        RXCHARISK_sr_done       <= RXCHARISK_sr(5 downto 0) & RXCHARISK_R_lane(1 downto 0);       
                        RXCHARISvalid_sr_done   <= RXCHARISvalid_sr(5 downto 0) & RXCHARISvalid_R_lane(1 downto 0);                    
                    elsif valid_byte_cntr = "111" then
                        irregular_stream        <= '1';
                        rx_done                 <= '1';
                        done_cntr               <= (others => '0');
                        RXDATA_sr_done          <= RXDATA_sr(55 downto 0)   & RXDATA_R_lane(15 downto 8);
                        RXCHARISK_sr_done       <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1);       
                        RXCHARISvalid_sr_done   <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1);  
                    elsif done_cntr = "11" then   
                        rx_done                 <= '0';                 
                        RXCHARISK_sr_done       <= (others => '1');
                        RXCHARISvalid_sr_done   <= (others => '0');
                    end if;         
                else
                --- [__VV] : It can appear only in the beginning                
                    if valid_byte_cntr = "100" then
                        valid_byte_cntr    <= valid_byte_cntr + '1';    
                    else -- either it is an irregular start or something went wrong
                        valid_byte_cntr    <= "001";
                        irregular_stream   <= '1';
                    end if;
                    RXDATA_sr          <= RXDATA_sr(63 downto 0)   & RXDATA_R_lane(7 downto 0);
                    RXCHARISK_sr       <= RXCHARISK_sr(7 downto 0) & RXCHARISK_R_lane(0);       
                    RXCHARISvalid_sr   <= RXCHARISvalid_sr(7 downto 0) & RXCHARISvalid_R_lane(0);  
                    if done_cntr = "11" then         
                        rx_done                 <= '0';           
                        RXCHARISK_sr_done       <= (others => '1');
                        RXCHARISvalid_sr_done   <= (others => '0');
                    end if; 
                end if;
            else
                if RXCHARISvalid_R_lane(1) = '1' and (RXCHARISK_R_lane(1) = '0' or (RXCHARISK_R_lane(1) = '1' and (RXDATA_R_lane(15 downto 8) = SC or RXDATA_R_lane(15 downto 8) = PD))) then
                --- [VV__] : It can appear only in the end               
                    RXDATA_sr          <= RXDATA_sr(63 downto 0)   & RXDATA_R_lane(15 downto 8);
                    RXCHARISK_sr       <= RXCHARISK_sr(7 downto 0) & RXCHARISK_R_lane(1);       
                    RXCHARISvalid_sr   <= RXCHARISvalid_sr(7 downto 0) & RXCHARISvalid_R_lane(1);   
                    if valid_byte_cntr = "011" then
                        valid_byte_cntr    <= valid_byte_cntr + '1';        
                        irregular_stream   <= '0'; -- irregularity has been compensated for the first symbol
                        if done_cntr = "11" then         
                            rx_done                 <= '0';           
                            RXCHARISK_sr_done       <= (others => '1');
                            RXCHARISvalid_sr_done   <= (others => '0');
                        end if;                     
                    elsif valid_byte_cntr = "111" then -- 2 symbols (2x32b) are done
                        valid_byte_cntr         <= (others => '0');
                        irregular_stream        <= '0'; -- irregularity has been compensated for the second symbol
                        rx_done                 <= '1';
                        done_cntr               <= (others => '0');
                        RXDATA_sr_done          <= RXDATA_sr(55 downto 0)   & RXDATA_R_lane(15 downto 8);
                        RXCHARISK_sr_done       <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1);       
                        RXCHARISvalid_sr_done   <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1);  
                    else -- something went wrong
                        valid_byte_cntr    <= (others => '0');
                        irregular_stream   <= '0';           
                        if done_cntr = "11" then         
                            rx_done                 <= '0';           
                            RXCHARISK_sr_done       <= (others => '1');
                            RXCHARISvalid_sr_done   <= (others => '0');
                        end if; 
                    end if; 
                else
                --- [____]
                    if valid_byte_cntr /= "100" then  -- No IDLE allowed, unless between two symbols: Something went wrong probably
                        valid_byte_cntr    <= "000";
                        irregular_stream   <= '0';
                    end if;
                    if done_cntr = "11" then         
                        rx_done                 <= '0';           
                        RXCHARISK_sr_done       <= (others => '1');
                        RXCHARISvalid_sr_done   <= (others => '0');
                    end if;            
                end if;
            end if;    
        end if;    
    end if;    
end process;  
 
RXDATA_u           <= RXDATA_swap(63 downto 56) & RXDATA_swap(47 downto 40) & RXDATA_swap(31 downto 24) & RXDATA_swap(15 downto  8) when mode_sel = '1' else -- x4 mode 
                      RXDATA_sr_done(63 downto 32);                                                                                                          -- x1 mode 
RXCHARISK_u        <= RXCHARISK_swap(7) & RXCHARISK_swap(5) & RXCHARISK_swap(3) & RXCHARISK_swap(1) when mode_sel = '1' else                                 -- x4 mode 
                      RXCHARISK_sr_done(7 downto 4);                                                                                                         -- x1 mode                     
RXCHARISvalid_u    <= RXCHARISvalid_swap(7) & RXCHARISvalid_swap(5) & RXCHARISvalid_swap(3) & RXCHARISvalid_swap(1) when mode_sel = '1' else                 -- x4 mode 
                      RXCHARISvalid_sr_done(7 downto 4);                                                                                                     -- x1 mode 
RXDATA_l           <= RXDATA_swap(55 downto 48) & RXDATA_swap(39 downto 32) & RXDATA_swap(23 downto 16) & RXDATA_swap(7 downto  0) when mode_sel = '1' else  -- x4 mode 
                      RXDATA_sr_done(31 downto 0);                                                                                                           -- x1 mode 
RXCHARISK_l        <= RXCHARISK_swap(6) & RXCHARISK_swap(4) & RXCHARISK_swap(2) & RXCHARISK_swap(0) when mode_sel = '1' else                                 -- x4 mode 
                      RXCHARISK_sr_done(3 downto 0);                                                                                                         -- x1 mode
RXCHARISvalid_l    <= RXCHARISvalid_swap(6) & RXCHARISvalid_swap(4) & RXCHARISvalid_swap(2) & RXCHARISvalid_swap(0) when mode_sel = '1' else                 -- x4 mode 
                      RXCHARISvalid_sr_done(3 downto 0);                                                                                                     -- x1 mode 
 
-- RXDATA_u           <= RXDATA_swap(63 downto 56) & RXDATA_swap(47 downto 40) & RXDATA_swap(31 downto 24) & RXDATA_swap(15 downto  8);
-- RXCHARISK_u        <= RXCHARISK_swap(7) & RXCHARISK_swap(5) & RXCHARISK_swap(3) & RXCHARISK_swap(1);
-- RXDATA_l           <= RXDATA_swap(55 downto 48) & RXDATA_swap(39 downto 32) & RXDATA_swap(23 downto 16) & RXDATA_swap(7 downto  0);
-- RXCHARISK_l        <= RXCHARISK_swap(6) & RXCHARISK_swap(4) & RXCHARISK_swap(2) & RXCHARISK_swap(0);                   
-- RXCHARISvalid_u    <= RXCHARISvalid_swap(7) & RXCHARISvalid_swap(5) & RXCHARISvalid_swap(3) & RXCHARISvalid_swap(1);
-- RXCHARISvalid_l    <= RXCHARISvalid_swap(6) & RXCHARISvalid_swap(4) & RXCHARISvalid_swap(2) & RXCHARISvalid_swap(0);
 
upper_symbol_type  <= SYMBOL_IDLE       when RXCHARISK_u = "1111" and RXCHARISvalid_u = "1111" else  
                      SYMBOL_CONTROL    when RXCHARISK_u = "1000" and RXCHARISvalid_u = "1111" and (RXDATA_u(31 downto 24) = SC or RXDATA_u(31 downto 24) = PD) else    
                      SYMBOL_DATA       when RXCHARISK_u = "0000" and RXCHARISvalid_u = "1111" else    
                      SYMBOL_ERROR;
 
lower_symbol_type  <= SYMBOL_IDLE       when RXCHARISK_l = "1111" and RXCHARISvalid_l = "1111" else  
                      SYMBOL_CONTROL    when RXCHARISK_l = "1000" and RXCHARISvalid_l = "1111" and (RXDATA_l(31 downto 24) = SC or RXDATA_l(31 downto 24) = PD) else    
                      SYMBOL_DATA       when RXCHARISK_l = "0000" and RXCHARISvalid_l = "1111" else    
                      SYMBOL_ERROR;
 
-- 
upper_symbol_not_idle   <= '0' when upper_symbol_type = SYMBOL_IDLE  else '1';                   
lower_symbol_not_idle   <= '0' when lower_symbol_type = SYMBOL_IDLE  else '1'; 
upper_symbol_not_error  <= '0' when upper_symbol_type = SYMBOL_ERROR else '1';                   
lower_symbol_not_error  <= '0' when lower_symbol_type = SYMBOL_ERROR else '1'; 
 
upper_symbol_valid      <= upper_symbol_not_idle and upper_symbol_not_error;
lower_symbol_valid      <= lower_symbol_not_idle and lower_symbol_not_error;
 
 
end RTL;
---------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--
-- File name:    pcs_tx_controller.vhd
-- Rev:          0.0
-- Description:  This entity controls the TX stream 
--               
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use work.rio_common.all;
 
entity pcs_tx_controller is
  generic (
    TCQ         : time      := 100 ps
  );
  port ( 
    rst_n                   : in  std_logic;
    rio_clk                 : in  std_logic;  -- ~150 MHz
    UCLK_x2                 : in  std_logic;  --  312,5 MHz
    UCLK                    : in  std_logic;  --  156,25 MHz 
    UCLK_x2_DV2             : in  std_logic;  --  312,5 MHz @ x4 mode / 78,125 @ x1 (fallback mode) 
    UCLK_or_DV4             : in  std_logic;  --  156,25 MHz @ x4 mode / 39,0625 @ x1 (fallback mode)
    --
    -- Interface to the RioSerial
    outboundWrite_i         : in  std_logic;
    outboundFull_o          : out std_logic;
    outboundSymbol_i        : in  std_logic_vector(33 downto 0);
    -- outboundSymbolEmpty_i   : in  std_logic;
    -- outboundSymbolRead_o    : out std_logic;
    -- outboundSymbol_i        : in  std_logic_vector(33 downto 0);
    --
    -- Interface to the GTX transceivers
    TXDATA_o                : out std_logic_vector(63 downto 0);  -- N = 4
    TXCHARISK_o             : out std_logic_vector(7 downto 0);
    --
    -- Interface to the other blocks
    send_ccs_i              : in  std_logic;    
    ccs_timer_rst_o         : out std_logic;    
    send_idle_o             : out std_logic_vector(1 downto 0);    
    send_K_i                : in  std_logic_vector(1 downto 0);    
    send_A_i                : in  std_logic_vector(1 downto 0);    
    send_R_i                : in  std_logic_vector(1 downto 0);
    --
    -- Interface to the port init
    TXINHIBIT_02            : in  std_logic;
    TXINHIBIT_others        : in  std_logic;
    port_initalized_i       : in  std_logic;
    mode_sel_i              : in  std_logic;
    mode_0_lane_sel_i       : in  std_logic
 
  );
end pcs_tx_controller;
 
architecture RTL of pcs_tx_controller is
 
-------------------------------------------------------------------------------
COMPONENT pcs_tx_boudary_32b_in_64b_out
    PORT (
    rst          : IN STD_LOGIC;
    wr_clk       : IN STD_LOGIC;
    rd_clk       : IN STD_LOGIC;
    din          : IN STD_LOGIC_VECTOR(33 DOWNTO 0);
    wr_en        : IN STD_LOGIC;
    rd_en        : IN STD_LOGIC;
    dout         : OUT STD_LOGIC_VECTOR(67 DOWNTO 0);
    full         : OUT STD_LOGIC;
    empty        : OUT STD_LOGIC;
    almost_empty : out STD_LOGIC; 
    almost_full  : out STD_LOGIC;
    valid        : OUT STD_LOGIC
  );
END COMPONENT;
-------------------------------------------------------------------------------
-- COMPONENT pcs_tx_boudary_32b_v2
--     PORT (
--     rst            : IN STD_LOGIC;
--     wr_clk         : IN STD_LOGIC;
--     rd_clk         : IN STD_LOGIC;
--     din            : IN STD_LOGIC_VECTOR(33 DOWNTO 0);
--     wr_en          : IN STD_LOGIC;
--     rd_en          : IN STD_LOGIC;
--     dout           : OUT STD_LOGIC_VECTOR(33 DOWNTO 0);
--     full           : OUT STD_LOGIC;
--     empty          : OUT STD_LOGIC;
--     almost_empty   : OUT STD_LOGIC;
--     valid          : OUT STD_LOGIC
--   );
-- END COMPONENT;
-------------------------------------------------------------------------------
signal rst                  : std_logic:= '0';
signal fragment_counter     : std_logic_vector(9 downto 0)  := (others => '0');
signal outboundSymbolType   : std_logic_vector(1 downto 0)  := (others => '0');
signal outboundSymbol       : std_logic_vector(33 downto 0) := (others => '0');
signal outboundSymbolRead   : std_logic:= '0';
signal non_idle             : std_logic:= '0';
signal decrement_frag_cntr  : std_logic:= '0';
 
signal tx_fifo_full         : std_logic:= '0';
signal symbol_empty         : std_logic:= '0';
signal symbol_almost_empty  : std_logic:= '0';
signal symbol_read          : std_logic:= '0';
signal symbol_valid         : std_logic:= '0';
-- signal symbol               : std_logic_vector(33 downto 0) := (others => '0');
signal symbol               : std_logic_vector(67 downto 0) := (others => '0');
signal symbol_u             : std_logic_vector(33 downto 0) := (others => '0');
signal symbol_l             : std_logic_vector(33 downto 0) := (others => '0');
-- signal symbol_type          : std_logic_vector(1  downto 0) := (others => '0');
signal symbol_type          : std_logic_vector(3  downto 0) := (others => '0');
signal symbol_type_u        : std_logic_vector(1  downto 0) := (others => '0');
signal symbol_type_l        : std_logic_vector(1  downto 0) := (others => '0');
 
signal TXDATA               : std_logic_vector(63 downto 0);  -- N = 4
signal TXCHARISK            : std_logic_vector(7 downto 0);
signal TXDATA_u             : std_logic_vector(31 downto 0); 
signal TXCHARISK_u          : std_logic_vector(3 downto 0);
signal TXDATA_l             : std_logic_vector(31 downto 0); 
signal TXCHARISK_l          : std_logic_vector(3 downto 0);
 
signal TXDATA_u_idle        : std_logic_vector(31 downto 0); 
signal TXDATA_l_idle        : std_logic_vector(31 downto 0); 
 
signal word_switch          : std_logic:= '0';
signal lane_switch          : std_logic_vector(1  downto 0) := (others => '0');
signal cycle_switch         : std_logic_vector(1  downto 0) := (others => '0');
signal read_switch          : std_logic_vector(1  downto 0) := (others => '0');
 
signal send_idle_q          : std_logic:= '0';
signal send_idle_reg        : std_logic_vector(1 downto 0)  := (others => '0');
signal send_idle            : std_logic_vector(1 downto 0)  := (others => '0');
signal idle_char_type_0     : std_logic_vector(2  downto 0) := (others => '0');
signal idle_char_type_1     : std_logic_vector(2  downto 0) := (others => '0');
 
signal send_ccs_cntr        : std_logic_vector(1  downto 0) := (others => '0');
signal send_K               : std_logic_vector(1 downto 0)  := (others => '0');
signal send_A               : std_logic_vector(1 downto 0)  := (others => '0');
signal send_R               : std_logic_vector(1 downto 0)  := (others => '0');
signal send_ccs             : std_logic:= '0';
signal send_ccs_q           : std_logic:= '0';
signal do_not_interrupt     : std_logic:= '0';
 
signal be_silent              : std_logic:= '0';
signal fifo_wr_selective      : std_logic:= '0';
signal fifo_wr_selective_q    : std_logic:= '0';
signal fifo_wr_always_even    : std_logic:= '0';
signal fifo_wr_odd_or_even    : std_logic:= '0';
signal fifo_wr_evenly         : std_logic:= '0';
signal outboundSymbolisData   : std_logic:= '0';
signal outboundSymbolisData_q : std_logic:= '0';
 
signal outboundSymbol_q       : std_logic_vector(33 downto 0) := (others => '0');
signal fifo_wr_evenly_q       : std_logic:= '0';
-- signal send_K_ccs           : std_logic:= '0';
-- signal send_R_ccs           : std_logic:= '0';
-- signal send_K_q             : std_logic:= '0';
-- signal send_A_q             : std_logic:= '0';
-- signal send_R_q             : std_logic:= '0';
----------------------------------------------------------------------------------
begin
-- 
rst                  <= not(rst_n);
 
outboundSymbolType  <= outboundSymbol_i(33 downto 32);
-- Filtering the ERROR symbol out
outboundSymbol      <= outboundSymbol_i when (outboundSymbolType = SYMBOL_DATA or outboundSymbolType = SYMBOL_CONTROL) else 
                       SYMBOL_IDLE & outboundSymbol_i(31 downto 0);    
 
fifo_wr_selective   <= outboundWrite_i when (outboundSymbolType = SYMBOL_DATA or outboundSymbolType = SYMBOL_CONTROL) else '0';
 
fifo_wr_always_even <= fifo_wr_selective or (fifo_wr_selective_q and fifo_wr_odd_or_even);
 
outboundSymbolisData <= '1' when outboundSymbolType = SYMBOL_DATA else '0';
 
fifo_wr_evenly  <= fifo_wr_selective or (fifo_wr_selective_q and fifo_wr_odd_or_even and not(outboundSymbolisData_q));
 
-- Writing to the FIFO
process(rio_clk)
    begin    
    if rising_edge(rio_clk) then 
        fifo_wr_selective_q     <= fifo_wr_selective;
        outboundSymbolisData_q  <= outboundSymbolisData;
        if fifo_wr_selective    = '1' then
            fifo_wr_odd_or_even <= not(fifo_wr_odd_or_even);
        elsif fifo_wr_selective_q = '1' then
            fifo_wr_odd_or_even <= fifo_wr_odd_or_even and outboundSymbolisData_q; -- '0';
        end if;        
 
        outboundSymbol_q <= outboundSymbol;
        fifo_wr_evenly_q <= fifo_wr_evenly;
    end if;
end process;
 
send_K <= send_K_i;  
send_A <= send_A_i;         
send_R <= send_R_i;  
 
-- idle_char_type  <= send_K & send_A & send_R;
idle_char_type_0  <= send_K(0) & send_A(0) & send_R(0);
idle_char_type_1  <= send_K(1) & send_A(1) & send_R(1);
 
be_silent   <= '1' when TXINHIBIT_02 = '1' and TXINHIBIT_others = '1' else '0';
 
-- symbol_type <= symbol(33 downto 32);  
symbol_type_u <= symbol_u(33 downto 32);  
symbol_type_l <= symbol_l(33 downto 32);  
 
symbol_u      <= symbol(67 downto 34);  
symbol_l      <= symbol(33 downto 0);  
 
send_idle(1)   <= '1'  when (send_ccs = '0')  and 
                         ((symbol_read = '1' and symbol_type_u = SYMBOL_IDLE) or 
                          (symbol_read = '0') or 
                          (port_initalized_i = '0')) 
                        else 
                  '0';                
 
send_idle(0)   <= '1'  when (send_ccs = '0')  and 
                         ((symbol_read = '1' and symbol_type_l = SYMBOL_IDLE) or 
                          (symbol_read = '0') or 
                          (port_initalized_i = '0')) 
                       else 
                  '0'; 
 
send_idle_o <= send_idle; -- _reg; 
 
-- symbol_read <= not(symbol_empty) and not(send_ccs) and not(send_ccs_q);
 
-- Pipelining
process(UCLK) -- _x2
    begin    
    if rising_edge(UCLK) then 
        send_ccs        <= not(do_not_interrupt) and send_ccs_i;  -- will be high only during real CCS transmission 
        -- send_idle_reg   <= send_idle;        
    end if;
end process;
 
-- Reading from the FIFO
process(UCLK_or_DV4) -- UCLK_x2_DV2
    begin    
    if rising_edge(UCLK_or_DV4) then 
      --   case symbol_read is
      --       when '0' => 
      --           symbol_read <= not(symbol_empty) and not(send_ccs) and not(send_ccs_q); -- after TCQ;                
      --       when '1' => 
      --           symbol_read <= not(symbol_almost_empty); -- after TCQ; -- and not(send_ccs) and not(send_ccs_q);                
      --       when others => 
      --           symbol_read <= '0'; -- after TCQ;
      --   end case;        
 
    end if;
end process;
 
tx_boundary_fifo : pcs_tx_boudary_32b_in_64b_out   -- FWFT FIFO
  PORT MAP (
    rst             => rst,
 
    wr_clk          => rio_clk,
    wr_en           => fifo_wr_evenly_q, --fifo_wr_always_even, --outboundWrite_i,
    din             => outboundSymbol_q,
    full            => open, -- outboundFull_o,
    almost_full     => outboundFull_o,
 
    rd_clk          => UCLK_or_DV4,
    rd_en           => symbol_read,
    dout            => symbol,
    empty           => symbol_empty,
    almost_empty    => symbol_almost_empty,
    valid           => symbol_valid
  ); 
 
-- FIFO read / TX output process
process(rst_n, UCLK) -- UCLK_x2
    begin    
    if rst_n = '0'  then         
 
        ccs_timer_rst_o  <= '0'; 
        do_not_interrupt <= '0';
        TXDATA_u         <= (others => '0');
        TXCHARISK_u      <= (others => '0');
        TXDATA_l         <= (others => '0');
        TXCHARISK_l      <= (others => '0');    
        cycle_switch     <= (others => '0');   
        read_switch      <= (others => '0');   
        symbol_read      <= '0';
 
    elsif rising_edge(UCLK) then 
 
      if be_silent = '0' then -- Transmitters are NOT inhibitied
        if send_ccs = '1' or send_ccs_q = '1' then -- Transmitting the clock compensation sequence (ccs) = |K|,|R|,|R|,|R|
            symbol_read      <= '0';
            if send_ccs_q = '0' then
                TXDATA_u        <= K_column;
                TXCHARISK_u     <= (others => '1');
                TXDATA_l        <= R_column;
                TXCHARISK_l     <= (others => '1');              
                ccs_timer_rst_o <= '1';
            else
                TXDATA_u        <= R_column;
                TXCHARISK_u     <= (others => '1');
                TXDATA_l        <= R_column;
                TXCHARISK_l     <= (others => '1');                          
            end if;
        else  -- Transmitting the IDLE sequence or the CONTROL/DATA symbols 
 
            read_switch  <= read_switch + '1'; 
            if read_switch = "00" then
                case symbol_read is
                    when '0' => 
                        symbol_read         <= not(symbol_empty); -- and not(send_ccs) and not(send_ccs_q); -- after TCQ; 
                        do_not_interrupt    <= not(symbol_empty);               
                    when '1' => 
                        symbol_read         <= not(symbol_almost_empty); -- after TCQ; -- and not(send_ccs) and not(send_ccs_q);        
                        do_not_interrupt    <= not(symbol_almost_empty);                       
                    when others => 
                        symbol_read         <= '0'; -- after TCQ;
                        do_not_interrupt    <= '0'; 
                end case;  
            end if;
 
            ccs_timer_rst_o <= '0';                                   
            if symbol_read = '1' then -- two symbols have been read, at least one of them is non-idle, they should be forwarded in 1 or 4 cycles
                case mode_sel_i is
                    when '1' => -- Lane stripping (x4 mode: rd_clk = UCLK)     
                        case symbol_type_u is                
                            when SYMBOL_DATA =>      
                                TXDATA_u      <= symbol_u(31 downto 24) & symbol_u(23 downto 16) & symbol_u(15 downto 8) & symbol_u(7 downto 0);
                                TXCHARISK_u   <= (others => '0');                                 
                            when SYMBOL_CONTROL => 
                                TXDATA_u      <= symbol_u(31 downto 24) & symbol_u(23 downto 16) & symbol_u(15 downto 8) & symbol_u(7 downto 0);
                                TXCHARISK_u   <= "1000";                                        
                            when SYMBOL_IDLE =>     
                                TXDATA_u      <= TXDATA_u_idle;
                                TXCHARISK_u   <= (others => '1');                                 
                            when others =>   
                                -- dummy
                                TXDATA_u      <= TXDATA_u_idle;
                                TXCHARISK_u   <= (others => '1');   
                        end case;  
                        case symbol_type_l is                
                            when SYMBOL_DATA =>      
                                TXDATA_l      <= symbol_l(31 downto 24) & symbol_l(23 downto 16) & symbol_l(15 downto 8) & symbol_l(7 downto 0);
                                TXCHARISK_l   <= (others => '0');                                 
                            when SYMBOL_CONTROL => 
                                TXDATA_l      <= symbol_l(31 downto 24) & symbol_l(23 downto 16) & symbol_l(15 downto 8) & symbol_l(7 downto 0);
                                TXCHARISK_l   <= "1000";                                        
                            when SYMBOL_IDLE =>     
                                TXDATA_l      <= TXDATA_l_idle;
                                TXCHARISK_l   <= (others => '1');                                 
                            when others =>   
                                -- dummy
                                TXDATA_l      <= TXDATA_l_idle;
                                TXCHARISK_l   <= (others => '1');   
                        end case;                               
                    when '0' => -- Slow motion read (x1 mode: rd_clk = UCLK_DV4)
                        cycle_switch    <= cycle_switch + '1'; 
                        -- Cycle | Symbol part to be sent  
                        ---------|----------------------
                        --   00  | symbol_u(31 downto 16)
                        --   01  | symbol_u(15 downto 0)
                        --   10  | symbol_l(31 downto 16)
                        --   11  | symbol_l(15 downto 0)
                        case cycle_switch(1) is
                            when '0' =>
                                case cycle_switch(0) is
                                    when '0' => --   00 
                                        if symbol_type_u /= SYMBOL_IDLE then 
                                            TXDATA_u        <= symbol_u(31 downto 24) & symbol_u(31 downto 24) & symbol_u(31 downto 24) & symbol_u(31 downto 24);
                                            if symbol_type_u = SYMBOL_DATA then 
                                                TXCHARISK_u     <= (others => '0');
                                            else -- if symbol_type_u = SYMBOL_CONTROL then 
                                                TXCHARISK_u     <= (others => '1');
                                            end if;
                                            TXDATA_l        <= symbol_u(23 downto 16) & symbol_u(23 downto 16) & symbol_u(23 downto 16) & symbol_u(23 downto 16);
                                            TXCHARISK_l     <= (others => '0');  
                                        else -- if symbol_type_u = SYMBOL_IDLE then                                         
                                            TXDATA_u      <= TXDATA_u_idle;
                                            TXCHARISK_u   <= (others => '1');  
                                            TXDATA_l      <= TXDATA_l_idle;
                                            TXCHARISK_l   <= (others => '1');                                            
                                        end if;                                        
                                    when '1' => --   01  
                                        if symbol_type_u /= SYMBOL_IDLE then 
                                            TXDATA_u        <= symbol_u(15 downto 8) & symbol_u(15 downto 8) & symbol_u(15 downto 8) & symbol_u(15 downto 8);
                                            TXCHARISK_u     <= (others => '0'); -- This is the second part: does not matter control or data
                                            TXDATA_l        <= symbol_u(7 downto 0) & symbol_u(7 downto 0) & symbol_u(7 downto 0) & symbol_u(7 downto 0);
                                            TXCHARISK_l     <= (others => '0');  
                                        else -- if symbol_type_u = SYMBOL_IDLE then                                         
                                            TXDATA_u      <= TXDATA_u_idle;
                                            TXCHARISK_u   <= (others => '1');  
                                            TXDATA_l      <= TXDATA_l_idle;
                                            TXCHARISK_l   <= (others => '1');                                            
                                        end if;                                        
                                    when others =>   
                                    -- dummy
                                end case;                                  
                            when '1' =>
                                case cycle_switch(0) is
                                    when '0' =>
                                        if symbol_type_l /= SYMBOL_IDLE then 
                                            TXDATA_u        <= symbol_l(31 downto 24) & symbol_l(31 downto 24) & symbol_l(31 downto 24) & symbol_l(31 downto 24);
                                            if symbol_type_l = SYMBOL_DATA then 
                                                TXCHARISK_u     <= (others => '0');
                                            else -- if symbol_type_l = SYMBOL_CONTROL then 
                                                TXCHARISK_u     <= (others => '1');
                                            end if;
                                            TXDATA_l        <= symbol_l(23 downto 16) & symbol_l(23 downto 16) & symbol_l(23 downto 16) & symbol_l(23 downto 16);
                                            TXCHARISK_l     <= (others => '0');  
                                        else -- if symbol_type_l = SYMBOL_IDLE then                                         
                                            TXDATA_u      <= TXDATA_u_idle;
                                            TXCHARISK_u   <= (others => '1');  
                                            TXDATA_l      <= TXDATA_l_idle;
                                            TXCHARISK_l   <= (others => '1');                                            
                                        end if;                                        
                                    when '1' =>
                                        if symbol_type_l /= SYMBOL_IDLE then 
                                            TXDATA_u        <= symbol_l(15 downto 8) & symbol_l(15 downto 8) & symbol_l(15 downto 8) & symbol_l(15 downto 8);
                                            TXCHARISK_u     <= (others => '0'); -- This is the second part: does not matter control or data
                                            TXDATA_l        <= symbol_l(7 downto 0) & symbol_l(7 downto 0) & symbol_l(7 downto 0) & symbol_l(7 downto 0);
                                            TXCHARISK_l     <= (others => '0');  
                                        else -- if symbol_type_l = SYMBOL_IDLE then                                         
                                            TXDATA_u      <= TXDATA_u_idle;
                                            TXCHARISK_u   <= (others => '1');  
                                            TXDATA_l      <= TXDATA_l_idle;
                                            TXCHARISK_l   <= (others => '1');                                            
                                        end if;                                        
                                    when others =>   
                                    -- dummy
                                end case;                                                                  
                            when others =>   
                                -- dummy
                        end case;  
 
                    when others =>           
                        -- dummy
                end case;  
            -----------------------------------------------------------------------------
            else -- No Symbols are present at the FIFO output: Transmitting an idle sequence: |K| or |A| or |R|
                TXDATA_u         <= TXDATA_u_idle;
                TXCHARISK_u      <= (others => '1'); 
                TXDATA_l         <= TXDATA_l_idle;
                TXCHARISK_l      <= (others => '1');     
            end if;
        end if;  
      else -- Transmitters are inhibitied
        TXDATA_u         <= x"BCBCBCBC"    ;
        TXCHARISK_u      <= (others => '1');
        TXDATA_l         <= x"FDFDFDFD"    ;
        TXCHARISK_l      <= (others => '1');  
      end if;
    end if;
end process;
 
-- Combinational idle drive process
process(idle_char_type_0, idle_char_type_1)
    begin  
    case idle_char_type_1 is                 
        when "100" =>  -- |K| (~%50)
            TXDATA_u_idle      <= K_column;
 
        when "010" => -- |A| (1/16 .. 1/32)
            TXDATA_u_idle      <= A_column; 
 
        when "001" => -- |R| (~%50)
            TXDATA_u_idle      <= R_column;
 
        when others =>
            -- dummy
            TXDATA_u_idle      <= K_column;                         
    end case;                 
    case idle_char_type_0 is                 
        when "100" =>  -- |K| (~%50)
            TXDATA_l_idle      <= K_column;
 
        when "010" => -- |A| (1/16 .. 1/32)
            TXDATA_l_idle      <= A_column; 
 
        when "001" => -- |R| (~%50)
            TXDATA_l_idle      <= R_column;
 
        when others =>
            -- dummy
            TXDATA_l_idle      <= R_column;                           
    end case; 
end process; 
 
-- TXDATA buffering by UCLK
process(UCLK)
    begin    
    if rising_edge(UCLK) then     
        ------------------
        -- MUST BE SWAPPED
        TXDATA_o    <=   TXDATA_u( 7 downto  0) & TXDATA_l( 7 downto  0) & TXDATA_u(15 downto  8) & TXDATA_l(15 downto  8)
                       & TXDATA_u(23 downto 16) & TXDATA_l(23 downto 16) & TXDATA_u(31 downto 24) & TXDATA_l(31 downto 24);   
        TXCHARISK_o <= TXCHARISK_u(0) & TXCHARISK_l(0) & TXCHARISK_u(1) & TXCHARISK_l(1) & TXCHARISK_u(2) & TXCHARISK_l(2) & TXCHARISK_u(3) & TXCHARISK_l(3);
        ------------------
    end if;
end process; 
 
-- Delaying send_ccs  
process(UCLK)
    begin    
    if rising_edge(UCLK) then     
        if be_silent = '0' then 
            send_ccs_q <= send_ccs; ---  
        else 
            send_ccs_q <= '0';
        end if;
    end if;
end process; 
 
end RTL;
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--
-- File name:    port_init_fsms.vhd
-- Rev:          0.0
-- Description:  This entity does the 1x/Nx port init according to the 
--               RIO Sepec. Part-6, subchapter 4.2
-- 
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use work.rio_common.all;
--use work.rio_common_sim.all;
 
entity port_init_fsms is
  generic (
    TCQ         : time      := 100 ps
  );
  port ( 
    rst_n               : in  std_logic;
    UCLK_x2             : in  std_logic;
    UCLK                : in  std_logic;
    UCLK_DV4            : in  std_logic; 
    UCLK_DV_1024        : in  std_logic;   
 
    force_reinit        : in  std_logic:='0';   -- force retraining
    mode_sel            : out std_logic;        -- 0: x1 fallback mode / 1: xN Mode
    mode_0_lane_sel     : out std_logic;        -- If mode_sel = 0 then 0: Lane 0 is active(R), 1: Lane 2 is active else don't care
    port_initalized     : out std_logic;        -- 1: Port initialization is successfully complete
    lane_sync           : out std_logic_vector(N-1 downto 0); -- Lane is synchoronised
    RXCHARISvalid       : out std_logic_vector(N*2-1 downto 0);
 
    -- GTXRESET            : out std_logic;
    TXINHIBIT_02        : out std_logic;
    TXINHIBIT_others    : out std_logic;
    ENCHANSYNC          : out std_logic;
    -- TXDATA              : out std_logic_vector(N*16-1 downto 0);
    -- TXCHARISK           : out std_logic_vector(N*2-1 downto 0);
    PLLLKDET            : in  std_logic;
    RXDATA              : in  std_logic_vector(N*16-1 downto 0);
    RXCHARISK           : in  std_logic_vector(N*2-1 downto 0);
    RXCHARISCOMMA       : in  std_logic_vector(N*2-1 downto 0);
    RXBYTEISALIGNED     : in  std_logic_vector(N-1 downto 0);
    RXBYTEREALIGN       : in  std_logic_vector(N-1 downto 0);
    RXELECIDLE          : in  std_logic_vector(N-1 downto 0);
    RXDISPERR           : in  std_logic_vector(N*2-1 downto 0);
    RXNOTINTABLE        : in  std_logic_vector(N*2-1 downto 0);
    RXBUFERR            : in  std_logic;
    RXBUFRST            : out std_logic;
    CHBONDDONE          : in  std_logic_vector(N-1 downto 0)
  );
end port_init_fsms;
 
architecture rtl of port_init_fsms is
-------------------------------------------------------------------------------------------------------------------------------------------
-- Lane_Synchronization State Machine 
type lane_sync_states is (NO_SYNC, NO_SYNC_1, NO_SYNC_2, NO_SYNC_2a, NO_SYNC_2b, NO_SYNC_3, SYNC, SYNCa, SYNCb, SYNC_1, SYNC_2, SYNC_2a, SYNC_2b, SYNC_3, SYNC_4);
type lane_sync_states_array is array (N-1 downto 0) of lane_sync_states;
 
signal lane_sync_state_n : lane_sync_states_array           := (others => NO_SYNC);
signal lane_sync_n       : std_logic_vector(N-1 downto 0)   := (others => '0');
signal Kcounter_n        : Kcounter_array_type              := (others => (others => '0'));
signal Vcounter_n        : Vcounter_array_type              := (others => (others => '0'));
signal Icounter_n        : Icounter_array_type              := (others => (others => '0'));
signal code_group_valid  : std_logic_vector(N*2-1 downto 0) := (others => '0');
-------------------------------------------------------------------------------------------------------------------------------------------
-- Lane_Alignment State Machine
type lane_alignment_states is (NOT_ALIGNED, NOT_ALIGNED_1, NOT_ALIGNED_2, ALIGNED, ALIGNED_1, ALIGNED_2, ALIGNED_3);
 
signal lane_alignment_state : lane_alignment_states          := NOT_ALIGNED;
signal N_lanes_aligned      : std_logic                      := '0';
signal Acounter             : std_logic_vector(2 downto 0)   := (others => '0');
signal Mcounter             : Mcounter_type                  := (others => '0');
signal lane_alignment_reset : std_logic                      := '0';
signal N_lane_sync          : std_logic                      := '0';
constant N_lanes_all_high   : std_logic_vector(N-1 downto 0) := (others => '1');
constant N_lanes_all_low    : std_logic_vector(N-1 downto 0) := (others => '0');
 
signal A_column_valid       : std_logic := '0';
signal align_error          : std_logic := '0';
signal A_column_valid_upper : std_logic := '0';
signal align_error_upper    : std_logic := '0';
signal A_column_valid_lower : std_logic := '0';
signal align_error_lower    : std_logic := '0';
 
signal RXCHARIS_A_upper     : std_logic_vector(N-1 downto 0) := (others => '0');
signal RXCHARIS_A_lower     : std_logic_vector(N-1 downto 0) := (others => '0');
-------------------------------------------------------------------------------------------------------------------------------------------
-- begin --dummy   
-- 1x/Nx Mode Init State Machine
type mode_init_states is (SILENT, SEEK, DISCOVERY, x1_RECOVERY, Nx_MODE, x1_MODE_LANE0, x1_MODE_LANE2);
 
signal mode_init_state      : mode_init_states          := SILENT;
signal lanes02_drvr_oe      : std_logic := '0';
signal N_lanes_drvr_oe      : std_logic := '0';
signal Nx_mode_active       : std_logic := '0';
signal receive_lane2        : std_logic := '0';
signal force_reinit_reg     : std_logic := '0';
signal force_reinit_clear   : std_logic := '0';
 
signal silence_timer_en     : std_logic := '0';
signal silence_timer_done   : std_logic := '0';
signal silence_timer        : std_logic_vector(4 downto 0)   := (others => '0');
 
signal disc_tmr_en          : std_logic := '0';
signal disc_tmr_done        : std_logic := '0';
signal disc_tmr             : std_logic_vector(15 downto 0)   := (others => '0'); 
 
signal port_initalized_reg  : std_logic := '0';
 
signal idle_selected        : std_logic := '1'; -- Only IDLE1 is to be used
signal Nx_mode_enabled      : std_logic := '1'; -- Nx mode is to be always enabled
signal force_1x_mode        : std_logic := '0'; -- don't force 1x mode
signal force_laneR          : std_logic := '0'; -- don't care, when force_1x_mode = 0
 
signal lane_ready_n         : std_logic_vector(N-1 downto 0)   := (others => '0');
signal rcvr_trained_n       : std_logic_vector(N-1 downto 0)   := (others => '0');
signal N_lanes_ready        : std_logic := '0';
 
signal rxbufrst_cntr        : std_logic_vector(2 downto 0)   := (others => '0');
signal rxbuferr_reg         : std_logic := '0';
-------------------------------------------------------------------------------------------------------------------------------------------
begin
 
lane_sync <= lane_sync_n;
----------------------------------------------------------------
-- Figure 4-14. Lane_Synchronization State Machine for N Lanes
GEN_LANE_SYNC_FSM: for i in 0 to N-1 generate
 
code_group_valid(i*2)   <= not(RXNOTINTABLE(i*2)  ) and not(RXDISPERR(i*2)  );
code_group_valid(i*2+1) <= not(RXNOTINTABLE(i*2+1)) and not(RXDISPERR(i*2+1)); 
 
RXCHARISvalid(i*2)    <= code_group_valid(i*2)  ;
RXCHARISvalid(i*2+1)  <= code_group_valid(i*2+1);
 
process(rst_n, UCLK)  -- (UCLK_x2) -- 
    begin
 
    if rst_n = '0'  then
 
        lane_sync_state_n(i) <= NO_SYNC;
        lane_sync_n(i)       <= '0';      
        Kcounter_n(i)        <= (others => '0');       
        Vcounter_n(i)        <= (others => '0');    
 
    elsif rising_edge(UCLK) then
 
        case lane_sync_state_n(i) is
            when NO_SYNC => 
                -- change(signal_detect[n])
                if RXELECIDLE(i) = '1' then
                    lane_sync_n(i)       <= '0';      
                    Kcounter_n(i)        <= (others => '0');       
                    Vcounter_n(i)        <= (others => '0'); 
                -- signal_detect[n] & /COMMA/   [ KK-- ] : /K/ is being detected at the upper half
                elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then
                    -- signal_detect[n] & /COMMA/   [ --KK ] :  /K/ is being detected also at the lower half
                    if (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then                         
                        lane_sync_state_n(i) <= NO_SYNC_2;               
                        Kcounter_n(i)        <= Kcounter_n(i) + "10";       
                        Vcounter_n(i)        <= Vcounter_n(i) + "10";
                    -- signal_detect[n]         [ --VV ] :  At the lower half: no comma, but valid 
                    elsif (code_group_valid(i*2) = '1') then
                        lane_sync_state_n(i) <= NO_SYNC_2;               
                        Kcounter_n(i)        <= Kcounter_n(i) + '1';       
                        Vcounter_n(i)        <= Vcounter_n(i) + "10";   
                    -- do nothing                     
                    else
                        lane_sync_n(i)       <= '0';      
                        Kcounter_n(i)        <= (others => '0');       
                        Vcounter_n(i)        <= (others => '0');    
                    end if;           
                ----------------------------------------------------------------------------------------------    
                -- signal_detect[n] & /COMMA/   [ --KK ] :  /K/ is being detected only at the lower half
                elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then                     
                    lane_sync_state_n(i) <= NO_SYNC_2;               
                    Kcounter_n(i)        <= Kcounter_n(i) + '1';       
                    Vcounter_n(i)        <= Vcounter_n(i) + '1';                       
                ----------------------------------------------------------------------------------------------    
                -- !signal_detect[n] | !/COMMA/ 
                else
                    lane_sync_n(i)       <= '0';      
                    Kcounter_n(i)        <= (others => '0');       
                    Vcounter_n(i)        <= (others => '0');                     
                end if;
                -- -- change(signal_detect[n])
                -- if RXELECIDLE(i) = '1' then
                --     lane_sync_n(i)       <= '0';      
                --     Kcounter_n(i)        <= (others => '0');       
                --     Vcounter_n(i)        <= (others => '0'); 
                -- -- signal_detect[n] & /COMMA/   [ KK-- ] : /K/ is being detected at the upper half
                -- elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then
                --     lane_sync_state_n(i) <= NO_SYNC_2a;               
                --     Kcounter_n(i)        <= Kcounter_n(i) + '1';       
                --     Vcounter_n(i)        <= Vcounter_n(i) + '1';                    
                -- -- signal_detect[n] & /COMMA/   [ --KK ] :  /K/ is being detected at the lower half
                -- elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then 
                --     lane_sync_state_n(i) <= NO_SYNC_2b;               
                --     Kcounter_n(i)        <= Kcounter_n(i) + '1';       
                --     Vcounter_n(i)        <= Vcounter_n(i) + '1';                       
                -- -- !signal_detect[n] | !/COMMA/ 
                -- else
                --     lane_sync_n(i)       <= '0';      
                --     Kcounter_n(i)        <= (others => '0');       
                --     Vcounter_n(i)        <= (others => '0');                     
                -- end if;
 
            -- when NO_SYNC_1 =>           
 
            when NO_SYNC_2 =>         
                -- [ IIXX or XXII ] -- One of both /INVALID/  
                if (code_group_valid(i*2) = '0' or code_group_valid(i*2+1) = '0') then
                    lane_sync_state_n(i) <= NO_SYNC;                           
                    lane_sync_n(i)       <= '0';      
                    Kcounter_n(i)        <= (others => '0');       
                    Vcounter_n(i)        <= (others => '0'); 
                -- [ KKKK ]         -- Both /COMMA/  
                elsif (RXCHARISCOMMA(i*2) = '1' and RXCHARISCOMMA(i*2+1) = '1') then    
                    -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) 
                    if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then 
                        lane_sync_state_n(i) <= SYNC;                              
                    -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) 
                    else                                                
                        Kcounter_n(i)        <= Kcounter_n(i) + "10";       
                        Vcounter_n(i)        <= Vcounter_n(i) + "10";                               
                    end if;                                               
                -- [ KKVV or VVKK ] -- One of both /COMMA/  
                elsif (RXCHARISCOMMA(i*2) = '1' or RXCHARISCOMMA(i*2+1) = '1') then  
                    -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) 
                    if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then 
                        lane_sync_state_n(i) <= SYNC;                              
                    -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) 
                    else                                                
                        Kcounter_n(i)        <= Kcounter_n(i) + '1' ;       
                        Vcounter_n(i)        <= Vcounter_n(i) + "10";                               
                    end if;                            
 
                -- [ VVVV ]         -- None of both /COMMA/, but both /VALID/  
                else -- if RXCHARISCOMMA(i*2) = '0') and RXCHARISCOMMA(i*2+1) = '0') then    
                    -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) 
                    if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then 
                        lane_sync_state_n(i) <= SYNC;                              
                    -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) 
                    else                                                
                        Vcounter_n(i)        <= Vcounter_n(i) + "10";                               
                    end if;    
                end if;
 
            -- when NO_SYNC_2a =>             
            --     -- !(/COMMA/|/INVALID/)
            --     if (code_group_valid(i*2) = '1' and not(RXCHARISCOMMA(i*2) = '1')) then --RXCHARISK(i*2) = '1' and RXDATA(i*16+7 downto i*16) = x"BC")) then
            --         lane_sync_state_n(i) <= NO_SYNC_2b;                
            --         Vcounter_n(i)        <= Vcounter_n(i) + '1';                      
            --     -- /COMMA/  
            --     elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then --RXCHARISK(i*2) = '1' and RXDATA(i*16+7 downto i*16) = x"BC") then
            --         -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) 
            --         if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then 
            --             lane_sync_state_n(i) <= SYNCb;                              
            --         -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) 
            --         else                                  
            --             lane_sync_state_n(i) <= NO_SYNC_2b;               
            --             Kcounter_n(i)        <= Kcounter_n(i) + '1';       
            --             Vcounter_n(i)        <= Vcounter_n(i) + '1';                               
            --         end if;                           
            --     -- /INVALID/  
            --     elsif (code_group_valid(i*2) = '0') then
            --         lane_sync_state_n(i) <= NO_SYNC;                           
            --         lane_sync_n(i)       <= '0';      
            --         Kcounter_n(i)        <= (others => '0');       
            --         Vcounter_n(i)        <= (others => '0');                     
            --     end if;                
            -- 
            -- when NO_SYNC_2b =>              
            --     -- !(/COMMA/|/INVALID/)
            --     if (code_group_valid(i*2+1) = '1' and not(RXCHARISCOMMA(i*2+1) = '1')) then --RXCHARISK(i*2+1) = '1' and RXDATA(i*16+15 downto i*16+8) = x"BC")) then
            --         lane_sync_state_n(i) <= NO_SYNC_2a;                
            --         Vcounter_n(i)        <= Vcounter_n(i) + '1';                                          
            --     -- /COMMA/  
            --     elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then --RXCHARISK(i*2+1) = '1' and RXDATA(i*16+15 downto i*16+8) = x"BC") then
            --         -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1) 
            --         if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then 
            --             lane_sync_state_n(i) <= SYNCa;                              
            --         -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin) 
            --         else                                  
            --             lane_sync_state_n(i) <= NO_SYNC_2a;               
            --             Kcounter_n(i)        <= Kcounter_n(i) + '1';       
            --             Vcounter_n(i)        <= Vcounter_n(i) + '1';                               
            --         end if;                           
            --     -- /INVALID/  
            --     elsif (code_group_valid(i*2+1) = '0') then
            --         lane_sync_state_n(i) <= NO_SYNC;                           
            --         lane_sync_n(i)       <= '0';      
            --         Kcounter_n(i)        <= (others => '0');       
            --         Vcounter_n(i)        <= (others => '0');                       
            --     end if;
 
            -- when NO_SYNC_3 => 
 
            when SYNC =>                      
                -- Both /VALID/  
                if (code_group_valid(i*2) = '1' and code_group_valid(i*2+1) = '1') then                              
                    lane_sync_n(i)       <= '1';        
                    Icounter_n(i)        <= (others => '0');                      
                -- One of both /INVALID/  
                elsif (code_group_valid(i*2) = '1' or code_group_valid(i*2+1) = '1') then      
                    Icounter_n(i)        <= Icounter_n(i) + '1';                      
                    lane_sync_state_n(i) <= SYNC_2;                         
                -- Both /INVALID/        
                else 
                    Icounter_n(i)        <= Icounter_n(i) + "10";                      
                    lane_sync_state_n(i) <= SYNC_2;                                 
                end if;
            -- 
            -- when SYNCa =>                      
            --     -- /INVALID/  
            --     if (code_group_valid(i*2) = '0') then      
            --         Icounter_n(i)        <= Icounter_n(i) + '1';                      
            --         lane_sync_state_n(i) <= SYNC_2b;                         
            --     -- /VALID/      
            --     else 
            --         lane_sync_state_n(i) <= SYNCb;                           
            --         lane_sync_n(i)       <= '1';        
            --         Icounter_n(i)        <= (others => '0');                       
            --     end if;
            --     
            -- when SYNCb =>                      
            --     -- /INVALID/  
            --     if (code_group_valid(i*2+1) = '0') then
            --         Icounter_n(i)        <= Icounter_n(i) + '1';        
            --         lane_sync_state_n(i) <= SYNC_2a;     
            --     -- /VALID/    
            --     else 
            --         lane_sync_state_n(i) <= SYNCa;                              
            --         lane_sync_n(i)       <= '1';        
            --         Icounter_n(i)        <= (others => '0');                      
            --     end if;
 
            -- when SYNC_1 => 
 
            when SYNC_2 =>      
                -- Both /VALID/  
                if (code_group_valid(i*2) = '1' and code_group_valid(i*2+1) = '1') then        
                    Vcounter_n(i)  <= Vcounter_n(i) + "10";  
                    -- (Vcounter[n] < 255) 
                    if Vcounter_n(i) < x"FF" then
                        -- do nothing
                        lane_sync_state_n(i) <= SYNC_2;  
                    -- (Vcounter[n] = 255) 
                    else
                        Icounter_n(i)   <= Icounter_n(i) - '1';
                        Vcounter_n(i)   <= (others => '0'); 
                        -- (Icounter[n] > 0) 
                        if Icounter_n(i) > Ione then
                            -- do nothing
                            lane_sync_state_n(i) <= SYNC_2;  
                        -- (Icounter[n] = 0) 
                        else
                            lane_sync_state_n(i) <= SYNC;        
                        end if;  
                    end if;  
                -- One of both /INVALID/  
                elsif (code_group_valid(i*2) = '1' or code_group_valid(i*2+1) = '1') then      
                    Icounter_n(i)        <= Icounter_n(i) + '1';      
                    Vcounter_n(i)        <= (others => '0');                     
                    -- (Icounter[n] = Imax) 
                    if Icounter_n(i) = Imax then 
                        lane_sync_state_n(i) <= NO_SYNC;                           
                        lane_sync_n(i)       <= '0';      
                        Kcounter_n(i)        <= (others => '0');     
                    -- (Icounter[n] < Imax) 
                    else      
                        -- do nothing
                        lane_sync_state_n(i) <= SYNC_2;       
                    end if;                      
                -- Both /INVALID/        
                else 
                    Icounter_n(i)        <= Icounter_n(i) + "10";      
                    Vcounter_n(i)        <= (others => '0');                     
                    -- (Icounter[n] = Imax) 
                    if Icounter_n(i) = Imax then 
                        lane_sync_state_n(i) <= NO_SYNC;                           
                        lane_sync_n(i)       <= '0';      
                        Kcounter_n(i)        <= (others => '0');     
                    -- (Icounter[n] < Imax) 
                    else      
                        -- do nothing
                        lane_sync_state_n(i) <= SYNC_2;       
                    end if;                            
                end if;
                ----------------------------------------------
 
            -- when SYNC_2a =>                  
            --     -- /INVALID/  
            --     if (code_group_valid(i*2+1) = '0') then
            --         Icounter_n(i)        <= Icounter_n(i) + '1';      
            --         Vcounter_n(i)        <= (others => '0');                     
            --         -- (Icounter[n] = Imax) 
            --         if Icounter_n(i) = Imax then 
            --             lane_sync_state_n(i) <= NO_SYNC;                           
            --             lane_sync_n(i)       <= '0';      
            --             Kcounter_n(i)        <= (others => '0');     
            --         -- (Icounter[n] < Imax) 
            --         else      
            --             lane_sync_state_n(i) <= SYNC_2b;       
            --         end if;                             
            --     -- /VALID/    
            --     else     
            --         Vcounter_n(i)  <= Vcounter_n(i) + '1';  
            --         -- (Vcounter[n] < 255) 
            --         if Vcounter_n(i) < x"FF" then
            --             lane_sync_state_n(i) <= SYNC_2b;  
            --         -- (Vcounter[n] = 255) 
            --         else
            --             Icounter_n(i)   <= Icounter_n(i) - '1';
            --             Vcounter_n(i)   <= (others => '0'); 
            --             -- (Icounter[n] > 0) 
            --             if Icounter_n(i) > Izero then
            --                 lane_sync_state_n(i) <= SYNC_2b;  
            --             -- (Icounter[n] = 0) 
            --             else
            --                 lane_sync_state_n(i) <= SYNCb;        
            --             end if;  
            --         end if;                                 
            --     end if;
            -- 
            -- when SYNC_2b =>                 
            --     -- /INVALID/  
            --     if (code_group_valid(i*2+1) = '0') then
            --         Icounter_n(i)        <= Icounter_n(i) + '1';      
            --         Vcounter_n(i)        <= (others => '0');                     
            --         -- (Icounter[n] = Imax) 
            --         if Icounter_n(i) = Imax then 
            --             lane_sync_state_n(i) <= NO_SYNC;                           
            --             lane_sync_n(i)       <= '0';      
            --             Kcounter_n(i)        <= (others => '0');     
            --         -- (Icounter[n] < Imax) 
            --         else      
            --             lane_sync_state_n(i) <= SYNC_2a;       
            --         end if;                             
            --     -- /VALID/    
            --     else     
            --         Vcounter_n(i)  <= Vcounter_n(i) + '1';  
            --         -- (Vcounter[n] < 255) 
            --         if Vcounter_n(i) < x"FF" then
            --             lane_sync_state_n(i) <= SYNC_2a;  
            --         -- (Vcounter[n] = 255) 
            --         else
            --             Icounter_n(i)   <= Icounter_n(i) - '1';
            --             Vcounter_n(i)   <= (others => '0'); 
            --             -- (Icounter[n] > 0) 
            --             if Icounter_n(i) > Izero then
            --                 lane_sync_state_n(i) <= SYNC_2a;  
            --             -- (Icounter[n] = 0) 
            --             else
            --                 lane_sync_state_n(i) <= SYNCa;        
            --             end if;  
            --         end if;                                 
            --     end if; 
 
            -- when SYNC_3 => 
 
            -- when SYNC_4 =>  
 
            when others =>     
                lane_sync_state_n(i) <= NO_SYNC;
                lane_sync_n(i)       <= '0';      
                Kcounter_n(i)        <= (others => '0');       
                Vcounter_n(i)        <= (others => '0');         
 
        end case;
    end if;
end process;
 
end generate GEN_LANE_SYNC_FSM;
----------------------------------------------------------------
-- Figure 4-15. Lane_Alignment State Machine (for N lanes)
 
N_lane_sync           <= '1' when lane_sync_n = N_lanes_all_high else '0';
lane_alignment_reset  <= N_lane_sync and rst_n;
A_column_valid_upper  <= '1' when (RXCHARIS_A_upper = N_lanes_all_high) else '0'; 
A_column_valid_lower  <= '1' when (RXCHARIS_A_lower = N_lanes_all_high) else '0'; 
A_column_valid        <= A_column_valid_upper or A_column_valid_lower; 
align_error_upper     <= '1' when (RXCHARIS_A_upper /= N_lanes_all_low) and (RXCHARIS_A_upper /= N_lanes_all_high) else '0';  
align_error_lower     <= '1' when (RXCHARIS_A_lower /= N_lanes_all_low) and (RXCHARIS_A_lower /= N_lanes_all_high) else '0'; 
align_error           <= align_error_upper or align_error_lower; 
GEN_CHAR_A_CHECKER: for i in 0 to N-1 generate    
RXCHARIS_A_upper(i)    <=  '1' when (code_group_valid(i*2+1) = '1') and (RXCHARISK(i*2+1) = '1') and (RXDATA(i*16+15 downto i*16+8) = A_align) else '0';
RXCHARIS_A_lower(i)    <=  '1' when (code_group_valid(i*2) = '1'  ) and (RXCHARISK(i*2) = '1'  ) and (RXDATA(i*16+7 downto i*16   ) = A_align) else '0';
end generate GEN_CHAR_A_CHECKER;
 
process(lane_alignment_reset, UCLK)
    begin
 
    if lane_alignment_reset = '0'  then
 
        lane_alignment_state <= NOT_ALIGNED;
        N_lanes_aligned      <= '0';      
        Acounter             <= (others => '0');       
        -- Mcounter             <= (others => '0');    
 
    elsif rising_edge(UCLK) then    
 
    -- if lane_alignment_reset = '1'  then
 
        case lane_alignment_state is
            when NOT_ALIGNED => 
                -- N_lane_sync & ||A||
                if N_lane_sync = '1' and A_column_valid = '1' then
                    Acounter  <= Acounter + '1';  
                    lane_alignment_state <= NOT_ALIGNED_2;            
                end if;
 
            -- when NOT_ALIGNED_1 =>
 
            when NOT_ALIGNED_2 =>
                -- align_error
                if align_error = '1' then
                    lane_alignment_state <= NOT_ALIGNED;
                    N_lanes_aligned      <= '0';      
                    Acounter             <= (others => '0');  
                -- ||A||    
                elsif A_column_valid = '1' then
                    Acounter  <= Acounter + '1';  
                    -- Acounter = 4 
                    if Acounter = "100" then
                        lane_alignment_state <= ALIGNED;                        
                    -- Acounter < 4
                    else
                        lane_alignment_state <= NOT_ALIGNED_2;                        
                    end if;                     
                -- !align_error & !||A||    
                else 
                    -- Do nothing: Wait for the next column
                end if;                
 
            when ALIGNED =>
                N_lanes_aligned      <= '1';          
                Mcounter             <= (others => '0');   
                -- align_error
                if align_error = '1' then
                    Acounter    <= (others => '0');  
                    Mcounter    <= Mcounter + '1';  
                    lane_alignment_state <= ALIGNED_2;            
                -- !(align_error)
                else 
                    -- Do nothing extra: Wait for the next column
                end if;
 
            -- when ALIGNED_1 =>
 
            when ALIGNED_2 => 
                -- align_error
                if align_error = '1' then 
                    Acounter             <= (others => '0');  
                    Mcounter             <= Mcounter + '1';  
                    -- Mcounter = Mmax
                    if Mcounter = Mmax then
                        lane_alignment_state <= NOT_ALIGNED;
                        N_lanes_aligned      <= '0';                      
                    -- Mcounter < Mmax
                    else
                        -- Do nothing extra: Wait for the next column                    
                    end if;                       
                -- ||A||    
                elsif A_column_valid = '1' then
                    Acounter  <= Acounter + '1';  
                    -- Acounter = 4 
                    if Acounter = "100" then
                        lane_alignment_state <= ALIGNED;                        
                    -- Acounter < 4
                    else
                        -- Do nothing extra: Wait for the next column                          
                    end if;                     
                -- !align_error & !||A||    
                else 
                    -- Do nothing: Wait for the next column
                end if;                
 
            -- when ALIGNED_3 =>
 
            when others =>     
                lane_alignment_state <= NOT_ALIGNED;
                N_lanes_aligned      <= '0';      
                Acounter             <= (others => '0');       
                Mcounter             <= (others => '0');          
 
        end case;
    -- else
    --     lane_alignment_state <= NOT_ALIGNED;
    --     N_lanes_aligned      <= '0';      
    --     Acounter             <= (others => '0'); 
    -- end if;
    end if;
end process;
 
-- Figure 4-18. 1x/Nx_Initialization State Machine for N = 4
TXINHIBIT_02        <= not(lanes02_drvr_oe);
TXINHIBIT_others    <= not(N_lanes_drvr_oe);
rcvr_trained_n      <= CHBONDDONE; -- TBD
lane_ready_n        <= lane_sync_n and rcvr_trained_n;
-- lane_ready_n        <= lane_sync_n; -- and rcvr_trained_n;
N_lanes_ready       <= '1' when N_lanes_aligned = '1' and lane_ready_n = N_lanes_all_high else '0';
 
-- process(UCLK)
--     begin    
--     if rising_edge(UCLK) then  
--         mode_sel         <= Nx_mode_active;
--         mode_0_lane_sel  <= receive_lane2;
--         port_initalized  <= port_initalized_reg;
--     end if;
-- end process;
mode_sel         <= Nx_mode_active;
mode_0_lane_sel  <= receive_lane2;
port_initalized  <= port_initalized_reg;
 
process(rst_n, UCLK)
    begin    
    if rst_n = '0'  then
 
        mode_init_state     <= SILENT;
        disc_tmr_en         <= '0';
        lanes02_drvr_oe     <= '0';
        N_lanes_drvr_oe     <= '0';
        port_initalized_reg <= '0';
        Nx_mode_active      <= '0';
        receive_lane2       <= '0';
        force_reinit_clear  <= '0';
        silence_timer_en    <= '0';     
        idle_selected       <= '1';
 
    elsif rising_edge(UCLK) then     
        case mode_init_state is
 
            when SILENT => 
                disc_tmr_en         <= '0';
                lanes02_drvr_oe     <= '0';
                N_lanes_drvr_oe     <= '0';
                port_initalized_reg <= '0';
                Nx_mode_active      <= '0';
                receive_lane2       <= '0';
                force_reinit_clear  <= '1'; -- = force_reinit <= '0';
                silence_timer_en    <= '1';  
                -- force_reinit
                if force_reinit_reg = '1' then
                    mode_init_state     <= SILENT;
                -- silence_timer_done
                elsif silence_timer_done = '1' then
                    mode_init_state     <= SEEK;
                end if;
 
            when SEEK => 
                lanes02_drvr_oe     <= '1';
                silence_timer_en    <= '0';   
                -- (lane_sync_0 | lane_sync_2) & idle_selected
                if (lane_sync_n(0) = '1' or lane_sync_n(2) = '1') and idle_selected = '1' then
                    mode_init_state     <= DISCOVERY;
                end if;
 
            when DISCOVERY => 
                port_initalized_reg <= '0';
                Nx_mode_active      <= '0';
                N_lanes_drvr_oe     <= Nx_mode_enabled;
                disc_tmr_en         <= '1';
                -- Nx_mode_enabled & N_lanes_ready
                if Nx_mode_enabled = '1' and N_lanes_ready = '1' then
 
                    mode_init_state     <= Nx_MODE;
 
                -- lane_ready[0] & (force_1x_mode & (!force_laneR | force_laneR & disc_tmr_done & !lane_ready[2]) 
                --               | !force_1x_mode & disc_tmr_done & !N_lanes_ready)
                elsif lane_ready_n(0) = '1' and ((force_1x_mode = '1' and (force_laneR = '0' or (force_laneR = '1' and disc_tmr_done = '1' and lane_ready_n(2) = '0')))
                                             or  (force_1x_mode = '0' and disc_tmr_done = '1' and N_lanes_ready = '0')) then
 
                    mode_init_state     <= x1_MODE_LANE0;
 
                -- lane_ready[2] & (force_1x_mode & force_laneR | disc_tmr_done & !lane_ready[0] 
                --               & (force_1x_mode & !force_laneR | !force_1x_mode & !N_lanes_ready))
                elsif lane_ready_n(2) = '1' and ((force_1x_mode = '1' and force_laneR = '1') or 
                                                 (disc_tmr_done = '1' and lane_ready_n(0) = '0' and 
                                                  ((force_1x_mode = '1' and force_laneR = '0') or (force_1x_mode = '0' and N_lanes_ready = '0')))) then
 
                    mode_init_state     <= x1_MODE_LANE2;       
 
                ---- -- !lane_sync[0] & !lane_sync[2] | disc_tmr_done & !lane_ready[0] & !lane_ready[2]    
                ---- elsif (lane_sync_n(0) = '0' and lane_sync_n(2) = '0') or (disc_tmr_done = '1' and lane_ready_n(0) = '0' and lane_ready_n(2) = '0')  then   
                -- disc_tmr_done & !lane_ready[0] & !lane_ready[2]    
                elsif (disc_tmr_done = '1' and lane_ready_n(0) = '0' and lane_ready_n(2) = '0')  then   
 
                    mode_init_state     <= SILENT;
 
                end if;
 
            when Nx_MODE => 
                disc_tmr_en         <= '0';
                port_initalized_reg <= '1';
                Nx_mode_active      <= '1';
                -- !N_lanes_ready & (lane_sync[0] | lane_sync[2])                
                if N_lanes_ready = '0' and (lane_sync_n(0) = '1' or lane_sync_n(2) = '1') then                
                    mode_init_state     <= DISCOVERY;                    
                -- !N_lanes_ready & !lane_sync[0] & !lane_sync[2]
                elsif N_lanes_ready = '0' and lane_sync_n(0) = '0' and lane_sync_n(2) = '0' then                    
                    mode_init_state     <= SILENT;                    
                end if;
 
            when x1_MODE_LANE0 => 
                disc_tmr_en         <= '0';
                N_lanes_drvr_oe     <= '0';
                port_initalized_reg <= '1';      
                -- !lane_sync[0]               
                if lane_sync_n(0) = '0' then                             
                    mode_init_state     <= SILENT;    
                -- !lane_ready[0] & lane_sync[0]
                elsif lane_ready_n(0) = '0' and lane_sync_n(0) = '1' then      
                    mode_init_state     <= x1_RECOVERY;                                     
                end if;                
 
            when x1_MODE_LANE2 => 
                disc_tmr_en         <= '0';
                receive_lane2       <= '1';
                N_lanes_drvr_oe     <= '0';
                port_initalized_reg <= '1';      
                -- !lane_sync[2]               
                if lane_sync_n(2) = '0' then                             
                    mode_init_state     <= SILENT;    
                -- !lane_ready[2] & lane_sync[2]
                elsif lane_ready_n(2) = '0' and lane_sync_n(2) = '1' then      
                    mode_init_state     <= x1_RECOVERY;                                     
                end if;            
 
            when x1_RECOVERY => 
                port_initalized_reg <= '0';  
                disc_tmr_en         <= '1';
                -- !lane_sync[0] & !lane_sync[2] & disc_tmr_done   (!!!)
                if lane_sync_n(0) = '0' and lane_sync_n(2) = '0' and disc_tmr_done = '1' then
 
                    mode_init_state     <= SILENT;  
 
                -- lane_ready[0] & !receive_lane2 & !disc_tmr_done
                elsif lane_sync_n(0) = '1' and receive_lane2 = '0' and disc_tmr_done = '0' then
 
                    mode_init_state     <= x1_MODE_LANE0; 
 
                -- lane_ready[2] & receive_lane2 & !disc_tmr_done
                elsif lane_sync_n(2) = '1' and receive_lane2 = '1' and disc_tmr_done = '0' then
 
                    mode_init_state     <= x1_MODE_LANE2; 
 
                end if;   
 
            when others =>
                port_initalized_reg <= '0'; 
                mode_init_state     <= SILENT;
 
        end case;
 
    end if;
 
end process;
 
-- Sticky force_reinit set-reset register
process(rst_n, UCLK)
    begin    
    if rst_n = '0'  then    
        force_reinit_reg       <= '0';      
    elsif rising_edge(UCLK) then    
        case force_reinit_reg is
            when '0' => 
                force_reinit_reg <= force_reinit or rxbuferr_reg;            
            when '1' => 
                -- force_reinit_reg <= not(force_reinit_clear) and not(force_reinit);
                force_reinit_reg <= not(force_reinit_clear and not(force_reinit) and not(rxbuferr_reg));
            when others =>
                force_reinit_reg <= '0';
        end case;
    end if;
end process;
 
-- RXBUFRST handler
process(rst_n, UCLK)
    begin    
    if rst_n = '0'  then    
        rxbufrst_cntr    <= (others => '0');  
        rxbuferr_reg     <= '0';  
        RXBUFRST         <= '0';
 
    elsif rising_edge(UCLK) then    
        case rxbuferr_reg is
            when '0' => 
                rxbuferr_reg     <= RXBUFERR;   
                RXBUFRST         <= '0';
            when '1' =>                 
                if rxbufrst_cntr = "111" then
                    rxbuferr_reg     <= '0'; 
                    rxbufrst_cntr    <= (others => '0');  
                else
                    RXBUFRST         <= '1';
                    rxbufrst_cntr    <= rxbufrst_cntr + '1';  
                end if;                
            when others =>
                rxbuferr_reg     <= '0';   
        end case;
    end if;
end process;
 
 
-- Silence Timer Process
-- silence_timer_done: Asserted when silence_timer_en has been continuously asserted
-- for 120 +/- 40 µs and the state machine is in the SILENT state. The assertion of
-- silence_timer_done causes silence_timer_en to be de-asserted. When the state
-- machine is not in the SILENT state, silence_timer_done is de-asserted.
process(rst_n, UCLK_DV_1024)
    begin    
    if rst_n = '0'  then        
        silence_timer_done  <= '0'; 
        silence_timer       <= (others => '0');         
    elsif rising_edge(UCLK_DV_1024) then 
 
        case silence_timer_en is            
            when '0' =>   
                silence_timer       <= (others => '0');  
                silence_timer_done  <= '0'; 
            when '1' => 
                if silence_timer = SILENT_ENOUGH then
                    if mode_init_state = SILENT then
                        silence_timer_done  <= '1'; 
                    else
                        silence_timer_done  <= '0'; 
                    end if;
                else
                    silence_timer   <= silence_timer + '1';
                end if;
            when others =>
                silence_timer   <= (others => '0');              
        end case; 
    end if;
end process;
 
-- Discovery Timer Process
-- disc_tmr_done: Asserted when disc_tmr_en has been continuously asserted for 28 +/- 4 ms
-- and the state machine is in the DISCOVERY or a RECOVERY state. The assertion of 
-- disc_tmr_done causes disc_tmr_en to be de-asserted. When the state machine is in
-- a state other than the DISCOVERY or a RECOVERY state, disc_tmr_done is de-asserted.
process(rst_n, UCLK_DV_1024)
    begin    
    if rst_n = '0'  then        
        disc_tmr_done  <= '0'; 
        disc_tmr       <= (others => '0');         
    elsif rising_edge(UCLK_DV_1024) then 
 
        case disc_tmr_en is            
            when '0' =>   
                disc_tmr       <= (others => '0');  
                disc_tmr_done  <= '0'; 
            when '1' => 
                if disc_tmr = DISCOVERY_ENDS then
                    if mode_init_state = DISCOVERY or mode_init_state = x1_RECOVERY then
                        disc_tmr_done  <= '1'; 
                    else
                        disc_tmr_done  <= '0'; 
                    end if;
                else
                    disc_tmr   <= disc_tmr + '1';
                end if;
            when others =>
                disc_tmr   <= (others => '0');              
        end case; 
    end if;
end process;
 
ENCHANSYNC <= '0';
 
end rtl;
-------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pseudo_random_number_generator is
    Generic (
            lfsr_init   : std_logic_vector(7 downto 0) := x"01"
           );
    Port    ( 
            clk      : in  STD_LOGIC;
            rst_n    : in  STD_LOGIC;
            -- Pseudo random number
            q        : out STD_LOGIC_VECTOR(7 downto 0)           
           );
end pseudo_random_number_generator;
 
architecture Behavioral of pseudo_random_number_generator is
 
signal lfsr   : std_logic_vector(7 downto 0) := x"01"; 
signal q0     : std_logic; 
 
 begin 
 
q  <= lfsr;
 
-- Polynomial: x^7 + x^6 + 1
q0 <= lfsr(7) xnor lfsr(6) xnor lfsr(0) ;
 
process (clk, rst_n) begin 
 
  if rst_n = '0' then 
 
    lfsr <= lfsr_init; -- x"01"; --(others => '0');
 
  elsif rising_edge(clk) then 
 
    lfsr <= lfsr(6 downto 0) & q0; 
 
  end if; 
 
end process;
 
end Behavioral;
 
-------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--
-- File name:    serdes_wrapper_v0.vhd
-- Rev:          0.0
-- Description:  This entity instantiates 4-Lane SerDes (GTX-Quad) of Virtex-6
-- 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
entity serdes_wrapper_v0 is
  port ( 
         REFCLK              : in std_logic;
         RXUSRCLK            : in std_logic;
         RXUSRCLK2           : in std_logic;
         TXUSRCLK            : in std_logic;
         TXUSRCLK2           : in std_logic;
         GTXRESET            : in std_logic;
         RXBUFRST            : in std_logic;
 
         -- RXN                 : in  std_logic_vector(N-1 downto 0);
         -- RXP                 : in  std_logic_vector(N-1 downto 0);
         RXN                 : in  std_logic_vector(0 to N-1);
         RXP                 : in  std_logic_vector(0 to N-1);
         TXINHIBIT_02        : in  std_logic;
         TXINHIBIT_others    : in  std_logic;
         ENCHANSYNC          : in  std_logic;
         TXDATA              : in  std_logic_vector(N*16-1 downto 0);
         TXCHARISK           : in  std_logic_vector(N*2-1 downto 0);
         -- TXN                 : out std_logic_vector(N-1 downto 0);
         -- TXP                 : out std_logic_vector(N-1 downto 0);
         TXN                 : out std_logic_vector(0 to N-1);
         TXP                 : out std_logic_vector(0 to N-1);
         PLLLKDET            : out std_logic;
         RXDATA              : out std_logic_vector(N*16-1 downto 0);
         RXCHARISK           : out std_logic_vector(N*2-1 downto 0);
         RXCHARISCOMMA       : out std_logic_vector(N*2-1 downto 0);
         RXBYTEISALIGNED     : out std_logic_vector(N-1 downto 0);
         RXBYTEREALIGN       : out std_logic_vector(N-1 downto 0);
         RXELECIDLE          : out std_logic_vector(N-1 downto 0);
         RXDISPERR           : out std_logic_vector(N*2-1 downto 0);
         RXNOTINTABLE        : out std_logic_vector(N*2-1 downto 0);
         RXBUFERR            : out std_logic;
         CHBONDDONE          : out std_logic_vector(N-1 downto 0)
  );
end serdes_wrapper_v0;
 
architecture struct of serdes_wrapper_v0 is
 
	COMPONENT srio_gt_wrapper_v6_4x
	PORT(
		REFCLK : IN std_logic;
		RXUSRCLK : IN std_logic;
		RXUSRCLK2 : IN std_logic;
		TXUSRCLK : IN std_logic;
		TXUSRCLK2 : IN std_logic;
		GTXRESET : IN std_logic;
		RXBUFRST : IN std_logic;
		RXN0 : IN std_logic;
		RXN1 : IN std_logic;
		RXN2 : IN std_logic;
		RXN3 : IN std_logic;
		RXP0 : IN std_logic;
		RXP1 : IN std_logic;
		RXP2 : IN std_logic;
		RXP3 : IN std_logic;
		TXINHIBIT_02 : IN std_logic;
		TXINHIBIT_13 : IN std_logic;
		ENCHANSYNC : IN std_logic;
		TXDATA0 : IN std_logic_vector(15 downto 0);
		TXDATA1 : IN std_logic_vector(15 downto 0);
		TXDATA2 : IN std_logic_vector(15 downto 0);
		TXDATA3 : IN std_logic_vector(15 downto 0);
		TXCHARISK0 : IN std_logic_vector(1 downto 0);
		TXCHARISK1 : IN std_logic_vector(1 downto 0);
		TXCHARISK2 : IN std_logic_vector(1 downto 0);
		TXCHARISK3 : IN std_logic_vector(1 downto 0);          
		TXN0 : OUT std_logic;
		TXN1 : OUT std_logic;
		TXN2 : OUT std_logic;
		TXN3 : OUT std_logic;
		TXP0 : OUT std_logic;
		TXP1 : OUT std_logic;
		TXP2 : OUT std_logic;
		TXP3 : OUT std_logic;
		PLLLKDET : OUT std_logic;
		RXDATA0 : OUT std_logic_vector(15 downto 0);
		RXDATA1 : OUT std_logic_vector(15 downto 0);
		RXDATA2 : OUT std_logic_vector(15 downto 0);
		RXDATA3 : OUT std_logic_vector(15 downto 0);
		RXCHARISK0 : OUT std_logic_vector(1 downto 0);
		RXCHARISK1 : OUT std_logic_vector(1 downto 0);
		RXCHARISK2 : OUT std_logic_vector(1 downto 0);
		RXCHARISK3 : OUT std_logic_vector(1 downto 0);
		RXCHARISCOMMA0 : OUT std_logic_vector(1 downto 0);
		RXCHARISCOMMA1 : OUT std_logic_vector(1 downto 0);
		RXCHARISCOMMA2 : OUT std_logic_vector(1 downto 0);
		RXCHARISCOMMA3 : OUT std_logic_vector(1 downto 0);
        RXBYTEISALIGNED: OUT  std_logic_vector(3 downto 0);
        RXBYTEREALIGN  : OUT  std_logic_vector(3 downto 0);
        RXELECIDLE     : OUT std_logic_vector(3 downto 0);
		RXDISPERR0 : OUT std_logic_vector(1 downto 0);
		RXDISPERR1 : OUT std_logic_vector(1 downto 0);
		RXDISPERR2 : OUT std_logic_vector(1 downto 0);
		RXDISPERR3 : OUT std_logic_vector(1 downto 0);
		RXNOTINTABLE0 : OUT std_logic_vector(1 downto 0);
		RXNOTINTABLE1 : OUT std_logic_vector(1 downto 0);
		RXNOTINTABLE2 : OUT std_logic_vector(1 downto 0);
		RXNOTINTABLE3 : OUT std_logic_vector(1 downto 0);
		RXBUFERR : OUT std_logic;
		CHBONDDONE0 : OUT std_logic;
		CHBONDDONE1 : OUT std_logic;
		CHBONDDONE2 : OUT std_logic;
		CHBONDDONE3 : OUT std_logic
		);
	END COMPONENT;
 
begin
 
	Inst_srio_gt_wrapper_v6_4x: srio_gt_wrapper_v6_4x PORT MAP(
		REFCLK              => REFCLK                       ,
		RXUSRCLK            => RXUSRCLK                     ,
		RXUSRCLK2           => RXUSRCLK2                    ,
		TXUSRCLK            => TXUSRCLK                     ,
		TXUSRCLK2           => TXUSRCLK2                    ,
		GTXRESET            => GTXRESET                     ,
		RXBUFRST            => RXBUFRST                     ,
		RXN0                => RXN(0)                       ,
		RXN1                => RXN(1)                       ,
		RXN2                => RXN(2)                       ,
		RXN3                => RXN(3)                       ,
		RXP0                => RXP(0)                       ,
		RXP1                => RXP(1)                       ,
		RXP2                => RXP(2)                       ,
		RXP3                => RXP(3)                       ,
		TXINHIBIT_02        => TXINHIBIT_02                 ,
		TXINHIBIT_13        => TXINHIBIT_others             ,
		ENCHANSYNC          => ENCHANSYNC                   ,
		TXDATA0             => TXDATA(15 downto 0)          ,
		TXDATA1             => TXDATA(31 downto 16)         ,
		TXDATA2             => TXDATA(47 downto 32)         ,
		TXDATA3             => TXDATA(63 downto 48)         ,
		TXCHARISK0          => TXCHARISK(1 downto 0)        ,
		TXCHARISK1          => TXCHARISK(3 downto 2)        ,
		TXCHARISK2          => TXCHARISK(5 downto 4)        ,
		TXCHARISK3          => TXCHARISK(7 downto 6)        ,
		TXN0                => TXN(0)                       ,
		TXN1                => TXN(1)                       ,
		TXN2                => TXN(2)                       ,
		TXN3                => TXN(3)                       ,
		TXP0                => TXP(0)                       ,
		TXP1                => TXP(1)                       ,
		TXP2                => TXP(2)                       ,
		TXP3                => TXP(3)                       ,
		PLLLKDET            => PLLLKDET                     ,
		RXDATA0             => RXDATA(15 downto 0)          ,
		RXDATA1             => RXDATA(31 downto 16)         ,
		RXDATA2             => RXDATA(47 downto 32)         ,
		RXDATA3             => RXDATA(63 downto 48)         ,
		RXCHARISK0          => RXCHARISK(1 downto 0)        ,
		RXCHARISK1          => RXCHARISK(3 downto 2)        ,
		RXCHARISK2          => RXCHARISK(5 downto 4)        ,
		RXCHARISK3          => RXCHARISK(7 downto 6)        ,
		RXCHARISCOMMA0      => RXCHARISCOMMA(1 downto 0)    ,
		RXCHARISCOMMA1      => RXCHARISCOMMA(3 downto 2)    ,
		RXCHARISCOMMA2      => RXCHARISCOMMA(5 downto 4)    ,
		RXCHARISCOMMA3      => RXCHARISCOMMA(7 downto 6)    ,        
        RXBYTEISALIGNED     => RXBYTEISALIGNED              ,
        RXBYTEREALIGN       => RXBYTEREALIGN                ,
        RXELECIDLE          => RXELECIDLE                   ,
		RXDISPERR0          => RXDISPERR(1 downto 0)        ,
		RXDISPERR1          => RXDISPERR(3 downto 2)        ,
		RXDISPERR2          => RXDISPERR(5 downto 4)        ,
		RXDISPERR3          => RXDISPERR(7 downto 6)        ,
		RXNOTINTABLE0       => RXNOTINTABLE(1 downto 0)     ,
		RXNOTINTABLE1       => RXNOTINTABLE(3 downto 2)     ,
		RXNOTINTABLE2       => RXNOTINTABLE(5 downto 4)     ,
		RXNOTINTABLE3       => RXNOTINTABLE(7 downto 6)     ,
		RXBUFERR            => RXBUFERR                     ,
		CHBONDDONE0         => CHBONDDONE(0)                ,
		CHBONDDONE1         => CHBONDDONE(1)                ,
		CHBONDDONE2         => CHBONDDONE(2)                ,
		CHBONDDONE3         => CHBONDDONE(3)      
	);
 
end struct;
-------------------------------------------------------------------------------
-- 
-- RapidIO IP Library Core
-- 
-- This file is part of the RapidIO IP library project
-- http://www.opencores.org/cores/rio/
-- 
-- To Do:
-- -
-- 
-- Author(s): 
-- - A. Demirezen, azdem@opencores.org 
-- 
-------------------------------------------------------------------------------
-- 
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
-- 
-- This source file may be used and distributed without 
-- restriction provided that this copyright statement is not 
-- removed from the file and that any derivative work contains 
-- the original copyright notice and the associated disclaimer. 
-- 
-- This source file is free software; you can redistribute it 
-- and/or modify it under the terms of the GNU Lesser General 
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any 
-- later version. 
-- 
-- This source is distributed in the hope that it will be 
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
-- PURPOSE. See the GNU Lesser General Public License for more 
-- details. 
-- 
-- You should have received a copy of the GNU Lesser General 
-- Public License along with this source; if not, download it 
-- from http://www.opencores.org/lgpl.shtml 
-- 
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.Vcomponents.ALL;
 
entity srio_pcs_struct is
   port ( CHBONDDONE         : in    std_logic_vector (3 downto 0); 
          force_reinit_i     : in    std_logic; 
          inboundRead_i      : in    std_logic; 
          outboundSymbol_i   : in    std_logic_vector (33 downto 0); 
          outboundWrite_i    : in    std_logic; 
          PLLLKDET           : in    std_logic; 
          rio_clk            : in    std_logic; 
          rst_n              : in    std_logic; 
          RXBUFERR           : in    std_logic; 
          RXBYTEISALIGNED    : in    std_logic_vector (3 downto 0); 
          RXBYTEREALIGN      : in    std_logic_vector (3 downto 0); 
          RXCAHRISCOMMA      : in    std_logic_vector (7 downto 0); 
          RXCAHRISK          : in    std_logic_vector (7 downto 0); 
          RXDATA             : in    std_logic_vector (63 downto 0); 
          RXDISPERR          : in    std_logic_vector (7 downto 0); 
          RXELECIDLE         : in    std_logic_vector (3 downto 0); 
          RXNOTINTABLE       : in    std_logic_vector (7 downto 0); 
          UCLK               : in    std_logic; 
          UCLK_DV4           : in    std_logic; 
          UCLK_DV1024        : in    std_logic; 
          UCLK_or_DV4        : in    std_logic; 
          UCLK_x2            : in    std_logic; 
          UCLK_x2_DV2        : in    std_logic; 
          ENCHANSYNC         : out   std_logic; 
          inboundEmpty_o     : out   std_logic; 
          inboundSymbol_o    : out   std_logic_vector (33 downto 0); 
          lane_sync_o        : out   std_logic_vector (3 downto 0); 
          mode_sel_o         : out   std_logic; 
          mode_0_lane_sel_o  : out   std_logic; 
          outboundFull_o     : out   std_logic; 
          port_initialized_o : out   std_logic; 
          RXBUFRST           : out   std_logic; 
          TXCAHRISK          : out   std_logic_vector (7 downto 0); 
          TXDATA             : out   std_logic_vector (63 downto 0); 
          TXINHIBIT_others   : out   std_logic; 
          TXINHIBIT_02       : out   std_logic);
end srio_pcs_struct;
 
architecture BEHAVIORAL of srio_pcs_struct is
   signal ccs_timer_rst            : std_logic;
   signal RXCAHRISvalid            : std_logic_vector (7 downto 0);
   signal send_A                   : std_logic_vector (1 downto 0);
   signal send_ccs                 : std_logic;
   signal send_idle                : std_logic_vector (1 downto 0);
   signal send_K                   : std_logic_vector (1 downto 0);
   signal send_R                   : std_logic_vector (1 downto 0);
   signal mode_0_lane_sel_o_DUMMY  : std_logic;
   signal TXINHIBIT_02_DUMMY       : std_logic;
   signal mode_sel_o_DUMMY         : std_logic;
   signal port_initialized_o_DUMMY : std_logic;
   signal TXINHIBIT_others_DUMMY   : std_logic;
   component ccs_timer
      port ( rst_n         : in    std_logic; 
             ccs_timer_rst : in    std_logic; 
             send_ccs      : out   std_logic; 
             UCLK          : in    std_logic);
   end component;
 
   component idle_generator_dual
      port ( UCLK      : in    std_logic; 
             rst_n     : in    std_logic; 
             send_K    : out   std_logic_vector (1 downto 0); 
             send_A    : out   std_logic_vector (1 downto 0); 
             send_R    : out   std_logic_vector (1 downto 0); 
             send_idle : in    std_logic_vector (1 downto 0));
   end component;
 
   component port_init_fsms
      port ( rst_n            : in    std_logic; 
             UCLK_x2          : in    std_logic; 
             UCLK             : in    std_logic; 
             UCLK_DV4         : in    std_logic; 
             UCLK_DV_1024     : in    std_logic; 
             force_reinit     : in    std_logic; 
             PLLLKDET         : in    std_logic; 
             RXBUFERR         : in    std_logic; 
             RXDATA           : in    std_logic_vector (63 downto 0); 
             RXCHARISK        : in    std_logic_vector (7 downto 0); 
             RXCHARISCOMMA    : in    std_logic_vector (7 downto 0); 
             RXBYTEISALIGNED  : in    std_logic_vector (3 downto 0); 
             RXBYTEREALIGN    : in    std_logic_vector (3 downto 0); 
             RXELECIDLE       : in    std_logic_vector (3 downto 0); 
             RXDISPERR        : in    std_logic_vector (7 downto 0); 
             RXNOTINTABLE     : in    std_logic_vector (7 downto 0); 
             CHBONDDONE       : in    std_logic_vector (3 downto 0); 
             mode_sel         : out   std_logic; 
             port_initalized  : out   std_logic; 
             TXINHIBIT_02     : out   std_logic; 
             TXINHIBIT_others : out   std_logic; 
             ENCHANSYNC       : out   std_logic; 
             RXBUFRST         : out   std_logic; 
             lane_sync        : out   std_logic_vector (3 downto 0); 
             mode_0_lane_sel  : out   std_logic; 
             RXCHARISvalid    : out   std_logic_vector (7 downto 0));
   end component;
 
   component pcs_rx_controller
      port ( rst_n             : in    std_logic; 
             rio_clk           : in    std_logic; 
             UCLK_x2           : in    std_logic; 
             UCLK              : in    std_logic; 
             UCLK_x2_DV2       : in    std_logic; 
             inboundRead_i     : in    std_logic; 
             port_initalized_i : in    std_logic; 
             mode_sel_i        : in    std_logic; 
             mode_0_lane_sel_i : in    std_logic; 
             RXDATA_i          : in    std_logic_vector (63 downto 0); 
             RXCHARISK_i       : in    std_logic_vector (7 downto 0); 
             RXCHARISvalid_i   : in    std_logic_vector (7 downto 0); 
             inboundEmpty_o    : out   std_logic; 
             inboundSymbol_o   : out   std_logic_vector (33 downto 0); 
             UCLK_or_DV4       : in    std_logic);
   end component;
 
   component pcs_tx_controller
      port ( rst_n             : in    std_logic; 
             rio_clk           : in    std_logic; 
             UCLK_x2           : in    std_logic; 
             UCLK              : in    std_logic; 
             UCLK_x2_DV2       : in    std_logic; 
             UCLK_or_DV4       : in    std_logic; 
             outboundWrite_i   : in    std_logic; 
             send_ccs_i        : in    std_logic; 
             TXINHIBIT_02      : in    std_logic; 
             TXINHIBIT_others  : in    std_logic; 
             port_initalized_i : in    std_logic; 
             mode_sel_i        : in    std_logic; 
             mode_0_lane_sel_i : in    std_logic; 
             outboundSymbol_i  : in    std_logic_vector (33 downto 0); 
             send_K_i          : in    std_logic_vector (1 downto 0); 
             send_A_i          : in    std_logic_vector (1 downto 0); 
             send_R_i          : in    std_logic_vector (1 downto 0); 
             outboundFull_o    : out   std_logic; 
             ccs_timer_rst_o   : out   std_logic; 
             TXDATA_o          : out   std_logic_vector (63 downto 0); 
             TXCHARISK_o       : out   std_logic_vector (7 downto 0); 
             send_idle_o       : out   std_logic_vector (1 downto 0));
   end component;
 
begin
   mode_sel_o <= mode_sel_o_DUMMY;
   mode_0_lane_sel_o <= mode_0_lane_sel_o_DUMMY;
   port_initialized_o <= port_initialized_o_DUMMY;
   TXINHIBIT_others <= TXINHIBIT_others_DUMMY;
   TXINHIBIT_02 <= TXINHIBIT_02_DUMMY;
   ccs_timer_inst : ccs_timer
      port map (ccs_timer_rst=>ccs_timer_rst,
                rst_n=>rst_n,
                UCLK=>UCLK,
                send_ccs=>send_ccs);
 
   dual_idle_generator : idle_generator_dual
      port map (rst_n=>rst_n,
                send_idle(1 downto 0)=>send_idle(1 downto 0),
                UCLK=>UCLK,
                send_A(1 downto 0)=>send_A(1 downto 0),
                send_K(1 downto 0)=>send_K(1 downto 0),
                send_R(1 downto 0)=>send_R(1 downto 0));
 
   port_init_fsms_inst : port_init_fsms
      port map (CHBONDDONE(3 downto 0)=>CHBONDDONE(3 downto 0),
                force_reinit=>force_reinit_i,
                PLLLKDET=>PLLLKDET,
                rst_n=>rst_n,
                RXBUFERR=>RXBUFERR,
                RXBYTEISALIGNED(3 downto 0)=>RXBYTEISALIGNED(3 downto 0),
                RXBYTEREALIGN(3 downto 0)=>RXBYTEREALIGN(3 downto 0),
                RXCHARISCOMMA(7 downto 0)=>RXCAHRISCOMMA(7 downto 0),
                RXCHARISK(7 downto 0)=>RXCAHRISK(7 downto 0),
                RXDATA(63 downto 0)=>RXDATA(63 downto 0),
                RXDISPERR(7 downto 0)=>RXDISPERR(7 downto 0),
                RXELECIDLE(3 downto 0)=>RXELECIDLE(3 downto 0),
                RXNOTINTABLE(7 downto 0)=>RXNOTINTABLE(7 downto 0),
                UCLK=>UCLK,
                UCLK_DV_1024=>UCLK_DV1024,
                UCLK_DV4=>UCLK_DV4,
                UCLK_x2=>UCLK_x2,
                ENCHANSYNC=>ENCHANSYNC,
                lane_sync(3 downto 0)=>lane_sync_o(3 downto 0),
                mode_sel=>mode_sel_o_DUMMY,
                mode_0_lane_sel=>mode_0_lane_sel_o_DUMMY,
                port_initalized=>port_initialized_o_DUMMY,
                RXBUFRST=>RXBUFRST,
                RXCHARISvalid(7 downto 0)=>RXCAHRISvalid(7 downto 0),
                TXINHIBIT_others=>TXINHIBIT_others_DUMMY,
                TXINHIBIT_02=>TXINHIBIT_02_DUMMY);
 
   rx_controller_inst : pcs_rx_controller
      port map (inboundRead_i=>inboundRead_i,
                mode_sel_i=>mode_sel_o_DUMMY,
                mode_0_lane_sel_i=>mode_0_lane_sel_o_DUMMY,
                port_initalized_i=>port_initialized_o_DUMMY,
                rio_clk=>rio_clk,
                rst_n=>rst_n,
                RXCHARISK_i(7 downto 0)=>RXCAHRISK(7 downto 0),
                RXCHARISvalid_i(7 downto 0)=>RXCAHRISvalid(7 downto 0),
                RXDATA_i(63 downto 0)=>RXDATA(63 downto 0),
                UCLK=>UCLK,
                UCLK_or_DV4=>UCLK_or_DV4,
                UCLK_x2=>UCLK_x2,
                UCLK_x2_DV2=>UCLK_x2_DV2,
                inboundEmpty_o=>inboundEmpty_o,
                inboundSymbol_o(33 downto 0)=>inboundSymbol_o(33 downto 0));
 
   tx_controller_inst : pcs_tx_controller
      port map (mode_sel_i=>mode_sel_o_DUMMY,
                mode_0_lane_sel_i=>mode_0_lane_sel_o_DUMMY,
                outboundSymbol_i(33 downto 0)=>outboundSymbol_i(33 downto 0),
                outboundWrite_i=>outboundWrite_i,
                port_initalized_i=>port_initialized_o_DUMMY,
                rio_clk=>rio_clk,
                rst_n=>rst_n,
                send_A_i(1 downto 0)=>send_A(1 downto 0),
                send_ccs_i=>send_ccs,
                send_K_i(1 downto 0)=>send_K(1 downto 0),
                send_R_i(1 downto 0)=>send_R(1 downto 0),
                TXINHIBIT_others=>TXINHIBIT_others_DUMMY,
                TXINHIBIT_02=>TXINHIBIT_02_DUMMY,
                UCLK=>UCLK,
                UCLK_or_DV4=>UCLK_or_DV4,
                UCLK_x2=>UCLK_x2,
                UCLK_x2_DV2=>UCLK_x2_DV2,
                ccs_timer_rst_o=>ccs_timer_rst,
                outboundFull_o=>outboundFull_o,
                send_idle_o(1 downto 0)=>send_idle(1 downto 0),
                TXCHARISK_o(7 downto 0)=>TXCAHRISK(7 downto 0),
                TXDATA_o(63 downto 0)=>TXDATA(63 downto 0));
 
end BEHAVIORAL;
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.