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

Subversion Repositories rio

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rio/trunk/rtl
    from Rev 8 to Rev 9
    Reverse comparison

Rev 8 → Rev 9

/vhdl/srio_pcs_struct.vhd
0,0 → 1,2912
-------------------------------------------------------------------------------
--
-- 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
 
-- 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;
 
 

powered by: WebSVN 2.1.0

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