URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
[/] [rio/] [branches/] [parallelSymbols/] [rtl/] [vhdl/] [srio_pcs_struct.vhd] - Rev 26
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