--
-- data_logger.vhd
--
-- Timing Signal Edge detection and multiplexing
--
--
-- Version 1.0 4/1/06 A.McCormick (Alpha Data)


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;

entity data_logger is
  
  port (
    clk               : in  std_logic;
    rst               : in  std_logic;
    ten_mhz_clk       : in  std_logic;
    -- Inputs from PLL
    ms_pulse          : in  std_logic;
    acq               : in  std_logic;
    cycle             : in  std_logic_vector(31 downto 0);
    ctime             : in  std_logic_vector(31 downto 0);
    sigma_avg         : in  std_logic_vector(15 downto 0);
    deltax_avg        : in  std_logic_vector(15 downto 0);
    deltay_avg        : in  std_logic_vector(15 downto 0);
    avg_valid         : in  std_logic;
    init              : in  std_logic;
    bunchmean_acc     : in  std_logic_vector(1 downto 0);
    phase_table_sync  : in std_Logic;
    hchange_sync           : in  std_logic;
    injection_sync      : in std_logic;
    cal_start_sync      : in std_logic;
    -- Timing Inputs (already edge detected)
    cycle_start_edge       : in  std_logic;
    cycle_stop_edge        : in  std_logic;
    cal_start_edge         : in  std_logic;
    cal_stop_edge          : in  std_logic;
    injection_edge         : in  std_logic;
    hchange_edge           : in  std_logic;
    -- Timing Inputs 
    cycle_start       : in  std_logic;
    cycle_start_ten_mhz       : in  std_logic;
    cycle_stop        : in  std_logic;
    cal_start         : in  std_logic;
    cal_stop          : in  std_logic;
    injection         : in  std_logic;
    hchange           : in  std_logic;
    fref              : in  std_logic;
    -- Diagnostics from PLL
    diagnostics       : in  std_logic_vector(255 downto 0);
    -- Host Control Registers
    diag_control      : in  std_logic_vector(31 downto 0);
    diag_control_set  : in  std_logic;
    diag_delay      : in  std_logic_vector(31 downto 0);
    diag_delay_set  : in  std_logic;
    diag_trigger      : in  std_logic_vector(31 downto 0);
    diag_status       : out   std_logic_vector(31 downto 0);
    diag_irq          : out std_logic;
    -- Write Signals to Memory
    sdram_addr        : out std_logic_vector(24 downto 0);
    sdram_data        : out std_logic_vector(63 downto 0);
    sdram_write       : out std_logic;
    timing_addr       : out std_logic_vector(11 downto 0);
    timing_data       : out std_logic_vector(63 downto 0);
    timing_write      : out std_logic;
    info_addr         : out std_logic_vector(5 downto 0);
    info_data         : out std_logic_vector(63 downto 0);
    info_write        : out std_logic;
    diagnostics_data  : out std_logic_vector(63 downto 0);
    diagnostics_addr  : out std_logic_vector(11 downto 0);
    diagnostics_write : out std_logic;
    bunchmean0_data   : out std_logic_vector(63 downto 0);
    bunchmean0_addr   : out std_logic_vector(11 downto 0);
    bunchmean0_write   : out std_logic;
    bunchmean1_data   : out std_logic_vector(63 downto 0);
    bunchmean1_addr   : out std_logic_vector(11 downto 0);
    bunchmean1_write   : out std_logic);

end data_logger;

