diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 073fa739ed01f57cb35d8e1ac66f7d9ea0ba17ea..4b3b7516a3fc7cc7105fda0f832a3ad86c9e302d 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -32,6 +32,7 @@ synth_files = src/vhdl/dp_force_data_parallel.vhd src/vhdl/mms_dp_force_data_parallel.vhd src/vhdl/mms_dp_force_data_parallel_arr.vhd + src/vhdl/dp_force_data_serial.vhd src/vhdl/dp_paged_sop_eop_reg.vhd src/vhdl/dp_packet_detect.vhd src/vhdl/dp_shiftreg.vhd diff --git a/libraries/base/dp/src/vhdl/dp_force_data_serial.vhd b/libraries/base/dp/src/vhdl/dp_force_data_serial.vhd new file mode 100644 index 0000000000000000000000000000000000000000..868c878b5ac1ee66ba8fda1cd5d4c30bf9bd7d42 --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_force_data_serial.vhd @@ -0,0 +1,154 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2017 +-- 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/>. +-- +------------------------------------------------------------------------------- +-- +-- Author: E. Kooistra, 27 jul 2017 +-- Purpose: +-- Force the sosi data field at a certain index in series or pass on. +-- Description: +-- The force_en input dynamically enables or disables the entire force +-- function. +-- The force value and index value are signal inputs to allow control via MM. +-- If the index counts on the valid and is reset by the sop then the value at +-- that index in each block is forced. If the index counts on the sop and is +-- reset by the sync then the entire block of values at that index in each +-- each sync interval is forced. +-- Data at the index can be forced to a value or passed on transparently. +-- Data not at the index is forced to zero. +-- +-- force_en = '0': pass on src_out = snk_in +-- force_en = '1': +-- when at force_index: +-- force_value = TRUE: force src_out data,re,im to force_data,re,im +-- force_value = FALSE: pass on src_out = snk_in +-- when not at force_index: +-- force src_out data,re,im to zero +-- +-- Usage: +-- . DSP tests: The amplitude of constant data is useful to verify scaling and +-- requantization. +-- . Data move test: Forcing constant (zero) data is useful for to trace data +-- when the data gets reordered. +-- Remarks: +-- . Ready latency = 1 +-- . When force_en='0' then this dp_force_data_serial is equivalent to +-- dp_pipeline. + +LIBRARY IEEE, common_lib; +USE IEEE.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE work.dp_stream_pkg.ALL; + +ENTITY dp_force_data_serial IS + GENERIC ( + g_dat_w : NATURAL := 32; -- must be <= 32 to fit INTEGER range + g_index_period : NATURAL := 10; -- number of indices in time + g_index_sample_block_n : BOOLEAN := FALSE -- when TRUE sample index in block, else block index in sync interval + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + -- MM control + force_en : IN STD_LOGIC := '0'; + force_value : IN STD_LOGIC := '0'; -- when TRUE force value at index, else pass on snk_in at index + force_data : IN INTEGER := 0; -- force value used for sosi.data + force_re : IN INTEGER := 0; -- force value used for sosi.re + force_im : IN INTEGER := 0; -- force value used for sosi.im + force_index : IN NATURAL := 0; -- sample index or block index in time dependent on g_index_sample_block_n + -- ST sink + snk_out : OUT t_dp_siso; + snk_in : IN t_dp_sosi; + -- ST source + src_in : IN t_dp_siso := c_dp_siso_rdy; + src_out : OUT t_dp_sosi + ); +END dp_force_data_serial; + + +ARCHITECTURE str OF dp_force_data_serial IS + + CONSTANT c_cnt_w : NATURAL := ceil_log2(g_index_period); + + SIGNAL cnt_clr : STD_LOGIC; + SIGNAL cnt_en : STD_LOGIC; + SIGNAL cnt : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0); + + SIGNAL data_in : t_dp_sosi; + +BEGIN + + cnt_clr <= snk_in.sop WHEN g_index_sample_block_n=TRUE ELSE snk_in.sync; + cnt_en <= snk_in.valid WHEN g_index_sample_block_n=TRUE ELSE snk_in.sop; + + u_common_counter : ENTITY common_lib.common_counter + GENERIC MAP ( + g_latency => 0, -- default 1 for registered count output, use 0 for immediate combinatorial count output + g_width => c_cnt_w, + g_max => g_index_period + ) + PORT MAP ( + rst => rst, + clk => clk, + cnt_clr => cnt_clr, + cnt_en => cnt_en, + count => cnt + ); + + p_comb : PROCESS(snk_in, cnt, force_en, force_index, force_value, force_data, force_re, force_im) + BEGIN + data_in <= snk_in; + IF force_en='1' THEN + -- default force zero for when not at index + data_in.data <= TO_DP_SDATA(force_data); + data_in.re <= TO_DP_DSP_DATA(force_re); + data_in.im <= TO_DP_DSP_DATA(force_im); + IF UNSIGNED(cnt)=force_index THEN + -- at index + IF force_value='1' THEN + -- force constant + data_in.data <= TO_DP_SDATA(force_data); + data_in.re <= TO_DP_DSP_DATA(force_re); + data_in.im <= TO_DP_DSP_DATA(force_im); + ELSE + -- transparant so keep snk_in + data_in <= snk_in; + END IF; + END IF; + END IF; + END PROCESS; + + u_dp_pipeline : ENTITY work.dp_pipeline + GENERIC MAP ( + g_pipeline => 1 + ) + PORT MAP ( + rst => rst, + clk => clk, + -- ST sink + snk_out => snk_out, + snk_in => data_in, + -- ST source + src_in => src_in, + src_out => src_out + ); + +END str;