diff --git a/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd b/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd
index 4d80e5106f9f13403e8961ac68a59c0be0c28733..102434984b1dc609bc3b119c45ce89ac3ba34595 100644
--- a/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd
+++ b/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd
@@ -30,14 +30,14 @@ USE dp_lib.dp_stream_pkg.ALL;
 -- Description:
 -- . A RAM-block is used to store the running sums as wel as to output the
 --   corresponding previous running sum so both align at the adder inputs.
--- . g_nof_words_to_acc=0 connects the source to the sink.
+-- . g_integration_period=0 connects the source to the sink.
 
 ENTITY corr_accumulator IS
   GENERIC (
-    g_nof_inputs        : NATURAL; -- Number of input streams
-    g_nof_acc_per_input : NATURAL; -- Number of accumulators to keep per input stream (a.k.a. channels)
-    g_nof_words_to_acc  : NATURAL; -- Number of words to accumulate
-    g_data_w            : NATURAL  -- Complex input data width
+    g_nof_inputs         : NATURAL; -- Number of input streams
+    g_nof_channels       : NATURAL; -- Number of accumulators to keep per input stream
+    g_integration_period : NATURAL; -- Number of timesamples to accumulate
+    g_data_w             : NATURAL  -- Complex input data width
    ); 
   PORT (
     rst            : IN  STD_LOGIC;
@@ -50,22 +50,22 @@ END corr_accumulator;
 
 ARCHITECTURE str OF corr_accumulator IS
 
-  -- Complex accumulator data width: wide enough to support g_nof_words_to_acc accumulations
-  CONSTANT c_acc_data_w               : NATURAL := ceil_log2(g_nof_words_to_acc*(pow2(g_data_w)-1));
+  -- Complex accumulator data width: wide enough to support g_integration_period accumulations
+  CONSTANT c_acc_data_w               : NATURAL := ceil_log2(g_integration_period*(pow2(g_data_w)-1));
 
   -- c_shiftram_delay is such that common_shiftram output aligns exactly with snk_in_arr. Functionally this 
   -- means we aligned the current word to the corresponding previous word at the adder inputs.
   CONSTANT c_shiftram_io_delay        : NATURAL := 4; -- common_shiftram data_in takes 4 cycles to emerge as data_out
 
   -- Note: Increase corr_adder pipelining by n = decrease c_shiftram_io_delay by n and vice versa.
-  CONSTANT c_shiftram_delay           : NATURAL := g_nof_acc_per_input-c_shiftram_io_delay-2;
+  CONSTANT c_shiftram_delay           : NATURAL := g_nof_channels-c_shiftram_io_delay-2;
 
-  CONSTANT c_shift_w                  : NATURAL := ceil_log2(g_nof_acc_per_input);
+  CONSTANT c_shift_w                  : NATURAL := ceil_log2(g_nof_channels);
   CONSTANT c_common_shiftram_shift_in : STD_LOGIC_VECTOR(c_shift_w-1 DOWNTO 0) := TO_UVEC(c_shiftram_delay, c_shift_w);
 
   -- Counter to keep track of the total numer of accumulations so we know when to reset accumulator to zero
-  SIGNAL acc_cnt                      : STD_LOGIC_VECTOR(ceil_log2(g_nof_acc_per_input*g_nof_words_to_acc)-1 DOWNTO 0);
-  SIGNAL nxt_acc_cnt                  : STD_LOGIC_VECTOR(ceil_log2(g_nof_acc_per_input*g_nof_words_to_acc)-1 DOWNTO 0);
+  SIGNAL acc_cnt                      : STD_LOGIC_VECTOR(ceil_log2(g_nof_channels*g_integration_period)-1 DOWNTO 0);
+  SIGNAL nxt_acc_cnt                  : STD_LOGIC_VECTOR(ceil_log2(g_nof_channels*g_integration_period)-1 DOWNTO 0);
 
   SIGNAL corr_adder_snk_in_2arr_2     : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0); -- Array of pairs
   SIGNAL nxt_corr_adder_snk_in_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0); -- Array of pairs