architecture rtl of data_logger is

  constant bunch_mean_base_addr  : integer := 254*1024*1024/8;
  constant number_of_bunches : integer := 24;
  
  signal sdram_addr_i : std_logic_vector(24 downto 0);
  signal sdram_addr_sync : std_logic_vector(24 downto 0);
  signal timing_addr_i : std_logic_vector(11 downto 0);
  signal event_counter : std_logic_vector(3 downto 0);

  signal trigger,trigger1 : std_logic_vector(7 downto 0);
  signal analyser_data,analyser_data1,analyser_data2: std_logic_vector(63 downto 0);
  signal analyser_src : std_logic_vector(1 downto 0);
  signal store_trigger : std_logic;
  signal arm : std_logic;
  signal capturing : std_logic;
  
  signal clk_counter : std_logic_vector(16 downto 0);
  signal clk_count_limit : std_logic_vector(16 downto 0);
  signal clk_count_strb : std_logic;
  signal clk_select  : std_logic_vector(4 downto 0);

  signal trig_and,trig_or,data_and,data_or : std_logic;
  signal wait_clk : std_logic;
  signal capture_count : std_logic_vector(11 downto 0);
  signal sample_clk : std_logic;
  
  signal diagnostics_r1       :  std_logic_vector(255 downto 0);

  signal fref_reg : std_logic;

  signal trig_delay : std_logic_vector(31 downto 0);
  signal trig_delayed : std_logic;

  signal info_clear_count : std_logic_vector(3 downto 0);

  -- BRAM based bunch mean average system
  signal bma_s0,bma_dx0,bma_dy0,bma_s1,bma_dx1,bma_dy1 : std_logic_vector(15 downto 0);
  signal bma_counter2,bma_counter3 : std_logic_vector(15 downto 0);
  signal bma_s2,bma_dx2,bma_dy2,bma_s3,bma_dx3,bma_dy3 : std_logic_vector(27 downto 0);


  -- SDRAM based bunch mean average system
  type bunch_mean_array is array (natural range <>) of std_logic_vector(31 downto 0);

  signal sigma_averages,deltax_averages,deltay_averages,counts : bunch_mean_array(0 to number_of_bunches);

  signal bunch_one_hot : std_logic_vector(number_of_bunches-1 downto 0);
  signal bunch_mean_acc_valid : std_logic_vector(number_of_bunches downto 0);
  
  component bunch_mean_acc
    port (
      clk : in std_logic;
      acc : in std_logic;
      clr : in std_logic;
      sigma  : in std_logic_vector(15 downto 0);
      deltax : in std_logic_vector(15 downto 0);
      deltay : in std_logic_vector(15 downto 0);
      sum_sigma : out std_logic_vector(31 downto 0);
      sum_deltax : out std_logic_vector(31 downto 0);
      sum_deltay : out std_logic_vector(31 downto 0);
      count  : out std_logic_vector(31 downto 0));
  end component;      

  signal bunch_writing : std_logic;
  signal ms_pulse_reg : std_logic;
  signal bunch_write_state,next_bunch_write_state : std_logic_vector(5 downto 0);
  signal bunch_sdram_data : std_logic_vector(63 downto 0);
  signal timing_addr_bunch : std_logic_vector(11 downto 0);
  signal bunch_sdram_addr : std_logic_vector(24 downto 0);
  
