library ieee;
use ieee.std_logic_1164.all;
library UNISIM;
use UNISIM.vcomponents.all;
library utilities;
entity processing_block is
port (
-- clock:
clk_iserdes_in : in std_logic;
clk_iserdes_in_div : in std_logic;
clk_global : in std_logic;
-- reset:
rst : in std_logic;
-- bitslip:
bitslip : in std_logic;
bitslip_done : in std_logic; -- todo: use this
bitslip_drop_byte : in std_logic;
-- input signal:
in_data_p : in std_logic;
in_data_n : in std_logic;
in_data_swap_pn : in std_logic;
-- input switch for counter output:
in_output_counting : in std_logic;
-- output after iserdes and pack16 for bitslip:
o_iserdes_output : out std_logic_vector( 15 downto 0 );
o_iserdes_output_valid : out std_logic;
-- output fwft FIFO:
o_data : out std_logic_vector( 31 downto 0 );
o_valid : out std_logic;
i_rden : in std_logic
);
end processing_block;
architecture behavioral of processing_block is
component swap_endianness
port (
i_data : in std_logic_vector;
o_data : out std_logic_vector
);
end component;
component fifo_32x512_dualclk_fwft
port (
rst : in std_logic;
wr_clk : in std_logic;
rd_clk : in std_logic;
din : in std_logic_vector(31 downto 0);
wr_en : in std_logic;
rd_en : in std_logic;
dout : out std_logic_vector(31 downto 0);
full : out std_logic;
empty : out std_logic;
valid : out std_logic
);
end component;
component myserdes_ddr_wrapper
generic
( sys_w : integer := 1;
dev_w : integer := 8);
port (
-- CLOCK:
clk_in : in std_logic;
clk_in_div : in std_logic;
-- PADS IN:
data_in_from_pins_p : in std_logic;
data_in_from_pins_n : in std_logic;
-- DATA OUT:
data_in_to_device : out std_logic_vector( dev_w - 1 downto 0 );
bitslip : in std_logic;
rst_in : in std_logic );
end component;
component saw_generator_wrapper
generic (
G_INCREASE_EVERY_NTH : positive := 4
);
port (
i_clk : in std_logic;
i_rst : in std_logic;
o_valid : out std_logic;
o_data : out std_logic_vector
);
end component;
-- Frame signal
signal s_in_frame_for_data : std_logic_vector( 7 downto 0 );
signal s_in_frame_for_data_precorrect : std_logic_vector( 7 downto 0 );
signal s_in_frame_for_data_packed16 : std_logic_vector( 15 downto 0 );
signal s_in_frame_for_data_packed16_le : std_logic_vector( 15 downto 0 );
signal s_in_frame_for_data_packed16_swapped : std_logic_vector( 15 downto 0 );
signal s_in_frame_for_data_packed16_valid : std_logic;
signal s_in_frame_for_data_packed16_valid_wbitslip_done : std_logic;
signal s_in_frame_for_data_packed32 : std_logic_vector( 31 downto 0 );
signal s_in_frame_for_data_packed32_valid : std_logic;
signal s_rst_n : std_logic;
-- counter:
signal s_counter_valid : std_logic;
signal s_counter_data : std_logic_vector( 31 downto 0 );
-- selection signals for the final FIFO:
signal s_selected_source_valid : std_logic;
signal s_selected_source_data : std_logic_vector( 31 downto 0 );
-- byte drop request
signal s_bitslip_drop_byte_n : std_logic;
begin
s_rst_n <= not rst;
s_bitslip_drop_byte_n <= not bitslip_drop_byte;
-- iserdes wrapper:
myserdes_ddr_wrapper_inst : myserdes_ddr_wrapper
port map (
clk_in => clk_iserdes_in, clk_in_div => clk_iserdes_in_div,
data_in_from_pins_p => in_data_p, data_in_from_pins_n => in_data_n, data_in_to_device => s_in_frame_for_data_precorrect,
bitslip => bitslip, rst_in => rst );
-- correct hardware swapping of P&N wires:
s_in_frame_for_data <= s_in_frame_for_data_precorrect when in_data_swap_pn = '0' else
not s_in_frame_for_data_precorrect;
-- glue two parts to 16-bit full data:
glue_data_inst : entity work.glue_data
port map (
i_clk => clk_iserdes_in_div, i_reset_n => s_rst_n,
i_data => s_in_frame_for_data, i_valid => s_bitslip_drop_byte_n, o_enable => open,
o_data => s_in_frame_for_data_packed16, o_valid => s_in_frame_for_data_packed16_valid, i_enable => '1' );
-- output the 16-bit to manage bitslip:
o_iserdes_output <= s_in_frame_for_data_packed16;
o_iserdes_output_valid <= s_in_frame_for_data_packed16_valid;
-- these data go further after bitslip has been set:
s_in_frame_for_data_packed16_le <= s_in_frame_for_data_packed16;
s_in_frame_for_data_packed16_valid_wbitslip_done <= bitslip_done and s_in_frame_for_data_packed16_valid;
-- insert the pack block to 32 bits:
pack_data32_inst : entity utilities.pack_data
generic map (
G_OUTPUT_WIDTH => 32 )
port map (
i_clk => clk_iserdes_in_div, i_reset_n => s_rst_n,
i_data => s_in_frame_for_data_packed16_le, i_valid => s_in_frame_for_data_packed16_valid_wbitslip_done, o_enable => open,
o_data => s_in_frame_for_data_packed32, o_valid => s_in_frame_for_data_packed32_valid, i_enable => '1' );
-- counter:
counter_inst : saw_generator_wrapper
generic map( G_INCREASE_EVERY_NTH => 4 )
port map(
i_clk => clk_iserdes_in_div, i_rst => rst, o_valid => s_counter_valid, o_data => s_counter_data );
-- output either the grabbed data or the counter, based on request:
s_selected_source_valid <= s_counter_valid when in_output_counting = '1' else s_in_frame_for_data_packed32_valid;
s_selected_source_data <= s_counter_data when in_output_counting = '1' else s_in_frame_for_data_packed32;
-- insert the cross-domain FIFO:
cross_domain_fifo_inst : fifo_32x512_dualclk_fwft
port map (
rst => rst, wr_clk => clk_iserdes_in_div, rd_clk => clk_global,
din => s_selected_source_data, wr_en => s_selected_source_valid, full => open,
dout => o_data, valid => o_valid, rd_en => i_rden, empty => open );
end architecture;