diff --git a/applications/apertif/designs/apertif_unb1_correlator/hdllib.cfg b/applications/apertif/designs/apertif_unb1_correlator/hdllib.cfg index 9f6ed50ebedc277a8a4e36f13bad4342d31a42ae..bc2d35b7fa6e2d0740e0b82c0f657cdd4fce149b 100644 --- a/applications/apertif/designs/apertif_unb1_correlator/hdllib.cfg +++ b/applications/apertif/designs/apertif_unb1_correlator/hdllib.cfg @@ -20,6 +20,7 @@ synth_files = $HDL_BUILD_DIR/unb1/quartus/apertif_unb1_correlator/sopc_apertif_unb1_correlator.vhd src/vhdl/mmm_apertif_unb1_correlator.vhd src/vhdl/apertif_unb1_correlator_vis_offload.vhd + src/vhdl/apertif_unb1_correlator_vis_offload_output_framer.vhd src/vhdl/apertif_unb1_correlator.vhd test_bench_files = diff --git a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_output_framer.vhd b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_output_framer.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8b76aa1d392a3c9a1b76a2d91a95a074f17f85bd --- /dev/null +++ b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_output_framer.vhd @@ -0,0 +1,173 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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/>. +-- +-------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +-- Purpose: +-- . Forward input stream with added channel (and optional sync, BSN) field +-- Description: +-- . The above is implemented as follows: +-- . dp_block_gen_sop_eop_sync generates the SOP, EOP and Sync +-- . A clocked process adds: +-- . channel based on SOP. +-- . the BSN based on Sync. + +ENTITY corr_output_framer IS + GENERIC ( + g_nof_streams : NATURAL; -- Number of input/output streams + g_nof_folds : NATURAL := 0; -- If >0, channel indices are folded accordingly + g_nof_channels : NATURAL; -- Number of channels + g_nof_channel_frames_per_sync : NATURAL; -- Number of channel frames (g_nof_channels long) per sync + g_generate_sync_and_bsn : BOOLEAN; -- FALSE uses sync and BSN from snk_in_arr + g_fft_channel_index_reorder : BOOLEAN -- TRUE if input data is FFT output that needs channel reordering + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + + snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + + src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) + ); +END corr_output_framer; + +ARCHITECTURE str OF corr_output_framer IS + + SIGNAL dp_pipeline_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + + SIGNAL dp_block_gen_src_out : t_dp_sosi; + SIGNAL reg_dp_block_gen_src_out : t_dp_sosi; + + SIGNAL channel_bsn_src_out : t_dp_sosi; + SIGNAL nxt_channel_bsn_src_out : t_dp_sosi; + + SIGNAL folded_word_cnt : STD_LOGIC_VECTOR(g_nof_folds-1 DOWNTO 0); + SIGNAL nxt_folded_word_cnt : STD_LOGIC_VECTOR(g_nof_folds-1 DOWNTO 0); + +BEGIN + + ----------------------------------------------------------------------------- + -- dp_block_gen to create correc SOP,EOP and Sync + ----------------------------------------------------------------------------- + u_dp_block_gen_sop_eop_sync: ENTITY dp_lib.dp_block_gen + GENERIC MAP ( + g_use_src_in => FALSE, + g_nof_data => g_nof_channels*pow2(g_nof_folds), + g_nof_blk_per_sync => g_nof_channel_frames_per_sync + ) + PORT MAP ( + rst => rst, + clk => clk, + + snk_in => snk_in_arr(0), + + src_out => dp_block_gen_src_out + ); + + ----------------------------------------------------------------------------- + -- Create channel (based on SOP) and BSN (based on Sync) + -- . account for folding + ----------------------------------------------------------------------------- + p_channel_bsn : PROCESS(dp_block_gen_src_out, channel_bsn_src_out, folded_word_cnt) + BEGIN + nxt_channel_bsn_src_out.channel <= channel_bsn_src_out.channel; + nxt_channel_bsn_src_out.bsn <= channel_bsn_src_out.bsn; + nxt_folded_word_cnt <= folded_word_cnt; + -- Channel + + IF dp_block_gen_src_out.valid = '1' THEN + nxt_folded_word_cnt <= INCR_UVEC(folded_word_cnt, 1); + IF UNSIGNED(folded_word_cnt)=pow2(g_nof_folds)-1 THEN + nxt_channel_bsn_src_out.channel <= INCR_UVEC(channel_bsn_src_out.channel, 1); + nxt_folded_word_cnt <= (OTHERS=>'0'); + END IF; + END IF; + + IF dp_block_gen_src_out.sop='1' THEN + IF (channel_bsn_src_out.channel = TO_DP_CHANNEL(g_nof_channels-1)) AND (UNSIGNED(folded_word_cnt)=pow2(g_nof_folds)-1) THEN + nxt_channel_bsn_src_out.channel <= TO_DP_CHANNEL(0); + END IF; + END IF; + + -- BSN + IF dp_block_gen_src_out.sync='1' THEN + nxt_channel_bsn_src_out.bsn <= INCR_UVEC(channel_bsn_src_out.bsn, 1); + END IF; + END PROCESS; + + -- Registers: also register dp_block_gen_src_out to align it with p_channel_bsn outputs + p_clk: PROCESS(clk, rst) + BEGIN + IF rst='1' THEN + channel_bsn_src_out <= (c_dp_sosi_rst); + reg_dp_block_gen_src_out <= (c_dp_sosi_rst); + FOR i IN 0 TO g_nof_streams-1 LOOP + channel_bsn_src_out.channel <= X"FFFFFFFF"; -- Wrap to 0 on first increment + channel_bsn_src_out.bsn <= X"FFFFFFFF_FFFFFFFF"; -- Wrap to 0 on first increment +-- channel_bsn_src_out.channel <= (OTHERS=>'0'); +-- channel_bsn_src_out.bsn <= (OTHERS=>'0'); + folded_word_cnt <= (OTHERS=>'1'); -- Wrap to 0 on first increment + END LOOP; + ELSIF rising_edge(clk) THEN + channel_bsn_src_out <= nxt_channel_bsn_src_out; + reg_dp_block_gen_src_out <= dp_block_gen_src_out; + folded_word_cnt <= nxt_folded_word_cnt; + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- Pipeline the inputs to align them with locally generated fields + ----------------------------------------------------------------------------- + gen_dp_pipeline : FOR i IN 0 TO g_nof_streams-1 GENERATE + u_dp_pipeline : ENTITY dp_lib.dp_pipeline + GENERIC MAP ( + g_pipeline => 2 + ) + PORT MAP ( + rst => rst, + clk => clk, + + snk_in => snk_in_arr(i), + src_out => dp_pipeline_src_out_arr(i) + ); + END GENERATE; + + ----------------------------------------------------------------------------- + -- Add channel,bsn fields to reg_dp_block_gen_src_out and forward to src_out_arr + ----------------------------------------------------------------------------- + p_wires : PROCESS(reg_dp_block_gen_src_out, channel_bsn_src_out, dp_pipeline_src_out_arr) + BEGIN + src_out_arr <= dp_pipeline_src_out_arr; + FOR i IN 0 TO g_nof_streams-1 LOOP + src_out_arr(i).data <= (OTHERS=>'0'); + src_out_arr(i).sync <= reg_dp_block_gen_src_out.sync; + + src_out_arr(i).channel <= channel_bsn_src_out.channel; + src_out_arr(i).bsn <= channel_bsn_src_out.bsn; + END LOOP; + END PROCESS; + +END str; +