begin  -- rtl

  --
  -- Data logging for normal operation
  --
  log_data: process (clk, rst)
  begin  -- process log_data
    if rst = '1' then                   -- asynchronous reset
      sdram_addr_i <= (others => '0');
      timing_addr_i <= (others => '0');
      event_counter <= (others => '0');
      sdram_addr_sync <= (others => '0');
      fref_reg <= '0';
    elsif clk'event and clk = '1' then  -- rising clock edge
      fref_reg <= fref;
      if init = '1' then
        sdram_addr_i <= (others => '0');
        timing_addr_i <= (others => '0');
        event_counter <= (others => '0');
      else
        if avg_valid = '1' and acq = '1' then
          if sdram_addr_i = CONV_STD_LOGIC_VECTOR(bunch_mean_base_addr-1,25) then
            sdram_addr_i <= (others => '0');
          else
            sdram_addr_i <= sdram_addr_i+1;
          end if;

        end if;
        if ms_pulse = '1' and acq = '1' then
           timing_addr_i <=  timing_addr_i +1;
        end if;
        if (hchange_sync or injection_sync or cal_stop_edge or cal_start_sync) = '1'  then
          event_counter <= event_counter +1;
        elsif cycle_stop_edge = '1' then
          event_counter <= (others => '0');
        elsif cycle_start_edge = '1' then
          event_counter <= "0001";
        end if;
      end if;
      if phase_table_sync = '1' then
        sdram_addr_sync <= sdram_addr_i;
      end if;
      if avg_valid = '1' then
        sdram_addr <= sdram_addr_i;
        sdram_data <= ctime(15 downto 0) & deltay_avg & deltax_avg & sigma_avg;
      else
        sdram_addr <= bunch_sdram_addr;
        sdram_data <= bunch_sdram_data;
      end if;
 
      sdram_write <= (avg_valid or bunch_writing) and acq;
      timing_addr <= timing_addr_i;
      timing_data <= EXT(sdram_addr_sync,32) & ctime;
      timing_write <= ms_pulse and acq;
      if cycle_start_edge = '0' then
        if info_clear_count = "0000" then
          info_write <= (hchange_sync or injection_sync or cal_stop_edge or cal_start_sync or cycle_stop_edge or cycle_start_edge);
          info_data <= EXT(sdram_addr_i,32) & EXT(hchange_sync & injection_sync & cal_stop_edge & cal_start_sync & cycle_stop_edge & cycle_start_edge,8) & EXT(timing_addr_i,24);    
          info_addr <= cycle(1 downto 0) & event_counter;
        else
          info_data <= (others => '0');
          info_write <= '1';
          info_clear_count <= info_clear_count+1;
          info_addr <= cycle(1 downto 0) & info_clear_count;
        end if;
      else
        info_write <= '1';
        info_data <= EXT(sdram_addr_i,32) & EXT(hchange_sync & injection_sync & cal_stop_edge & cal_start_edge & cycle_stop_edge & cycle_start_edge,8) & EXT(timing_addr_i,24);  
        info_addr <= cycle(1 downto 0) & "0000";
        info_clear_count <= "0001";
      end if;
      
      
    end if;
  end process log_data;


  --
  -- Built in Logic Analyser
  --
  analyser0: process (clk, rst)
    variable trig_valid : std_logic;
  begin  -- process analyser0
    if rst = '1' then                   -- asynchronous reset
      arm <= '0';
      capturing <= '0';
      analyser_src <= "00";
      store_trigger <= '0';
      clk_counter <= (others => '0');
      clk_count_limit <= (others => '0');
      clk_count_strb <= '0';
      capture_count <= (others => '0');
      diagnostics_data <= (others => '0');
      diagnostics_addr <= (others => '0');
      diagnostics_write <= '0';
      diag_status <= (others => '0');
      sample_clk <= '0';
      diag_irq <= '0';
      diagnostics_r1 <= (others => '0');
      trigger1 <= (others => '0');
      trig_delay <= (others => '0');
      trig_delayed <= '0';
    elsif clk'event and clk = '1' then  -- rising clock edge
      diagnostics_r1 <= diagnostics;
      -- Select Trigger source and AND/OR mask operation
      case diag_control(6 downto 5) is
        when "00" => trig_valid := trig_or;
        when "01" => trig_valid := trig_and;
        when "10" => trig_valid := data_or;
        when "11" => trig_valid := data_and;
        when others => trig_valid := '0';
      end case;
      
      if diag_control_set = '1' then
        arm <= diag_control(0);
        wait_clk <= diag_control(7);
        capturing <= '0';
        analyser_src <= diag_control(3 downto 2);
        store_trigger <= diag_control(4);
        clk_counter <= (others => '0');
        clk_count_strb <= '0';
        clk_select <= diag_control(12 downto 8);
        capture_count <= (others => '0');
        case diag_control(12 downto 8) is
          when "00000" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(0,17);
          when "00001" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(1,17);
          when "00010" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(4,17);
          when "00011" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(9,17);
          when "00100" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(19,17);
          when "00101" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(49,17);
          when "00110" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(99,17);
          when "00111" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(199,17);
          when "01000" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(499,17);
          when "01001" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(999,17);
          when "01010" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(1999,17);
          when "01011" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(4999,17);
          when "01100" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(9999,17);
          when "01101" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(19999,17);
          when "01110" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(49999,17);
          when "01111" => clk_count_limit <= CONV_STD_LOGIC_VECTOR(99999,17);                         
          when others => clk_count_limit <= CONV_STD_LOGIC_VECTOR(0,17);
        end case;
        sample_clk <= '0';
        diag_irq <= '0';
        if diag_control(7) = '0' then
          trig_delay <= diag_delay;
        else
          trig_delay <= (others => '0');
        end if;
      else  
        if clk_counter = clk_count_limit then
          clk_counter <= (others => '0');
          clk_count_strb <= '1';
        else
          clk_count_strb <= '0';
          clk_counter <= clk_counter+1;
        end if;
        if clk_select(4) = '1' then
          if clk_select(0) = '0' then
            sample_clk <= ms_pulse;
          else
            sample_clk <= fref and not fref_reg;
          end if;
        else
          sample_clk <= clk_count_strb;
        end if;
        if ctime(15 downto 0) = diag_control(31 downto 16) then
          wait_clk <= '0';
        end if;
        if capturing = '0' then
          if wait_clk = '0' and arm = '1' and (trig_valid = '1' or trig_delayed = '1') then         
            if OR_reduce(trig_delay) = '1' then
              trig_delay <= trig_delay -1;
              trig_delayed <= '1';
            else
              trig_delayed <= '0';
              capturing <= '1';
              arm <= '0';
            end if;            
            capture_count <= (others => '0');
          end if;
          diag_irq <= '0';
        else
          if sample_clk = '1' then
            if AND_reduce(capture_count) = '1' then
              capturing <= '0';
              diag_irq <= '1';
            else
              diag_irq <= '0';
            end if;
            capture_count <= capture_count+1;
          else
            diag_irq <= '0';
          end if;
        end if;
      end if;
      case analyser_src is
        when "00" =>
          analyser_data <= diagnostics_r1(63 downto 0);
        when "01" =>
          analyser_data <= diagnostics_r1(127 downto 64);
        when "10" =>
          analyser_data <= diagnostics_r1(191 downto 128);
        when "11" =>
          analyser_data <= diagnostics_r1(255 downto 192);
        when others =>
          analyser_data <= (others => '0');
      end case;
      trigger1 <= fref & hchange & injection &  cal_stop & cal_start & cycle_stop & cycle_start & ten_mhz_clk;
      trigger <= trigger1;
      if store_trigger = '1' then
        analyser_data1 <= analyser_data(63 downto 8) & trigger;
      else
        analyser_data1 <= analyser_data;
      end if;
      trig_and <= not AND_reduce(trigger or diag_trigger(7 downto 0));
      trig_or <= OR_reduce(trigger and diag_trigger(7 downto 0));
      data_and <= not AND_reduce(analyser_data(31 downto 0) or diag_trigger);
      data_or <= OR_reduce(analyser_data(31 downto 0) and diag_trigger);

      analyser_data2 <= analyser_data1;
      diagnostics_data <= analyser_data2;
      diagnostics_addr <= capture_count;
      diagnostics_write <= sample_clk and capturing;
      diag_status <= diag_control(31 downto 2) & capturing & arm;
    end if;
  end process analyser0;
  
  --
  -- Bunch Mean Averaging
  --
  -- Use IIR filter y[n] = x[n] + 0.75 y[n-1]
