library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library desy; use desy.ram_tdp; library desyrdl; use desyrdl.pkg_corr_matrixpi.t_mem_PSCIDTABLE_out; use desyrdl.pkg_corr_matrixpi.t_mem_PSCIDTABLE_in; use work.pkg_corr_matrixpi.all; entity data_serializer is port( clk : in std_logic; rst_n : in std_logic; -- PSCID memory pscid_table_i : in t_mem_PSCIDTABLE_out; pscid_table_o : out t_mem_PSCIDTABLE_in; -- Status overrun : out std_logic; -- Corr parallel input corrout_valid : in std_logic; corrout_seq : in std_logic_vector(C_W_BPMSEQ-1 downto 0); corrout : in signed_array(0 to C_N_MM_PSC-1)(C_W_COR-1 downto 0); -- AXIS serial output m_axis_tdata : out std_logic_vector(C_W_COR+C_W_PSCID-1 downto 0); m_axis_tuser : out std_logic_vector(C_W_BPMSEQ-1 downto 0); m_axis_tvalid : out std_logic; m_axis_tready : in std_logic ); end entity data_serializer; architecture rtl of data_serializer is ------------------------ -- SIGNAL DECLARATION -- ------------------------ signal cnt : unsigned(C_W_SER_CNT-1 downto 0); signal run_serial : std_logic; signal pscid : std_logic_vector(C_W_PSCID-1 downto 0); signal r_corr : signed_array(0 to C_N_MM_PSC-1)(C_W_COR-1 downto 0); signal r_seq : std_logic_vector(C_W_BPMSEQ-1 downto 0); begin ------------------------ -- SERIALIZER COUNTER -- ------------------------ p_cnt:process(clk, rst_n) begin if rst_n = '0' then cnt <= (others => '0'); run_serial <= '0'; overrun <= '0'; elsif rising_edge(clk) then if run_serial = '1' then if cnt = C_N_MM_PSC-1 then -- stop at the end run_serial <= '0'; else if m_axis_tready = '1' then cnt <= cnt+1; end if; end if; -- Transmit overrun if a valid comes here overrun <= corrout_valid; else if corrout_valid= '1' then -- start on valid run_serial <= '1'; cnt <= (others => '0'); end if; -- No overrun possible here overrun <= '0'; end if; end if; end process; --------------------- -- SHIFT REGISTERS -- --------------------- p_shiftreg:process(clk, rst_n) begin if rst_n = '0' then r_corr <= (others => (others => '0')); r_seq <= (others => '0'); elsif rising_edge(clk) then if run_serial = '1' then if m_axis_tready = '1' then for I in 0 to C_N_MM_PSC-2 loop r_corr(I) <= r_corr(I+1); end loop; end if; else r_corr <= corrout; r_seq <= corrout_seq; end if; end if; end process; ----------------- -- PSCID TABLE -- ------------------ -- Port A is read write from AXI controller, Port B is read only from logic inst_refx_table: entity desy.ram_tdp generic map( G_ADDR => C_W_SER_CNT, G_DATA => C_W_PSCID ) port map( pi_clk_a => clk, pi_en_a => pscid_table_i.en, pi_we_a => pscid_table_i.we, pi_addr_a => pscid_table_i.addr(C_W_SER_CNT-1 downto 0), pi_data_a => pscid_table_i.data(C_W_PSCID-1 downto 0), po_data_a => pscid_table_o.data(C_W_PSCID-1 downto 0), pi_clk_b => clk, pi_en_b => '1', pi_we_b => '0', pi_addr_b => std_logic_vector(cnt), pi_data_b => (others => '0'), po_data_b => pscid ); pscid_table_o.data(31 downto C_W_PSCID) <= (others => '0'); ----------------------- -- OUTPUT CONNEXIONS -- ----------------------- m_axis_tdata <= pscid & std_logic_vector(r_corr(0)); m_axis_tuser <= r_seq; m_axis_tvalid <= run_serial; end architecture;