@@ -88,15 +88,15 @@ BEGIN
   -- we'll feed zeros into the second adder input to reset the accumulator value
   -- for each channel.
   -----------------------------------------------------------------------------
-  nxt_acc_cnt <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)=g_nof_acc_per_input*g_nof_words_to_acc-1 ELSE
+  nxt_acc_cnt <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)=g_nof_channels*g_integration_period-1 ELSE
                  INCR_UVEC(acc_cnt, 1) WHEN snk_in_arr(0).valid = '1' ELSE acc_cnt;
 
   gen_adder_inputs : FOR i IN 0 TO g_nof_inputs-1 GENERATE
     nxt_corr_adder_snk_in_2arr_2(i)(0) <= snk_in_arr(i);
     nxt_corr_adder_snk_in_2arr_2(i)(1).valid                       <= common_shiftram_src_out_arr(i).valid; 
-    nxt_corr_adder_snk_in_2arr_2(i)(1).re(c_acc_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)<=g_nof_acc_per_input-1 ELSE
+    nxt_corr_adder_snk_in_2arr_2(i)(1).re(c_acc_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)<=g_nof_channels-1 ELSE
                                                                       common_shiftram_src_out_arr(i).data(2*c_acc_data_w-1 DOWNTO c_acc_data_w);
-    nxt_corr_adder_snk_in_2arr_2(i)(1).im(c_acc_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)<=g_nof_acc_per_input-1 ELSE
+    nxt_corr_adder_snk_in_2arr_2(i)(1).im(c_acc_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)<=g_nof_channels-1 ELSE
                                                                       common_shiftram_src_out_arr(i).data(  c_acc_data_w-1 DOWNTO 0);  
   END GENERATE;
 
@@ -132,7 +132,7 @@ BEGIN
     u_common_shiftram : ENTITY common_lib.common_shiftram
     GENERIC MAP (
       g_data_w                           => 2*c_acc_data_w,
-      g_nof_words                        => pow2(ceil_log2(g_nof_acc_per_input)),
+      g_nof_words                        => pow2(ceil_log2(g_nof_channels)),
       g_output_invalid_during_shift_incr => TRUE,
       g_fixed_shift                      => TRUE
     )
@@ -151,8 +151,8 @@ BEGIN
   END GENERATE;
 
   -----------------------------------------------------------------------------
-  -- Output g_nof_words_to_acc per stream once per integration period
-  -- . The first g_nof_acc_per_input words are output. At the same time, the
+  -- Output g_integration_period per stream once per integration period
+  -- . The first g_nof_channels words are output. At the same time, the
   --   accumulators are reset (zeros) at the adder inputs.
   -- . Make sure the shiftram output is valid too so we don't output a block
   --   of zeros initially.
@@ -161,9 +161,9 @@ BEGIN
     nxt_src_out_arr(i).re(c_acc_data_w-1 DOWNTO 0) <= common_shiftram_src_out_arr(i).data(2*c_acc_data_w-1 DOWNTO c_acc_data_w);
     nxt_src_out_arr(i).im(c_acc_data_w-1 DOWNTO 0) <= common_shiftram_src_out_arr(i).data(  c_acc_data_w-1 DOWNTO 0);
     
-    nxt_src_out_arr(i).valid <= '1' WHEN TO_UINT(acc_cnt)<g_nof_acc_per_input   AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
-    nxt_src_out_arr(i).sop   <= '1' WHEN TO_UINT(acc_cnt)=0                     AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
-    nxt_src_out_arr(i).eop   <= '1' WHEN TO_UINT(acc_cnt)=g_nof_acc_per_input-1 AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
+    nxt_src_out_arr(i).valid <= '1' WHEN TO_UINT(acc_cnt)<g_nof_channels   AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
+    nxt_src_out_arr(i).sop   <= '1' WHEN TO_UINT(acc_cnt)=0                AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
+    nxt_src_out_arr(i).eop   <= '1' WHEN TO_UINT(acc_cnt)=g_nof_channels-1 AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
   END GENERATE;
 
   -----------------------------------------------------------------------------