--  bunchmean_avg0: process (clk, rst)
--  begin  -- process bunchmean_avg0
--    if rst = '1' then                   -- asynchronous reset
--      bma_s0 <= (others => '0');
--      bma_dx0 <= (others => '0');
--      bma_dy0 <= (others => '0');
--      bma_s1 <= (others => '0');
--      bma_dx1 <= (others => '0');
--      bma_dy1 <= (others => '0');
--    elsif clk'event and clk = '1' then  -- rising clock edge
--      if bunchmean_acc(0) = '1' then
--        bma_s0 <= sigma_avg + SXT(bma_s0(15 downto 1),16) + SXT(bma_s0(15 downto 2),16);
--        bma_dx0 <= deltax_avg + SXT(bma_dx0(15 downto 1),16) + SXT(bma_dx0(15 downto 2),16);
--        bma_dy0 <= deltay_avg + SXT(bma_dy0(15 downto 1),16) + SXT(bma_dy0(15 downto 2),16);
--      end if;
--      bunchmean0_data <= EXT(bma_dy0 & bma_dx0 & bma_s0,64);
--      bunchmean0_addr <= timing_addr_i;
--      bunchmean0_write <= ms_pulse and acq;
--      if bunchmean_acc(1) = '1' then
--        bma_s1 <= sigma_avg + SXT(bma_s1(15 downto 1),16) + SXT(bma_s1(15 downto 2),16);
--        bma_dx1 <= deltax_avg + SXT(bma_dx1(15 downto 1),16) + SXT(bma_dx1(15 downto 2),16);
--        bma_dy1 <= deltay_avg + SXT(bma_dy1(15 downto 1),16) + SXT(bma_dy1(15 downto 2),16);
--      end if;
--      bunchmean1_data <= EXT(bma_dy1 & bma_dx1 & bma_s1,64);
--      bunchmean1_addr <= timing_addr_i;
--      bunchmean1_write <= ms_pulse and acq;
--    end if;
--  end process bunchmean_avg0;


  -- Bunch mean averaging
  -- Old system using block RAM
  
  bunchmean_avg0: process (clk, rst)
  begin  -- process bunchmean_avg0
    if rst = '1' then                   -- asynchronous reset
      bma_s2 <= (others => '0');
      bma_dx2 <= (others => '0');
      bma_dy2 <= (others => '0');
      bma_s3 <= (others => '0');
      bma_dx3 <= (others => '0');
      bma_dy3 <= (others => '0');
      bma_counter2 <= (others => '0');
      bma_counter3 <= (others => '0');
    elsif clk'event and clk = '1' then  -- rising clock edge
      if ms_pulse = '1' then
        bma_s2 <= (others => '0');
        bma_dx2 <= (others => '0');
        bma_dy2 <= (others => '0');
        bma_s3 <= (others => '0');
        bma_dx3 <= (others => '0');
        bma_dy3 <= (others => '0');
        bma_counter2 <= (others => '0');
        bma_counter3 <= (others => '0'); 
      else
        if bunchmean_acc(0) = '1' then
          bma_s2 <= SXT(sigma_avg,28) + bma_s2;
          bma_dx2 <= SXT(deltax_avg,28) + bma_dx2;
          bma_dy2 <= SXT(deltay_avg,28) + bma_dy2;
          bma_counter2 <= bma_counter2+1;
        end if;
        if bunchmean_acc(1) = '1' then
          bma_s3 <= SXT(sigma_avg,28) + bma_s3;
          bma_dx3 <= SXT(deltax_avg,28) + bma_dx3;
          bma_dy3 <= SXT(deltay_avg,28) + bma_dy3;
          bma_counter3 <= bma_counter3+1;
        end if;
      end if;
      if OR_reduce(bma_counter2(15 downto 11)) = '1' then
        bunchmean0_data <= bma_counter2 & bma_dy2(27 downto 12) & bma_dx2(27 downto 12) & bma_s2(27 downto 12);
      elsif bma_counter2(10) = '1' then
        bunchmean0_data <= bma_counter2 & bma_dy2(26 downto 11) & bma_dx2(26 downto 11) & bma_s2(26 downto 11);
      elsif bma_counter2(9) = '1' then
        bunchmean0_data <= bma_counter2 & bma_dy2(25 downto 10) & bma_dx2(25 downto 10) & bma_s2(25 downto 10);
      elsif bma_counter2(8) = '1' then
        bunchmean0_data <= bma_counter2 & bma_dy2(24 downto 9) & bma_dx2(24 downto 9) & bma_s2(24 downto 9);
      else
        bunchmean0_data <= bma_counter2 & bma_dy2(23 downto 8) & bma_dx2(23 downto 8) & bma_s2(23 downto 8);
      end if;
      --bunchmean0_data <= bma_counter2 & bma_dy2(23 downto 8) & bma_dx2(23 downto 8) & bma_s2(23 downto 8);
      bunchmean0_addr <= timing_addr_i;
      bunchmean0_write <= ms_pulse and acq;
      if OR_reduce(bma_counter3(15 downto 11)) = '1' then
        bunchmean1_data <= bma_counter3 & bma_dy3(27 downto 12) & bma_dx3(27 downto 12) & bma_s3(27 downto 12);
      elsif bma_counter3(10) = '1' then
        bunchmean1_data <= bma_counter3 & bma_dy3(26 downto 11) & bma_dx3(26 downto 11) & bma_s3(26 downto 11);
      elsif bma_counter3(9) = '1' then
        bunchmean1_data <= bma_counter3 & bma_dy3(25 downto 10) & bma_dx3(25 downto 10) & bma_s3(25 downto 10);
      elsif bma_counter3(8) = '1' then
        bunchmean1_data <= bma_counter3 & bma_dy3(24 downto 9) & bma_dx3(24 downto 9) & bma_s3(24 downto 9);
      else
        bunchmean1_data <= bma_counter3 & bma_dy3(23 downto 8) & bma_dx3(23 downto 8) & bma_s3(23 downto 8);
      end if;
      --bunchmean1_data <= bma_counter3 & bma_dy3(23 downto 8) & bma_dx3(23 downto 8) & bma_s3(23 downto 8);
      bunchmean1_addr <= timing_addr_i;
      bunchmean1_write <= ms_pulse and acq;
    end if;
  end process bunchmean_avg0;

  
  -- Bunch Mean averaging
  -- New system using upper 2MB of SDRAM

  gen_bma_accs: for i in 0 to number_of_bunches generate
    bma0: bunch_mean_acc
      port map (
        clk        => clk,
        acc        => bunch_mean_acc_valid(i),
        clr        => ms_pulse,
        sigma      => sigma_avg,
        deltax     => deltax_avg,
        deltay     => deltay_avg,
        sum_sigma  => sigma_averages(i),
        sum_deltax => deltax_averages(i),
        sum_deltay => deltay_averages(i),
        count      => counts(i));    
  end generate gen_bma_accs;

  bunch_mean_acc_valid(0) <=  bunchmean_acc(0);
  gen_bma_accs_v: for i in 1 to number_of_bunches-1 generate
    bunch_mean_acc_valid(i) <=  bunchmean_acc(0) and bunch_one_hot(i-1);
  end generate gen_bma_accs_v;

  bunch_mean_logic0: process (clk, rst)
  begin  -- process bunch_mean_logic0
    if rst = '1' then                   -- asynchronous reset (active low)
      bunch_one_hot <= (others => '0');
      bunch_writing <= '0';
      bunch_write_state <= (others => '0');
      next_bunch_write_state <= (others => '0');
      ms_pulse_reg <= '0';
      bunch_sdram_data <= (others => '0');
      timing_addr_bunch <= (others => '0');
    elsif clk'event and clk = '1' then  -- rising clock edge
      -- Write bunches 1 to 30 into averages 1 to 30
      if phase_table_sync = '1' then
        bunch_one_hot(0) <= '1';
        bunch_one_hot(number_of_bunches-1 downto 1) <= (others => '0');
      elsif bunchmean_acc(0) = '1' then
        bunch_one_hot <= bunch_one_hot(number_of_bunches-2 downto 0) & '0';
      end if;

      -- Write out data after ms_pulse
      ms_pulse_reg <= ms_pulse;
      if ms_pulse = '1' then
        timing_addr_bunch <= timing_addr_i;
      end if;
      
      
      if ms_pulse_reg = '1' then
        bunch_writing <= '1';
        bunch_write_state <= (others => '0');
        next_bunch_write_state <= CONV_STD_LOGIC_VECTOR(1,6);
        bunch_sdram_data <=deltax_averages(0) & sigma_averages(0);
      else
        if bunch_writing = '1' and avg_valid = '0' then
          bunch_write_state <= next_bunch_write_state;
          next_bunch_write_state <= next_bunch_write_state+1;
          if bunch_write_state = CONV_STD_LOGIC_VECTOR(number_of_bunches*2-1,6) then
            bunch_writing <= '0';
          end if;
          if next_bunch_write_state(0) = '0' then
            bunch_sdram_data <= deltax_averages(CONV_INTEGER(next_bunch_write_state(5 downto 1))) & sigma_averages(CONV_INTEGER(next_bunch_write_state(5 downto 1)));
          else
            bunch_sdram_data <= counts(CONV_INTEGER(next_bunch_write_state(5 downto 1))) & deltay_averages(CONV_INTEGER(next_bunch_write_state(5 downto 1)));           
          end if;          
        end if;
      end if;
    end if;
  end process bunch_mean_logic0;
  
  bunch_sdram_addr <=  "1111111" & bunch_write_state(5 downto 1) & timing_addr_bunch & bunch_write_state(0);
  
end rtl;
