From 9dd990582e35bc2172cd1d29552ef4fe6f20a61d Mon Sep 17 00:00:00 2001
From: Daniel van der Schuur <schuur@astron.nl>
Date: Wed, 18 Nov 2015 08:21:03 +0000
Subject: [PATCH] -Added output framer.

---
 .../apertif_unb1_correlator/hdllib.cfg        |   1 +
 .../apertif_unb1_correlator_output_framer.vhd | 173 ++++++++++++++++++
 2 files changed, 174 insertions(+)
 create mode 100644 applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_output_framer.vhd

diff --git a/applications/apertif/designs/apertif_unb1_correlator/hdllib.cfg b/applications/apertif/designs/apertif_unb1_correlator/hdllib.cfg
index 9f6ed50ebe..bc2d35b7fa 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 0000000000..8b76aa1d39
--- /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;
+
-- 
GitLab