diff --git a/libraries/dsp/correlator/src/vhdl/correlator.vhd b/libraries/dsp/correlator/src/vhdl/correlator.vhd
index 94f11bafa6bdddd5bb1f7c826488acfaf0a4e7c7..715e115a74f42afd3ded8c0401c2f43709e2a5f3 100644
--- a/libraries/dsp/correlator/src/vhdl/correlator.vhd
+++ b/libraries/dsp/correlator/src/vhdl/correlator.vhd
@@ -32,12 +32,12 @@ USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY correlator IS
   GENERIC (
-    g_nof_inputs        : NATURAL;
-    g_nof_mults         : NATURAL;
-    g_data_w            : NATURAL := 16;
-    g_conjugate         : BOOLEAN := TRUE;
-    g_nof_acc_per_input : NATURAL := 64; -- aka channels
-    g_nof_words_to_acc  : NATURAL := 55  -- Internally forced to g_nof_mults as a minimum unless zero
+    g_nof_inputs         : NATURAL;
+    g_nof_pre_mult_folds : NATURAL := 0;  -- Number of pre-multiplier stage folds.
+    g_data_w             : NATURAL := 16; -- Complex data width
+    g_conjugate          : BOOLEAN := TRUE;
+    g_nof_channels       : NATURAL := 64; -- Number of (serial) channels per (parallel) input
+    g_integration_period : NATURAL := 0   -- Expressed as the number of samples per channel to accumulate 
    ); 
   PORT (
     rst            : IN  STD_LOGIC;
@@ -51,21 +51,34 @@ END correlator;
 
 ARCHITECTURE str OF correlator IS
 
+  CONSTANT c_nof_visibilities           : NATURAL := (g_nof_inputs*(g_nof_inputs+1))/2;
+
+  -----------------------------------------------------------------------------
+  -- The array of multiplier input streams can be folded, e.g.:
+  -- . c_nof_visibilities=10, g_nof_pre_mult_folds=0 -> c_nof_mults=10
+  -- . c_nof_visibilities=10, g_nof_pre_mult_folds=1 -> c_nof_mults= 5
+  -- . c_nof_visibilities=10, g_nof_pre_mult_folds=2 -> c_nof_mults= 3
+  -- . c_nof_visibilities=10, g_nof_pre_mult_folds=3 -> c_nof_mults= 2
+  -- . c_nof_visibilities=10, g_nof_pre_mult_folds=4 -> c_nof_mults= 1
+  -- . c_nof_visibilities=10, g_nof_pre_mult_folds<0 -> c_nof_mults= 1
+  -----------------------------------------------------------------------------
+  CONSTANT c_nof_mults                  : NATURAL := sel_a_b(g_nof_pre_mult_folds>=0, ceil_div(c_nof_visibilities, ceil_pow2(g_nof_pre_mult_folds)), 1);
+
   -- We can multiplex the accumulator outputs onto one stream as long as the integration period is
   -- equal to or larger than the number of accumulator outputs.
-  CONSTANT c_nof_words_to_acc : NATURAL := largest(g_nof_words_to_acc, g_nof_mults);
+  CONSTANT c_integration_period         : NATURAL := largest(g_integration_period, c_nof_mults);
 
-  CONSTANT c_acc_data_w                 : NATURAL := ceil_log2(c_nof_words_to_acc*(pow2(g_data_w)-1));
+  CONSTANT c_acc_data_w                 : NATURAL := ceil_log2(c_integration_period*(pow2(g_data_w)-1));
 
   SIGNAL corr_permutator_src_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs
   SIGNAL corr_folder_snk_in_2arr_2      : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs, not folded yet
   SIGNAL corr_folder_src_out_2arr_2     : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs, not folded yet
-  SIGNAL corr_multiplier_src_out_arr    : t_dp_sosi_arr(g_nof_mults-1 DOWNTO 0);
-  SIGNAL corr_accumulator_snk_in_arr    : t_dp_sosi_arr(g_nof_mults-1 DOWNTO 0);
-  SIGNAL corr_accumulator_src_out_arr   : t_dp_sosi_arr(g_nof_mults-1 DOWNTO 0);
-  SIGNAL dp_fifo_sc_snk_in_arr          : t_dp_sosi_arr(g_nof_mults-1 DOWNTO 0);
-  SIGNAL dp_fifo_sc_src_out_arr         : t_dp_sosi_arr(g_nof_mults-1 DOWNTO 0);
-  SIGNAL dp_fifo_sc_src_in_arr          : t_dp_siso_arr(g_nof_mults-1 DOWNTO 0);
+  SIGNAL corr_multiplier_src_out_arr    : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0);
+  SIGNAL corr_accumulator_snk_in_arr    : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0);
+  SIGNAL corr_accumulator_src_out_arr   : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0);
+  SIGNAL dp_fifo_sc_snk_in_arr          : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0);
+  SIGNAL dp_fifo_sc_src_out_arr         : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0);
+  SIGNAL dp_fifo_sc_src_in_arr          : t_dp_siso_arr(c_nof_mults-1 DOWNTO 0);
   SIGNAL corr_folder_src_out_arr        : t_dp_sosi_arr(1-1 DOWNTO 0);
 
 BEGIN
