diff --git a/libraries/base/dp/src/vhdl/dp_sync_checker.vhd b/libraries/base/dp/src/vhdl/dp_sync_checker.vhd new file mode 100644 index 0000000000000000000000000000000000000000..32a7de5be9fa62d4e85170a7c5da968bcdf50cf4 --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_sync_checker.vhd @@ -0,0 +1,150 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2011 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-------------------------------------------------------------------------------- + +-- Purpose: Checks if the number of SOPs within a sync interval is as expected and +-- corrects if sync is too early or too late. + +-- +-- Description: +-- +-- Remarks: Parsing of backpressure is not yet implemented, since it was not +-- required for the first purpose of this block (in reorder_transpose). +-- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE work.dp_stream_pkg.ALL; + +ENTITY dp_sync_checker IS + GENERIC( + g_nof_blk_per_sync : NATURAL := 16 + ); + PORT ( + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + dp_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + + -- ST sinks + snk_out : OUT t_dp_siso := c_dp_siso_rdy; + snk_in : IN t_dp_sosi; + -- ST source + src_in : IN t_dp_siso; + src_out : OUT t_dp_sosi + + -- Memory Mapped +-- reg_dp_sync_checker_mosi : IN t_mem_mosi; +-- reg_dp_sync_checker_miso : OUT t_mem_miso + ); +END dp_sync_checker; + +ARCHITECTURE str OF dp_sync_checker IS + + CONSTANT c_nof_blk_per_sync : NATURAL := g_nof_blk_per_sync - 1; + + TYPE reg_type IS RECORD + snk_in : t_dp_sosi; + src_out : t_dp_sosi; + cnt_sop : NATURAL; + sync_too_early : STD_LOGIC; + wait_for_next_sync : STD_LOGIC; + nof_early_syncs : NATURAL; + nof_late_syncs : NATURAL; + END RECORD; + + SIGNAL r, rin : reg_type; + +BEGIN + + p_comb : PROCESS(r, dp_rst, snk_in ) + VARIABLE v : reg_type; + BEGIN + v := r; + + v.snk_in := snk_in; + + IF(snk_in.sync = '1') THEN + v.wait_for_next_sync := '0'; + v.sync_too_early := '0'; + END IF; + + -- Check on incoming SOP if things are OK + IF (snk_in.sop = '1') THEN + IF(r.wait_for_next_sync = '0') THEN + v.cnt_sop := r.cnt_sop + 1; + END IF; + IF(r.cnt_sop = c_nof_blk_per_sync) THEN + v.cnt_sop := 0; + IF(r.sync_too_early = '1') THEN + -- Too early + v.wait_for_next_sync := '1'; + ELSIF(snk_in.sync = '0') THEN + -- Too late + v.wait_for_next_sync := '1'; + v.nof_late_syncs := r.nof_late_syncs + 1; + END IF; + END IF; + END IF; + + -- Detect SYNC that is too early + IF (snk_in.sync ='1' AND r.cnt_sop < c_nof_blk_per_sync AND r.wait_for_next_sync = '0') THEN + v.sync_too_early := '1'; + v.snk_in.sync := '0'; -- Remove sync from input. + v.nof_early_syncs := r.nof_early_syncs + 1; + END IF; + + -- Only pass input to output when not waiting for valid SYNC. + IF(r.wait_for_next_sync ='0') THEN + v.src_out := r.snk_in; + ELSE + v.src_out := c_dp_sosi_rst; + END IF; + + IF(dp_rst = '1') THEN + v.snk_in := c_dp_sosi_rst; + v.src_out := c_dp_sosi_rst; + v.cnt_sop := 0; + v.sync_too_early := '0'; + v.wait_for_next_sync := '1'; + v.nof_early_syncs := 0; + v.nof_late_syncs := 0; + END IF; + + rin <= v; + + END PROCESS; + + p_regs : PROCESS(dp_clk) + BEGIN + IF RISING_EDGE(dp_clk) THEN + r <= rin; + END IF; + END PROCESS; + + src_out <= r.src_out; + +END str; + +