From b96563e11dc57e763e4ec470590256ed4f4c0a95 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Wed, 6 May 2015 11:51:39 +0000 Subject: [PATCH] Ported dp_gap.vhd to $RADIOHDL, because now snk_out also passes on src_in.xon. --- libraries/base/dp/hdllib.cfg | 2 +- libraries/base/dp/src/vhdl/dp_gap.vhd | 154 ++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 libraries/base/dp/src/vhdl/dp_gap.vhd diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index b52394c2d5..ccbb6e1acf 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -78,7 +78,7 @@ synth_files = $UNB/Firmware/modules/dp/src/vhdl/dp_packet_enc_channel_lo.vhd $UNB/Firmware/modules/dp/src/vhdl/dp_packet_dec.vhd $UNB/Firmware/modules/dp/src/vhdl/dp_packet_dec_channel_lo.vhd - $UNB/Firmware/modules/dp/src/vhdl/dp_gap.vhd + src/vhdl/dp_gap.vhd $UNB/Firmware/modules/dp/src/vhdl/dp_mon.vhd $UNB/Firmware/modules/dp/src/vhdl/dp_bsn_monitor.vhd $UNB/Firmware/modules/dp/src/vhdl/dp_bsn_monitor_reg.vhd diff --git a/libraries/base/dp/src/vhdl/dp_gap.vhd b/libraries/base/dp/src/vhdl/dp_gap.vhd new file mode 100644 index 0000000000..a98cb37ded --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_gap.vhd @@ -0,0 +1,154 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012 +-- 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: Deassert snk_out.ready to greate gaps in source output. +-- +-- Description: +-- . g_dat_len indicates the maximum number of valid data cycles. +-- During the last of these valid cycles, snk_out.ready is deasserted so +-- g_gap_len invalid cycles are produced at the source. +-- +-- Remark: +-- . If a gap of sufficient (g_gap_len) length occured by itself (without +-- dp_gap de-asserting snk_out.ready, this gap is accounted for and +-- dp_gap will restart counting valid cycles as soon as the first +-- valid data work comes in. + +LIBRARY IEEE, common_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE work.dp_stream_pkg.ALL; +USE common_lib.common_pkg.ALL; + +ENTITY dp_gap IS + GENERIC ( + g_dat_len : NATURAL := 1000000; + g_gap_len : NATURAL := 5; + g_gap_extend : BOOLEAN := FALSE -- if TRUE, the first valid='0' cycle is extended to g_gap_len by de-assertion of snk_out.ready. + ); -- This results in all gaps having a minimum length of g_gap_len. + PORT ( + clk : IN STD_LOGIC; + rst : IN STD_LOGIC; + -- ST sink + snk_out : OUT t_dp_siso; + snk_in : IN t_dp_sosi; + -- ST source + src_in : IN t_dp_siso; + src_out : OUT t_dp_sosi + ); +END dp_gap; + +ARCHITECTURE rtl OF dp_gap IS + + CONSTANT c_dat_len_w : NATURAL := ceil_log2(g_dat_len); + CONSTANT c_gap_len_w : NATURAL := ceil_log2(largest(g_gap_len, 1)); + + TYPE t_state_enum IS (s_wait_for_val, s_counting, s_force_not_rdy); + + SIGNAL state : t_state_enum; + SIGNAL nxt_state : t_state_enum; + + SIGNAL clk_cnt : STD_LOGIC_VECTOR(c_dat_len_w-1 DOWNTO 0); + SIGNAL nxt_clk_cnt : STD_LOGIC_VECTOR(c_dat_len_w-1 DOWNTO 0); + + SIGNAL gap_cnt : STD_LOGIC_VECTOR(c_gap_len_w-1 DOWNTO 0); + SIGNAL nxt_gap_cnt : STD_LOGIC_VECTOR(c_gap_len_w-1 DOWNTO 0); + +BEGIN + + src_out <= snk_in; + + gen_rtl : IF g_gap_len>0 GENERATE + + p_clk : PROCESS(clk, rst) + BEGIN + IF rst='1' THEN + state <= s_wait_for_val; + clk_cnt <= (OTHERS=>'0'); + gap_cnt <= (OTHERS=>'0'); + ELSIF rising_edge(clk) THEN + state <= nxt_state; + clk_cnt <= nxt_clk_cnt; + gap_cnt <= nxt_gap_cnt; + END IF; + END PROCESS; + + p_state : PROCESS(state, clk_cnt, gap_cnt, snk_in, src_in) + BEGIN + nxt_state <= state; + nxt_clk_cnt <= clk_cnt; + nxt_gap_cnt <= gap_cnt; + snk_out <= src_in; -- Pass on the flow control by default + + CASE state IS + + WHEN s_wait_for_val => -- Wait for valid data to come in + IF snk_in.valid = '1' THEN + nxt_clk_cnt <= TO_UVEC(1, c_dat_len_w); + nxt_gap_cnt <= (OTHERS=>'0'); + nxt_state <= s_counting; + END IF; + + WHEN s_counting => -- Start counting cycles + nxt_clk_cnt <= INCR_UVEC(clk_cnt, 1); + IF clk_cnt = TO_UVEC(g_dat_len-1, c_dat_len_w) THEN -- time to force a gap + nxt_state <= s_force_not_rdy; + snk_out.ready <= '0'; + nxt_clk_cnt <= TO_UVEC(1, c_dat_len_w); -- we already have 1 clk cycle with ready='0' here + END IF; + IF snk_in.valid = '0' THEN -- Also start counting any invalid cycles + IF g_gap_extend = TRUE THEN + snk_out.ready <= '0'; -- Keep ready de-asserted. Gap_cnt will increment so it will be released again after g_gap_len. + END IF; + nxt_gap_cnt <= INCR_UVEC(gap_cnt, 1); + ELSE + nxt_gap_cnt <= (OTHERS=>'0'); + END IF; + IF gap_cnt = TO_UVEC(g_gap_len-1, c_gap_len_w) AND snk_in.valid = '0' THEN -- A gap of sufficient length occured by itself (or valid='0' was extended); no need to force gap + -- We've counted g_gap_len-1, plus the current gap cycle = g_gap_len + nxt_gap_cnt <= (OTHERS=>'0'); + nxt_clk_cnt <= (OTHERS=>'0'); + nxt_state <= s_wait_for_val; + IF g_gap_extend = TRUE THEN + snk_out.ready <= src_in.ready; -- Release the ready signal again if it was forced down because of gap extension + END IF; + END IF; + + WHEN s_force_not_rdy => -- Force snk_out.ready to '0' for g_gap_len clk cycles + snk_out.ready <= '0'; + nxt_clk_cnt <= INCR_UVEC(clk_cnt, 1); + IF clk_cnt = TO_UVEC(g_gap_len-1, c_dat_len_w) THEN + nxt_state <= s_wait_for_val; + nxt_clk_cnt <= (OTHERS=>'0'); + END IF; + + END CASE; + END PROCESS; + + END GENERATE; + + no_rtl : IF g_gap_len=0 GENERATE -- bypass + snk_out <= src_in; + END GENERATE; + +END rtl; + -- GitLab