@@ -88,7 +101,7 @@ BEGIN
   -----------------------------------------------------------------------------
   -- Permutator -> folder pipeline
   -----------------------------------------------------------------------------
-  gen_dp_pipeline_corr_permutator_src_out_2arr2 : FOR i IN 0 TO g_nof_mults-1 GENERATE
+  gen_dp_pipeline_corr_permutator_src_out_2arr2 : FOR i IN 0 TO c_nof_mults-1 GENERATE
     gen_dp_pipeline : FOR j IN 0 TO 2-1 GENERATE
       u_dp_pipeline : ENTITY dp_lib.dp_pipeline
       GENERIC MAP (
@@ -105,7 +118,7 @@ BEGIN
   END GENERATE;
 
   -----------------------------------------------------------------------------
-  -- Fold the streams if g_nof_mults < g_nof_inputs
+  -- Fold the streams if c_nof_mults < g_nof_inputs
   -- . Folder not implemented yet; section bypassed.
   -----------------------------------------------------------------------------
   corr_folder_src_out_2arr_2 <= corr_folder_snk_in_2arr_2;
@@ -115,7 +128,7 @@ BEGIN
   -----------------------------------------------------------------------------
   u_corr_multiplier : ENTITY work.corr_multiplier
   GENERIC MAP (
-    g_nof_inputs => g_nof_mults,
+    g_nof_inputs => c_nof_mults,
     g_data_w     => g_data_w,
     g_conjugate  => g_conjugate
   )
@@ -130,7 +143,7 @@ BEGIN
   -----------------------------------------------------------------------------
   -- Multiplier -> Accumulator pipeline
   -----------------------------------------------------------------------------
-  gen_dp_pipeline_corr_multiplier_src_out_arr : FOR i IN 0 TO g_nof_mults-1 GENERATE
+  gen_dp_pipeline_corr_multiplier_src_out_arr : FOR i IN 0 TO c_nof_mults-1 GENERATE
     u_dp_pipeline : ENTITY dp_lib.dp_pipeline
     GENERIC MAP (
       g_pipeline => 0
@@ -149,10 +162,10 @@ BEGIN
   -----------------------------------------------------------------------------
   u_corr_accumulator : ENTITY work.corr_accumulator
   GENERIC MAP (
-    g_nof_inputs        => g_nof_mults,
-    g_nof_acc_per_input => g_nof_acc_per_input,
-    g_nof_words_to_acc  => c_nof_words_to_acc,
-    g_data_w            => g_data_w 
+    g_nof_inputs         => c_nof_mults,
+    g_nof_channels       => g_nof_channels,
+    g_integration_period => c_integration_period,
+    g_data_w             => g_data_w 
   )
   PORT MAP (
     clk            => clk,
@@ -165,7 +178,7 @@ BEGIN
   -----------------------------------------------------------------------------
   -- Accumulator -> FIFO pipeline
   -----------------------------------------------------------------------------
-  gen_dp_pipeline_corr_accumulator_src_out_arr : FOR i IN 0 TO g_nof_mults-1 GENERATE
+  gen_dp_pipeline_corr_accumulator_src_out_arr : FOR i IN 0 TO c_nof_mults-1 GENERATE
     u_dp_pipeline : ENTITY dp_lib.dp_pipeline
     GENERIC MAP (
       g_pipeline => 0
@@ -185,7 +198,7 @@ BEGIN
   --   to buffer the visibilities so we can take our time to multiplex them 
   --   onto one stream.
   ------------------------------------------------------------------------------
-  gen_dp_fifo_sc : FOR i IN 0 TO g_nof_mults-1 GENERATE
+  gen_dp_fifo_sc : FOR i IN 0 TO c_nof_mults-1 GENERATE
     u_dp_fifo_sc : ENTITY dp_lib.dp_fifo_sc
     GENERIC MAP (
       g_data_w         => 2*c_acc_data_w,
@@ -232,11 +245,11 @@ BEGIN
   --  14) |                           [0] .                           [1]       
   --  15) |<---g_init_valid_delay(15)-->[0]                             [1]     
   ------------------------------------------------------------------------------
-  gen_dp_src_out_timer : FOR i IN 0 TO g_nof_mults-1 GENERATE
+  gen_dp_src_out_timer : FOR i IN 0 TO c_nof_mults-1 GENERATE
     u_dp_src_out_timer : ENTITY dp_lib.dp_src_out_timer
     GENERIC MAP (
       g_init_valid_delay      => i, --relative to dp_fifo_sc_src_out_arr(i).valid
-      g_nof_invalid_per_valid => g_nof_mults
+      g_nof_invalid_per_valid => c_nof_mults
     )
     PORT MAP (
       rst                  => rst,
@@ -254,7 +267,7 @@ BEGIN
   ------------------------------------------------------------------------------
   u_corr_folder : ENTITY work.corr_folder
   GENERIC MAP (
-    g_nof_inputs => c_nof_words_to_acc,
+    g_nof_inputs => c_integration_period,
     g_nof_folds  => -1 
   )
   PORT MAP (
@@ -268,12 +281,12 @@ BEGIN
 
   -----------------------------------------------------------------------------
   -- Add proper SOP and EOP to mux output
-  -- . Output one block of g_nof_mults for each channel
+  -- . Output one block of c_nof_mults for each channel
   -----------------------------------------------------------------------------
   dp_block_gen: ENTITY dp_lib.dp_block_gen
   GENERIC MAP (
     g_use_src_in         => FALSE,
-    g_nof_data           => g_nof_mults,
+    g_nof_data           => c_nof_mults,
     g_nof_blk_per_sync   => 10 -- Randomly chosen sync interval 
   )
   PORT MAP (
diff --git a/libraries/dsp/correlator/tb/vhdl/tb_correlator.vhd b/libraries/dsp/correlator/tb/vhdl/tb_correlator.vhd
index a65e002c13d59fd253c50698eea8dde2679f6c13..adce654f818c73dd93b2ad1b8974d5e5805f894a 100644
--- a/libraries/dsp/correlator/tb/vhdl/tb_correlator.vhd
+++ b/libraries/dsp/correlator/tb/vhdl/tb_correlator.vhd
@@ -36,7 +36,6 @@ END tb_correlator;
 ARCHITECTURE tb OF tb_correlator IS
 
   CONSTANT c_nof_inputs         : NATURAL := 10;
-  CONSTANT c_nof_mults          : NATURAL := (c_nof_inputs*(c_nof_inputs+1))/2;
   CONSTANT c_nof_channels       : NATURAL := 64;
 
   CONSTANT c_dp_clk_period      : TIME := 10 ns;
@@ -131,9 +130,7 @@ BEGIN
   u_correlator : ENTITY work.correlator
   GENERIC MAP (
     g_nof_inputs => c_nof_inputs,
-    g_nof_mults  => c_nof_mults,
-    g_data_w     => c_complex_data_w,
-    g_nof_words_to_acc => c_nof_mults
+    g_data_w     => c_complex_data_w
   )
   PORT MAP (
     clk         => dp_clk,