]> jspc29.x-matter.uni-frankfurt.de Git - tdc.git/commitdiff
added tdc_v2.3.1
authorCahit <c.ugur@gsi.de>
Sun, 23 Apr 2017 21:29:00 +0000 (23:29 +0200)
committerCahit <c.ugur@gsi.de>
Sun, 23 Apr 2017 21:29:00 +0000 (23:29 +0200)
41 files changed:
releases/tdc_v2.3.1/Adder_304.ngo [new symlink]
releases/tdc_v2.3.1/BusHandler.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/BusHandler_record.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Channel.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Channel_200.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Channel_200.vhd.304 [new file with mode: 0644]
releases/tdc_v2.3.1/Encoder_288_Bit.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Encoder_304_Bit.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/LogicAnalyser.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/ROM_encoder_ecp3.vhd [new symlink]
releases/tdc_v2.3.1/ROM_encoder_ecp5.vhd [new symlink]
releases/tdc_v2.3.1/Readout.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Readout_record.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Readout_record_noDecode.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/ShiftRegisterSISO.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Stretcher.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Stretcher_A.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/Stretcher_B.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/TDC.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/TDC_record.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/TriggerHandler.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/TriggerHandler_noDecode.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/bit_sync.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/cbmtof.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/dirich.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/dirich_tdc_constraints.lpf [new file with mode: 0644]
releases/tdc_v2.3.1/dirich_trbnet_constraints.lpf [new file with mode: 0644]
releases/tdc_v2.3.1/fallingEdgeDetect.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/hit_mux.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/risingEdgeDetect.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/tdc_components.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/tdc_constraints_64.lpf [new file with mode: 0644]
releases/tdc_v2.3.1/tdc_version.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/trb3_periph_32PinAddOn.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/trb3_periph_ADA.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/trb3_periph_gpin.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/trb3_periph_padiwa.vhd [new file with mode: 0644]
releases/tdc_v2.3.1/trbnet_constraints.lpf [new file with mode: 0644]
releases/tdc_v2.3.1/trbnet_constraints_dirich.lpf [new file with mode: 0644]
releases/tdc_v2.3.1/unimportant_lines_constraints.lpf [new file with mode: 0644]
releases/tdc_v2.3.1/up_counter.vhd [new file with mode: 0644]

diff --git a/releases/tdc_v2.3.1/Adder_304.ngo b/releases/tdc_v2.3.1/Adder_304.ngo
new file mode 120000 (symlink)
index 0000000..ccfbe20
--- /dev/null
@@ -0,0 +1 @@
+../../base/cores/ecp3/TDC/Adder_304.ngo
\ No newline at end of file
diff --git a/releases/tdc_v2.3.1/BusHandler.vhd b/releases/tdc_v2.3.1/BusHandler.vhd
new file mode 100644 (file)
index 0000000..1801f27
--- /dev/null
@@ -0,0 +1,74 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+
+entity BusHandler is
+  generic (
+    BUS_LENGTH : integer range 0 to 64 := 2);
+  port (
+    RESET            : in  std_logic;
+    CLK              : in  std_logic;
+--
+    DATA_IN          : in  std_logic_vector_array_32(0 to BUS_LENGTH);
+    READ_EN_IN       : in  std_logic;
+    WRITE_EN_IN      : in  std_logic;
+    ADDR_IN          : in  std_logic_vector(6 downto 0);
+    DATA_OUT         : out std_logic_vector(31 downto 0);
+    DATAREADY_OUT    : out std_logic;
+    UNKNOWN_ADDR_OUT : out std_logic);
+end BusHandler;
+
+architecture Behavioral of BusHandler is
+
+  --Output signals
+  signal data_out_reg     : std_logic_vector(31 downto 0);
+  signal data_ready_reg   : std_logic;
+  signal unknown_addr_reg : std_logic;
+  signal read_en          : std_logic;
+  signal write_en         : std_logic;
+  signal addr             : std_logic_vector(6 downto 0);
+  
+begin
+
+  read_en  <= READ_EN_IN  when rising_edge(CLK);
+  write_en <= WRITE_EN_IN when rising_edge(CLK);
+  addr     <= ADDR_IN     when rising_edge(CLK);
+
+  READ_WRITE_RESPONSE : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        data_out_reg     <= (others => '0');
+        data_ready_reg   <= '0';
+        unknown_addr_reg <= '0';
+      elsif read_en = '1' then
+        if to_integer(unsigned(addr)) > BUS_LENGTH then  -- if bigger than 64
+          data_out_reg     <= (others => '0');
+          data_ready_reg   <= '0';
+          unknown_addr_reg <= '1';
+        else
+          data_out_reg     <= DATA_IN(to_integer(unsigned(addr)));
+          data_ready_reg   <= '1';
+          unknown_addr_reg <= '0';
+        end if;
+      elsif write_en = '1' then
+        data_out_reg     <= (others => '0');
+        data_ready_reg   <= '0';
+        unknown_addr_reg <= '1';
+      else
+        data_out_reg     <= (others => '0');
+        data_ready_reg   <= '0';
+        unknown_addr_reg <= '0';
+      end if;
+    end if;
+  end process READ_WRITE_RESPONSE;
+
+  DATA_OUT         <= data_out_reg;
+  DATAREADY_OUT    <= data_ready_reg;
+  UNKNOWN_ADDR_OUT <= unknown_addr_reg;
+
+end Behavioral;
+
diff --git a/releases/tdc_v2.3.1/BusHandler_record.vhd b/releases/tdc_v2.3.1/BusHandler_record.vhd
new file mode 100644 (file)
index 0000000..316bd68
--- /dev/null
@@ -0,0 +1,65 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+
+entity BusHandler_record is
+  generic (
+    BUS_LENGTH : integer range 0 to 64 := 1);
+  port (
+    RESET    : in  std_logic;
+    CLK      : in  std_logic;
+--
+    BUS_RX   : in  CTRLBUS_RX;
+    BUS_TX   : out CTRLBUS_TX;
+--
+    DATA_IN  : in  std_logic_vector_array_32(0 to BUS_LENGTH);
+    DATA_OUT : out std_logic_vector_array_32(0 to BUS_LENGTH));
+end BusHandler_record;
+
+architecture Behavioral of BusHandler_record is
+
+  --Output signals
+  signal rx_data   : std_logic_vector(31 downto 0);
+  signal rx_read   : std_logic;
+  signal rx_read_r : std_logic;
+  signal rx_write  : std_logic;
+  signal rx_addr   : std_logic_vector(6 downto 0);
+  
+begin
+
+  rx_data  <= BUS_RX.data             when rising_edge(CLK);
+  rx_read  <= BUS_RX.read             when rising_edge(CLK);
+  rx_write <= BUS_RX.write            when rising_edge(CLK);
+  rx_addr  <= BUS_RX.addr(6 downto 0) when rising_edge(CLK);
+
+  READ_WRITE_RESPONSE : process (CLK)
+  begin
+    if rising_edge(CLK) then
+      BUS_TX.ack     <= '0';
+      BUS_TX.unknown <= '0';
+      BUS_TX.nack    <= '0';
+      rx_read_r      <= rx_read;
+      
+      if rx_read_r = '1' then
+        if to_integer(unsigned(rx_addr)) > BUS_LENGTH then  -- if bigger than 64
+          BUS_TX.unknown <= '1';
+        else
+          BUS_TX.data <= DATA_IN(to_integer(unsigned(rx_addr)));
+          BUS_TX.ack  <= '1';
+        end if;
+      elsif rx_write = '1' then
+        if to_integer(unsigned(rx_addr)) > BUS_LENGTH then  -- if bigger than 64
+          BUS_TX.unknown <= '1';
+        else
+          DATA_OUT(to_integer(unsigned(rx_addr))) <= rx_data;
+          BUS_TX.ack                              <= '1';
+        end if;
+      end if;
+    end if;
+  end process READ_WRITE_RESPONSE;
+
+end Behavioral;
+
diff --git a/releases/tdc_v2.3.1/Channel.vhd b/releases/tdc_v2.3.1/Channel.vhd
new file mode 100644 (file)
index 0000000..02fb0e8
--- /dev/null
@@ -0,0 +1,304 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.tdc_components.all;
+use work.config.all;
+
+entity Channel is
+
+  generic (
+    CHANNEL_ID : integer range 0 to 64;
+    DEBUG      : integer range 0 to 1;
+    SIMULATION : integer range 0 to 1;
+    REFERENCE  : integer range 0 to 1);
+  port (
+    RESET_200                 : in  std_logic;
+    RESET_100                 : in  std_logic;
+    RESET_COUNTERS            : in  std_logic;
+    CLK_200                   : in  std_logic;
+    CLK_100                   : in  std_logic;
+--
+    HIT_IN                    : in  std_logic;
+    HIT_EDGE_IN               : in  std_logic;
+    TRG_WIN_END_TDC_IN        : in  std_logic;
+    TRG_WIN_END_RDO_IN        : in  std_logic;
+    READ_EN_IN                : in  std_logic;
+    FIFO_DATA_OUT             : out std_logic_vector(35 downto 0);
+    FIFO_DATA_VALID_OUT       : out std_logic;
+    FIFO_ALMOST_FULL_OUT      : out std_logic;  -- fifo almost full signal ringbuffer overwrite detection
+    FIFO_EMPTY_OUT            : out std_logic;
+    RING_BUFFER_FULL_THRES_IN : in  std_logic_vector(6 downto 0);
+    COARSE_COUNTER_IN         : in  std_logic_vector(10 downto 0);
+    EPOCH_COUNTER_IN          : in  std_logic_vector(27 downto 0);
+--
+    EPOCH_WRITE_EN_IN         : in  std_logic;
+    LOST_HIT_NUMBER           : out std_logic_vector(23 downto 0);
+    HIT_DETECT_NUMBER         : out std_logic_vector(30 downto 0);
+    ENCODER_START_NUMBER      : out std_logic_vector(23 downto 0);
+    ENCODER_FINISHED_NUMBER   : out std_logic_vector(23 downto 0);
+    FIFO_WRITE_NUMBER         : out std_logic_vector(23 downto 0);
+--
+    Channel_200_DEBUG_OUT     : out std_logic_vector(31 downto 0);
+    Channel_DEBUG_OUT         : out std_logic_vector(31 downto 0)
+    );
+
+end Channel;
+
+architecture Channel of Channel is
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+
+  -- time stamp
+  signal trg_win_end_tdc : std_logic;
+  signal trg_win_end_rdo : std_logic;
+
+  -- from channel
+  signal ch_data       : std_logic_vector(35 downto 0);
+  signal ch_data_valid : std_logic;
+
+  -- from buffer
+  signal buf_data       : std_logic_vector(35 downto 0);
+  signal buf_data_valid : std_logic;
+  signal buf_empty      : std_logic;
+  signal buf_empty_reg  : std_logic;
+  signal buf_full       : std_logic;
+
+  -- fron readout
+  signal rd_en_reg : std_logic;
+
+  -- debug
+  signal hit_pulse_100           : std_logic;
+  signal encoder_finished        : std_logic;
+  signal encoder_finished_100    : std_logic;
+  signal encoder_start           : std_logic;
+  signal encoder_start_100       : std_logic;
+  signal fifo_write              : std_logic;
+  signal fifo_write_100          : std_logic;
+  signal lost_hit_cntr           : unsigned(23 downto 0);
+  signal hit_detect_cntr         : unsigned(30 downto 0);
+  signal encoder_start_cntr      : unsigned(23 downto 0);
+  signal encoder_finished_cntr   : unsigned(23 downto 0);
+  signal fifo_write_cntr         : unsigned(23 downto 0);
+  signal channel_200_debug       : std_logic_vector(31 downto 0);
+  signal ch_buffer_counter       : unsigned(15 downto 0) := (others => '0');
+  signal ch_buffer_out_counter   : unsigned(15 downto 0) := (others => '0');
+  signal ch_buffer_valid_counter : unsigned(15 downto 0) := (others => '0');
+
+  -- other
+
+-------------------------------------------------------------------------------
+
+  attribute syn_keep                    : boolean;
+  attribute syn_keep of trg_win_end_rdo : signal is true;
+  attribute syn_preserve                : boolean;
+  attribute nomerge                     : string;
+  attribute nomerge of trg_win_end_rdo  : signal is "true";
+
+-------------------------------------------------------------------------------
+
+begin
+
+  Channel200 : Channel_200
+    generic map (
+      CHANNEL_ID => CHANNEL_ID,
+      DEBUG      => DEBUG,
+      SIMULATION => SIMULATION,
+      REFERENCE  => REFERENCE)
+    port map (
+      CLK_200                   => CLK_200,
+      RESET_200                 => RESET_200,
+      CLK_100                   => CLK_100,
+      RESET_100                 => RESET_100,
+      HIT_IN                    => HIT_IN,
+      HIT_EDGE_IN               => HIT_EDGE_IN,
+      TRG_WIN_END_TDC_IN        => trg_win_end_tdc,
+      TRG_WIN_END_RDO_IN        => trg_win_end_rdo,
+      EPOCH_COUNTER_IN          => EPOCH_COUNTER_IN,
+      COARSE_COUNTER_IN         => COARSE_COUNTER_IN,
+      FIFO_DATA_OUT             => ch_data,
+      FIFO_DATA_VALID_OUT       => ch_data_valid,
+      FIFO_ALMOST_FULL_OUT      => FIFO_ALMOST_FULL_OUT,
+      RING_BUFFER_FULL_THRES_IN => RING_BUFFER_FULL_THRES_IN,
+      EPOCH_WRITE_EN_IN         => EPOCH_WRITE_EN_IN,
+      ENCODER_START_OUT         => encoder_start,
+      ENCODER_FINISHED_OUT      => encoder_finished,
+      FIFO_WRITE_OUT            => fifo_write,
+      CHANNEL_200_DEBUG_OUT     => channel_200_debug);
+
+  Buffer_128 : if RING_BUFFER_SIZE = 3 or RING_BUFFER_SIZE = 7 generate
+    The_Buffer : FIFO_36x128_OutReg
+      port map (
+        Data  => ch_data,
+        Clock => CLK_100,
+        WrEn  => ch_data_valid,
+        RdEn  => READ_EN_IN,
+        Reset => RESET_100,
+        Q     => buf_data,
+        Empty => buf_empty,
+        Full  => buf_full);
+  end generate Buffer_128;
+
+  Buffer_64 : if RING_BUFFER_SIZE = 1 or RING_BUFFER_SIZE = 5 generate
+    The_Buffer : FIFO_36x64_OutReg
+      port map (
+        Data  => ch_data,
+        Clock => CLK_100,
+        WrEn  => ch_data_valid,
+        RdEn  => READ_EN_IN,
+        Reset => RESET_100,
+        Q     => buf_data,
+        Empty => buf_empty,
+        Full  => buf_full);
+  end generate Buffer_64;
+
+  Buffer_32 : if RING_BUFFER_SIZE = 0 generate
+    The_Buffer : FIFO_36x32_OutReg
+      port map (
+        Data  => ch_data,
+        Clock => CLK_100,
+        WrEn  => ch_data_valid,
+        RdEn  => READ_EN_IN,
+        Reset => RESET_100,
+        Q     => buf_data,
+        Empty => buf_empty,
+        Full  => buf_full);
+  end generate Buffer_32;
+
+  FIFO_DATA_OUT       <= buf_data;
+  FIFO_DATA_VALID_OUT <= buf_data_valid;
+--  FIFO_EMPTY_OUT      <= buf_empty;
+  FIFO_EMPTY_OUT      <= buf_empty                       when rising_edge(CLK_100);
+  trg_win_end_tdc     <= TRG_WIN_END_TDC_IN;
+  trg_win_end_rdo     <= TRG_WIN_END_RDO_IN;
+  rd_en_reg           <= READ_EN_IN                      when rising_edge(CLK_100);
+  buf_empty_reg       <= buf_empty                       when rising_edge(CLK_100);
+  buf_data_valid      <= rd_en_reg and not buf_empty_reg when rising_edge(CLK_100);
+
+  pulse_sync_encoder_start : pulse_sync
+    port map (
+      CLK_A_IN    => CLK_200,
+      RESET_A_IN  => RESET_200,
+      PULSE_A_IN  => encoder_start,
+      CLK_B_IN    => CLK_100,
+      RESET_B_IN  => RESET_100,
+      PULSE_B_OUT => encoder_start_100);
+
+  pulse_sync_encoder_finished : pulse_sync
+    port map (
+      CLK_A_IN    => CLK_200,
+      RESET_A_IN  => RESET_200,
+      PULSE_A_IN  => encoder_finished,
+      CLK_B_IN    => CLK_100,
+      RESET_B_IN  => RESET_100,
+      PULSE_B_OUT => encoder_finished_100);
+
+  pulse_sync_fifo_write : pulse_sync
+    port map (
+      CLK_A_IN    => CLK_200,
+      RESET_A_IN  => RESET_200,
+      PULSE_A_IN  => fifo_write,
+      CLK_B_IN    => CLK_100,
+      RESET_B_IN  => RESET_100,
+      PULSE_B_OUT => fifo_write_100);
+
+-------------------------------------------------------------------------------
+-- DEBUG Counters
+-------------------------------------------------------------------------------
+  HIT_DETECT_NUMBER <= (others => '0');  -- Moved to TDC.vhd
+
+  gen_DEBUG : if DEBUG = c_YES generate
+    --purpose: Counts the detected but unwritten hits
+    Lost_Hit_Counter : process (CLK_100)
+    begin
+      if rising_edge(CLK_100) then
+        if RESET_COUNTERS = '1' then
+          lost_hit_cntr <= (others => '0');
+        elsif hit_pulse_100 = '1' then
+          lost_hit_cntr <= lost_hit_cntr + to_unsigned(1, 24);
+        elsif fifo_write_100 = '1' then
+          lost_hit_cntr <= lost_hit_cntr - to_unsigned(1, 24);
+        end if;
+      end if;
+    end process Lost_Hit_Counter;
+
+    LOST_HIT_NUMBER <= std_logic_vector(lost_hit_cntr) when rising_edge(CLK_100);
+
+    --purpose: Counts the encoder start times
+    Encoder_Start_Counter : process (CLK_100)
+    begin
+      if rising_edge(CLK_100) then
+        if RESET_COUNTERS = '1' then
+          ch_buffer_counter <= (others => '0');
+        elsif ch_data_valid = '1' then
+          if ch_data(35 downto 31) = "00011" then  -- it is a data word
+            ch_buffer_counter <= ch_buffer_counter + to_unsigned(1, 16);
+          end if;
+        end if;
+      --elsif encoder_start_100 = '1' then
+      --  encoder_start_cntr <= encoder_start_cntr + to_unsigned(1, 24);
+      --end if;
+      end if;
+    end process Encoder_Start_Counter;
+
+    --ENCODER_START_NUMBER <= std_logic_vector(encoder_start_cntr) when rising_edge(CLK_100);
+    ENCODER_START_NUMBER(15 downto 0) <= std_logic_vector(ch_buffer_counter) when rising_edge(CLK_100);
+
+    --purpose: Counts the encoder finished signals
+    ENCODER_FINISHED_Counter : process (CLK_100)
+    begin
+      if rising_edge(CLK_100) then
+        if RESET_COUNTERS = '1' then
+          ch_buffer_out_counter <= (others => '0');
+        elsif buf_data(35 downto 31) = "00011" then
+          ch_buffer_out_counter <= ch_buffer_out_counter + to_unsigned(1, 16);
+        end if;
+      end if;
+    end process ENCODER_FINISHED_Counter;
+
+    --ENCODER_FINISHED_NUMBER <= std_logic_vector(encoder_finished_cntr) when rising_edge(CLK_100);
+    ENCODER_FINISHED_NUMBER(15 downto 0) <= std_logic_vector(ch_buffer_out_counter) when rising_edge(CLK_100);
+
+    --purpose: Counts the written hits
+    FIFO_WRITE_Counter : process (CLK_100)
+    begin
+      if rising_edge(CLK_100) then
+        if RESET_COUNTERS = '1' then
+          ch_buffer_valid_counter <= (others => '0');
+        elsif buf_data_valid = '1' then
+          if buf_data(35 downto 31) = "00011" then
+            ch_buffer_valid_counter <= ch_buffer_valid_counter + to_unsigned(1, 16);
+          end if;
+        end if;
+      end if;
+    end process FIFO_WRITE_Counter;
+
+    --FIFO_WRITE_NUMBER <= std_logic_vector(fifo_write_cntr) when rising_edge(CLK_100);
+    FIFO_WRITE_NUMBER(15 downto 0) <= std_logic_vector(ch_buffer_valid_counter) when rising_edge(CLK_100);
+  end generate gen_DEBUG;
+
+-------------------------------------------------------------------------------
+-- DEBUG
+-------------------------------------------------------------------------------
+  Channel_DEBUG_OUT(7 downto 0) <= buf_data(35 downto 28);
+  Channel_DEBUG_OUT(8)          <= buf_data_valid;
+  Channel_DEBUG_OUT(9)          <= READ_EN_IN;
+
+
+  Channel_200_DEBUG_OUT <= channel_200_debug;
+  --Channel_DEBUG_OUT(0) <= fifo_write_100 when rising_edge(CLK_100);
+  --Channel_DEBUG_OUT(1)            <= result_2_reg;
+  --Channel_DEBUG_OUT(2)            <= hit_detect;
+  --Channel_DEBUG_OUT(3)            <= hit_detect_reg;
+  --Channel_DEBUG_OUT(4)            <= '0';
+  --Channel_DEBUG_OUT(5)            <= ff_array_en;
+  --Channel_DEBUG_OUT(6)            <= encoder_start;
+  --Channel_DEBUG_OUT(7)            <= encoder_finished;
+  --Channel_DEBUG_OUT(15 downto 8)  <= result(7 downto 0);
+  --Channel_DEBUG_OUT(31 downto 16) <= (others => '0');
+
+end Channel;
diff --git a/releases/tdc_v2.3.1/Channel_200.vhd b/releases/tdc_v2.3.1/Channel_200.vhd
new file mode 100644 (file)
index 0000000..1049c74
--- /dev/null
@@ -0,0 +1,897 @@
+-------------------------------------------------------------------------------
+-- Title      : Channel 200 MHz Part
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : Channel_200.vhd
+-- Author     : c.ugur@gsi.de
+-- Created    : 2012-08-28
+-- Last update: 2017-04-22
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.config.all;
+
+entity Channel_200 is
+
+  generic (
+    CHANNEL_ID : integer range 0 to 64 := 1;
+    DEBUG      : integer range 0 to 1  := 0;
+    SIMULATION : integer range 0 to 1  := 0;
+    REFERENCE  : integer range 0 to 1  := 0);
+  port (
+    CLK_200                   : in  std_logic;  -- 200 MHz clk
+    RESET_200                 : in  std_logic;  -- reset sync with 200Mhz clk
+    CLK_100                   : in  std_logic;  -- 100 MHz clk
+    RESET_100                 : in  std_logic;  -- reset sync with 100Mhz clk
+--
+    HIT_IN                    : in  std_logic;  -- hit in
+    HIT_EDGE_IN               : in  std_logic;  -- hit edge in
+    TRG_WIN_END_TDC_IN        : in  std_logic;  -- trigger window end strobe
+    TRG_WIN_END_RDO_IN        : in  std_logic;  -- trigger window end strobe
+    EPOCH_COUNTER_IN          : in  std_logic_vector(27 downto 0);  -- system coarse counter
+    COARSE_COUNTER_IN         : in  std_logic_vector(10 downto 0);
+    FIFO_DATA_OUT             : out std_logic_vector(35 downto 0);  -- fifo data out
+    FIFO_DATA_VALID_OUT       : out std_logic;  -- fifo data valid signal
+    FIFO_ALMOST_FULL_OUT      : out std_logic;  -- fifo almost full signal ringbuffer overwrite detection
+    RING_BUFFER_FULL_THRES_IN : in  std_logic_vector(6 downto 0);  -- ring buffer almost full threshold
+--
+    EPOCH_WRITE_EN_IN         : in  std_logic;
+    ENCODER_START_OUT         : out std_logic;
+    ENCODER_FINISHED_OUT      : out std_logic;
+    FIFO_WRITE_OUT            : out std_logic;
+    CHANNEL_200_DEBUG_OUT     : out std_logic_vector(31 downto 0)
+    );
+
+end Channel_200;
+
+architecture Channel_200 of Channel_200 is
+
+  component FD1P3IX
+    port (D  : in  std_logic;
+          SP : in  std_logic;
+          CK : in  std_logic;
+          CD : in  std_logic;
+          Q  : out std_logic);
+  end component;
+
+  -- carry chain
+  signal data_a      : std_logic_vector(287 downto 0);
+  signal data_b      : std_logic_vector(287 downto 0);
+  signal result      : std_logic_vector(287 downto 0);
+  signal ff_array_en : std_logic;
+
+  -- hit detection
+  signal result_2_r          : std_logic                    := '0';
+  signal hit_detect          : std_logic                    := '0';
+  signal hit_detect_r        : std_logic;
+  signal hit_detect_2r       : std_logic;
+  signal edge_type           : std_logic                    := '0';
+  signal rising_edge_written : std_logic                    := '0';
+  signal memory              : std_logic_vector(7 downto 0) := (others => '0');
+  signal wr_ptr              : integer range 0 to 7         := 0;
+  signal rd_ptr              : integer range 0 to 7         := 0;
+
+  -- time stamp
+  signal time_stamp              : std_logic_vector(10 downto 0);
+  signal time_stamp_r            : std_logic_vector(10 downto 0);
+  signal time_stamp_2r           : std_logic_vector(10 downto 0);
+  signal time_stamp_3r           : std_logic_vector(10 downto 0);
+  signal time_stamp_4r           : std_logic_vector(10 downto 0);
+  signal time_stamp_5r           : std_logic_vector(10 downto 0);
+  signal time_stamp_6r           : std_logic_vector(10 downto 0);
+  signal time_stamp_7r           : std_logic_vector(10 downto 0);
+  signal coarse_cntr_r           : std_logic_vector(10 downto 0);
+  signal coarse_cntr_overflow    : std_logic;
+  signal coarse_cntr_overflow_r  : std_logic;
+  signal coarse_cntr_overflow_2r : std_logic;
+  signal coarse_cntr_overflow_3r : std_logic;
+  signal coarse_cntr_overflow_4r : std_logic;
+  signal coarse_cntr_overflow_5r : std_logic;
+  signal coarse_cntr_overflow_6r : std_logic;
+  signal coarse_cntr_overflow_7r : std_logic;
+
+  -- encoder
+  signal encoder_start    : std_logic;
+  signal encoder_finished : std_logic;
+  signal encoder_data_out : std_logic_vector(9 downto 0);
+  signal encoder_info     : std_logic;
+  signal encoder_debug    : std_logic_vector(31 downto 0);
+  signal thermocode       : std_logic_vector(287 downto 0);
+
+  -- epoch counter
+  signal epoch_cntr         : std_logic_vector(27 downto 0) := (others => '0');
+  signal epoch_cntr_r       : std_logic_vector(27 downto 0) := (others => '0');
+  signal epoch_cntr_updated : std_logic                     := '0';
+  signal epoch_value        : std_logic_vector(35 downto 0) := (others => '0');
+
+  -- ring bugger
+  signal ringBuffer_data_out         : std_logic_vector(35 downto 0);
+  signal ringBuffer_data_in          : std_logic_vector(35 downto 0);
+  signal ringBuffer_empty            : std_logic;
+  signal ringBuffer_full             : std_logic;
+  signal ringBuffer_almost_full_sync : std_logic;
+  signal ringBuffer_almost_full      : std_logic := '0';
+  signal ringBuffer_almost_full_flag : std_logic := '0';
+  signal ringBuffer_wr_en            : std_logic;
+  signal ringBuffer_rd_en            : std_logic;
+  signal ringBuffer_rd_data          : std_logic;
+  signal fifo_data                   : std_logic_vector(35 downto 0);
+  signal fifo_data_valid             : std_logic;
+
+  -- fsm
+  type FSM_WR is (WRITE_EPOCH_WORD, WRITE_DATA_WORD, WRITE_STOP_WORD_A, WRITE_STOP_WORD_B,
+                  WRITE_STOP_WORD_C, WRITE_STOP_WORD_D, WAIT_FOR_HIT, WAIT_FOR_VALIDITY,
+                  EXCEPTION);
+  signal FSM_WR_CURRENT           : FSM_WR    := WRITE_EPOCH_WORD;
+  signal FSM_WR_NEXT              : FSM_WR;
+  signal write_epoch_fsm          : std_logic;
+  signal write_epoch              : std_logic := '0';
+  signal write_data_fsm           : std_logic;
+  signal write_data               : std_logic := '0';
+  signal write_stop_a_fsm         : std_logic;
+  signal write_stop_a             : std_logic := '0';
+  signal write_stop_b_fsm         : std_logic;
+  signal write_stop_b             : std_logic := '0';
+  signal write_data_flag_fsm      : std_logic;
+  signal write_data_flag          : std_logic := '0';
+  signal write_chain              : std_logic := '0';
+  signal chain                    : std_logic_vector(15 downto 0);
+  signal trg_win_end_tdc_flag_fsm : std_logic;
+  signal trg_win_end_tdc_flag     : std_logic := '0';
+  signal trg_win_end_tdc          : std_logic := '0';
+  signal trg_cntr                 : std_logic_vector(7 downto 0) := (others => '0');
+  signal fsm_wr_debug_fsm         : std_logic_vector(3 downto 0);
+  signal fsm_wr_debug             : std_logic_vector(3 downto 0);
+
+  type FSM_RD is (IDLE, FLUSH_A, FLUSH_B, FLUSH_C, FLUSH_D, READOUT_EPOCH, READOUT_DATA_A, READOUT_DATA_B, READOUT_DATA_C);
+  signal FSM_RD_STATE         : FSM_RD;
+  signal trg_win_end_rdo_flag : std_logic := '0';
+  signal fsm_rd_debug         : std_logic_vector(3 downto 0);
+
+  -----------------------------------------------------------------------------
+  -- debug
+  signal data_cnt_total       : integer range 0 to 2147483647 := 0;
+  signal data_cnt_event       : integer range 0 to 255        := 0;
+  signal epoch_cnt_total      : integer range 0 to 65535      := 0;
+  signal epoch_cnt_event      : integer range 0 to 127        := 0;
+  signal trg_win_end_tdc_pipe : std_logic_vector(31 downto 0) := (others => '0');
+  -----------------------------------------------------------------------------
+
+  attribute syn_keep                : boolean;
+  attribute syn_keep of ff_array_en : signal is true;
+  
+begin  -- Channel_200
+
+  GEN_TrgWinEndTdcDist : if SIMULATION = 0 and TDC_DATA_FORMAT /= 15 generate
+    TrgWinEndTdcDist : FD1P3IX
+      port map (D  => '1',
+                SP => TRG_WIN_END_TDC_IN,
+                CK => CLK_200,
+                CD => trg_win_end_tdc,
+                Q  => trg_win_end_tdc);
+    TheTriggerCounter : up_counter
+      generic map (
+        NUMBER_OF_BITS => 8)
+      port map (
+        CLK       => CLK_200,
+        RESET     => RESET_200,
+        COUNT_OUT => trg_cntr,
+        UP_IN     => trg_win_end_tdc);
+
+  end generate GEN_TrgWinEndTdcDist;
+
+  GEN_TrgWinEndTdcDist_Chain : if SIMULATION = 0 and TDC_DATA_FORMAT = 15 generate
+    TrgWinEndTdcDist : FD1P3IX
+      port map (D  => '1',
+                SP => TRG_WIN_END_TDC_IN,
+                CK => CLK_200,
+                CD => trg_win_end_tdc_pipe(0),
+                Q  => trg_win_end_tdc_pipe(0));
+    trg_win_end_tdc_pipe(31 downto 1) <= trg_win_end_tdc_pipe (30 downto 0) when rising_edge(CLK_200);
+    trg_win_end_tdc                   <= trg_win_end_tdc_pipe(31);
+  end generate GEN_TrgWinEndTdcDist_Chain;
+
+  GEN_TrgWinEndTdcDist_Sim : if SIMULATION = 1 generate
+    trg_win_end_tdc_pipe(0)           <= TRG_WIN_END_TDC_IN                 when rising_edge(CLK_200);
+    trg_win_end_tdc_pipe(31 downto 1) <= trg_win_end_tdc_pipe (30 downto 0) when rising_edge(CLK_200);
+    trg_win_end_tdc                   <= trg_win_end_tdc_pipe(31);
+    
+  end generate GEN_TrgWinEndTdcDist_Sim;
+
+
+  SimAdderYes : if SIMULATION = c_YES generate
+    --purpose: Tapped Delay Line 304 (Carry Chain) with wave launcher (21) double transition
+    FC : Adder_288
+      port map (
+        CLK    => CLK_200,
+        RESET  => '0',
+        DataA  => data_a,
+        DataB  => data_b,
+        ClkEn  => ff_array_en,
+        Result => result);
+    data_a <= x"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFc00000F"&x"EFFFF";
+    data_b <= x"0000000000000000000000000000000000000000000000000000000000000000000"&"000"&HIT_IN&x"000"&"000"&HIT_IN;
+  end generate SimAdderYes;
+  SimAdderNo : if SIMULATION = c_NO generate
+    --purpose: Tapped Delay Line 304 (Carry Chain) with wave launcher (21) double transition
+    FC : Adder_288
+      port map (
+        CLK    => CLK_200,
+        RESET  => '0',
+        DataA  => data_a,
+        DataB  => data_b,
+        ClkEn  => ff_array_en,
+        Result => result);
+    data_a <= x"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"&x"EFFFF";
+    data_b <= x"0000000000000000000000000000000000000000000000000000000000000000000"&"000"&HIT_IN&x"000"&"000"&HIT_IN;
+  end generate SimAdderNo;
+
+  ff_array_en <= not(hit_detect or hit_detect_r);  -- or hit_detect_2r);
+
+  result_2_r <= result(2) when rising_edge(CLK_200);
+  hit_detect <= (not result_2_r) and result(2);  -- detects the hit by
+                                                 -- comparing the
+                                                 -- previous state of the
+                                                 -- hit detection bit
+
+  hit_detect_r      <= hit_detect           when rising_edge(CLK_200);
+  hit_detect_2r     <= hit_detect_r         when rising_edge(CLK_200);
+  coarse_cntr_r     <= COARSE_COUNTER_IN    when rising_edge(CLK_200);
+  ENCODER_START_OUT <= encoder_start;
+-------------------------------------------------------------------------------
+-- 
+-------------------------------------------------------------------------------
+  --thermocode        <= result(287 downto 0);
+  --encoder_start     <= hit_detect;
+  thermocode        <= result(287 downto 0) when rising_edge(CLK_200);
+  encoder_start     <= hit_detect           when rising_edge(CLK_200);
+-------------------------------------------------------------------------------
+
+  isReferenceEdge : if REFERENCE = c_YES or DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 2 generate
+    edge_type <= '1';
+  end generate isReferenceEdge;
+
+  isChannelEdge : if REFERENCE = c_NO and (DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3) generate
+    EdgeTypeCapture : process (CLK_200) is
+    begin  -- process EdgeTypeCapture
+      if rising_edge(CLK_200) then
+        if hit_detect_2r = '1' then
+          memory(wr_ptr) <= HIT_EDGE_IN;
+          if wr_ptr = 7 then
+            wr_ptr <= 0;
+          else
+            wr_ptr <= wr_ptr + 1;
+          end if;
+        end if;
+        if encoder_finished = '1' then
+          edge_type <= memory(rd_ptr);
+          if rd_ptr = 7 then
+            rd_ptr <= 0;
+          else
+            rd_ptr <= rd_ptr + 1;
+          end if;
+        end if;
+      end if;
+    end process EdgeTypeCapture;
+  end generate isChannelEdge;
+
+  DATA_FORMAT_0 : if TDC_DATA_FORMAT = 0 or TDC_DATA_FORMAT = 13 or TDC_DATA_FORMAT = 14 generate
+    TimeStampCapture : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if hit_detect_r = '1' then
+          time_stamp <= coarse_cntr_r;
+        end if;
+        time_stamp_r  <= time_stamp;
+        time_stamp_2r <= time_stamp_r;
+        time_stamp_3r <= time_stamp_2r;
+        time_stamp_4r <= time_stamp_3r;
+        time_stamp_5r <= time_stamp_4r;
+        time_stamp_6r <= time_stamp_5r;
+        time_stamp_7r <= time_stamp_6r;
+      end if;
+    end process TimeStampCapture;
+  end generate DATA_FORMAT_0;
+
+  DATA_FORMAT_1 : if TDC_DATA_FORMAT = 1 generate
+    TimeStampCapture : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if hit_detect_r = '1' then
+          time_stamp_r <= coarse_cntr_r;
+        end if;
+        time_stamp_2r <= time_stamp_r;
+        time_stamp_3r <= time_stamp_2r;
+        time_stamp_4r <= time_stamp_3r;
+        time_stamp_5r <= time_stamp_4r;
+        time_stamp_6r <= time_stamp_5r;
+        time_stamp_7r <= time_stamp_6r;
+      end if;
+    end process TimeStampCapture;
+  end generate DATA_FORMAT_1;
+
+  CoarseCounterOverflow : entity work.fallingEdgeDetect
+    port map (
+      CLK       => CLK_200,
+      SIGNAL_IN => coarse_cntr_r(10),
+      PULSE_OUT => coarse_cntr_overflow);
+
+  coarse_cntr_overflow_r  <= coarse_cntr_overflow    when rising_edge(CLK_200);
+  coarse_cntr_overflow_2r <= coarse_cntr_overflow_r  when rising_edge(CLK_200);
+  coarse_cntr_overflow_3r <= coarse_cntr_overflow_2r when rising_edge(CLK_200);
+  coarse_cntr_overflow_4r <= coarse_cntr_overflow_3r when rising_edge(CLK_200);
+  coarse_cntr_overflow_5r <= coarse_cntr_overflow_4r when rising_edge(CLK_200);
+  coarse_cntr_overflow_6r <= coarse_cntr_overflow_5r when rising_edge(CLK_200);
+  coarse_cntr_overflow_7r <= coarse_cntr_overflow_6r when rising_edge(CLK_200);
+
+  EpochCounterCapture : process (CLK_200)
+  begin
+    if rising_edge(CLK_200) then
+      if coarse_cntr_overflow_7r = '1' then
+        epoch_cntr         <= EPOCH_COUNTER_IN;
+        epoch_cntr_updated <= '1';
+      elsif write_epoch = '1' then
+        epoch_cntr_updated <= '0';
+      end if;
+    end if;
+  end process EpochCounterCapture;
+
+  --purpose: Encoder
+  --Encoder : Encoder_304_Bit
+  --  port map (
+  --    RESET           => RESET_200,
+  --    CLK             => CLK_200,
+  --    START_IN        => encoder_start,
+  --    THERMOCODE_IN   => result,
+  --    FINISHED_OUT    => encoder_finished,
+  --    DECIMAL_CODE_OUT => encoder_data_out,
+  --    ENCODER_DEBUG   => encoder_debug);
+
+  --purpose: Encoder
+  Encoder : Encoder_288_Bit
+    port map (
+      RESET            => RESET_200,
+      CLK              => CLK_200,
+      START_IN         => encoder_start,
+      THERMOCODE_IN    => thermocode,
+      FINISHED_OUT     => encoder_finished,
+      DECIMAL_CODE_OUT => encoder_data_out,
+      ENCODER_INFO_OUT => encoder_info,
+      ENCODER_DEBUG    => encoder_debug,
+      CHAIN_VALID_OUT  => write_chain,
+      CHAIN_DATA_OUT   => chain
+      );
+
+  RingBuffer_128_dyn : if RING_BUFFER_SIZE = 7 generate
+    FIFO : FIFO_DC_36x128_DynThr_OutReg
+      port map (
+        Data         => ringBuffer_data_in,
+        WrClock      => CLK_200,
+        RdClock      => CLK_100,
+        WrEn         => ringBuffer_wr_en,
+        RdEn         => ringBuffer_rd_en,
+        Reset        => RESET_100,
+        RPReset      => RESET_100,
+        AmFullThresh => RING_BUFFER_FULL_THRES_IN,
+        Q            => ringBuffer_data_out,
+        Empty        => ringBuffer_empty,
+        Full         => ringBuffer_full,
+        AlmostFull   => ringBuffer_almost_full);
+  end generate RingBuffer_128_dyn;
+
+  RingBuffer_64_dyn : if RING_BUFFER_SIZE = 5 generate
+    FIFO : FIFO_DC_36x64_DynThr_OutReg
+      port map (
+        Data         => ringBuffer_data_in,
+        WrClock      => CLK_200,
+        RdClock      => CLK_100,
+        WrEn         => ringBuffer_wr_en,
+        RdEn         => ringBuffer_rd_en,
+        Reset        => RESET_100,
+        RPReset      => RESET_100,
+        AmFullThresh => RING_BUFFER_FULL_THRES_IN(5 downto 0),
+        Q            => ringBuffer_data_out,
+        Empty        => ringBuffer_empty,
+        Full         => ringBuffer_full,
+        AlmostFull   => ringBuffer_almost_full);
+  end generate RingBuffer_64_dyn;
+
+  RingBuffer_128 : if RING_BUFFER_SIZE = 3 generate
+    FIFO : FIFO_DC_36x128_OutReg
+      port map (
+        Data       => ringBuffer_data_in,
+        WrClock    => CLK_200,
+        RdClock    => CLK_100,
+        WrEn       => ringBuffer_wr_en,
+        RdEn       => ringBuffer_rd_en,
+        Reset      => RESET_100,
+        RPReset    => RESET_100,
+        Q          => ringBuffer_data_out,
+        Empty      => ringBuffer_empty,
+        Full       => ringBuffer_full,
+        AlmostFull => ringBuffer_almost_full);
+  end generate RingBuffer_128;
+
+  RingBuffer_64 : if RING_BUFFER_SIZE = 1 generate
+    FIFO : FIFO_DC_36x64_OutReg
+      port map (
+        Data       => ringBuffer_data_in,
+        WrClock    => CLK_200,
+        RdClock    => CLK_100,
+        WrEn       => ringBuffer_wr_en,
+        RdEn       => ringBuffer_rd_en,
+        Reset      => RESET_100,
+        RPReset    => RESET_100,
+        Q          => ringBuffer_data_out,
+        Empty      => ringBuffer_empty,
+        Full       => ringBuffer_full,
+        AlmostFull => ringBuffer_almost_full);
+  end generate RingBuffer_64;
+
+  RingBuffer_32 : if RING_BUFFER_SIZE = 0 generate
+    FIFO : FIFO_DC_36x32_OutReg
+      port map (
+        Data       => ringBuffer_data_in,
+        WrClock    => CLK_200,
+        RdClock    => CLK_100,
+        WrEn       => ringBuffer_wr_en,
+        RdEn       => ringBuffer_rd_en,
+        Reset      => RESET_100,
+        RPReset    => RESET_100,
+        Q          => ringBuffer_data_out,
+        Empty      => ringBuffer_empty,
+        Full       => ringBuffer_full,
+        AlmostFull => ringBuffer_almost_full);
+  end generate RingBuffer_32;
+
+  ringBuffer_almost_full_sync <= ringBuffer_almost_full                            when rising_edge(CLK_100);
+  ringBuffer_rd_en            <= ringBuffer_rd_data or ringBuffer_almost_full_sync when rising_edge(CLK_100);
+  FIFO_ALMOST_FULL_OUT        <= ringBuffer_almost_full_flag;
+
+  FifoAlmostEmptyFlag : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        ringBuffer_almost_full_flag <= '0';
+      elsif FSM_RD_STATE = READOUT_DATA_C then
+        ringBuffer_almost_full_flag <= '0';
+      elsif ringBuffer_almost_full_sync = '1' then
+        ringBuffer_almost_full_flag <= '1';
+      end if;
+    end if;
+  end process FifoAlmostEmptyFlag;
+
+
+-------------------------------------------------------------------------------
+-- Write Stage
+-------------------------------------------------------------------------------
+  -- Readout fsm
+  FSM_CLK : process (CLK_200)
+  begin
+    if RESET_200 = '1' then
+      FSM_WR_CURRENT <= WRITE_EPOCH_WORD;
+    elsif rising_edge(CLK_200) then
+      FSM_WR_CURRENT  <= FSM_WR_NEXT;
+      write_epoch     <= write_epoch_fsm;
+      write_data      <= write_data_fsm;
+      write_stop_a    <= write_stop_a_fsm;
+      write_stop_b    <= write_stop_b_fsm;
+      write_data_flag <= write_data_flag_fsm;
+      fsm_wr_debug    <= fsm_wr_debug_fsm;
+    end if;
+  end process FSM_CLK;
+
+  FSM_PROC : process (FSM_WR_CURRENT, encoder_finished, epoch_cntr_updated, trg_win_end_tdc,
+                      trg_win_end_tdc_flag, write_data_flag)
+  begin
+
+    FSM_WR_NEXT         <= WRITE_EPOCH_WORD;
+    write_epoch_fsm     <= '0';
+    write_data_fsm      <= '0';
+    write_stop_a_fsm    <= '0';
+    write_stop_b_fsm    <= '0';
+    write_data_flag_fsm <= write_data_flag;
+    fsm_wr_debug_fsm    <= x"0";
+
+    case (FSM_WR_CURRENT) is
+      when WRITE_EPOCH_WORD =>
+        if encoder_finished = '1' or write_data_flag = '1' then
+          write_epoch_fsm     <= '1';
+          write_data_flag_fsm <= '0';
+          FSM_WR_NEXT         <= EXCEPTION;
+        elsif trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+          FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+        else
+          write_epoch_fsm <= '0';
+          FSM_WR_NEXT     <= WRITE_EPOCH_WORD;
+        end if;
+        fsm_wr_debug_fsm <= x"1";
+--
+      when WRITE_DATA_WORD =>
+        if epoch_cntr_updated = '1' then
+          write_epoch_fsm <= '1';
+          FSM_WR_NEXT     <= EXCEPTION;
+        else
+          write_data_fsm <= '1';
+          if trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+            FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+          else
+            FSM_WR_NEXT <= WAIT_FOR_HIT;
+          end if;
+        end if;
+        fsm_wr_debug_fsm <= x"2";
+--
+      when EXCEPTION =>
+        write_data_fsm <= '1';
+        if trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+          FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+        else
+          FSM_WR_NEXT <= WAIT_FOR_HIT;
+        end if;
+        fsm_wr_debug_fsm <= x"3";
+--
+      when WAIT_FOR_HIT =>
+        if epoch_cntr_updated = '1' and encoder_finished = '0' then
+          FSM_WR_NEXT <= WRITE_EPOCH_WORD;
+        elsif epoch_cntr_updated = '0' and encoder_finished = '1' then
+          FSM_WR_NEXT <= WRITE_DATA_WORD;
+        elsif epoch_cntr_updated = '1' and encoder_finished = '1' then
+          FSM_WR_NEXT <= WRITE_DATA_WORD;
+        elsif trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+          FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+        else
+          FSM_WR_NEXT <= WAIT_FOR_HIT;
+        end if;
+        fsm_wr_debug_fsm <= x"4";
+--
+      when WRITE_STOP_WORD_A =>
+        write_stop_a_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_STOP_WORD_B;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--
+      when WRITE_STOP_WORD_B =>
+        write_stop_a_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_STOP_WORD_C;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--
+      when WRITE_STOP_WORD_C =>
+        write_stop_b_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_STOP_WORD_D;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--
+      when WRITE_STOP_WORD_D =>
+        write_stop_b_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_EPOCH_WORD;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--        
+      when others =>
+        FSM_WR_NEXT      <= WRITE_EPOCH_WORD;
+        write_epoch_fsm  <= '0';
+        write_data_fsm   <= '0';
+        write_stop_a_fsm <= '0';
+        write_stop_b_fsm <= '0';
+        fsm_wr_debug_fsm <= x"0";
+    end case;
+  end process FSM_PROC;
+
+  TriggerWindowFlag : process (CLK_200)
+  begin
+    if rising_edge(CLK_200) then
+      if RESET_200 = '1' then
+        trg_win_end_tdc_flag <= '0';
+      elsif trg_win_end_tdc = '1' then
+        trg_win_end_tdc_flag <= '1';
+      elsif FSM_WR_CURRENT = WRITE_STOP_WORD_D then
+        trg_win_end_tdc_flag <= '0';
+      end if;
+    end if;
+  end process TriggerWindowFlag;
+
+  -- purpose: Generate Fifo Wr Signal
+  DATA_FORMAT_NORMAL : if TDC_DATA_FORMAT = 0 or TDC_DATA_FORMAT = 1 generate
+    FifoWriteSignal : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if write_epoch = '1' and EPOCH_WRITE_EN_IN = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31 downto 29) <= "011";
+          ringBuffer_data_in(28)           <= '0';
+          ringBuffer_data_in(27 downto 0)  <= epoch_cntr;
+          ringBuffer_wr_en                 <= '1';
+        elsif write_data = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31)           <= '1';        -- data marker
+          ringBuffer_data_in(30)           <= '0';        -- reserved bits
+          ringBuffer_data_in(29)           <= encoder_info;   -- reserved bits
+          ringBuffer_data_in(28 downto 22) <= std_logic_vector(to_unsigned(CHANNEL_ID, 7));  -- channel number
+          ringBuffer_data_in(21 downto 12) <= encoder_data_out;  -- fine time from the encoder
+          ringBuffer_data_in(11)           <= edge_type;  -- rising '1' or falling '0' edge
+          ringBuffer_data_in(10 downto 0)  <= time_stamp_7r;  -- hit time stamp
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_a = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"f";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_b = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"0";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        else
+          ringBuffer_data_in(35 downto 32) <= x"e";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '0';
+        end if;
+      end if;
+    end process FifoWriteSignal;
+  end generate DATA_FORMAT_NORMAL;
+
+  DATA_FORMAT_DEBUG : if TDC_DATA_FORMAT = 13 or TDC_DATA_FORMAT = 14 or TDC_DATA_FORMAT = 15 generate
+    FifoWriteSignal : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if write_epoch = '1' and EPOCH_WRITE_EN_IN = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31 downto 29) <= "011";
+          ringBuffer_data_in(28)           <= '0';
+          ringBuffer_data_in(27 downto 0)  <= epoch_cntr;
+          ringBuffer_wr_en                 <= '1';
+        elsif write_data = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31)           <= '1';        -- data marker
+          ringBuffer_data_in(30)           <= '0';        -- reserved bits
+          ringBuffer_data_in(29)           <= encoder_info;   -- reserved bits
+          ringBuffer_data_in(28 downto 22) <= std_logic_vector(to_unsigned(CHANNEL_ID, 7));  -- channel number
+          ringBuffer_data_in(21 downto 12) <= encoder_data_out;  -- fine time from the encoder
+          ringBuffer_data_in(11)           <= edge_type;  -- rising '1' or falling '0' edge
+          ringBuffer_data_in(10 downto 0)  <= time_stamp_7r;  -- hit time stamp
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_a = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"f";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_b = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"0";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        elsif write_chain = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31)           <= '1';        -- data marker
+          ringBuffer_data_in(30)           <= '1';        -- reserved bits
+          ringBuffer_data_in(29)           <= '1';        -- reserved bits
+          ringBuffer_data_in(28 downto 22) <= std_logic_vector(to_unsigned(CHANNEL_ID, 7));  -- channel number
+          ringBuffer_data_in(21 downto 16) <= (others => '0');  -- fine time from the encoder
+          ringBuffer_data_in(15 downto 0)  <= chain;      -- hit time stamp
+          ringBuffer_wr_en                 <= '1';
+        else
+          ringBuffer_data_in(35 downto 32) <= x"e";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '0';
+        end if;
+      end if;
+    end process FifoWriteSignal;
+  end generate DATA_FORMAT_DEBUG;
+
+  FIFO_WRITE_OUT       <= ringBuffer_wr_en;
+  ENCODER_FINISHED_OUT <= encoder_finished;
+
+-------------------------------------------------------------------------------
+-- Read Stage
+-------------------------------------------------------------------------------
+  -- Determine the next state synchronously, based on the current state and the
+  -- input
+  FSM_DATA_STATE : process (CLK_100)
+  begin
+    if (rising_edge(CLK_100)) then
+      if RESET_100 = '1' then
+        FSM_RD_STATE <= IDLE;
+      else
+
+        case FSM_RD_STATE is
+          when IDLE =>
+            -- if the data readout is triggered by the end of the trigger window
+            if TRG_WIN_END_RDO_IN = '1' then
+              FSM_RD_STATE <= READOUT_DATA_A;
+            -- if the data readout is triggered by full fifo
+            elsif ringBuffer_almost_full_flag = '1' then
+              FSM_RD_STATE <= FLUSH_A;
+            else
+              FSM_RD_STATE <= IDLE;
+            end if;
+          --
+          when FLUSH_A =>
+            FSM_RD_STATE <= FLUSH_D;
+          --
+          when FLUSH_B =>
+            FSM_RD_STATE <= FLUSH_C;
+          --
+          when FLUSH_C =>
+            FSM_RD_STATE <= FLUSH_D;
+          --
+          when FLUSH_D =>
+            -- wait until a readout request and register the last epoch word
+            if TRG_WIN_END_RDO_IN = '1' or trg_win_end_rdo_flag = '1' then
+              FSM_RD_STATE <= READOUT_EPOCH;
+            else
+              FSM_RD_STATE <= FLUSH_D;
+            end if;
+          --
+          when READOUT_EPOCH =>
+            -- first epoch word should be readout
+            FSM_RD_STATE <= READOUT_DATA_A;
+          --
+          when READOUT_DATA_A =>
+            FSM_RD_STATE <= READOUT_DATA_B;
+          --
+          when READOUT_DATA_B =>
+            FSM_RD_STATE <= READOUT_DATA_C;
+          --  
+          when READOUT_DATA_C =>
+            -- normal data readout until the end of the readout request
+            if ringBuffer_data_out(35 downto 32) = x"f" then
+              FSM_RD_STATE <= IDLE;
+            else
+              FSM_RD_STATE <= READOUT_DATA_C;
+            end if;
+          --
+          when others =>
+            FSM_RD_STATE <= IDLE;
+        end case;
+      end if;
+    end if;
+  end process FSM_DATA_STATE;
+
+  -- Determine the output based only on the current state and the input (do not wait for a clock
+  -- edge).
+  FSM_DATA_OUTPUT : process (FSM_RD_STATE, TRG_WIN_END_RDO_IN, ringBuffer_data_out, epoch_value)
+  begin
+    trg_win_end_rdo_flag <= trg_win_end_rdo_flag;
+    epoch_value          <= epoch_value;
+
+    case FSM_RD_STATE is
+      when IDLE =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        fsm_rd_debug       <= x"1";
+      when FLUSH_A =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if TRG_WIN_END_RDO_IN = '1' then
+          trg_win_end_rdo_flag <= '1';
+        end if;
+        fsm_rd_debug <= x"2";
+      when FLUSH_B =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if TRG_WIN_END_RDO_IN = '1' then
+          trg_win_end_rdo_flag <= '1';
+        end if;
+        fsm_rd_debug <= x"3";
+      when FLUSH_C =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if TRG_WIN_END_RDO_IN = '1' then
+          trg_win_end_rdo_flag <= '1';
+        end if;
+        fsm_rd_debug <= x"4";
+      when FLUSH_D =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if ringBuffer_data_out(31 downto 29) = "011" then
+          epoch_value <= ringBuffer_data_out;
+        end if;
+        fsm_rd_debug <= x"5";
+      when READOUT_EPOCH =>
+        fifo_data          <= epoch_value;
+        fifo_data_valid    <= '1';
+        ringBuffer_rd_data <= '1';
+        fsm_rd_debug       <= x"6";
+      when READOUT_DATA_A =>
+        fifo_data            <= (others => '0');
+        fifo_data_valid      <= '0';
+        ringBuffer_rd_data   <= '1';
+        trg_win_end_rdo_flag <= '0';
+        fsm_rd_debug         <= x"7";
+      when READOUT_DATA_B =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '1';
+        fsm_rd_debug       <= x"8";
+      when READOUT_DATA_C =>
+        fifo_data <= ringBuffer_data_out;
+        if ringBuffer_data_out(35 downto 32) = x"0" then
+          fifo_data_valid <= '0';
+        else
+          fifo_data_valid <= '1';
+        end if;
+        ringBuffer_rd_data <= '1';
+        fsm_rd_debug       <= x"9";
+      when others =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        fsm_rd_debug       <= x"0";
+    end case;
+  end process FSM_DATA_OUTPUT;
+
+--FIFO_DATA_OUT       <= fifo_data;
+--FIFO_DATA_VALID_OUT <= fifo_data_valid;
+
+  FIFO_DATA_OUT       <= fifo_data       when rising_edge(CLK_100);
+  FIFO_DATA_VALID_OUT <= fifo_data_valid when rising_edge(CLK_100);
+
+-------------------------------------------------------------------------------
+-- DEBUG
+-------------------------------------------------------------------------------
+  --CHANNEL_200_DEBUG_OUT(7 downto 0)   <= ringBuffer_data_in(35 downto 28);
+  --CHANNEL_200_DEBUG_OUT(15 downto 8)  <= fifo_data(35 downto 28);
+  --CHANNEL_200_DEBUG_OUT(16)           <= ringBuffer_wr_en;
+  --CHANNEL_200_DEBUG_OUT(17)           <= fifo_data_valid;
+  --CHANNEL_200_DEBUG_OUT(18)           <= ringBuffer_rd_en;
+  --CHANNEL_200_DEBUG_OUT(23 downto 19) <= (others => '0');
+--  CHANNEL_200_DEBUG_OUT(0)            <= ff_array_en;
+  CHANNEL_200_DEBUG_OUT(15 downto 0)  <= (others => '0');
+  CHANNEL_200_DEBUG_OUT(23 downto 16) <= trg_cntr;
+  CHANNEL_200_DEBUG_OUT(27 downto 24) <= fsm_rd_debug;
+  CHANNEL_200_DEBUG_OUT(31 downto 28) <= fsm_wr_debug;
+
+  gen_SIMULATION : if SIMULATION = c_YES generate
+    -- count data written
+    data_cntr : process
+    begin
+      wait until rising_edge(CLK_100);
+      if fifo_data_valid = '1' and fifo_data(31 downto 29) = "100" then
+        data_cnt_event <= data_cnt_event + 1;
+      elsif fifo_data_valid = '1' and fifo_data(31 downto 29) = "011" then
+        epoch_cnt_event <= epoch_cnt_event + 1;
+      elsif TRG_WIN_END_RDO_IN = '1' then
+        data_cnt_event  <= 0;
+        epoch_cnt_event <= 0;
+      end if;
+    end process data_cntr;
+
+    process(fifo_data_valid)
+    begin  -- process
+      data_cnt_total  <= data_cnt_total + data_cnt_event;
+      epoch_cnt_total <= epoch_cnt_total + epoch_cnt_event;
+    end process;
+
+    -- check if data count per event is correct
+    --CheckEpochCounter : process
+    --begin
+    --  wait until falling_edge(fifo_data_valid);
+    --  wait for 1 ns;
+    --  if data_cnt_event /= 30 then
+    --    report "wrong number of hits in channel " & integer'image(CHANNEL_ID) severity error;
+    --  end if;
+    --end process CheckEpochCounter;
+
+  end generate gen_SIMULATION;
+
+end Channel_200;
diff --git a/releases/tdc_v2.3.1/Channel_200.vhd.304 b/releases/tdc_v2.3.1/Channel_200.vhd.304
new file mode 100644 (file)
index 0000000..d4d5cfd
--- /dev/null
@@ -0,0 +1,886 @@
+-------------------------------------------------------------------------------
+-- Title      : Channel 200 MHz Part
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : Channel_200.vhd
+-- Author     : c.ugur@gsi.de
+-- Created    : 2012-08-28
+-- Last update: 2016-12-21
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.config.all;
+
+entity Channel_200 is
+
+  generic (
+    CHANNEL_ID : integer range 0 to 64 := 1;
+    DEBUG      : integer range 0 to 1  := 0;
+    SIMULATION : integer range 0 to 1  := 0;
+    REFERENCE  : integer range 0 to 1  := 0);
+  port (
+    CLK_200                   : in  std_logic;  -- 200 MHz clk
+    RESET_200                 : in  std_logic;  -- reset sync with 200Mhz clk
+    CLK_100                   : in  std_logic;  -- 100 MHz clk
+    RESET_100                 : in  std_logic;  -- reset sync with 100Mhz clk
+--
+    HIT_IN                    : in  std_logic;  -- hit in
+    HIT_EDGE_IN               : in  std_logic;  -- hit edge in
+    TRG_WIN_END_TDC_IN        : in  std_logic;  -- trigger window end strobe
+    TRG_WIN_END_RDO_IN        : in  std_logic;  -- trigger window end strobe
+    EPOCH_COUNTER_IN          : in  std_logic_vector(27 downto 0);  -- system coarse counter
+    COARSE_COUNTER_IN         : in  std_logic_vector(10 downto 0);
+    FIFO_DATA_OUT             : out std_logic_vector(35 downto 0);  -- fifo data out
+    FIFO_DATA_VALID_OUT       : out std_logic;  -- fifo data valid signal
+    FIFO_ALMOST_FULL_OUT      : out std_logic;  -- fifo almost full signal ringbuffer overwrite detection
+    RING_BUFFER_FULL_THRES_IN : in  std_logic_vector(6 downto 0);  -- ring buffer almost full threshold
+--
+    EPOCH_WRITE_EN_IN         : in  std_logic;
+    ENCODER_START_OUT         : out std_logic;
+    ENCODER_FINISHED_OUT      : out std_logic;
+    FIFO_WRITE_OUT            : out std_logic;
+    CHANNEL_200_DEBUG_OUT     : out std_logic_vector(31 downto 0)
+    );
+
+end Channel_200;
+
+architecture Channel_200 of Channel_200 is
+
+  component FD1P3IX
+    port (D  : in  std_logic;
+          SP : in  std_logic;
+          CK : in  std_logic;
+          CD : in  std_logic;
+          Q  : out std_logic);
+  end component;
+
+  -- carry chain
+  signal data_a      : std_logic_vector(303 downto 0);
+  signal data_b      : std_logic_vector(303 downto 0);
+  signal result      : std_logic_vector(303 downto 0);
+  signal ff_array_en : std_logic;
+
+  -- hit detection
+  signal result_2_r          : std_logic                    := '0';
+  signal hit_detect          : std_logic                    := '0';
+  signal hit_detect_r        : std_logic;
+  signal hit_detect_2r       : std_logic;
+  signal edge_type           : std_logic                    := '0';
+  signal rising_edge_written : std_logic                    := '0';
+  signal memory              : std_logic_vector(7 downto 0) := (others => '0');
+  signal wr_ptr              : integer range 0 to 7         := 0;
+  signal rd_ptr              : integer range 0 to 7         := 0;
+
+  -- time stamp
+  signal time_stamp              : std_logic_vector(10 downto 0);
+  signal time_stamp_r            : std_logic_vector(10 downto 0);
+  signal time_stamp_2r           : std_logic_vector(10 downto 0);
+  signal time_stamp_3r           : std_logic_vector(10 downto 0);
+  signal time_stamp_4r           : std_logic_vector(10 downto 0);
+  signal time_stamp_5r           : std_logic_vector(10 downto 0);
+  signal time_stamp_6r           : std_logic_vector(10 downto 0);
+  signal time_stamp_7r           : std_logic_vector(10 downto 0);
+  signal coarse_cntr_r           : std_logic_vector(10 downto 0);
+  signal coarse_cntr_overflow    : std_logic;
+  signal coarse_cntr_overflow_r  : std_logic;
+  signal coarse_cntr_overflow_2r : std_logic;
+  signal coarse_cntr_overflow_3r : std_logic;
+  signal coarse_cntr_overflow_4r : std_logic;
+  signal coarse_cntr_overflow_5r : std_logic;
+  signal coarse_cntr_overflow_6r : std_logic;
+  signal coarse_cntr_overflow_7r : std_logic;
+
+  -- encoder
+  signal encoder_start    : std_logic;
+  signal encoder_finished : std_logic;
+  signal encoder_data_out : std_logic_vector(9 downto 0);
+  signal encoder_info     : std_logic;
+  signal encoder_debug    : std_logic_vector(31 downto 0);
+  signal thermocode       : std_logic_vector(287 downto 0);
+
+  -- epoch counter
+  signal epoch_cntr         : std_logic_vector(27 downto 0) := (others => '0');
+  signal epoch_cntr_r       : std_logic_vector(27 downto 0) := (others => '0');
+  signal epoch_cntr_updated : std_logic                     := '0';
+  signal epoch_value        : std_logic_vector(35 downto 0) := (others => '0');
+
+  -- ring bugger
+  signal ringBuffer_data_out         : std_logic_vector(35 downto 0);
+  signal ringBuffer_data_in          : std_logic_vector(35 downto 0);
+  signal ringBuffer_empty            : std_logic;
+  signal ringBuffer_full             : std_logic;
+  signal ringBuffer_almost_full_sync : std_logic;
+  signal ringBuffer_almost_full      : std_logic := '0';
+  signal ringBuffer_almost_full_flag : std_logic := '0';
+  signal ringBuffer_wr_en            : std_logic;
+  signal ringBuffer_rd_en            : std_logic;
+  signal ringBuffer_rd_data          : std_logic;
+  signal fifo_data                   : std_logic_vector(35 downto 0);
+  signal fifo_data_valid             : std_logic;
+
+  -- fsm
+  type FSM_WR is (WRITE_EPOCH_WORD, WRITE_DATA_WORD, WRITE_STOP_WORD_A, WRITE_STOP_WORD_B,
+                  WRITE_STOP_WORD_C, WRITE_STOP_WORD_D, WAIT_FOR_HIT, WAIT_FOR_VALIDITY,
+                  EXCEPTION);
+  signal FSM_WR_CURRENT           : FSM_WR    := WRITE_EPOCH_WORD;
+  signal FSM_WR_NEXT              : FSM_WR;
+  signal write_epoch_fsm          : std_logic;
+  signal write_epoch              : std_logic := '0';
+  signal write_data_fsm           : std_logic;
+  signal write_data               : std_logic := '0';
+  signal write_stop_a_fsm         : std_logic;
+  signal write_stop_a             : std_logic := '0';
+  signal write_stop_b_fsm         : std_logic;
+  signal write_stop_b             : std_logic := '0';
+  signal write_data_flag_fsm      : std_logic;
+  signal write_data_flag          : std_logic := '0';
+  signal write_chain              : std_logic := '0';
+  signal chain                    : std_logic_vector(15 downto 0);
+  signal trg_win_end_tdc_flag_fsm : std_logic;
+  signal trg_win_end_tdc_flag     : std_logic := '0';
+  signal trg_win_end_tdc          : std_logic := '0';
+  signal fsm_wr_debug_fsm         : std_logic_vector(3 downto 0);
+  signal fsm_wr_debug             : std_logic_vector(3 downto 0);
+
+  type FSM_RD is (IDLE, FLUSH_A, FLUSH_B, FLUSH_C, FLUSH_D, READOUT_EPOCH, READOUT_DATA_A, READOUT_DATA_B, READOUT_DATA_C);
+  signal FSM_RD_STATE         : FSM_RD;
+  signal trg_win_end_rdo_flag : std_logic := '0';
+  signal fsm_rd_debug         : std_logic_vector(3 downto 0);
+
+  -----------------------------------------------------------------------------
+  -- debug
+  signal data_cnt_total       : integer range 0 to 2147483647 := 0;
+  signal data_cnt_event       : integer range 0 to 255        := 0;
+  signal epoch_cnt_total      : integer range 0 to 65535      := 0;
+  signal epoch_cnt_event      : integer range 0 to 127        := 0;
+  signal trg_win_end_tdc_pipe : std_logic_vector(31 downto 0) := (others => '0');
+  -----------------------------------------------------------------------------
+
+  attribute syn_keep                : boolean;
+  attribute syn_keep of ff_array_en : signal is true;
+  
+begin  -- Channel_200
+
+  GEN_TrgWinEndTdcDist : if SIMULATION = 0 and TDC_DATA_FORMAT /= 15 generate
+    TrgWinEndTdcDist : FD1P3IX
+      port map (D  => '1',
+                SP => TRG_WIN_END_TDC_IN,
+                CK => CLK_200,
+                CD => trg_win_end_tdc,
+                Q  => trg_win_end_tdc);
+  end generate GEN_TrgWinEndTdcDist;
+
+  GEN_TrgWinEndTdcDist_Chain : if SIMULATION = 0 and TDC_DATA_FORMAT = 15 generate
+    TrgWinEndTdcDist : FD1P3IX
+      port map (D  => '1',
+                SP => TRG_WIN_END_TDC_IN,
+                CK => CLK_200,
+                CD => trg_win_end_tdc_pipe(0),
+                Q  => trg_win_end_tdc_pipe(0));
+    trg_win_end_tdc_pipe(31 downto 1) <= trg_win_end_tdc_pipe (30 downto 0) when rising_edge(CLK_200);
+    trg_win_end_tdc                   <= trg_win_end_tdc_pipe(31);
+  end generate GEN_TrgWinEndTdcDist_Chain;
+
+  GEN_TrgWinEndTdcDist_Sim : if SIMULATION = 1 generate
+    trg_win_end_tdc_pipe(0)           <= TRG_WIN_END_TDC_IN                 when rising_edge(CLK_200);
+    trg_win_end_tdc_pipe(31 downto 1) <= trg_win_end_tdc_pipe (30 downto 0) when rising_edge(CLK_200);
+    trg_win_end_tdc                   <= trg_win_end_tdc_pipe(31);
+    
+  end generate GEN_TrgWinEndTdcDist_Sim;
+
+
+  SimAdderYes : if SIMULATION = c_YES generate
+    --purpose: Tapped Delay Line 304 (Carry Chain) with wave launcher (21) double transition
+    FC : Adder_288
+      port map (
+        CLK    => CLK_200,
+        RESET  => '0',
+        DataA  => data_a,
+        DataB  => data_b,
+        ClkEn  => ff_array_en,
+        Result => result);
+    data_a <= x"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFc00000F"&x"7FFFFFF";
+    data_b <= x"000000000000000000000000000000000000000000000000000000000000000000000"& HIT_IN & x"000000"&"00" & not(HIT_IN);
+  end generate SimAdderYes;
+  SimAdderNo : if SIMULATION = c_NO generate
+    --purpose: Tapped Delay Line 304 (Carry Chain) with wave launcher (21) double transition
+    FC : Adder_288
+      port map (
+        CLK    => CLK_200,
+        RESET  => '0',
+        DataA  => data_a,
+        DataB  => data_b,
+        ClkEn  => ff_array_en,
+        Result => result);
+    data_a <= x"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"&x"EFFF";
+    data_b <= x"000000000000000000000000000000000000000000000000000000000000000000000000"&"000"&HIT_IN&x"00"&"000"&not(HIT_IN);
+  end generate SimAdderNo;
+
+  ff_array_en <= not(hit_detect or hit_detect_r);  -- or hit_detect_2r);
+
+  result_2_r <= result(2) when rising_edge(CLK_200);
+  hit_detect <= (not result_2_r) and result(2);  -- detects the hit by
+                                                 -- comparing the
+                                                 -- previous state of the
+                                                 -- hit detection bit
+
+  hit_detect_r      <= hit_detect           when rising_edge(CLK_200);
+  hit_detect_2r     <= hit_detect_r         when rising_edge(CLK_200);
+  coarse_cntr_r     <= COARSE_COUNTER_IN    when rising_edge(CLK_200);
+  ENCODER_START_OUT <= encoder_start;
+-------------------------------------------------------------------------------
+-- 
+-------------------------------------------------------------------------------
+  --thermocode        <= result(287 downto 0);
+  --encoder_start     <= hit_detect;
+  thermocode        <= result(287 downto 0) when rising_edge(CLK_200);
+  encoder_start     <= hit_detect           when rising_edge(CLK_200);
+-------------------------------------------------------------------------------
+
+  isReferenceEdge : if REFERENCE = c_YES or DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 2 generate
+    edge_type <= '1';
+  end generate isReferenceEdge;
+
+  isChannelEdge : if REFERENCE = c_NO and (DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3) generate
+    EdgeTypeCapture : process (CLK_200) is
+    begin  -- process EdgeTypeCapture
+      if rising_edge(CLK_200) then
+        if hit_detect_2r = '1' then
+          memory(wr_ptr) <= HIT_EDGE_IN;
+          if wr_ptr = 7 then
+            wr_ptr <= 0;
+          else
+            wr_ptr <= wr_ptr + 1;
+          end if;
+        end if;
+        if encoder_finished = '1' then
+          edge_type <= memory(rd_ptr);
+          if rd_ptr = 7 then
+            rd_ptr <= 0;
+          else
+            rd_ptr <= rd_ptr + 1;
+          end if;
+        end if;
+      end if;
+    end process EdgeTypeCapture;
+  end generate isChannelEdge;
+
+  DATA_FORMAT_0 : if TDC_DATA_FORMAT = 0 or TDC_DATA_FORMAT = 13 or TDC_DATA_FORMAT = 14 generate
+    TimeStampCapture : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if hit_detect_r = '1' then
+          time_stamp <= coarse_cntr_r;
+        end if;
+        time_stamp_r  <= time_stamp;
+        time_stamp_2r <= time_stamp_r;
+        time_stamp_3r <= time_stamp_2r;
+        time_stamp_4r <= time_stamp_3r;
+        time_stamp_5r <= time_stamp_4r;
+        time_stamp_6r <= time_stamp_5r;
+        time_stamp_7r <= time_stamp_6r;
+      end if;
+    end process TimeStampCapture;
+  end generate DATA_FORMAT_0;
+
+  DATA_FORMAT_1 : if TDC_DATA_FORMAT = 1 generate
+    TimeStampCapture : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if hit_detect_r = '1' then
+          time_stamp_r <= coarse_cntr_r;
+        end if;
+        time_stamp_2r <= time_stamp_r;
+        time_stamp_3r <= time_stamp_2r;
+        time_stamp_4r <= time_stamp_3r;
+        time_stamp_5r <= time_stamp_4r;
+        time_stamp_6r <= time_stamp_5r;
+        time_stamp_7r <= time_stamp_6r;
+      end if;
+    end process TimeStampCapture;
+  end generate DATA_FORMAT_1;
+
+  CoarseCounterOverflow : entity work.fallingEdgeDetect
+    port map (
+      CLK       => CLK_200,
+      SIGNAL_IN => coarse_cntr_r(10),
+      PULSE_OUT => coarse_cntr_overflow);
+
+  coarse_cntr_overflow_r  <= coarse_cntr_overflow    when rising_edge(CLK_200);
+  coarse_cntr_overflow_2r <= coarse_cntr_overflow_r  when rising_edge(CLK_200);
+  coarse_cntr_overflow_3r <= coarse_cntr_overflow_2r when rising_edge(CLK_200);
+  coarse_cntr_overflow_4r <= coarse_cntr_overflow_3r when rising_edge(CLK_200);
+  coarse_cntr_overflow_5r <= coarse_cntr_overflow_4r when rising_edge(CLK_200);
+  coarse_cntr_overflow_6r <= coarse_cntr_overflow_5r when rising_edge(CLK_200);
+  coarse_cntr_overflow_7r <= coarse_cntr_overflow_6r when rising_edge(CLK_200);
+
+  EpochCounterCapture : process (CLK_200)
+  begin
+    if rising_edge(CLK_200) then
+      if coarse_cntr_overflow_7r = '1' then
+        epoch_cntr         <= EPOCH_COUNTER_IN;
+        epoch_cntr_updated <= '1';
+      elsif write_epoch = '1' then
+        epoch_cntr_updated <= '0';
+      end if;
+    end if;
+  end process EpochCounterCapture;
+
+  --purpose: Encoder
+  --Encoder : Encoder_304_Bit
+  --  port map (
+  --    RESET           => RESET_200,
+  --    CLK             => CLK_200,
+  --    START_IN        => encoder_start,
+  --    THERMOCODE_IN   => result,
+  --    FINISHED_OUT    => encoder_finished,
+  --    DECIMAL_CODE_OUT => encoder_data_out,
+  --    ENCODER_DEBUG   => encoder_debug);
+
+  --purpose: Encoder
+  Encoder : Encoder_288_Bit
+    port map (
+      RESET            => RESET_200,
+      CLK              => CLK_200,
+      START_IN         => encoder_start,
+      THERMOCODE_IN    => thermocode,
+      FINISHED_OUT     => encoder_finished,
+      DECIMAL_CODE_OUT => encoder_data_out,
+      ENCODER_INFO_OUT => encoder_info,
+      ENCODER_DEBUG    => encoder_debug,
+      CHAIN_VALID_OUT  => write_chain,
+      CHAIN_DATA_OUT   => chain
+      );
+
+  RingBuffer_128_dyn : if RING_BUFFER_SIZE = 7 generate
+    FIFO : FIFO_DC_36x128_DynThr_OutReg
+      port map (
+        Data         => ringBuffer_data_in,
+        WrClock      => CLK_200,
+        RdClock      => CLK_100,
+        WrEn         => ringBuffer_wr_en,
+        RdEn         => ringBuffer_rd_en,
+        Reset        => RESET_100,
+        RPReset      => RESET_100,
+        AmFullThresh => RING_BUFFER_FULL_THRES_IN,
+        Q            => ringBuffer_data_out,
+        Empty        => ringBuffer_empty,
+        Full         => ringBuffer_full,
+        AlmostFull   => ringBuffer_almost_full);
+  end generate RingBuffer_128_dyn;
+
+  RingBuffer_64_dyn : if RING_BUFFER_SIZE = 5 generate
+    FIFO : FIFO_DC_36x64_DynThr_OutReg
+      port map (
+        Data         => ringBuffer_data_in,
+        WrClock      => CLK_200,
+        RdClock      => CLK_100,
+        WrEn         => ringBuffer_wr_en,
+        RdEn         => ringBuffer_rd_en,
+        Reset        => RESET_100,
+        RPReset      => RESET_100,
+        AmFullThresh => RING_BUFFER_FULL_THRES_IN(5 downto 0),
+        Q            => ringBuffer_data_out,
+        Empty        => ringBuffer_empty,
+        Full         => ringBuffer_full,
+        AlmostFull   => ringBuffer_almost_full);
+  end generate RingBuffer_64_dyn;
+
+  RingBuffer_128 : if RING_BUFFER_SIZE = 3 generate
+    FIFO : FIFO_DC_36x128_OutReg
+      port map (
+        Data       => ringBuffer_data_in,
+        WrClock    => CLK_200,
+        RdClock    => CLK_100,
+        WrEn       => ringBuffer_wr_en,
+        RdEn       => ringBuffer_rd_en,
+        Reset      => RESET_100,
+        RPReset    => RESET_100,
+        Q          => ringBuffer_data_out,
+        Empty      => ringBuffer_empty,
+        Full       => ringBuffer_full,
+        AlmostFull => ringBuffer_almost_full);
+  end generate RingBuffer_128;
+
+  RingBuffer_64 : if RING_BUFFER_SIZE = 1 generate
+    FIFO : FIFO_DC_36x64_OutReg
+      port map (
+        Data       => ringBuffer_data_in,
+        WrClock    => CLK_200,
+        RdClock    => CLK_100,
+        WrEn       => ringBuffer_wr_en,
+        RdEn       => ringBuffer_rd_en,
+        Reset      => RESET_100,
+        RPReset    => RESET_100,
+        Q          => ringBuffer_data_out,
+        Empty      => ringBuffer_empty,
+        Full       => ringBuffer_full,
+        AlmostFull => ringBuffer_almost_full);
+  end generate RingBuffer_64;
+
+  RingBuffer_32 : if RING_BUFFER_SIZE = 0 generate
+    FIFO : FIFO_DC_36x32_OutReg
+      port map (
+        Data       => ringBuffer_data_in,
+        WrClock    => CLK_200,
+        RdClock    => CLK_100,
+        WrEn       => ringBuffer_wr_en,
+        RdEn       => ringBuffer_rd_en,
+        Reset      => RESET_100,
+        RPReset    => RESET_100,
+        Q          => ringBuffer_data_out,
+        Empty      => ringBuffer_empty,
+        Full       => ringBuffer_full,
+        AlmostFull => ringBuffer_almost_full);
+  end generate RingBuffer_32;
+
+  ringBuffer_almost_full_sync <= ringBuffer_almost_full                            when rising_edge(CLK_100);
+  ringBuffer_rd_en            <= ringBuffer_rd_data or ringBuffer_almost_full_sync when rising_edge(CLK_100);
+  FIFO_ALMOST_FULL_OUT        <= ringBuffer_almost_full_flag;
+
+  FifoAlmostEmptyFlag : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        ringBuffer_almost_full_flag <= '0';
+      elsif FSM_RD_STATE = READOUT_DATA_C then
+        ringBuffer_almost_full_flag <= '0';
+      elsif ringBuffer_almost_full_sync = '1' then
+        ringBuffer_almost_full_flag <= '1';
+      end if;
+    end if;
+  end process FifoAlmostEmptyFlag;
+
+
+-------------------------------------------------------------------------------
+-- Write Stage
+-------------------------------------------------------------------------------
+  -- Readout fsm
+  FSM_CLK : process (CLK_200)
+  begin
+    if RESET_200 = '1' then
+      FSM_WR_CURRENT <= WRITE_EPOCH_WORD;
+    elsif rising_edge(CLK_200) then
+      FSM_WR_CURRENT  <= FSM_WR_NEXT;
+      write_epoch     <= write_epoch_fsm;
+      write_data      <= write_data_fsm;
+      write_stop_a    <= write_stop_a_fsm;
+      write_stop_b    <= write_stop_b_fsm;
+      write_data_flag <= write_data_flag_fsm;
+      fsm_wr_debug    <= fsm_wr_debug_fsm;
+    end if;
+  end process FSM_CLK;
+
+  FSM_PROC : process (FSM_WR_CURRENT, encoder_finished, epoch_cntr_updated, trg_win_end_tdc,
+                      trg_win_end_tdc_flag, write_data_flag)
+  begin
+
+    FSM_WR_NEXT         <= WRITE_EPOCH_WORD;
+    write_epoch_fsm     <= '0';
+    write_data_fsm      <= '0';
+    write_stop_a_fsm    <= '0';
+    write_stop_b_fsm    <= '0';
+    write_data_flag_fsm <= write_data_flag;
+    fsm_wr_debug_fsm    <= x"0";
+
+    case (FSM_WR_CURRENT) is
+      when WRITE_EPOCH_WORD =>
+        if encoder_finished = '1' or write_data_flag = '1' then
+          write_epoch_fsm     <= '1';
+          write_data_flag_fsm <= '0';
+          FSM_WR_NEXT         <= EXCEPTION;
+        elsif trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+          FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+        else
+          write_epoch_fsm <= '0';
+          FSM_WR_NEXT     <= WRITE_EPOCH_WORD;
+        end if;
+        fsm_wr_debug_fsm <= x"1";
+--
+      when WRITE_DATA_WORD =>
+        if epoch_cntr_updated = '1' then
+          write_epoch_fsm <= '1';
+          FSM_WR_NEXT     <= EXCEPTION;
+        else
+          write_data_fsm <= '1';
+          if trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+            FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+          else
+            FSM_WR_NEXT <= WAIT_FOR_HIT;
+          end if;
+        end if;
+        fsm_wr_debug_fsm <= x"2";
+--
+      when EXCEPTION =>
+        write_data_fsm <= '1';
+        if trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+          FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+        else
+          FSM_WR_NEXT <= WAIT_FOR_HIT;
+        end if;
+        fsm_wr_debug_fsm <= x"3";
+--
+      when WAIT_FOR_HIT =>
+        if epoch_cntr_updated = '1' and encoder_finished = '0' then
+          FSM_WR_NEXT <= WRITE_EPOCH_WORD;
+        elsif epoch_cntr_updated = '0' and encoder_finished = '1' then
+          FSM_WR_NEXT <= WRITE_DATA_WORD;
+        elsif epoch_cntr_updated = '1' and encoder_finished = '1' then
+          FSM_WR_NEXT <= WRITE_DATA_WORD;
+        elsif trg_win_end_tdc_flag = '1' or trg_win_end_tdc = '1' then
+          FSM_WR_NEXT <= WRITE_STOP_WORD_A;
+        else
+          FSM_WR_NEXT <= WAIT_FOR_HIT;
+        end if;
+        fsm_wr_debug_fsm <= x"4";
+--
+      when WRITE_STOP_WORD_A =>
+        write_stop_a_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_STOP_WORD_B;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--
+      when WRITE_STOP_WORD_B =>
+        write_stop_a_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_STOP_WORD_C;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--
+      when WRITE_STOP_WORD_C =>
+        write_stop_b_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_STOP_WORD_D;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--
+      when WRITE_STOP_WORD_D =>
+        write_stop_b_fsm <= '1';
+        FSM_WR_NEXT      <= WRITE_EPOCH_WORD;
+        if encoder_finished = '1' then
+          write_data_flag_fsm <= '1';
+        end if;
+        fsm_wr_debug_fsm <= x"5";
+--        
+      when others =>
+        FSM_WR_NEXT      <= WRITE_EPOCH_WORD;
+        write_epoch_fsm  <= '0';
+        write_data_fsm   <= '0';
+        write_stop_a_fsm <= '0';
+        write_stop_b_fsm <= '0';
+        fsm_wr_debug_fsm <= x"0";
+    end case;
+  end process FSM_PROC;
+
+  TriggerWindowFlag : process (CLK_200)
+  begin
+    if rising_edge(CLK_200) then
+      if RESET_200 = '1' then
+        trg_win_end_tdc_flag <= '0';
+      elsif trg_win_end_tdc = '1' then
+        trg_win_end_tdc_flag <= '1';
+      elsif FSM_WR_CURRENT = WRITE_STOP_WORD_D then
+        trg_win_end_tdc_flag <= '0';
+      end if;
+    end if;
+  end process TriggerWindowFlag;
+
+  -- purpose: Generate Fifo Wr Signal
+  DATA_FORMAT_NORMAL : if TDC_DATA_FORMAT = 0 or TDC_DATA_FORMAT = 1 generate
+    FifoWriteSignal : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if write_epoch = '1' and EPOCH_WRITE_EN_IN = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31 downto 29) <= "011";
+          ringBuffer_data_in(28)           <= '0';
+          ringBuffer_data_in(27 downto 0)  <= epoch_cntr;
+          ringBuffer_wr_en                 <= '1';
+        elsif write_data = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31)           <= '1';        -- data marker
+          ringBuffer_data_in(30)           <= '0';        -- reserved bits
+          ringBuffer_data_in(29)           <= encoder_info;   -- reserved bits
+          ringBuffer_data_in(28 downto 22) <= std_logic_vector(to_unsigned(CHANNEL_ID, 7));  -- channel number
+          ringBuffer_data_in(21 downto 12) <= encoder_data_out;  -- fine time from the encoder
+          ringBuffer_data_in(11)           <= edge_type;  -- rising '1' or falling '0' edge
+          ringBuffer_data_in(10 downto 0)  <= time_stamp_7r;  -- hit time stamp
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_a = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"f";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_b = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"0";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        else
+          ringBuffer_data_in(35 downto 32) <= x"e";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '0';
+        end if;
+      end if;
+    end process FifoWriteSignal;
+  end generate DATA_FORMAT_NORMAL;
+
+  DATA_FORMAT_DEBUG : if TDC_DATA_FORMAT = 13 or TDC_DATA_FORMAT = 14 or TDC_DATA_FORMAT = 15 generate
+    FifoWriteSignal : process (CLK_200)
+    begin
+      if rising_edge(CLK_200) then
+        if write_epoch = '1' and EPOCH_WRITE_EN_IN = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31 downto 29) <= "011";
+          ringBuffer_data_in(28)           <= '0';
+          ringBuffer_data_in(27 downto 0)  <= epoch_cntr;
+          ringBuffer_wr_en                 <= '1';
+        elsif write_data = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31)           <= '1';        -- data marker
+          ringBuffer_data_in(30)           <= '0';        -- reserved bits
+          ringBuffer_data_in(29)           <= encoder_info;   -- reserved bits
+          ringBuffer_data_in(28 downto 22) <= std_logic_vector(to_unsigned(CHANNEL_ID, 7));  -- channel number
+          ringBuffer_data_in(21 downto 12) <= encoder_data_out;  -- fine time from the encoder
+          ringBuffer_data_in(11)           <= edge_type;  -- rising '1' or falling '0' edge
+          ringBuffer_data_in(10 downto 0)  <= time_stamp_7r;  -- hit time stamp
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_a = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"f";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        elsif write_stop_b = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"0";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '1';
+        elsif write_chain = '1' then
+          ringBuffer_data_in(35 downto 32) <= x"1";
+          ringBuffer_data_in(31)           <= '1';        -- data marker
+          ringBuffer_data_in(30)           <= '1';        -- reserved bits
+          ringBuffer_data_in(29)           <= '1';        -- reserved bits
+          ringBuffer_data_in(28 downto 22) <= std_logic_vector(to_unsigned(CHANNEL_ID, 7));  -- channel number
+          ringBuffer_data_in(21 downto 16) <= (others => '0');  -- fine time from the encoder
+          ringBuffer_data_in(15 downto 0)  <= chain;      -- hit time stamp
+          ringBuffer_wr_en                 <= '1';
+        else
+          ringBuffer_data_in(35 downto 32) <= x"e";
+          ringBuffer_data_in(31 downto 0)  <= (others => '0');
+          ringBuffer_wr_en                 <= '0';
+        end if;
+      end if;
+    end process FifoWriteSignal;
+  end generate DATA_FORMAT_DEBUG;
+
+  FIFO_WRITE_OUT       <= ringBuffer_wr_en;
+  ENCODER_FINISHED_OUT <= encoder_finished;
+
+-------------------------------------------------------------------------------
+-- Read Stage
+-------------------------------------------------------------------------------
+  -- Determine the next state synchronously, based on the current state and the
+  -- input
+  FSM_DATA_STATE : process (CLK_100)
+  begin
+    if (rising_edge(CLK_100)) then
+      if RESET_100 = '1' then
+        FSM_RD_STATE <= IDLE;
+      else
+
+        case FSM_RD_STATE is
+          when IDLE =>
+            -- if the data readout is triggered by the end of the trigger window
+            if TRG_WIN_END_RDO_IN = '1' then
+              FSM_RD_STATE <= READOUT_DATA_A;
+            -- if the data readout is triggered by full fifo
+            elsif ringBuffer_almost_full_flag = '1' then
+              FSM_RD_STATE <= FLUSH_A;
+            else
+              FSM_RD_STATE <= IDLE;
+            end if;
+          --
+          when FLUSH_A =>
+            FSM_RD_STATE <= FLUSH_D;
+          --
+          when FLUSH_B =>
+            FSM_RD_STATE <= FLUSH_C;
+          --
+          when FLUSH_C =>
+            FSM_RD_STATE <= FLUSH_D;
+          --
+          when FLUSH_D =>
+            -- wait until a readout request and register the last epoch word
+            if TRG_WIN_END_RDO_IN = '1' or trg_win_end_rdo_flag = '1' then
+              FSM_RD_STATE <= READOUT_EPOCH;
+            else
+              FSM_RD_STATE <= FLUSH_D;
+            end if;
+          --
+          when READOUT_EPOCH =>
+            -- first epoch word should be readout
+            FSM_RD_STATE <= READOUT_DATA_A;
+          --
+          when READOUT_DATA_A =>
+            FSM_RD_STATE <= READOUT_DATA_B;
+          --
+          when READOUT_DATA_B =>
+            FSM_RD_STATE <= READOUT_DATA_C;
+          --  
+          when READOUT_DATA_C =>
+            -- normal data readout until the end of the readout request
+            if ringBuffer_data_out(35 downto 32) = x"f" then
+              FSM_RD_STATE <= IDLE;
+            else
+              FSM_RD_STATE <= READOUT_DATA_C;
+            end if;
+          --
+          when others =>
+            FSM_RD_STATE <= IDLE;
+        end case;
+      end if;
+    end if;
+  end process FSM_DATA_STATE;
+
+  -- Determine the output based only on the current state and the input (do not wait for a clock
+  -- edge).
+  FSM_DATA_OUTPUT : process (FSM_RD_STATE, TRG_WIN_END_RDO_IN, ringBuffer_data_out, epoch_value)
+  begin
+    trg_win_end_rdo_flag <= trg_win_end_rdo_flag;
+    epoch_value          <= epoch_value;
+
+    case FSM_RD_STATE is
+      when IDLE =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        fsm_rd_debug       <= x"1";
+      when FLUSH_A =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if TRG_WIN_END_RDO_IN = '1' then
+          trg_win_end_rdo_flag <= '1';
+        end if;
+        fsm_rd_debug <= x"2";
+      when FLUSH_B =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if TRG_WIN_END_RDO_IN = '1' then
+          trg_win_end_rdo_flag <= '1';
+        end if;
+        fsm_rd_debug <= x"3";
+      when FLUSH_C =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if TRG_WIN_END_RDO_IN = '1' then
+          trg_win_end_rdo_flag <= '1';
+        end if;
+        fsm_rd_debug <= x"4";
+      when FLUSH_D =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        if ringBuffer_data_out(31 downto 29) = "011" then
+          epoch_value <= ringBuffer_data_out;
+        end if;
+        fsm_rd_debug <= x"5";
+      when READOUT_EPOCH =>
+        fifo_data          <= epoch_value;
+        fifo_data_valid    <= '1';
+        ringBuffer_rd_data <= '1';
+        fsm_rd_debug       <= x"6";
+      when READOUT_DATA_A =>
+        fifo_data            <= (others => '0');
+        fifo_data_valid      <= '0';
+        ringBuffer_rd_data   <= '1';
+        trg_win_end_rdo_flag <= '0';
+        fsm_rd_debug         <= x"7";
+      when READOUT_DATA_B =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '1';
+        fsm_rd_debug       <= x"8";
+      when READOUT_DATA_C =>
+        fifo_data <= ringBuffer_data_out;
+        if ringBuffer_data_out(35 downto 32) = x"0" then
+          fifo_data_valid <= '0';
+        else
+          fifo_data_valid <= '1';
+        end if;
+        ringBuffer_rd_data <= '1';
+        fsm_rd_debug       <= x"9";
+      when others =>
+        fifo_data          <= (others => '0');
+        fifo_data_valid    <= '0';
+        ringBuffer_rd_data <= '0';
+        fsm_rd_debug       <= x"0";
+    end case;
+  end process FSM_DATA_OUTPUT;
+
+--FIFO_DATA_OUT       <= fifo_data;
+--FIFO_DATA_VALID_OUT <= fifo_data_valid;
+
+  FIFO_DATA_OUT       <= fifo_data       when rising_edge(CLK_100);
+  FIFO_DATA_VALID_OUT <= fifo_data_valid when rising_edge(CLK_100);
+
+-------------------------------------------------------------------------------
+-- DEBUG
+-------------------------------------------------------------------------------
+  --CHANNEL_200_DEBUG_OUT(7 downto 0)   <= ringBuffer_data_in(35 downto 28);
+  --CHANNEL_200_DEBUG_OUT(15 downto 8)  <= fifo_data(35 downto 28);
+  --CHANNEL_200_DEBUG_OUT(16)           <= ringBuffer_wr_en;
+  --CHANNEL_200_DEBUG_OUT(17)           <= fifo_data_valid;
+  --CHANNEL_200_DEBUG_OUT(18)           <= ringBuffer_rd_en;
+  --CHANNEL_200_DEBUG_OUT(23 downto 19) <= (others => '0');
+--  CHANNEL_200_DEBUG_OUT(0)            <= ff_array_en;
+  CHANNEL_200_DEBUG_OUT(23 downto 0)  <= (others => '0');
+  CHANNEL_200_DEBUG_OUT(27 downto 24) <= fsm_rd_debug;
+  CHANNEL_200_DEBUG_OUT(31 downto 28) <= fsm_wr_debug;
+
+  gen_SIMULATION : if SIMULATION = c_YES generate
+    -- count data written
+    data_cntr : process
+    begin
+      wait until rising_edge(CLK_100);
+      if fifo_data_valid = '1' and fifo_data(31 downto 29) = "100" then
+        data_cnt_event <= data_cnt_event + 1;
+      elsif fifo_data_valid = '1' and fifo_data(31 downto 29) = "011" then
+        epoch_cnt_event <= epoch_cnt_event + 1;
+      elsif TRG_WIN_END_RDO_IN = '1' then
+        data_cnt_event  <= 0;
+        epoch_cnt_event <= 0;
+      end if;
+    end process data_cntr;
+
+    process(fifo_data_valid)
+    begin  -- process
+      data_cnt_total  <= data_cnt_total + data_cnt_event;
+      epoch_cnt_total <= epoch_cnt_total + epoch_cnt_event;
+    end process;
+
+    -- check if data count per event is correct
+    --CheckEpochCounter : process
+    --begin
+    --  wait until falling_edge(fifo_data_valid);
+    --  wait for 1 ns;
+    --  if data_cnt_event /= 30 then
+    --    report "wrong number of hits in channel " & integer'image(CHANNEL_ID) severity error;
+    --  end if;
+    --end process CheckEpochCounter;
+
+  end generate gen_SIMULATION;
+
+end Channel_200;
diff --git a/releases/tdc_v2.3.1/Encoder_288_Bit.vhd b/releases/tdc_v2.3.1/Encoder_288_Bit.vhd
new file mode 100644 (file)
index 0000000..9ffb423
--- /dev/null
@@ -0,0 +1,464 @@
+-------------------------------------------------------------------------------
+-- Title      : Encoder 288 bits
+-------------------------------------------------------------------------------
+-- File       : Encoder_288_Bit.vhd
+-- Author     : Cahit Ugur
+-- Created    : 2011-11-28
+-- Last update: 2017-04-08
+-------------------------------------------------------------------------------
+-- Description: Encoder for 288 bits
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author  Description
+-- 2011-11-28  1.0      ugur    Created
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.tdc_components.all;
+use work.config.all;
+
+-- synopsys translate_off
+library ecp3;
+use ecp3.components.all;
+-- synopsys translate_on
+
+entity Encoder_288_Bit is
+  port (
+    RESET            : in  std_logic;   -- system reset
+    CLK              : in  std_logic;   -- system clock
+    START_IN         : in  std_logic;
+    THERMOCODE_IN    : in  std_logic_vector(287 downto 0);
+    FINISHED_OUT     : out std_logic;
+    DECIMAL_CODE_OUT : out std_logic_vector(9 downto 0);
+    ENCODER_INFO_OUT : out std_logic;
+    ENCODER_DEBUG    : out std_logic_vector(31 downto 0);
+    CHAIN_VALID_OUT  : out std_logic;
+    CHAIN_DATA_OUT   : out std_logic_vector(15 downto 0)
+    );
+end Encoder_288_Bit;
+
+architecture behavioral of Encoder_288_Bit is
+
+-------------------------------------------------------------------------------
+-- Component Declarations
+-------------------------------------------------------------------------------
+  component LUT4
+    generic (
+      INIT : std_logic_vector);
+    port (
+      A, B, C, D : in  std_ulogic;
+      Z          : out std_ulogic);
+  end component;
+
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+  signal P_lut                     : std_logic_vector(35 downto 0);
+  signal P_one                     : std_logic_vector(35 downto 0);
+  signal P_mux                     : std_logic_vector(34 downto 0);
+  signal mux_control               : std_logic_vector(5 downto 0);
+  signal mux_control_reg           : std_logic_vector(5 downto 0);
+  signal mux_control_2reg          : std_logic_vector(5 downto 0);
+  signal mux_control_3reg          : std_logic_vector(5 downto 0);
+  signal interval_reg              : std_logic_vector(8 downto 0);
+  signal interval_decimal          : std_logic_vector(2 downto 0);
+  signal decimal_code_f            : std_logic_vector(8 downto 0);
+  signal decimal_code_r            : std_logic_vector(8 downto 0);
+  signal address                   : std_logic_vector(9 downto 0);
+  signal address_r                 : std_logic_vector(9 downto 0);
+  signal q_reg                     : std_logic_vector(7 downto 0);
+  signal info                      : std_logic_vector(1 downto 0);
+  signal info_reg                  : std_logic_vector(1 downto 0);
+  signal info_2reg                 : std_logic_vector(1 downto 0);
+  signal info_3reg                 : std_logic_vector(1 downto 0);
+--
+  signal conv_finished             : std_logic;
+  signal thermocode                : std_logic_vector(288 downto 0);
+  signal thermocode_r              : std_logic_vector(287 downto 0);
+  signal thermocode_tmp            : std_logic_vector(287 downto 0);
+  signal start_pipeline            : std_logic_vector(10 downto 0) := (others => '0');
+  signal chain_pipeline            : std_logic_vector(18 downto 0) := (others => '0');
+--debug
+  type std_logic_vector_array_288 is array(integer range <>) of std_logic_vector(287 downto 0);
+  type std_logic_vector_array_10 is array(integer range <>) of std_logic_vector(9 downto 0);
+  signal decimal_code_i            : std_logic_vector_array_10(0 to 3);
+  signal chain                     : std_logic_vector(15 downto 0);
+  signal chain_valid               : std_logic;
+  signal start_in_r                : std_logic                     := '0';
+  signal start_in_2r               : std_logic                     := '0';
+  signal thermocode_array          : std_logic_vector_array_288(0 to 1);
+  signal thermocode_r1             : std_logic_vector(287 downto 0);
+  signal thermocode_f1             : std_logic_vector(287 downto 0);
+  signal thermocode_r2             : std_logic_vector(287 downto 0);
+  signal thermocode_f2             : std_logic_vector(287 downto 0);
+  signal start_r                   : std_logic                     := '0';
+  signal start_f                   : std_logic                     := '0';
+  signal chain_r                   : std_logic_vector(15 downto 0);
+  signal chain_f                   : std_logic_vector(15 downto 0);
+  type CHAIN_FSM_TYPE is (IDLE, LEADING_EDGE, LEADING_EDGE_2ND, TRAILING_EDGE);
+  signal STATE_CURRENT, STATE_NEXT : CHAIN_FSM_TYPE;
+    
+  
+  attribute syn_keep                     : boolean;
+  attribute syn_keep of mux_control      : signal is true;
+  attribute syn_keep of mux_control_reg  : signal is true;
+  attribute syn_keep of mux_control_2reg : signal is true;
+  attribute syn_keep of mux_control_3reg : signal is true;
+-------------------------------------------------------------------------------
+begin
+
+  thermocode(288 downto 1) <= THERMOCODE_IN;
+  thermocode(0)            <= '1';
+  mux_control_reg          <= mux_control      when rising_edge(CLK);
+  mux_control_2reg         <= mux_control_reg  when rising_edge(CLK);
+  mux_control_3reg         <= mux_control_2reg when rising_edge(CLK);
+
+  Interval_Determination_First : LUT4
+    generic map (INIT => X"37A8")
+    port map (A => '1', B => '1', C => THERMOCODE_IN(0), D => START_IN,
+              Z => P_lut(0));
+
+  Interval_Determination : for i in 1 to 35 generate
+    U : LUT4
+      generic map (INIT => X"37A8")
+      port map (A => THERMOCODE_IN(8*i-2), B => THERMOCODE_IN(8*i-1), C => THERMOCODE_IN(8*i), D => START_IN,
+                Z => P_lut(i));
+  end generate Interval_Determination;
+-------------------------------------------------------------------------------
+
+  Gen_P_one : for i in 0 to 34 generate
+    P_one(i) <= P_lut(i) and (not P_lut(i+1)) when rising_edge(CLK);
+  end generate Gen_P_one;
+  P_one(35) <= P_lut(35) and START_IN when rising_edge(CLK);
+
+  P_mux(34 downto 0) <= P_one(35 downto 1);
+
+  Interval_Number_to_Decimal : process (CLK)
+  begin  -- The interval number with the 0-1 transition is converted from 1-of-N code to decimal
+    -- code for the control of the MUX.
+    if rising_edge(CLK) then
+      if start_pipeline(1) = '1' or start_pipeline(0) = '1' then
+        mux_control(0) <= P_mux(0) or P_mux(2) or P_mux(4) or P_mux(6) or P_mux(8) or P_mux(10) or
+                          P_mux(12) or P_mux(14) or P_mux(16) or P_mux(18) or P_mux(20) or P_mux(22) or
+                          P_mux(24) or P_mux(26) or P_mux(28) or P_mux(30) or P_mux(32) or P_mux(34);
+        mux_control(1) <= P_mux(1) or P_mux(2) or P_mux(5) or P_mux(6) or P_mux(9) or P_mux(10) or
+                          P_mux(13) or P_mux(14) or P_mux(17) or P_mux(18) or P_mux(21) or P_mux(22) or
+                          P_mux(25) or P_mux(26) or P_mux(29) or P_mux(30) or P_mux(33) or P_mux(34);
+        mux_control(2) <= P_mux(3) or P_mux(4) or P_mux(5) or P_mux(6) or P_mux(11) or P_mux(12) or
+                          P_mux(13) or P_mux(14) or P_mux(19) or P_mux(20) or P_mux(21) or P_mux(22) or
+                          P_mux(27) or P_mux(28) or P_mux(29) or P_mux(30);
+        mux_control(3) <= P_mux(7) or P_mux(8) or P_mux(9) or P_mux(10) or P_mux(11) or P_mux(12) or
+                          P_mux(13) or P_mux(14) or P_mux(23) or P_mux(24) or P_mux(25) or P_mux(26) or
+                          P_mux(27) or P_mux(28) or P_mux(29) or P_mux(30);
+        mux_control(4) <= P_mux(15) or P_mux(16) or P_mux(17) or P_mux(18) or P_mux(19) or P_mux(20) or
+                          P_mux(21) or P_mux(22) or P_mux(23) or P_mux(24) or P_mux(25) or P_mux(26) or
+                          P_mux(27) or P_mux(28) or P_mux(29) or P_mux(30);
+        mux_control(5) <= P_mux(31) or P_mux(32) or P_mux(33) or P_mux(34);
+      else
+        mux_control <= (others => '0');
+      end if;
+    end if;
+  end process Interval_Number_to_Decimal;
+
+  Interval_Selection : process (CLK)
+    variable tmp : std_logic_vector(9 downto 1);
+  begin  -- The interval with the 0-1 transition is selected.
+    if rising_edge(CLK) then
+      tmp := (others => '0');
+      make_mux : for i in 0 to 35 loop
+        make_mux_2 : for j in 1 to 9 loop
+          tmp(j) := tmp(j) or (thermocode(i*8-1+j) and P_one(i));
+        end loop;
+      end loop;
+      interval_reg <= tmp;
+    end if;
+  end process Interval_Selection;
+
+--  The_ROM : entity work.ROM_encoder_3 --SIMULATION
+  The_ROM : entity work.ROM_encoder_4   --REAL
+    port map (
+      Address    => address,
+      OutClock   => CLK,
+      OutClockEn => '1',
+      Reset      => RESET,
+      Q          => q_reg);
+
+  address          <= start_pipeline(1) & interval_reg;
+  interval_decimal <= q_reg(2 downto 0)                     when rising_edge(CLK);
+  info             <= q_reg(7 downto 6)                     when rising_edge(CLK);
+  info_reg         <= info                                  when rising_edge(CLK);
+  info_2reg        <= info_reg                              when rising_edge(CLK);
+  info_3reg        <= info_2reg                             when rising_edge(CLK);
+  start_pipeline   <= start_pipeline(9 downto 0) & START_IN when rising_edge(CLK);
+
+  DATA_FORMAT_0 : if TDC_DATA_FORMAT = 0 generate  -- Fine time as the sum of the two transitions
+    Decimal_Code_Calculation : process (CLK)
+    begin
+      if rising_edge(CLK) then
+        if conv_finished = '1' then
+          if info_reg(1) = '1' and info_2reg(1) = '1' then
+            DECIMAL_CODE_OUT <= ('0' & decimal_code_r) + ('0' & decimal_code_f);
+          else
+            DECIMAL_CODE_OUT <= (others => '1');
+          end if;
+          ENCODER_INFO_OUT <= info(0) or info_reg(0);
+        end if;
+
+        FINISHED_OUT   <= conv_finished;
+        decimal_code_r <= mux_control_3reg & interval_decimal;
+        decimal_code_f <= decimal_code_r;
+        conv_finished  <= start_pipeline(5);
+      end if;
+    end process Decimal_Code_Calculation;
+  end generate DATA_FORMAT_0;
+
+  DATA_FORMAT_1 : if TDC_DATA_FORMAT = 1 generate  -- Fine time seperate two transitions
+    Decimal_Code_Calculation : process (CLK)
+    begin
+      if rising_edge(CLK) then
+        if conv_finished = '1' then
+          if info(1) = '1' then
+            DECIMAL_CODE_OUT <= '0' & decimal_code_r;
+          else
+            DECIMAL_CODE_OUT <= (others => '1');
+          end if;
+          ENCODER_INFO_OUT <= info(0);
+        end if;
+
+        FINISHED_OUT <= conv_finished;
+        if (start_pipeline(4) = '1' or start_pipeline(5) = '1') then
+          decimal_code_r <= mux_control_3reg & interval_decimal;
+        end if;
+        conv_finished <= start_pipeline(2) or start_pipeline(3) or start_pipeline(4) or start_pipeline(5);
+      end if;
+    end process Decimal_Code_Calculation;
+  end generate DATA_FORMAT_1;
+
+-------------------------------------------------------------------------------
+-- DEBUG DATA FORMATS
+-------------------------------------------------------------------------------
+  DATA_FORMAT_13 : if TDC_DATA_FORMAT = 13 generate
+    -- purpose: write decimal value and the chain
+    SampleThermocode : process (CLK) is
+    begin
+      if rising_edge(CLK) then          -- rising clock edge
+        if START_IN = '1' then
+          thermocode_r <= THERMOCODE_IN;
+        end if;
+      end if;
+    end process SampleThermocode;
+--
+    Decimal_Code_Calculation : process (CLK)
+    begin
+      if rising_edge(CLK) then
+        if conv_finished = '1' then
+          if info_reg(1) = '1' and info_2reg(1) = '1' then
+            DECIMAL_CODE_OUT  <= ('0' & decimal_code_r) + ('0' & decimal_code_f);
+            chain_pipeline(0) <= '0';
+          else
+            DECIMAL_CODE_OUT  <= (others => '1');
+            chain_pipeline(0) <= '1';
+          end if;
+          ENCODER_INFO_OUT <= info(0) or info_reg(0);
+        else
+          chain_pipeline(0) <= '0';
+        end if;
+
+        FINISHED_OUT   <= conv_finished;
+        decimal_code_r <= mux_control_3reg & interval_decimal;
+        decimal_code_f <= decimal_code_r;
+        conv_finished  <= start_pipeline(5);
+      end if;
+    end process Decimal_Code_Calculation;
+--
+    Chain_Readout : process (CLK)
+      variable tmp : std_logic_vector(15 downto 0);
+    begin
+      if rising_edge(CLK) then
+        tmp := (others => '0');
+        make_mux : for i in 0 to 17 loop
+          make_mux_2 : for j in 0 to 15 loop
+            tmp(j) := tmp(j) or (thermocode_r(i*16+j) and chain_pipeline(i+1));
+          end loop;
+        end loop;
+        chain                       <= tmp;
+        chain_pipeline(18 downto 1) <= chain_pipeline(17 downto 0);
+        chain_valid                 <= or_all(chain_pipeline(18 downto 1));
+        CHAIN_DATA_OUT              <= chain;
+        CHAIN_VALID_OUT             <= chain_valid;
+      end if;
+    end process Chain_Readout;
+--
+  end generate DATA_FORMAT_13;
+-------------------------------------------------------------------------------
+  DATA_FORMAT_14 : if TDC_DATA_FORMAT = 14 generate
+    -- purpose: 
+    Decimal_Code_Calculation : process (CLK)
+    begin
+      if rising_edge(CLK) then
+        if start_pipeline(2) = '1' then
+          address_r <= address;
+        end if;
+        if start_pipeline(1) = '1' then
+          DECIMAL_CODE_OUT <= address;
+          FINISHED_OUT     <= '1';
+          ENCODER_INFO_OUT <= '1';
+        elsif start_pipeline(4) = '1' then
+          DECIMAL_CODE_OUT <= address_r;
+          FINISHED_OUT     <= '1';
+          ENCODER_INFO_OUT <= '1';
+        elsif conv_finished = '1' then
+          if info_2reg(1) = '1' and info_3reg(1) = '1' then
+            DECIMAL_CODE_OUT <= decimal_code_i(0);
+          else
+            DECIMAL_CODE_OUT <= (others => '1');
+          end if;
+          ENCODER_INFO_OUT <= info_2reg(0) or info_3reg(0);
+          FINISHED_OUT     <= '1';
+        else
+          FINISHED_OUT <= '0';
+        end if;
+
+        decimal_code_r         <= mux_control_3reg & interval_decimal;
+        decimal_code_f         <= decimal_code_r;
+        decimal_code_i(0)      <= ('0' & decimal_code_r) + ('0' & decimal_code_f);
+        decimal_code_i(1 to 3) <= decimal_code_i(0 to 2);
+        conv_finished          <= start_pipeline(6);
+      end if;
+    end process Decimal_Code_Calculation;
+  end generate DATA_FORMAT_14;
+-------------------------------------------------------------------------------
+  DATA_FORMAT_15 : if TDC_DATA_FORMAT = 15 generate
+    FSM_CHAIN_SEQUENTIAL: process (CLK) is
+    begin
+      -- Outputs to be registered
+      if rising_edge(CLK) then  -- rising clock edge
+        if RESET = '1' then
+          STATE_CURRENT <= IDLE;
+        else
+          STATE_CURRENT <= STATE_NEXT;
+        end if;
+        thermocode_r1 <= thermocode_f1;
+        thermocode_r2 <= thermocode_f2;
+        start_r       <= start_f;
+        chain_r       <= chain_f;
+        
+        chain_pipeline(18 downto 0) <= chain_pipeline(17 downto 0) & start_r;
+        chain_valid                 <= or_all(chain_pipeline(16 downto 0)) or start_r;
+        CHAIN_DATA_OUT              <= chain_r;
+        CHAIN_VALID_OUT             <= chain_valid;
+      end if;
+      -- Outputs not to be registered
+      
+    end process FSM_CHAIN_SEQUENTIAL;
+
+    FSM_CHAIN_COMBINATIONAL : process (STATE_CURRENT, START_IN, THERMOCODE_IN, chain_pipeline, chain_valid, thermocode_r1, thermocode_r2) is
+    begin
+      -- Default values
+      STATE_NEXT    <= STATE_CURRENT;
+      thermocode_f1 <= (others => '0');
+      thermocode_f2 <= thermocode_r2;
+      start_f       <= '0';
+      chain_f       <= (others => '0');
+      
+      case STATE_CURRENT is
+        when IDLE =>
+          if START_IN = '1' then
+            STATE_NEXT    <= LEADING_EDGE;
+            thermocode_f1 <= THERMOCODE_IN;
+            start_f       <= '1';
+          end if;
+
+        when LEADING_EDGE =>
+          if START_IN = '1' then
+            STATE_NEXT    <= LEADING_EDGE_2ND;
+            thermocode_f2 <= THERMOCODE_IN;
+          elsif chain_pipeline(18) = '1' then
+            STATE_NEXT <= IDLE;
+          end if;
+          chain_f       <= thermocode_r1(15 downto 0);
+          thermocode_f1 <= x"0000" & thermocode_r1(287 downto 16);
+
+        when LEADING_EDGE_2ND =>
+          if chain_valid = '0' then
+            STATE_NEXT <= TRAILING_EDGE;
+            start_f    <= '1';
+          end if;
+          chain_f       <= thermocode_r1(15 downto 0);
+          thermocode_f1 <= x"0000" & thermocode_r1(287 downto 16);
+
+        when TRAILING_EDGE =>
+          if chain_valid = '0' and start_r = '0'then
+            STATE_NEXT <= IDLE;
+          end if;
+          chain_f       <= thermocode_r2(15 downto 0);
+          thermocode_f2 <= x"0000" & thermocode_r2(287 downto 16);
+                    
+        when others =>
+          STATE_NEXT <= IDLE;
+      end case;
+    end process FSM_CHAIN_COMBINATIONAL;
+
+
+    
+
+--    SampleThermocode : process (CLK) is
+--    begin
+--      if rising_edge(CLK) then          -- rising clock edge
+--        if START_IN = '1' then
+--          thermocode_tmp <= THERMOCODE_IN;
+--        end if;
+--        if chain_pipeline = "0000000000000000001" or chain_pipeline = "1000000000000000000"then
+--          thermocode_r <= thermocode_tmp;
+--        end if;
+--      end if;
+--    end process SampleThermocode;
+----
+--    Chain_Readout : process (CLK)
+--      variable tmp : std_logic_vector(15 downto 0);
+--    begin
+--      if rising_edge(CLK) then
+--        tmp := (others => '0');
+--        make_mux : for i in 0 to 17 loop
+--          make_mux_2 : for j in 0 to 15 loop
+--            tmp(j) := tmp(j) or (thermocode_r(i*16+j) and chain_pipeline(i+1));
+--          end loop;
+--        end loop;
+--        chain                       <= tmp;
+--        chain_valid                 <= or_all(chain_pipeline(18 downto 1));
+--        CHAIN_DATA_OUT              <= chain;
+--        CHAIN_VALID_OUT             <= chain_valid;
+--        chain_pipeline(18 downto 0) <= chain_pipeline(17 downto 0) & START_IN;
+--      end if;
+--    end process Chain_Readout;
+  end generate DATA_FORMAT_15;
+
+-------------------------------------------------------------------------------
+-- DEBUG
+-------------------------------------------------------------------------------
+
+  --Decimal_Code_Calculation : process (CLK, RESET)
+  --begin
+  -- if rising_edge(CLK) then
+  --   if RESET = '1' then
+  --     DECIMAL_CODE_OUT <= (others => '0');
+  --     FINISHED_OUT    <= '0';
+  --   elsif start_pipeline(1) = '1' or start_pipeline(2) = '1' then
+  --     DECIMAL_CODE_OUT <= address;
+  --     FINISHED_OUT    <= '1';
+  --   else
+  --     DECIMAL_CODE_OUT <= (others => '0');
+  --     FINISHED_OUT    <= '0';
+  --   end if;
+  -- end if;
+  --end process Decimal_Code_Calculation;
+
+  --ENCODER_DEBUG(8 downto 0) <= interval_reg;
+
+end behavioral;
diff --git a/releases/tdc_v2.3.1/Encoder_304_Bit.vhd b/releases/tdc_v2.3.1/Encoder_304_Bit.vhd
new file mode 100644 (file)
index 0000000..9037c1f
--- /dev/null
@@ -0,0 +1,240 @@
+-------------------------------------------------------------------------------
+-- Title      : Encoder 304 bits
+-------------------------------------------------------------------------------
+-- File       : Encoder_304_Bit.vhd
+-- Author     : Cahit Ugur
+-- Created    : 2011-11-28
+-- Last update: 2014-12-04
+-------------------------------------------------------------------------------
+-- Description: Encoder for 304 bits
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author  Description
+-- 2011-11-28  1.0      ugur    Created
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.tdc_components.all;
+
+-- synopsys translate_off
+library ecp3;
+use ecp3.components.all;
+-- synopsys translate_on
+
+entity Encoder_304_Bit is
+  port (
+    RESET            : in  std_logic;   -- system reset
+    CLK              : in  std_logic;   -- system clock
+    START_IN         : in  std_logic;
+    THERMOCODE_IN    : in  std_logic_vector(303 downto 0);
+    FINISHED_OUT     : out std_logic;
+    BINARY_CODE_OUT  : out std_logic_vector(9 downto 0);
+    ENCODER_INFO_OUT : out std_logic_vector(1 downto 0);
+    ENCODER_DEBUG    : out std_logic_vector(31 downto 0)
+    );
+end Encoder_304_Bit;
+
+architecture behavioral of Encoder_304_Bit is
+
+-------------------------------------------------------------------------------
+-- Component Declarations
+-------------------------------------------------------------------------------
+  component LUT4
+    generic (
+      INIT : std_logic_vector);
+    port (
+      A, B, C, D : in  std_ulogic;
+      Z          : out std_ulogic);
+  end component;
+
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+  signal P_lut            : std_logic_vector(37 downto 0);
+  signal P_one            : std_logic_vector(37 downto 0);
+  signal mux_control      : std_logic_vector(5 downto 0);
+  signal mux_control_reg  : std_logic_vector(5 downto 0);
+  signal mux_control_2reg : std_logic_vector(5 downto 0);
+  signal mux_control_3reg : std_logic_vector(5 downto 0);
+  signal interval_reg     : std_logic_vector(8 downto 0);
+  signal interval_binary  : std_logic_vector(2 downto 0);
+  signal binary_code_f    : std_logic_vector(8 downto 0);
+  signal binary_code_r    : std_logic_vector(8 downto 0);
+  signal start_reg        : std_logic;
+  signal start_2reg       : std_logic;
+  signal address          : std_logic_vector(9 downto 0);
+  signal q_reg            : std_logic_vector(7 downto 0);
+  signal info             : std_logic_vector(1 downto 0);
+  signal info_reg         : std_logic_vector(1 downto 0);
+  signal info_2reg        : std_logic_vector(1 downto 0);
+--
+  signal conv_finished    : std_logic;
+  signal thermocode       : std_logic_vector(304 downto 0);
+  signal start_pipeline   : std_logic_vector(6 downto 0) := (others => '0');
+
+  attribute syn_keep                     : boolean;
+  attribute syn_keep of mux_control      : signal is true;
+  attribute syn_keep of mux_control_reg  : signal is true;
+  attribute syn_keep of mux_control_2reg : signal is true;
+  attribute syn_keep of mux_control_3reg : signal is true;
+-------------------------------------------------------------------------------
+begin
+
+
+  thermocode(304 downto 1) <= THERMOCODE_IN;
+  thermocode(0)            <= '1';
+  start_reg                <= START_IN         when rising_edge(CLK);
+  start_2reg               <= start_reg        when rising_edge(CLK);
+  mux_control_reg          <= mux_control      when rising_edge(CLK);
+  mux_control_2reg         <= mux_control_reg  when rising_edge(CLK);
+  mux_control_3reg         <= mux_control_2reg when rising_edge(CLK);
+
+  Interval_Determination_First : LUT4
+    generic map (INIT => X"15A8")
+    port map (A => '1', B => '1', C => THERMOCODE_IN(0), D => START_IN,
+              Z => P_lut(0));
+
+  Interval_Determination : for i in 1 to 37 generate
+    U : LUT4
+      generic map (INIT => X"15A8")
+      port map (A => THERMOCODE_IN(8*i-2), B => THERMOCODE_IN(8*i-1), C => THERMOCODE_IN(8*i), D => START_IN,
+                Z => P_lut(i));
+  end generate Interval_Determination;
+-------------------------------------------------------------------------------
+
+  Gen_P_one : for i in 0 to 36 generate
+    P_one(i) <= P_lut(i) and (not P_lut(i+1)) when rising_edge(CLK);
+  end generate Gen_P_one;
+
+  P_one_assign : process (CLK)
+  begin
+    if rising_edge(CLK) then
+      if START_IN = '0' then
+        P_one(37) <= '0';
+      else
+        P_one(37) <= P_lut(37);
+      end if;
+    end if;
+  end process P_one_assign;
+
+  Interval_Number_to_Binary : process (CLK)
+  begin  -- The interval number with the 0-1 transition is converted from 1-of-N code to binary
+    -- code for the control of the MUX.
+    if rising_edge(CLK) then
+      if start_2reg = '1' or start_reg = '1' then
+        mux_control(0) <= P_one(0) or P_one(2) or P_one(4) or P_one(6) or P_one(8) or P_one(10) or
+                          P_one(12) or P_one(14) or P_one(16) or P_one(18) or P_one(20) or P_one(22) or
+                          P_one(24) or P_one(26) or P_one(28) or P_one(30) or P_one(32) or P_one(34) or
+                          P_one(36);
+        mux_control(1) <= P_one(1) or P_one(2) or P_one(5) or P_one(6) or P_one(9) or P_one(10) or
+                          P_one(13) or P_one(14) or P_one(17) or P_one(18) or P_one(21) or P_one(22) or
+                          P_one(25) or P_one(26) or P_one(29) or P_one(30) or P_one(33) or P_one(34) or
+                          P_one(37);
+        mux_control(2) <= P_one(3) or P_one(4) or P_one(5) or P_one(6) or P_one(11) or P_one(12) or
+                          P_one(13) or P_one(14) or P_one(19) or P_one(20) or P_one(21) or P_one(22) or
+                          P_one(27) or P_one(28) or P_one(29) or P_one(30) or P_one(35) or P_one(36) or
+                          P_one(37);
+        mux_control(3) <= P_one(7) or P_one(8) or P_one(9) or P_one(10) or P_one(11) or P_one(12) or
+                          P_one(13) or P_one(14) or P_one(23) or P_one(24) or P_one(25) or P_one(26) or
+                          P_one(27) or P_one(28) or P_one(29) or P_one(30);
+        mux_control(4) <= P_one(15) or P_one(16) or P_one(17) or P_one(18) or P_one(19) or P_one(20) or
+                          P_one(21) or P_one(22) or P_one(23) or P_one(24) or P_one(25) or P_one(26) or
+                          P_one(27) or P_one(28) or P_one(29) or P_one(30);
+        mux_control(5) <= P_one(31) or P_one(32) or P_one(33) or P_one(34) or P_one(35) or P_one(36) or
+                          P_one(37);
+      else
+        mux_control <= (others => '0');
+      end if;
+    end if;
+  end process Interval_Number_to_Binary;
+
+  Interval_Selection : process (CLK)
+    variable tmp : std_logic_vector(9 downto 1);
+  begin  -- The interval with the 0-1 transition is selected.
+    if rising_edge(CLK) then
+      tmp := (others => '0');
+      make_mux : for i in 0 to 37 loop
+        make_mux_2 : for j in 1 to 9 loop
+          tmp(j) := tmp(j) or (thermocode(i*8-1+j) and P_one(i));
+        end loop;
+      end loop;
+      interval_reg <= tmp;
+    end if;
+  end process Interval_Selection;
+
+  The_ROM : entity work.ROM_encoder_3
+    port map (
+      Address    => address,
+      OutClock   => CLK,
+      OutClockEn => '1',
+      Reset      => RESET,
+      Q          => q_reg);
+
+  address         <= start_2reg & interval_reg;
+  interval_binary <= q_reg(2 downto 0) when rising_edge(CLK);
+  info            <= q_reg(7 downto 6) when rising_edge(CLK);
+  info_reg        <= info              when rising_edge(CLK);
+  info_2reg       <= info_reg          when rising_edge(CLK);
+
+  Binary_Code_Calculation_rf : process (CLK)
+  begin
+    if rising_edge(CLK) then
+      binary_code_r <= (mux_control_3reg - 1) & interval_binary;
+      binary_code_f <= binary_code_r;
+    end if;
+  end process Binary_Code_Calculation_rf;
+
+  Binary_Code_Calculation : process (CLK)
+  begin
+    if rising_edge(CLK) then
+      if conv_finished = '1' then
+        if info_reg(1) = '1' and info_2reg(1) = '1' then
+          BINARY_CODE_OUT <= ('0' & binary_code_r) + ('0' & binary_code_f);
+        else
+          BINARY_CODE_OUT <= (others => '1');
+        end if;
+        ENCODER_INFO_OUT <= (others => '0');  --info_reg or info_2reg;
+        FINISHED_OUT     <= '1';
+      else
+        FINISHED_OUT <= '0';
+      end if;
+    end if;
+  end process Binary_Code_Calculation;
+
+  StartSignalPipeLine : process (CLK)
+  begin
+    if rising_edge(CLK) then
+      start_pipeline <= start_pipeline(5 downto 0) & START_IN;
+    end if;
+  end process StartSignalPipeLine;
+  conv_finished <= start_pipeline(6);
+
+-------------------------------------------------------------------------------
+-- DEBUG
+-------------------------------------------------------------------------------
+
+  --Binary_Code_Calculation : process (CLK, RESET)
+  --begin
+  -- if rising_edge(CLK) then
+  --   if RESET = '1' then
+  --     BINARY_CODE_OUT <= (others => '0');
+  --     FINISHED_OUT    <= '0';
+  --   elsif proc_finished_1 = '1' then
+  --     BINARY_CODE_OUT <= address; --'0' & interval_reg;
+  --     FINISHED_OUT    <= '1';
+  --   else
+  --     BINARY_CODE_OUT <= (others => '0');
+  --     FINISHED_OUT    <= '0';
+  --   end if;
+  -- end if;
+  --end process Binary_Code_Calculation;
+
+  --ENCODER_DEBUG(8 downto 0) <= interval_reg;
+
+end behavioral;
diff --git a/releases/tdc_v2.3.1/LogicAnalyser.vhd b/releases/tdc_v2.3.1/LogicAnalyser.vhd
new file mode 100644 (file)
index 0000000..3c6091d
--- /dev/null
@@ -0,0 +1,76 @@
+-------------------------------------------------------------------------------
+-- Title      : Logic Analyser Signals
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : LogicAnalyser.vhd
+-- Author     : cugur@gsi.de
+-- Created    : 2012-10-26
+-- Last update: 2015-04-21
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+
+entity LogicAnalyser is
+  generic (
+    CHANNEL_NUMBER : integer range 2 to 64);
+
+  port (
+    CLK        : in  std_logic;
+    RESET      : in  std_logic;
+--
+    DATA_IN    : in  std_logic_vector(3*32-1 downto 0);
+    CONTROL_IN : in  std_logic_vector(3 downto 0);
+    DATA_OUT   : out std_logic_vector(15 downto 0)
+    );
+
+end LogicAnalyser;
+
+
+architecture behavioral of LogicAnalyser is
+  
+  signal mux_out : std_logic_vector(15 downto 0);
+
+begin  -- behavioral
+
+-------------------------------------------------------------------------------
+-- Logic Analyser Signals
+-------------------------------------------------------------------------------
+  REG_LOGIC_ANALYSER_OUTPUT : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        mux_out <= (others => '0');
+      elsif CONTROL_IN = x"1" then      -- TRBNET connections debugging
+        mux_out(7 downto 0) <= DATA_IN(7 downto 0);      --fsm_debug;
+        mux_out(8)          <= DATA_IN(8);   --REFERENCE_TIME;
+        mux_out(9)          <= DATA_IN(9);   --VALID_TIMING_TRG_IN;
+        mux_out(10)         <= DATA_IN(10);  --VALID_NOTIMING_TRG_IN;
+        mux_out(11)         <= DATA_IN(11);  --INVALID_TRG_IN;
+        mux_out(12)         <= DATA_IN(12);  --TRG_DATA_VALID_IN;
+        mux_out(13)         <= DATA_IN(13);  --data_wr_reg;
+        mux_out(14)         <= DATA_IN(14);  --data_finished_reg;
+        mux_out(15)         <= DATA_IN(15);  --trg_release_reg;
+      elsif CONTROL_IN = x"2" then      -- Reference channel debugging
+        mux_out <= DATA_IN(31 downto 16);    --ref_debug(15 downto 0);
+      elsif CONTROL_IN = x"3" then      -- Data out
+        mux_out(7 downto 0)   <= DATA_IN(7 downto 0);    --fsm_debug;
+        mux_out(8)            <= DATA_IN(8);             --REFERENCE_TIME;
+        mux_out(9)            <= DATA_IN(13);            --data_wr_reg;
+        mux_out(15 downto 10) <= DATA_IN(37 downto 32);  --data_out_reg(27 downto 22);
+
+      --elsif CONTROL_IN = x"4" then  -- channel debugging
+      --  mux_out <= DATA_IN();  --ch_debug(1)(15 downto 0);
+      end if;
+    end if;
+  end process REG_LOGIC_ANALYSER_OUTPUT;
+
+  DATA_OUT <= mux_out;
+
+
+end behavioral;
diff --git a/releases/tdc_v2.3.1/ROM_encoder_ecp3.vhd b/releases/tdc_v2.3.1/ROM_encoder_ecp3.vhd
new file mode 120000 (symlink)
index 0000000..10a014d
--- /dev/null
@@ -0,0 +1 @@
+rom_encoder/ecp3/ROM_encoder_3.vhd
\ No newline at end of file
diff --git a/releases/tdc_v2.3.1/ROM_encoder_ecp5.vhd b/releases/tdc_v2.3.1/ROM_encoder_ecp5.vhd
new file mode 120000 (symlink)
index 0000000..15d512f
--- /dev/null
@@ -0,0 +1 @@
+rom_encoder/ecp5/ROM_encoder_4/ROM_encoder_4.vhd
\ No newline at end of file
diff --git a/releases/tdc_v2.3.1/Readout.vhd b/releases/tdc_v2.3.1/Readout.vhd
new file mode 100644 (file)
index 0000000..77c37b1
--- /dev/null
@@ -0,0 +1,976 @@
+-------------------------------------------------------------------------------
+-- Title      : Readout Entity
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : Readout.vhd
+-- Author     : cugur@gsi.de
+-- Created    : 2012-10-25
+-- Last update: 2015-05-12
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+-- Copyright (c) 2012 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.tdc_components.all;
+
+entity Readout is
+  generic (
+    CHANNEL_NUMBER : integer range 2 to 65;
+    STATUS_REG_NR  : integer range 0 to 31); 
+  port (
+    RESET_100             : in  std_logic;
+    RESET_200             : in  std_logic;
+    RESET_COUNTERS        : in  std_logic;
+    CLK_100               : in  std_logic;
+    CLK_200               : in  std_logic;
+    HIT_IN                : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+-- from the channels
+    CH_DATA_IN            : in  std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+    CH_DATA_VALID_IN      : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+    CH_ALMOST_FULL_IN     : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+    CH_EMPTY_IN           : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+-- from the endpoint
+    TRG_DATA_VALID_IN     : in  std_logic;
+    VALID_TIMING_TRG_IN   : in  std_logic;
+    VALID_NOTIMING_TRG_IN : in  std_logic;
+    INVALID_TRG_IN        : in  std_logic;
+    TMGTRG_TIMEOUT_IN     : in  std_logic;
+    SPIKE_DETECTED_IN     : in  std_logic;
+    MULTI_TMG_TRG_IN      : in  std_logic;
+    SPURIOUS_TRG_IN       : in  std_logic;
+    TRG_CODE_IN           : in  std_logic_vector(7 downto 0);
+    TRG_INFORMATION_IN    : in  std_logic_vector(23 downto 0);
+    TRG_TYPE_IN           : in  std_logic_vector(3 downto 0);
+-- to the endpoint
+    TRG_RELEASE_OUT       : out std_logic;
+    TRG_STATUSBIT_OUT     : out std_logic_vector(31 downto 0);
+    DATA_OUT              : out std_logic_vector(31 downto 0);
+    DATA_WRITE_OUT        : out std_logic;
+    DATA_FINISHED_OUT     : out std_logic;
+-- to the channels
+    READ_EN_OUT           : out std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+-- trigger window settings
+    TRG_WIN_PRE_IN        : in  std_logic_vector(10 downto 0);
+    TRG_WIN_POST_IN       : in  std_logic_vector(10 downto 0);
+    TRG_WIN_EN_IN         : in  std_logic;
+-- from the trigger handler
+    TRG_WIN_END_TDC_IN    : in  std_logic;
+    TRG_WIN_END_RDO_IN    : in  std_logic;
+    TRG_TDC_IN            : in  std_logic;
+    TRG_TIME_IN           : in  std_logic_vector(38 downto 0);
+    MISSING_REF_TIME_IN   : in  std_logic;
+-- miscellaneous
+    LIGHT_MODE_IN         : in  std_logic;
+    DEBUG_MODE_EN_IN      : in  std_logic;
+    STATISTICS_OUT        : out std_logic_vector_array_24(0 to 15);
+    READOUT_DEBUG         : out std_logic_vector(31 downto 0)
+    );
+end entity Readout;
+
+architecture behavioral of Readout is
+
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+
+  -- trigger window
+  signal trg_win_pre             : unsigned(10 downto 0);
+  signal trg_win_post            : unsigned(10 downto 0);
+  signal trg_time                : std_logic_vector(38 downto 0);
+  signal TW_pre                  : std_logic_vector(38 downto 0);
+  signal TW_post                 : std_logic_vector(38 downto 0);
+  signal trg_win_l               : std_logic;
+  signal trg_win_r               : std_logic;
+  signal start_trg_win_cnt       : std_logic := '0';
+  signal start_trg_win_cnt_200_p : std_logic;
+  signal trg_win_cnt             : std_logic_vector(11 downto 0);
+  signal trg_win_end_200         : std_logic := '0';
+  signal trg_win_end_200_p       : std_logic;
+  signal trg_win_end_100_p       : std_logic;
+  signal trg_win_end_100_r       : std_logic;
+  signal trg_win_end_100_2r      : std_logic;
+  signal trg_win_end_100_3r      : std_logic;
+  signal trg_win_end_100_4r      : std_logic;
+  -- channel signals
+  signal ch_data_r               : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_2r              : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_3r              : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_4r              : std_logic_vector(31 downto 0);
+  signal ch_hit_time             : std_logic_vector(38 downto 0);
+  signal ch_epoch_cntr           : std_logic_vector(27 downto 0);
+  signal buffer_transfer_done    : std_logic;
+  signal buffer_transfer_done_r  : std_logic;
+  signal buffer_transfer_done_2r : std_logic;
+  -- readout fsm
+  type FSM_READ is (IDLE, WAIT_FOR_TRG_WIND_END, RD_CH, WAIT_FOR_DATA_FINISHED, WAIT_FOR_LVL1_TRG_A,
+                    WAIT_FOR_LVL1_TRG_B, WAIT_FOR_LVL1_TRG_C, SEND_STATUS, SEND_TRG_RELEASE_A,
+                    SEND_TRG_RELEASE_B, SEND_TRG_RELEASE_C, WAIT_FOR_BUFFER_TRANSFER);
+  signal RD_CURRENT             : FSM_READ                          := IDLE;
+  signal RD_NEXT                : FSM_READ;
+  type FSM_WRITE is (IDLE, WR_CH, WAIT_A, WAIT_B, WAIT_C, WAIT_D);
+  signal WR_CURRENT             : FSM_WRITE                         := IDLE;
+  signal WR_NEXT                : FSM_WRITE;
+  signal start_trg_win_cnt_fsm  : std_logic;
+  signal rd_fsm_debug_fsm       : std_logic_vector(3 downto 0);
+  signal wr_fsm_debug_fsm       : std_logic_vector(3 downto 0);
+  signal rd_en_fsm              : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal data_finished_fsm      : std_logic;
+  signal wr_finished_fsm        : std_logic;
+  signal trg_release_fsm        : std_logic;
+  signal wr_header_fsm          : std_logic;
+  signal wr_trailer_fsm         : std_logic;
+  signal wr_ch_data_fsm         : std_logic;
+  signal wr_status_fsm          : std_logic;
+  signal missing_ref_time_fsm   : std_logic;
+  signal missing_ref_time       : std_logic;
+  signal wrong_readout_fsm      : std_logic;
+  signal wrong_readout          : std_logic;
+  signal fifo_nr_rd_fsm         : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_fsm         : integer range 0 to CHANNEL_NUMBER := 0;
+  signal buf_delay_fsm          : integer range 0 to 63             := 0;
+  signal buf_delay              : integer range 0 to 63             := 0;
+--  signal isLastTriggerNoTiming  : std_logic                         := '0';
+--  signal wr_trailer_fsm          : std_logic;
+  signal idle_fsm               : std_logic;
+  signal readout_fsm            : std_logic;
+  signal wait_fsm               : std_logic;
+  -- fifo number
+  type Std_Logic_8_array is array (0 to 8) of std_logic_vector(3 downto 0);
+  signal empty_channels         : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal fifo_nr_rd             : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr             : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_r           : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_2r          : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_3r          : integer range 0 to CHANNEL_NUMBER := 0;
+  -- fifo read
+  signal rd_en                  : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  -- data mux
+  signal start_write            : std_logic                         := '0';
+  signal wr_header              : std_logic;
+  signal wr_ch_data             : std_logic;
+  signal wr_ch_data_r           : std_logic;
+  signal wr_status              : std_logic;
+  signal wr_trailer             : std_logic;
+  signal wr_info                : std_logic;
+  signal wr_time                : std_logic;
+  signal wr_epoch               : std_logic;
+  signal stop_status            : std_logic;
+  -- to endpoint
+  signal data_out_r             : std_logic_vector(31 downto 0);
+  signal data_wr_r              : std_logic;
+  signal data_finished          : std_logic;
+  signal wr_finished            : std_logic;
+  signal trg_release            : std_logic;
+  signal trg_statusbit          : std_logic_vector(31 downto 0)     := (others => '0');
+  -- statistics
+  signal trg_number             : unsigned(23 downto 0)             := (others => '0');
+  signal release_number         : unsigned(23 downto 0)             := (others => '0');
+  signal valid_tmg_trg_number   : unsigned(23 downto 0)             := (others => '0');
+  signal valid_NOtmg_trg_number : unsigned(23 downto 0)             := (others => '0');
+  signal invalid_trg_number     : unsigned(23 downto 0)             := (others => '0');
+  signal multi_tmg_trg_number   : unsigned(23 downto 0)             := (others => '0');
+  signal spurious_trg_number    : unsigned(23 downto 0)             := (others => '0');
+  signal wrong_readout_number   : unsigned(23 downto 0)             := (others => '0');
+  signal spike_number           : unsigned(23 downto 0)             := (others => '0');
+  signal timeout_number         : unsigned(23 downto 0)             := (others => '0');
+  signal total_empty_channel    : unsigned(23 downto 0)             := (others => '0');
+  signal idle_time              : unsigned(23 downto 0)             := (others => '0');
+  signal readout_time           : unsigned(23 downto 0)             := (others => '0');
+  signal wait_time              : unsigned(23 downto 0)             := (others => '0');
+  signal finished_number        : unsigned(23 downto 0)             := (others => '0');
+  signal valid_timing_trg_p     : std_logic;
+  signal valid_notiming_trg_p   : std_logic;
+  signal invalid_trg_p          : std_logic;
+  signal multi_tmg_trg_p        : std_logic;
+  signal spurious_trg_p         : std_logic;
+  signal spike_detected_p       : std_logic;
+  signal timeout_detected_p     : std_logic;
+  signal idle_time_up           : std_logic;
+  signal readout_time_up        : std_logic;
+  signal wait_time_up           : std_logic;
+  signal wrong_readout_up       : std_logic;
+  signal finished               : std_logic;
+  -- control
+  signal sync_q                 : std_logic_vector((CHANNEL_NUMBER-2)*3+2 downto 0);
+  signal isNoHit                : std_logic                         := '1';
+  signal isNoHit_r              : std_logic                         := '1';
+  signal isCalTrig              : std_logic                         := '0';
+  signal hit_in_i               : std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+  -- debug
+  signal header_error_bits      : std_logic_vector(15 downto 0);
+  signal trailer_error_bits     : std_logic_vector(15 downto 0);
+  signal rd_fsm_debug           : std_logic_vector(3 downto 0);
+  signal rd_fsm_debug_r         : std_logic_vector(3 downto 0);
+  signal history_rd_fsm         : std_logic_vector(31 downto 0)     := (others => '0');
+  signal wr_fsm_debug           : std_logic_vector(3 downto 0);
+  signal wr_fsm_debug_r         : std_logic_vector(3 downto 0);
+  signal history_wr_fsm         : std_logic_vector(31 downto 0)     := (others => '0');
+  signal any_hit                : std_logic                         := '0';
+  
+begin  -- behavioral
+
+  trg_win_pre  <= unsigned(TRG_WIN_PRE_IN);
+  trg_win_post <= unsigned(TRG_WIN_POST_IN);
+
+-------------------------------------------------------------------------------
+-- Trigger window
+-------------------------------------------------------------------------------
+-- Trigger window borders
+  TrigWinCalculation : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      TW_pre  <= std_logic_vector(unsigned(trg_time)-trg_win_pre);
+      TW_post <= std_logic_vector(unsigned(trg_time)+trg_win_post);
+    end if;
+  end process TrigWinCalculation;
+
+-- Trigger Time Determination
+  DefineTriggerTime : process (CLK_200)
+  begin
+    if rising_edge(CLK_200) then
+      if RESET_200 = '1' then
+        trg_time <= (others => '0');
+      elsif TRG_TDC_IN = '1' then
+        trg_time <= TRG_TIME_IN;
+      end if;
+    end if;
+  end process DefineTriggerTime;
+
+-- Channel Hit Time Determination
+  ChannelHitTime : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31 downto 29) = "011" then
+        ch_epoch_cntr <= ch_data_r(fifo_nr_wr)(27 downto 0);
+      end if;
+
+      if ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31) = '1' then
+        ch_hit_time <= ch_epoch_cntr& ch_data_r(fifo_nr_wr)(10 downto 0);
+      elsif ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31 downto 29) = "011" then
+        ch_hit_time <= (others => '0');
+      end if;
+    end if;
+  end process ChannelHitTime;
+
+-- Controls if the data coming from the channel is greater than the trigger window pre-edge
+  Check_Trigger_Win_Left : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if unsigned(TW_pre) <= unsigned(ch_hit_time) then
+        trg_win_l <= '1';
+      else
+        trg_win_l <= '0';
+      end if;
+    end if;
+  end process Check_Trigger_Win_Left;
+
+-- Controls if the data coming from the channel is smaller than the trigger window post-edge
+  Check_Trigger_Win_Right : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if unsigned(ch_hit_time) <= unsigned(TW_post) then
+        trg_win_r <= '1';
+      else
+        trg_win_r <= '0';
+      end if;
+    end if;
+  end process Check_Trigger_Win_Right;
+
+-------------------------------------------------------------------------------
+-- Readout
+-------------------------------------------------------------------------------
+-- Readout fsm
+  RD_FSM_CLK : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        RD_CURRENT <= IDLE;
+        fifo_nr_rd <= 0;
+      else
+        RD_CURRENT              <= RD_NEXT;
+        rd_en                   <= rd_en_fsm;
+        wr_header               <= wr_header_fsm;
+        wr_trailer              <= wr_trailer_fsm;
+        wr_status               <= wr_status_fsm;
+        data_finished           <= data_finished_fsm;
+        trg_release             <= trg_release_fsm;
+        missing_ref_time        <= missing_ref_time_fsm;
+        buf_delay               <= buf_delay_fsm;
+        wrong_readout           <= wrong_readout_fsm;
+        idle_time_up            <= idle_fsm;
+        readout_time_up         <= readout_fsm;
+        wait_time_up            <= wait_fsm;
+        fifo_nr_rd              <= fifo_nr_rd_fsm;
+        rd_fsm_debug            <= rd_fsm_debug_fsm;
+        buffer_transfer_done    <= and_all(CH_EMPTY_IN);
+        buffer_transfer_done_r  <= buffer_transfer_done;
+        buffer_transfer_done_2r <= buffer_transfer_done_r;
+      end if;
+    end if;
+  end process RD_FSM_CLK;
+  READ_EN_OUT <= rd_en;
+
+  RD_FSM_PROC : process (RD_CURRENT, VALID_TIMING_TRG_IN, VALID_NOTIMING_TRG_IN, TRG_DATA_VALID_IN,
+                         INVALID_TRG_IN, TMGTRG_TIMEOUT_IN, TRG_TYPE_IN, SPURIOUS_TRG_IN, stop_status,
+                         DEBUG_MODE_EN_IN, fifo_nr_rd, TRG_WIN_END_RDO_IN, buf_delay, CH_EMPTY_IN,
+                         buffer_transfer_done_2r, MISSING_REF_TIME_IN, wrong_readout, isNoHit_r)
+  begin
+
+    RD_NEXT              <= RD_CURRENT;
+    rd_en_fsm            <= (others => '0');
+    wr_header_fsm        <= '0';
+    wr_trailer_fsm       <= '0';
+    wr_status_fsm        <= '0';
+    data_finished_fsm    <= '0';
+    trg_release_fsm      <= '0';
+    missing_ref_time_fsm <= '0';
+    wrong_readout_fsm    <= wrong_readout;
+    idle_fsm             <= '0';
+    readout_fsm          <= '0';
+    wait_fsm             <= '0';
+    buf_delay_fsm        <= 0;
+    fifo_nr_rd_fsm       <= fifo_nr_rd;
+    rd_fsm_debug_fsm     <= x"0";
+
+    case (RD_CURRENT) is
+      when IDLE =>
+        if VALID_TIMING_TRG_IN = '1' then  -- physical trigger
+          RD_NEXT <= WAIT_FOR_TRG_WIND_END;
+          --if isLastTriggerNoTiming = '1' then
+          --  wrong_readout_fsm <= '1';
+          --end if;
+          readout_fsm <= '1';
+        elsif VALID_NOTIMING_TRG_IN = '1' then
+          if TRG_TYPE_IN = x"E" then       -- status trigger
+            wr_header_fsm <= '1';
+            RD_NEXT       <= SEND_STATUS;
+          elsif TRG_TYPE_IN = x"D" then    -- tdc calibration trigger
+            RD_NEXT       <= WAIT_FOR_TRG_WIND_END;
+            --wr_header_fsm <= '1';
+            readout_fsm   <= '1';
+          else                             -- the other triggers
+            RD_NEXT           <= SEND_TRG_RELEASE_A;
+            data_finished_fsm <= '1';
+          end if;
+        elsif INVALID_TRG_IN = '1' then    -- invalid trigger
+          RD_NEXT           <= SEND_TRG_RELEASE_A;
+          data_finished_fsm <= '1';
+        end if;
+        idle_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"1";
+        
+      when WAIT_FOR_TRG_WIND_END =>
+        if TRG_WIN_END_RDO_IN = '1' then
+          RD_NEXT <= WAIT_FOR_BUFFER_TRANSFER;
+          if MISSING_REF_TIME_IN = '1' or isNoHit_r = '0' then
+            wr_header_fsm        <= '1';
+            if MISSING_REF_TIME_IN = '1' then
+              missing_ref_time_fsm <= '1';
+            end if;
+          end if;
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"2";
+
+      when WAIT_FOR_BUFFER_TRANSFER =>  -- the data from channel fifo is written to the buffer
+        if buffer_transfer_done_2r = '0' or buf_delay = 63 then
+          RD_NEXT <= RD_CH;
+        else
+          buf_delay_fsm <= buf_delay+ 1;
+        end if;
+        rd_fsm_debug_fsm <= x"3";
+
+      when RD_CH =>
+        if CH_EMPTY_IN(fifo_nr_rd) = '0' then  -- read from channel if not empty
+          rd_en_fsm(fifo_nr_rd) <= '1';
+          fifo_nr_rd_fsm        <= fifo_nr_rd;
+        elsif fifo_nr_rd = CHANNEL_NUMBER-1 then  -- the last channel
+          rd_en_fsm(fifo_nr_rd) <= '0';
+          if DEBUG_MODE_EN_IN = '1' then  -- send status after channel data
+            RD_NEXT <= SEND_STATUS;
+          else
+            RD_NEXT <= WAIT_FOR_LVL1_TRG_A;
+          end if;
+        else                            -- go to the next channel
+          fifo_nr_rd_fsm <= fifo_nr_rd + 1 after 10 ps;
+        end if;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"4";
+
+      when WAIT_FOR_LVL1_TRG_A =>       -- wait for trigger data valid
+        if TRG_DATA_VALID_IN = '1' then
+          RD_NEXT <= WAIT_FOR_LVL1_TRG_B;
+        elsif TMGTRG_TIMEOUT_IN = '1' then
+          RD_NEXT           <= SEND_TRG_RELEASE_A;
+          data_finished_fsm <= '1';
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"6";
+
+      when WAIT_FOR_LVL1_TRG_B =>
+        RD_NEXT          <= WAIT_FOR_LVL1_TRG_C;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"7";
+
+      when WAIT_FOR_LVL1_TRG_C =>
+        if SPURIOUS_TRG_IN = '1' then
+          wrong_readout_fsm <= '1';
+--          wr_trailer_fsm    <= '1';
+        end if;
+        RD_NEXT          <= SEND_TRG_RELEASE_A;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"8";
+
+      when SEND_STATUS =>
+        if stop_status = '1' then
+          if DEBUG_MODE_EN_IN = '1' then
+            RD_NEXT <= WAIT_FOR_LVL1_TRG_A;
+          else
+            RD_NEXT           <= SEND_TRG_RELEASE_A;
+            data_finished_fsm <= '1';
+          end if;
+        else
+          wr_status_fsm <= '1';
+        end if;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"9";
+
+      when SEND_TRG_RELEASE_A =>
+        RD_NEXT          <= SEND_TRG_RELEASE_B;
+        fifo_nr_rd_fsm   <= 0;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"A";
+
+      when SEND_TRG_RELEASE_B =>
+        RD_NEXT           <= SEND_TRG_RELEASE_C;
+        data_finished_fsm <= '1';
+        readout_fsm       <= '1';
+        rd_fsm_debug_fsm  <= x"B";
+
+      when SEND_TRG_RELEASE_C =>
+        RD_NEXT           <= IDLE;
+        trg_release_fsm   <= '1';
+        wrong_readout_fsm <= '0';
+        readout_fsm       <= '1';
+        rd_fsm_debug_fsm  <= x"C";
+
+      when others =>
+        RD_NEXT          <= IDLE;
+        rd_fsm_debug_fsm <= x"0";
+    end case;
+  end process RD_FSM_PROC;
+
+
+  --purpose: FSM for writing data to endpoint buffer
+  WR_FSM_CLK : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        WR_CURRENT <= IDLE;
+      else
+        WR_CURRENT   <= WR_NEXT;
+        wr_ch_data   <= wr_ch_data_fsm;
+        fifo_nr_wr   <= fifo_nr_wr_fsm;
+        wr_finished  <= wr_finished_fsm;
+        wr_fsm_debug <= wr_fsm_debug_fsm;
+        start_write  <= or_all(CH_DATA_VALID_IN);
+      end if;
+    end if;
+  end process WR_FSM_CLK;
+
+  WR_FSM : process (WR_CURRENT, fifo_nr_wr, start_write, CH_DATA_VALID_IN, ch_data_2r,
+                    isNoHit_r)
+
+  begin
+
+    WR_NEXT          <= WR_CURRENT;
+    wr_ch_data_fsm   <= '0';
+    fifo_nr_wr_fsm   <= 0;
+    wr_finished_fsm  <= '0';
+    wr_fsm_debug_fsm <= x"0";
+
+    case (WR_CURRENT) is
+      when IDLE =>
+        if start_write = '1' then
+          fifo_nr_wr_fsm <= 0;
+          WR_NEXT        <= WR_CH;
+        end if;
+        wr_fsm_debug_fsm <= x"1";
+--
+      when WR_CH =>
+        if ch_data_2r(fifo_nr_wr)(35 downto 32) /= x"f" then
+          if isNoHit_r = '1' then
+            wr_ch_data_fsm <= '0';
+          else
+            wr_ch_data_fsm <= '1';
+          end if;
+          fifo_nr_wr_fsm <= fifo_nr_wr;
+        --wr_fsm_debug_fsm <= x"4";
+        elsif CH_DATA_VALID_IN(fifo_nr_wr) = '1' then
+          fifo_nr_wr_fsm <= fifo_nr_wr;
+        --wr_fsm_debug_fsm <= x"6";
+        elsif fifo_nr_wr = CHANNEL_NUMBER-1 then
+          wr_finished_fsm <= '1';
+          WR_NEXT         <= IDLE;
+        --wr_fsm_debug_fsm <= x"5";
+        else
+          fifo_nr_wr_fsm <= fifo_nr_wr + 1;
+          WR_NEXT        <= WAIT_A;
+        --wr_fsm_debug_fsm <= x"7";
+        end if;
+        wr_fsm_debug_fsm <= x"2";
+--
+      when WAIT_A =>
+        WR_NEXT          <= WAIT_B;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_B =>
+        WR_NEXT          <= WR_CH;      --WAIT_C;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_C =>
+        WR_NEXT          <= WAIT_D;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_D =>
+        WR_NEXT          <= WR_CH;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--      
+      when others =>
+        WR_NEXT          <= IDLE;
+        wr_fsm_debug_fsm <= x"0";
+
+    end case;
+  end process WR_FSM;
+
+  fifo_nr_wr_r  <= fifo_nr_wr    when rising_edge(CLK_100);
+  fifo_nr_wr_2r <= fifo_nr_wr_r  when rising_edge(CLK_100);
+  fifo_nr_wr_3r <= fifo_nr_wr_2r when rising_edge(CLK_100);
+  wr_ch_data_r  <= wr_ch_data    when rising_edge(CLK_100);
+
+-------------------------------------------------------------------------------
+-- Data out mux
+-------------------------------------------------------------------------------
+  isCalibrationTrigger: process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then  -- rising clock edge
+      if trg_release = '1' then
+        isCalTrig <= '0';
+      elsif VALID_NOTIMING_TRG_IN = '1' and TRG_TYPE_IN = x"D" then
+        isCalTrig <= '1';
+      end if;
+    end if;
+  end process isCalibrationTrigger;
+  
+  -- Trigger window selection
+  TriggerWindowElimination : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if ch_data_3r(fifo_nr_wr_r)(35 downto 32) = x"1" and ch_data_3r(fifo_nr_wr_r)(31) = '1' then  --DATA word
+        if TRG_WIN_EN_IN = '1' and isCalTrig = '0' then -- trigger window enabled
+          --elsif (TW_pre(10) = '1' and ref_time_coarse(10) = '0') or (TW_post(10) = '0' and ref_time_coarse(10) = '1') then  -- if one of the trigger window edges has an overflow
+          --  if (trg_win_l = '0' and trg_win_r = '1') or (trg_win_l = '1' and trg_win_r = '0') then
+          --    ch_data_4r <= ch_data_3r(fifo_nr);
+          --    data_wr_r  <= '1';
+          --  else
+          --    ch_data_4r <= (others => '1');
+          --    data_wr_r  <= '0';
+          --  end if;
+          if trg_win_l = '1' and trg_win_r = '1' then  -- if both of the trigger window edges are in the coarse counter boundries
+            ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+          elsif trg_win_r = '0' then  -- any hit that might come after the trigger window 
+            ch_data_4r <= (others => '0');
+          --else
+          --  ch_data_4r <= (others => '0');
+          end if;
+        else
+          ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+        end if;
+      else
+        ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+      end if;
+    end if;
+  end process TriggerWindowElimination;
+
+
+  Data_Out_MUX : process (CLK_100)
+    variable i : integer := 0;
+  begin
+    if rising_edge(CLK_100) then
+      if wr_header = '1' then
+        data_out_r  <= "001" & "0" & TRG_TYPE_IN & TRG_CODE_IN & header_error_bits;
+        stop_status <= '0';
+      elsif wr_ch_data_r = '1' then
+        data_out_r  <= ch_data_4r;
+        stop_status <= '0';
+      elsif wr_status = '1' then
+        case i is
+          when 0  => data_out_r <= "010" & "00000" & std_logic_vector(trg_number);
+          when 1  => data_out_r <= "010" & "00001" & std_logic_vector(release_number);
+          when 2  => data_out_r <= "010" & "00010" & std_logic_vector(valid_tmg_trg_number);
+          when 3  => data_out_r <= "010" & "00011" & std_logic_vector(valid_NOtmg_trg_number);
+          when 4  => data_out_r <= "010" & "00100" & std_logic_vector(invalid_trg_number);
+          when 5  => data_out_r <= "010" & "00101" & std_logic_vector(multi_tmg_trg_number);
+          when 6  => data_out_r <= "010" & "00110" & std_logic_vector(spurious_trg_number);
+          when 7  => data_out_r <= "010" & "00111" & std_logic_vector(wrong_readout_number);
+          when 8  => data_out_r <= "010" & "01000" & std_logic_vector(spike_number);
+          when 9  => data_out_r <= "010" & "01001" & std_logic_vector(idle_time);
+          when 10 => data_out_r <= "010" & "01010" & std_logic_vector(wait_time);
+          when 11 => data_out_r <= "010" & "01011" & std_logic_vector(total_empty_channel);
+          when 12 => data_out_r <= "010" & "01100" & std_logic_vector(readout_time);
+                     stop_status <= '1';
+          when 13 => data_out_r <= "010" & "01101" & std_logic_vector(timeout_number);
+                     i := -1;
+          when others => null;
+        end case;
+        i := i+1;
+      --elsif wr_trailer = '1' then
+      --  data_out_r  <= "011" & "0000000000000" & trailer_error_bits;
+      --  data_wr_r   <= '1';
+      --  stop_status<= '0';
+      else
+        data_out_r  <= (others => '1');
+        stop_status <= '0';
+      end if;
+    end if;
+  end process Data_Out_MUX;
+
+  wr_info  <= wr_header or wr_status          when rising_edge(CLK_100);
+  wr_time  <= wr_ch_data_r and ch_data_4r(31) when rising_edge(CLK_100);
+  wr_epoch <= wr_ch_data_r and not data_out_r(31) and data_out_r(30) and data_out_r(29) and ch_data_4r(31);
+
+
+  DATA_OUT                    <= data_out_r;
+  DATA_WRITE_OUT              <= wr_info or wr_time or wr_epoch;  --data_wr_r;
+  DATA_FINISHED_OUT           <= data_finished;
+  TRG_RELEASE_OUT             <= trg_release;
+  trg_statusbit(23)           <= wrong_readout when rising_edge(CLK_100);
+  TRG_STATUSBIT_OUT           <= trg_statusbit;
+  READOUT_DEBUG(3 downto 0)   <= rd_fsm_debug;
+  READOUT_DEBUG(7 downto 4)   <= wr_fsm_debug;
+  READOUT_DEBUG(8)            <= data_wr_r;
+  READOUT_DEBUG(9)            <= finished;
+  READOUT_DEBUG(10)           <= trg_release;
+  READOUT_DEBUG(16 downto 11) <= data_out_r(27 downto 22);
+  READOUT_DEBUG(31 downto 17) <= (others => '0');
+
+  -- Error, warning bits set in the header
+  
+  header_error_bits(0)           <= or_all(CH_ALMOST_FULL_IN);
+  header_error_bits(1)           <= missing_ref_time;
+  header_error_bits(15 downto 2) <= (others => '0');
+
+  -- Error, warning bits set in the trailer
+  trailer_error_bits <= (others => '0');
+  -- trailer_error_bits (0) <= wrong_readout;  -- if there is a wrong readout because of a spurious timing trigger
+
+
+-------------------------------------------------------------------------------
+-- Control bits
+-------------------------------------------------------------------------------
+  --purpose: Hit Signal Synchroniser
+  HitSignalSync : for i in 0 to CHANNEL_NUMBER-2 generate
+    sync_q(i*3)   <= HIT_IN(i+1) when rising_edge(CLK_100);
+    --sync_q(i*3+1) <= sync_q(i*3);       -- when rising_edge(CLK_100);
+    --sync_q(i*3+2) <= sync_q(i*3+1);     -- when rising_edge(CLK_100);
+    hit_in_i(i+1) <= HIT_IN(i+1);       --sync_q(i*3+2);
+  end generate HitSignalSync;
+
+  any_hit <= or_all(hit_in_i);
+
+  CheckHitStatus : process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then            -- rising clock edge
+      if LIGHT_MODE_IN = '0' or TRG_WIN_EN_IN = '1' then
+        isNoHit   <= '0';
+        isNoHit_r <= '0';
+      elsif VALID_TIMING_TRG_IN = '1' then
+        isNoHit   <= '1';
+        isNoHit_r <= isNoHit;
+      elsif or_all(hit_in_i) = '1' then
+        isNoHit <= '0';
+      end if;
+    end if;
+  end process CheckHitStatus;
+-------------------------------------------------------------------------------
+-- Debug and statistics words
+-------------------------------------------------------------------------------
+
+  edge_to_pulse_1 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => VALID_TIMING_TRG_IN,
+      pulse     => valid_timing_trg_p);
+
+  edge_to_pulse_2 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => VALID_NOTIMING_TRG_IN,
+      pulse     => valid_notiming_trg_p);
+
+  edge_to_pulse_3 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => INVALID_TRG_IN,
+      pulse     => invalid_trg_p);
+
+  edge_to_pulse_4 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => MULTI_TMG_TRG_IN,
+      pulse     => multi_tmg_trg_p);
+
+  edge_to_pulse_5 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => SPURIOUS_TRG_IN,
+      pulse     => spurious_trg_p);
+
+  edge_to_pulse_6 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => SPIKE_DETECTED_IN,
+      pulse     => spike_detected_p);
+
+  edge_to_pulse_7 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => TMGTRG_TIMEOUT_IN,
+      pulse     => timeout_detected_p);
+
+-- Internal trigger number counter (only valid triggers)
+  Statistics_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        trg_number <= (others => '0');
+      elsif valid_timing_trg_p = '1' or valid_notiming_trg_p = '1' then
+        trg_number <= trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Trigger_Number;
+
+-- Internal release number counter
+  Statistics_Release_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        release_number <= (others => '0');
+      elsif trg_release = '1' then
+        release_number <= release_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Release_Number;
+
+-- Internal valid timing trigger number counter
+  Statistics_Valid_Timing_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        valid_tmg_trg_number <= (others => '0');
+      elsif valid_timing_trg_p = '1' then
+        valid_tmg_trg_number <= valid_tmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Valid_Timing_Trigger_Number;
+
+-- Internal valid NOtiming trigger number counter
+  Statistics_Valid_NoTiming_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        valid_NOtmg_trg_number <= (others => '0');
+      elsif valid_notiming_trg_p = '1' then
+        valid_NOtmg_trg_number <= valid_NOtmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Valid_NoTiming_Trigger_Number;
+
+-- Internal invalid trigger number counter
+  Statistics_Invalid_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        invalid_trg_number <= (others => '0');
+      elsif invalid_trg_p = '1' then
+        invalid_trg_number <= invalid_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Invalid_Trigger_Number;
+
+-- Internal multi timing trigger number counter
+  Statistics_Multi_Timing_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        multi_tmg_trg_number <= (others => '0');
+      elsif multi_tmg_trg_p = '1' then
+        multi_tmg_trg_number <= multi_tmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Multi_Timing_Trigger_Number;
+
+-- Internal spurious trigger number counter
+  Statistics_Spurious_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        spurious_trg_number <= (others => '0');
+      elsif spurious_trg_p = '1' then
+        spurious_trg_number <= spurious_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Spurious_Trigger_Number;
+
+  wrongReadoutUp : entity work.risingEdgeDetect
+    port map (
+      CLK       => CLK_100,
+      SIGNAL_IN => wrong_readout,
+      PULSE_OUT => wrong_readout_up);
+-- Number of wrong readout becasue of spurious trigger
+  Statistics_Wrong_Readout_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        wrong_readout_number <= (others => '0');
+      elsif wrong_readout_up = '1' then
+        wrong_readout_number <= wrong_readout_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Wrong_Readout_Number;
+
+-- Internal spike number counter
+  Statistics_Spike_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        spike_number <= (others => '0');
+      elsif spike_detected_p = '1' then
+        spike_number <= spike_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Spike_Number;
+
+-- Internal timeout number counter
+  Statistics_Timeout_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        timeout_number <= (others => '0');
+      elsif timeout_detected_p = '1' then
+        timeout_number <= timeout_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Timeout_Number;
+
+-- IDLE time of the TDC readout
+  Statistics_Idle_Time : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        idle_time <= (others => '0');
+      elsif idle_time_up = '1' then
+        idle_time <= idle_time + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Idle_Time;
+
+-- Readout and Wait time of the TDC readout
+  Statistics_Readout_Wait_Time : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        readout_time <= (others => '0');
+        wait_time    <= (others => '0');
+      elsif readout_time_up = '1' then
+        readout_time <= readout_time + to_unsigned(1, 1);
+      elsif wait_time_up = '1' then
+        wait_time <= wait_time + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Readout_Wait_Time;
+
+  -- Number of sent data finished
+  Statistics_Finished_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        finished_number <= (others => '0');
+      elsif data_finished = '1' then    --finished = '1' then
+        finished_number <= finished_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Finished_Number;
+
+  HistoryReadDebug : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if rd_fsm_debug_r /= rd_fsm_debug then
+        history_rd_fsm <= history_rd_fsm(27 downto 0) & rd_fsm_debug;
+      end if;
+      rd_fsm_debug_r <= rd_fsm_debug;
+    end if;
+  end process HistoryReadDebug;
+
+  HistoryWriteDebug : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if wr_fsm_debug_r /= wr_fsm_debug then
+        history_wr_fsm <= history_wr_fsm(27 downto 0) & wr_fsm_debug;
+      end if;
+      wr_fsm_debug_r <= wr_fsm_debug;
+    end if;
+  end process HistoryWriteDebug;
+
+-------------------------------------------------------------------------------
+-- STATUS REGISTERS BUS
+-------------------------------------------------------------------------------
+  -- statistics
+  STATISTICS_OUT(0)  <= std_logic_vector(trg_number);
+  STATISTICS_OUT(1)  <= std_logic_vector(valid_tmg_trg_number);
+  STATISTICS_OUT(2)  <= std_logic_vector(valid_NOtmg_trg_number);
+  STATISTICS_OUT(3)  <= std_logic_vector(invalid_trg_number);
+  STATISTICS_OUT(4)  <= std_logic_vector(multi_tmg_trg_number);
+  STATISTICS_OUT(5)  <= std_logic_vector(spurious_trg_number);
+  STATISTICS_OUT(6)  <= std_logic_vector(wrong_readout_number);
+  STATISTICS_OUT(7)  <= std_logic_vector(spike_number);
+  STATISTICS_OUT(8)  <= std_logic_vector(idle_time);
+  STATISTICS_OUT(9)  <= std_logic_vector(wait_time);
+  STATISTICS_OUT(10) <= std_logic_vector(total_empty_channel);
+  STATISTICS_OUT(11) <= std_logic_vector(release_number);
+  STATISTICS_OUT(12) <= std_logic_vector(readout_time);
+  STATISTICS_OUT(13) <= std_logic_vector(timeout_number);
+  STATISTICS_OUT(14) <= std_logic_vector(finished_number);
+  STATISTICS_OUT(15) <= (others => '0');
+  
+-- readout debug history 
+  --STATUS_REGISTERS_BUS_OUT(19)              <= history_rd_fsm;
+  --STATUS_REGISTERS_BUS_OUT(20)              <= history_wr_fsm;
+
+
+-------------------------------------------------------------------------------
+-- Registering
+-------------------------------------------------------------------------------
+  ch_data_r  <= CH_DATA_IN when rising_edge(CLK_100);
+  ch_data_2r <= ch_data_r  when rising_edge(CLK_100);
+  ch_data_3r <= ch_data_2r when rising_edge(CLK_100);
+
+end behavioral;
diff --git a/releases/tdc_v2.3.1/Readout_record.vhd b/releases/tdc_v2.3.1/Readout_record.vhd
new file mode 100644 (file)
index 0000000..e92d0bc
--- /dev/null
@@ -0,0 +1,1009 @@
+-------------------------------------------------------------------------------
+-- Title      : Readout Entity
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : Readout_record.vhd
+-- Author     : cugur@gsi.de
+-- Created    : 2012-10-25
+-- Last update: 2016-07-24
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+-- Copyright (c) 2012 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.tdc_components.all;
+use work.version.all;
+use work.config.all;
+
+entity Readout_record is
+  generic (
+    CHANNEL_NUMBER : integer range 2 to 65;
+    STATUS_REG_NR  : integer range 0 to 31);
+  port (
+    RESET_100           : in  std_logic;
+    RESET_200           : in  std_logic;
+    RESET_COUNTERS      : in  std_logic;
+    CLK_100             : in  std_logic;
+    CLK_200             : in  std_logic;
+    HIT_IN              : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+-- from the channels
+    CH_DATA_IN          : in  std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+    CH_DATA_VALID_IN    : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+    CH_ALMOST_FULL_IN   : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+    CH_EMPTY_IN         : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+-- endpoint bus
+    READOUT_RX          : in  READOUT_RX;
+    READOUT_TX          : out READOUT_TX;
+-- to the channels
+    READ_EN_OUT         : out std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+-- trigger window settings
+    TRG_WIN_PRE_IN      : in  std_logic_vector(10 downto 0);
+    TRG_WIN_POST_IN     : in  std_logic_vector(10 downto 0);
+    TRG_WIN_EN_IN       : in  std_logic;
+-- from the trigger handler
+    TRG_WIN_END_TDC_IN  : in  std_logic;
+    TRG_WIN_END_RDO_IN  : in  std_logic;
+    TRG_TDC_IN          : in  std_logic;
+    TRG_TIME_IN         : in  std_logic_vector(38 downto 0);
+    MISSING_REF_TIME_IN : in  std_logic;
+-- miscellaneous
+    LIGHT_MODE_IN       : in  std_logic;
+    DEBUG_MODE_EN_IN    : in  std_logic;
+    INFO_IN             : in  TIMERS;
+    STATISTICS_OUT      : out std_logic_vector_array_24(0 to 15);
+    READOUT_DEBUG       : out std_logic_vector(31 downto 0)
+    );
+end entity Readout_record;
+
+architecture behavioral of Readout_record is
+
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+
+  -- trigger window
+  signal trg_win_pre             : unsigned(10 downto 0);
+  signal trg_win_post            : unsigned(10 downto 0);
+  signal trg_time                : std_logic_vector(38 downto 0);
+  signal TW_pre                  : std_logic_vector(38 downto 0);
+  signal TW_post                 : std_logic_vector(38 downto 0);
+  signal trg_win_l               : std_logic;
+  signal trg_win_r               : std_logic;
+  signal start_trg_win_cnt       : std_logic := '0';
+  signal start_trg_win_cnt_200_p : std_logic;
+  signal trg_win_cnt             : std_logic_vector(11 downto 0);
+  signal trg_win_end_200         : std_logic := '0';
+  signal trg_win_end_200_p       : std_logic;
+  signal trg_win_end_100_p       : std_logic;
+  signal trg_win_end_100_r       : std_logic;
+  signal trg_win_end_100_2r      : std_logic;
+  signal trg_win_end_100_3r      : std_logic;
+  signal trg_win_end_100_4r      : std_logic;
+  -- channel signals
+  signal ch_data_r               : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_2r              : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_3r              : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_4r              : std_logic_vector(31 downto 0);
+  signal ch_hit_time             : std_logic_vector(38 downto 0);
+  signal ch_epoch_cntr           : std_logic_vector(27 downto 0);
+  signal buffer_transfer_done    : std_logic;
+  signal buffer_transfer_done_r  : std_logic;
+  signal buffer_transfer_done_2r : std_logic;
+  -- readout fsm
+  type FSM_READ is (IDLE, WAIT_FOR_TRG_WIND_END, RD_CH, WAIT_FOR_DATA_FINISHED, WAIT_FOR_LVL1_TRG_A,
+                    WAIT_FOR_LVL1_TRG_B, WAIT_FOR_LVL1_TRG_C, SEND_STATUS, SEND_TRG_RELEASE_A,
+                    SEND_TRG_RELEASE_B, SEND_TRG_RELEASE_C, SEND_TRG_RELEASE_D, WAIT_FOR_BUFFER_TRANSFER);
+  signal RD_CURRENT             : FSM_READ                          := IDLE;
+  signal RD_NEXT                : FSM_READ;
+  type FSM_WRITE is (IDLE, WR_CH, WAIT_A, WAIT_B, WAIT_C, WAIT_D);
+  signal WR_CURRENT             : FSM_WRITE                         := IDLE;
+  signal WR_NEXT                : FSM_WRITE;
+  signal start_trg_win_cnt_fsm  : std_logic;
+  signal rd_fsm_debug_fsm       : std_logic_vector(3 downto 0);
+  signal wr_fsm_debug_fsm       : std_logic_vector(3 downto 0);
+  signal rd_en_fsm              : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal data_finished_fsm      : std_logic;
+  signal wr_finished_fsm        : std_logic;
+  signal trg_release_fsm        : std_logic;
+  signal wr_header_fsm          : std_logic;
+  signal wr_trailer_fsm         : std_logic;
+  signal wr_ch_data_fsm         : std_logic;
+  signal wr_status_fsm          : std_logic;
+  signal missing_ref_time_fsm   : std_logic;
+  signal missing_ref_time       : std_logic;
+  signal invalid_trg_fsm        : std_logic;
+  signal invalid_trg            : std_logic;
+  signal unknown_trg_fsm        : std_logic;
+  signal unknown_trg            : std_logic;
+  signal fifo_nr_rd_fsm         : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_fsm         : integer range 0 to CHANNEL_NUMBER := 0;
+  signal buf_delay_fsm          : integer range 0 to 63             := 0;
+  signal buf_delay              : integer range 0 to 63             := 0;
+  signal idle_fsm               : std_logic;
+  signal readout_fsm            : std_logic;
+  signal wait_fsm               : std_logic;
+  -- fifo number
+  type Std_Logic_8_array is array (0 to 8) of std_logic_vector(3 downto 0);
+  signal empty_channels         : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal fifo_nr_rd             : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr             : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_r           : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_2r          : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_3r          : integer range 0 to CHANNEL_NUMBER := 0;
+  -- fifo read
+  signal rd_en                  : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  -- data mux
+  signal start_write            : std_logic                         := '0';
+  signal wr_header              : std_logic;
+  signal wr_ch_data             : std_logic;
+  signal wr_ch_data_r           : std_logic;
+  signal wr_status              : std_logic;
+  signal wr_trailer             : std_logic;
+  signal wr_info                : std_logic;
+  signal wr_time                : std_logic;
+  signal wr_epoch               : std_logic;
+  signal stop_status            : std_logic;
+  -- to endpoint
+  signal data_out_r             : std_logic_vector(31 downto 0);
+  signal data_wr_r              : std_logic;
+  signal data_finished          : std_logic;
+  signal wr_finished            : std_logic;
+  signal trg_release            : std_logic;
+  signal trg_statusbit          : std_logic_vector(31 downto 0)     := (others => '0');
+  -- statistics
+  signal compile_time           : std_logic_vector(31 downto 0);
+  signal trg_number             : unsigned(23 downto 0)             := (others => '0');
+  signal release_number         : unsigned(23 downto 0)             := (others => '0');
+  signal valid_tmg_trg_number   : unsigned(23 downto 0)             := (others => '0');
+  signal valid_NOtmg_trg_number : unsigned(23 downto 0)             := (others => '0');
+  signal invalid_trg_number     : unsigned(23 downto 0)             := (others => '0');
+  signal multi_tmg_trg_number   : unsigned(23 downto 0)             := (others => '0');
+  signal spurious_trg_number    : unsigned(23 downto 0)             := (others => '0');
+  signal wrong_readout_number   : unsigned(23 downto 0)             := (others => '0');
+  signal spike_number           : unsigned(23 downto 0)             := (others => '0');
+  signal timeout_number         : unsigned(23 downto 0)             := (others => '0');
+  signal total_empty_channel    : unsigned(23 downto 0)             := (others => '0');
+  signal idle_time              : unsigned(23 downto 0)             := (others => '0');
+  signal readout_time           : unsigned(23 downto 0)             := (others => '0');
+  signal wait_time              : unsigned(23 downto 0)             := (others => '0');
+  signal finished_number        : unsigned(23 downto 0)             := (others => '0');
+  signal valid_timing_trg_p     : std_logic;
+  signal valid_notiming_trg_p   : std_logic;
+  signal invalid_trg_p          : std_logic;
+  signal multi_tmg_trg_p        : std_logic;
+  signal spurious_trg_p         : std_logic;
+  signal spike_detected_p       : std_logic;
+  signal timeout_detected_p     : std_logic;
+  signal idle_time_up           : std_logic;
+  signal readout_time_up        : std_logic;
+  signal wait_time_up           : std_logic;
+  signal wrong_readout_up       : std_logic;
+  signal finished               : std_logic;
+  -- control
+  signal sync_q                 : std_logic_vector((CHANNEL_NUMBER-2)*3+2 downto 0);
+  signal isNoHit                : std_logic                         := '1';
+  signal isNoHit_r              : std_logic                         := '1';
+  signal isCalTrig              : std_logic                         := '0';
+  signal hit_in_i               : std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+  -- debug
+  signal header_error_bits      : std_logic_vector(15 downto 0);
+  signal trailer_trg_type       : std_logic_vector(3 downto 0);
+  signal trailer_trg_code       : std_logic_vector(7 downto 0);
+  signal trailer_error_bits     : std_logic_vector(15 downto 0);
+  signal rd_fsm_debug           : std_logic_vector(3 downto 0);
+  signal rd_fsm_debug_r         : std_logic_vector(3 downto 0);
+  signal history_rd_fsm         : std_logic_vector(31 downto 0)     := (others => '0');
+  signal wr_fsm_debug           : std_logic_vector(3 downto 0);
+  signal wr_fsm_debug_r         : std_logic_vector(3 downto 0);
+  signal history_wr_fsm         : std_logic_vector(31 downto 0)     := (others => '0');
+  signal any_hit                : std_logic                         := '0';
+  signal data_format_i          : std_logic_vector(3 downto 0);
+
+begin  -- behavioral
+  DATA_FORMAT_0 : if TDC_DATA_FORMAT = 0 generate
+    data_format_i <= x"0";
+  end generate DATA_FORMAT_0;
+  DATA_FORMAT_1 : if TDC_DATA_FORMAT = 1 generate
+    data_format_i <= x"1";
+  end generate DATA_FORMAT_1;
+  DATA_FORMAT_2 : if TDC_DATA_FORMAT = 2 generate
+    data_format_i <= x"2";
+  end generate DATA_FORMAT_2;
+  DATA_FORMAT_13 : if TDC_DATA_FORMAT = 13 generate
+    data_format_i <= x"d";
+  end generate DATA_FORMAT_13;
+  DATA_FORMAT_14 : if TDC_DATA_FORMAT = 14 generate
+    data_format_i <= x"e";
+  end generate DATA_FORMAT_14;
+  DATA_FORMAT_15 : if TDC_DATA_FORMAT = 15 generate
+    data_format_i <= x"f";
+  end generate DATA_FORMAT_15;
+
+  trg_win_pre  <= unsigned(TRG_WIN_PRE_IN);
+  trg_win_post <= unsigned(TRG_WIN_POST_IN);
+
+-------------------------------------------------------------------------------
+-- Trigger window
+-------------------------------------------------------------------------------
+-- Trigger window borders
+  TrigWinCalculation : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      TW_pre  <= std_logic_vector(unsigned(trg_time)-trg_win_pre);
+      TW_post <= std_logic_vector(unsigned(trg_time)+trg_win_post);
+    end if;
+  end process TrigWinCalculation;
+
+-- Trigger Time Determination
+  DefineTriggerTime : process (CLK_200)
+  begin
+    if rising_edge(CLK_200) then
+      if RESET_200 = '1' then
+        trg_time <= (others => '0');
+      elsif TRG_TDC_IN = '1' then
+        trg_time <= TRG_TIME_IN;
+      end if;
+    end if;
+  end process DefineTriggerTime;
+
+-- Channel Hit Time Determination
+  ChannelHitTime : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31 downto 29) = "011" then
+        ch_epoch_cntr <= ch_data_r(fifo_nr_wr)(27 downto 0);
+      end if;
+
+      if ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31) = '1' then
+        ch_hit_time <= ch_epoch_cntr & ch_data_r(fifo_nr_wr)(10 downto 0);
+      elsif ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31 downto 29) = "011" then
+        ch_hit_time <= (others => '0');
+      end if;
+    end if;
+  end process ChannelHitTime;
+
+-- Controls if the data coming from the channel is greater than the trigger window pre-edge
+  Check_Trigger_Win_Left : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if unsigned(TW_pre) <= unsigned(ch_hit_time) then
+        trg_win_l <= '1';
+      else
+        trg_win_l <= '0';
+      end if;
+    end if;
+  end process Check_Trigger_Win_Left;
+
+-- Controls if the data coming from the channel is smaller than the trigger window post-edge
+  Check_Trigger_Win_Right : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if unsigned(ch_hit_time) <= unsigned(TW_post) then
+        trg_win_r <= '1';
+      else
+        trg_win_r <= '0';
+      end if;
+    end if;
+  end process Check_Trigger_Win_Right;
+
+-------------------------------------------------------------------------------
+-- Readout
+-------------------------------------------------------------------------------
+-- Readout fsm
+  RD_FSM_CLK : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        RD_CURRENT       <= IDLE;
+        missing_ref_time <= '0';
+        invalid_trg      <= '0';
+        unknown_trg      <= '0';
+        fifo_nr_rd       <= 0;
+      else
+        RD_CURRENT              <= RD_NEXT;
+        rd_en                   <= rd_en_fsm;
+        wr_header               <= wr_header_fsm;
+        wr_trailer              <= wr_trailer_fsm;
+        wr_status               <= wr_status_fsm;
+        data_finished           <= data_finished_fsm;
+        trg_release             <= trg_release_fsm;
+        missing_ref_time        <= missing_ref_time_fsm;
+        buf_delay               <= buf_delay_fsm;
+        invalid_trg             <= invalid_trg_fsm;
+        unknown_trg             <= unknown_trg_fsm;
+        idle_time_up            <= idle_fsm;
+        readout_time_up         <= readout_fsm;
+        wait_time_up            <= wait_fsm;
+        fifo_nr_rd              <= fifo_nr_rd_fsm;
+        rd_fsm_debug            <= rd_fsm_debug_fsm;
+        buffer_transfer_done    <= and_all(CH_EMPTY_IN);
+        buffer_transfer_done_r  <= buffer_transfer_done;
+        buffer_transfer_done_2r <= buffer_transfer_done_r;
+      end if;
+    end if;
+  end process RD_FSM_CLK;
+  READ_EN_OUT <= rd_en;
+
+  RD_FSM_PROC : process (RD_CURRENT, READOUT_RX, stop_status, DEBUG_MODE_EN_IN, fifo_nr_rd,
+                         TRG_WIN_END_RDO_IN, buf_delay, CH_EMPTY_IN, buffer_transfer_done_2r,
+                         MISSING_REF_TIME_IN, isNoHit_r, missing_ref_time, invalid_trg, unknown_trg)
+
+  begin
+
+    RD_NEXT              <= RD_CURRENT;
+    rd_en_fsm            <= (others => '0');
+    wr_header_fsm        <= '0';
+    wr_trailer_fsm       <= '0';
+    wr_status_fsm        <= '0';
+    data_finished_fsm    <= '0';
+    trg_release_fsm      <= '0';
+    missing_ref_time_fsm <= missing_ref_time;
+    invalid_trg_fsm      <= invalid_trg;
+    unknown_trg_fsm      <= unknown_trg;
+    idle_fsm             <= '0';
+    readout_fsm          <= '0';
+    wait_fsm             <= '0';
+    buf_delay_fsm        <= 0;
+    fifo_nr_rd_fsm       <= fifo_nr_rd;
+    rd_fsm_debug_fsm     <= x"0";
+
+    case (RD_CURRENT) is
+      when IDLE =>
+        if READOUT_RX.valid_timing_trg = '1' then  -- physical trigger
+          RD_NEXT <= WAIT_FOR_TRG_WIND_END;
+        elsif READOUT_RX.valid_notiming_trg = '1' then
+          if READOUT_RX.trg_type = x"E" then       -- status trigger
+            wr_header_fsm <= '1';
+            RD_NEXT       <= SEND_STATUS;
+          elsif READOUT_RX.trg_type = x"D" then    -- tdc calibration trigger
+            RD_NEXT <= WAIT_FOR_TRG_WIND_END;
+          else                                     -- the other triggers
+            RD_NEXT <= SEND_TRG_RELEASE_A;
+          end if;
+        elsif READOUT_RX.invalid_trg = '1' then    -- invalid trigger
+          RD_NEXT         <= SEND_TRG_RELEASE_A;
+          invalid_trg_fsm <= '1';
+        end if;
+        idle_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"1";
+
+      when WAIT_FOR_TRG_WIND_END =>
+        if TRG_WIN_END_RDO_IN = '1' then
+          RD_NEXT <= WAIT_FOR_BUFFER_TRANSFER;
+          if MISSING_REF_TIME_IN = '1' or isNoHit_r = '0' then
+            wr_header_fsm <= '1';
+          end if;
+          if MISSING_REF_TIME_IN = '1' then
+            missing_ref_time_fsm <= '1';
+          end if;
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"2";
+
+      when WAIT_FOR_BUFFER_TRANSFER =>  -- the data from channel fifo is written to the buffer
+        if buffer_transfer_done_2r = '0' or buf_delay = 63 then
+          RD_NEXT <= RD_CH;
+        else
+          buf_delay_fsm <= buf_delay+ 1;
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"3";
+
+      when RD_CH =>
+        if CH_EMPTY_IN(fifo_nr_rd) = '0' then  -- read from channel if not empty
+          rd_en_fsm(fifo_nr_rd) <= '1';
+          fifo_nr_rd_fsm        <= fifo_nr_rd;
+        elsif fifo_nr_rd = CHANNEL_NUMBER-1 then  -- the last channel
+          rd_en_fsm(fifo_nr_rd) <= '0';
+          if DEBUG_MODE_EN_IN = '1' then  -- send status after channel data
+            RD_NEXT <= SEND_STATUS;
+          else
+            RD_NEXT <= WAIT_FOR_LVL1_TRG_A;
+          end if;
+        else                            -- go to the next channel
+          fifo_nr_rd_fsm <= fifo_nr_rd + 1 after 10 ps;
+        end if;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"4";
+
+      when WAIT_FOR_LVL1_TRG_A =>       -- wait for trigger data valid
+        if READOUT_RX.data_valid = '1' or READOUT_RX.trg_timeout = '1' then
+          if READOUT_RX.trg_type /= x"1" and READOUT_RX.trg_type /= x"D" then
+            unknown_trg_fsm <= '1';
+          end if;
+          RD_NEXT <= SEND_TRG_RELEASE_A;
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"6";
+
+        --when WAIT_FOR_LVL1_TRG_B =>
+        --  RD_NEXT          <= WAIT_FOR_LVL1_TRG_C;
+        --  wait_fsm         <= '1';
+        --  rd_fsm_debug_fsm <= x"7";
+
+        --when WAIT_FOR_LVL1_TRG_C =>
+        --  if READOUT_RX.trg_spurious = '1' then
+        --    wrong_readout_fsm <= '1';
+        --  end if;
+        --  RD_NEXT          <= SEND_TRG_RELEASE_A;
+        --  wait_fsm         <= '1';
+        --  rd_fsm_debug_fsm <= x"8";
+
+      when SEND_STATUS =>
+        if stop_status = '1' then
+          if DEBUG_MODE_EN_IN = '1' then
+            RD_NEXT <= WAIT_FOR_LVL1_TRG_A;
+          else
+            RD_NEXT <= SEND_TRG_RELEASE_A;
+          end if;
+        else
+          wr_status_fsm <= '1';
+        end if;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"9";
+
+      when SEND_TRG_RELEASE_A =>
+        RD_NEXT          <= SEND_TRG_RELEASE_B;
+        wr_trailer_fsm   <= '1';
+        fifo_nr_rd_fsm   <= 0;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"A";
+
+      when SEND_TRG_RELEASE_B =>
+        RD_NEXT          <= SEND_TRG_RELEASE_C;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"A";
+      when SEND_TRG_RELEASE_C =>
+        RD_NEXT           <= SEND_TRG_RELEASE_D;
+        data_finished_fsm <= '1';
+        readout_fsm       <= '1';
+        rd_fsm_debug_fsm  <= x"B";
+      when SEND_TRG_RELEASE_D =>
+        RD_NEXT              <= IDLE;
+        trg_release_fsm      <= '1';
+        missing_ref_time_fsm <= '0';
+        invalid_trg_fsm      <= '0';
+        unknown_trg_fsm      <= '0';
+        readout_fsm          <= '1';
+        rd_fsm_debug_fsm     <= x"C";
+
+      when others =>
+        RD_NEXT          <= IDLE;
+        rd_fsm_debug_fsm <= x"0";
+    end case;
+  end process RD_FSM_PROC;
+
+
+  --purpose: FSM for writing data to endpoint buffer
+  WR_FSM_CLK : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        WR_CURRENT <= IDLE;
+      else
+        WR_CURRENT   <= WR_NEXT;
+        wr_ch_data   <= wr_ch_data_fsm;
+        fifo_nr_wr   <= fifo_nr_wr_fsm;
+        wr_finished  <= wr_finished_fsm;
+        wr_fsm_debug <= wr_fsm_debug_fsm;
+        start_write  <= or_all(CH_DATA_VALID_IN);
+      end if;
+    end if;
+  end process WR_FSM_CLK;
+
+  WR_FSM : process (WR_CURRENT, fifo_nr_wr, start_write, CH_DATA_VALID_IN, ch_data_2r,
+                    isNoHit_r)
+
+  begin
+
+    WR_NEXT          <= WR_CURRENT;
+    wr_ch_data_fsm   <= '0';
+    fifo_nr_wr_fsm   <= 0;
+    wr_finished_fsm  <= '0';
+    wr_fsm_debug_fsm <= x"0";
+
+    case (WR_CURRENT) is
+      when IDLE =>
+        if start_write = '1' then
+          fifo_nr_wr_fsm <= 0;
+          WR_NEXT        <= WR_CH;
+        end if;
+        wr_fsm_debug_fsm <= x"1";
+--
+      when WR_CH =>
+        if ch_data_2r(fifo_nr_wr)(35 downto 32) /= x"f" then
+          if isNoHit_r = '1' then
+            wr_ch_data_fsm <= '0';
+          else
+            wr_ch_data_fsm <= '1';
+          end if;
+          fifo_nr_wr_fsm <= fifo_nr_wr;
+        --wr_fsm_debug_fsm <= x"4";
+        elsif CH_DATA_VALID_IN(fifo_nr_wr) = '1' then
+          fifo_nr_wr_fsm <= fifo_nr_wr;
+        --wr_fsm_debug_fsm <= x"6";
+        elsif fifo_nr_wr = CHANNEL_NUMBER-1 then
+          wr_finished_fsm <= '1';
+          WR_NEXT         <= IDLE;
+        --wr_fsm_debug_fsm <= x"5";
+        else
+          fifo_nr_wr_fsm <= fifo_nr_wr + 1;
+          WR_NEXT        <= WAIT_A;
+        --wr_fsm_debug_fsm <= x"7";
+        end if;
+        wr_fsm_debug_fsm <= x"2";
+--
+      when WAIT_A =>
+        WR_NEXT          <= WAIT_B;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_B =>
+        WR_NEXT          <= WR_CH;      --WAIT_C;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_C =>
+        WR_NEXT          <= WAIT_D;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_D =>
+        WR_NEXT          <= WR_CH;
+        fifo_nr_wr_fsm   <= fifo_nr_wr;
+        wr_fsm_debug_fsm <= x"3";
+--      
+      when others =>
+        WR_NEXT          <= IDLE;
+        wr_fsm_debug_fsm <= x"0";
+
+    end case;
+  end process WR_FSM;
+
+  fifo_nr_wr_r  <= fifo_nr_wr    when rising_edge(CLK_100);
+  fifo_nr_wr_2r <= fifo_nr_wr_r  when rising_edge(CLK_100);
+  fifo_nr_wr_3r <= fifo_nr_wr_2r when rising_edge(CLK_100);
+  wr_ch_data_r  <= wr_ch_data    when rising_edge(CLK_100);
+
+-------------------------------------------------------------------------------
+-- Data out mux
+-------------------------------------------------------------------------------
+  isCalibrationTrigger : process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then        -- rising clock edge
+      if trg_release = '1' then
+        isCalTrig <= '0';
+      elsif READOUT_RX.valid_notiming_trg = '1' and READOUT_RX.trg_type = x"D" then
+        isCalTrig <= '1';
+      end if;
+    end if;
+  end process isCalibrationTrigger;
+
+  -- Trigger window selection
+  TriggerWindowElimination : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if ch_data_3r(fifo_nr_wr_r)(35 downto 32) = x"1" and ch_data_3r(fifo_nr_wr_r)(31) = '1' then  --DATA word
+        if TRG_WIN_EN_IN = '1' and isCalTrig = '0' then  -- trigger window enabled
+          --elsif (TW_pre(10) = '1' and ref_time_coarse(10) = '0') or (TW_post(10) = '0' and ref_time_coarse(10) = '1') then  -- if one of the trigger window edges has an overflow
+          --  if (trg_win_l = '0' and trg_win_r = '1') or (trg_win_l = '1' and trg_win_r = '0') then
+          --    ch_data_4r <= ch_data_3r(fifo_nr);
+          --    data_wr_r  <= '1';
+          --  else
+          --    ch_data_4r <= (others => '1');
+          --    data_wr_r  <= '0';
+          --  end if;
+          if trg_win_l = '1' and trg_win_r = '1' then  -- if both of the trigger window edges are in the coarse counter boundries
+            ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+          elsif trg_win_r = '0' then  -- any hit that might come after the trigger window 
+            ch_data_4r <= (others => '0');
+          --else
+          --  ch_data_4r <= (others => '0');
+          end if;
+        else
+          ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+        end if;
+      else
+        ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+      end if;
+    end if;
+  end process TriggerWindowElimination;
+
+  Data_Out_MUX : process (CLK_100)
+    variable i : integer := 0;
+  begin
+    if rising_edge(CLK_100) then
+      if wr_header = '1' then
+        --data_out_r  <= "001" & "0" & READOUT_RX.trg_type & READOUT_RX.trg_code & header_error_bits;
+        data_out_r  <= "001" & "0" & data_format_i & x"00" & header_error_bits;
+        stop_status <= '0';
+      elsif wr_ch_data_r = '1' then
+        data_out_r  <= ch_data_4r;
+        stop_status <= '0';
+      elsif wr_status = '1' then
+        case i is
+          when 0  => data_out_r <= "010" & "00000" & std_logic_vector(trg_number);
+          when 1  => data_out_r <= "010" & "00001" & std_logic_vector(release_number);
+          when 2  => data_out_r <= "010" & "00010" & std_logic_vector(valid_tmg_trg_number);
+          when 3  => data_out_r <= "010" & "00011" & std_logic_vector(valid_NOtmg_trg_number);
+          when 4  => data_out_r <= "010" & "00100" & std_logic_vector(invalid_trg_number);
+          when 5  => data_out_r <= "010" & "00101" & std_logic_vector(multi_tmg_trg_number);
+          when 6  => data_out_r <= "010" & "00110" & std_logic_vector(spurious_trg_number);
+          when 7  => data_out_r <= "010" & "00111" & std_logic_vector(wrong_readout_number);
+          when 8  => data_out_r <= "010" & "01000" & std_logic_vector(spike_number);
+          when 9  => data_out_r <= "010" & "01001" & std_logic_vector(idle_time);
+          when 10 => data_out_r <= "010" & "01010" & std_logic_vector(wait_time);
+          when 11 => data_out_r <= "010" & "01011" & std_logic_vector(total_empty_channel);
+          when 12 => data_out_r <= "010" & "01100" & std_logic_vector(readout_time);
+          when 13 => data_out_r <= "010" & "01101" & std_logic_vector(timeout_number);
+          when 14 => data_out_r <= "010" & "01110" & x"000" & INFO_IN.temperature;
+          when 15 => data_out_r <= "010" & "01111" & x"000000";  --reserved
+          when 16 => data_out_r <= "010" & "10000" & x"00" & compile_time(15 downto 0);
+                     stop_status <= '1';  -- set always before the last word to be written
+          when 17 => data_out_r <= "010" & "10001" & x"00" & compile_time(31 downto 16);
+                     i := -1;
+          when others => null;
+        end case;
+        i := i+1;
+      elsif wr_trailer = '1' then
+        data_out_r  <= "000" & "0" & trailer_trg_type & trailer_trg_code & trailer_error_bits;
+        stop_status <= '0';
+      else
+        data_out_r  <= (others => '1');
+        stop_status <= '0';
+      end if;
+    end if;
+    compile_time <= std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32));
+  end process Data_Out_MUX;
+
+  wr_info  <= wr_header or wr_status or wr_trailer when rising_edge(CLK_100);
+  wr_time  <= wr_ch_data_r and ch_data_4r(31)      when rising_edge(CLK_100);
+  wr_epoch <= wr_ch_data_r and not data_out_r(31) and data_out_r(30) and data_out_r(29) and ch_data_4r(31);
+
+
+  READOUT_TX.data          <= data_out_r                     when rising_edge(CLK_100);
+  READOUT_TX.data_write    <= wr_info or wr_time or wr_epoch when rising_edge(CLK_100);
+  READOUT_TX.data_finished <= data_finished                  when rising_edge(CLK_100);
+  READOUT_TX.busy_release  <= trg_release                    when rising_edge(CLK_100);
+  READOUT_TX.statusbits    <= trg_statusbit                  when rising_edge(CLK_100);
+  trg_statusbit(23)        <= READOUT_RX.trg_spurious        when rising_edge(CLK_100);
+
+  READOUT_DEBUG(3 downto 0)   <= rd_fsm_debug;
+  READOUT_DEBUG(7 downto 4)   <= wr_fsm_debug;
+  READOUT_DEBUG(8)            <= data_wr_r;
+  READOUT_DEBUG(9)            <= finished;
+  READOUT_DEBUG(10)           <= trg_release;
+  READOUT_DEBUG(16 downto 11) <= data_out_r(27 downto 22);
+  READOUT_DEBUG(31 downto 17) <= (others => '0');
+
+  -- Error, warning bits set in the header
+
+  header_error_bits(0)           <= or_all(CH_ALMOST_FULL_IN);
+  header_error_bits(15 downto 1) <= (others => '0');
+
+  -- Error, warning bits set in the trailer
+  trailer_error_bits(0)           <= missing_ref_time;  -- info from the triggerhandler
+  trailer_error_bits(1)           <= READOUT_RX.trg_spurious;  -- if there is a wrong readout because of a spurious timing trigger
+  trailer_error_bits(2)           <= invalid_trg;  -- if there is an invalid trigger
+  trailer_error_bits(3)           <= READOUT_RX.trg_missing;  -- if the trigger handler detects no reference time signal
+  trailer_error_bits(4)           <= READOUT_RX.trg_multiple;  -- if there is multiple triggers
+  trailer_error_bits(5)           <= READOUT_RX.trg_spike;  -- if there is spikes
+  trailer_error_bits(6)           <= READOUT_RX.trg_timeout;  -- if there is a timeout signal from the endpoint
+  trailer_error_bits(7)           <= unknown_trg;  -- if there is an unknown timing trigger
+  trailer_error_bits(15 downto 8) <= (others => '0');
+
+  TrailerTriggerInfo : process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then        -- rising clock edge
+      if READOUT_RX.data_valid = '1' or READOUT_RX.trg_timeout = '1' then
+        trailer_trg_type <= READOUT_RX.trg_type;
+        trailer_trg_code <= READOUT_RX.trg_code;
+      end if;
+    end if;
+  end process TrailerTriggerInfo;
+
+-------------------------------------------------------------------------------
+-- Control bits
+-------------------------------------------------------------------------------
+  --purpose: Hit Signal Synchroniser
+  HitSignalSync : for i in 0 to CHANNEL_NUMBER-2 generate
+    sync_q(i*3)   <= HIT_IN(i+1) when rising_edge(CLK_100);
+    --sync_q(i*3+1) <= sync_q(i*3);       -- when rising_edge(CLK_100);
+    --sync_q(i*3+2) <= sync_q(i*3+1);     -- when rising_edge(CLK_100);
+    hit_in_i(i+1) <= HIT_IN(i+1);       --sync_q(i*3+2);
+  end generate HitSignalSync;
+
+  any_hit <= or_all(hit_in_i);
+
+  CheckHitStatus : process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then        -- rising clock edge
+      if LIGHT_MODE_IN = '0' or TRG_WIN_EN_IN = '1' then
+        isNoHit   <= '0';
+        isNoHit_r <= '0';
+      elsif READOUT_RX.valid_timing_trg = '1' then
+        isNoHit   <= '1';
+        isNoHit_r <= isNoHit;
+      elsif or_all(hit_in_i) = '1' then
+        isNoHit <= '0';
+      end if;
+    end if;
+  end process CheckHitStatus;
+-------------------------------------------------------------------------------
+-- Debug and statistics words
+-------------------------------------------------------------------------------
+
+  edge_to_pulse_1 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.valid_timing_trg,
+      pulse     => valid_timing_trg_p);
+
+  edge_to_pulse_2 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.valid_notiming_trg,
+      pulse     => valid_notiming_trg_p);
+
+  edge_to_pulse_3 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.invalid_trg,
+      pulse     => invalid_trg_p);
+
+  edge_to_pulse_4 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_multiple,
+      pulse     => multi_tmg_trg_p);
+
+  edge_to_pulse_5 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_spurious,
+      pulse     => spurious_trg_p);
+
+  edge_to_pulse_6 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_spike,
+      pulse     => spike_detected_p);
+
+  edge_to_pulse_7 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_timeout,
+      pulse     => timeout_detected_p);
+
+-- Internal trigger number counter (only valid triggers)
+  Statistics_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        trg_number <= (others => '0');
+      elsif valid_timing_trg_p = '1' or valid_notiming_trg_p = '1' then
+        trg_number <= trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Trigger_Number;
+
+-- Internal release number counter
+  Statistics_Release_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        release_number <= (others => '0');
+      elsif trg_release = '1' then
+        release_number <= release_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Release_Number;
+
+-- Internal valid timing trigger number counter
+  Statistics_Valid_Timing_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        valid_tmg_trg_number <= (others => '0');
+      elsif valid_timing_trg_p = '1' then
+        valid_tmg_trg_number <= valid_tmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Valid_Timing_Trigger_Number;
+
+-- Internal valid NOtiming trigger number counter
+  Statistics_Valid_NoTiming_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        valid_NOtmg_trg_number <= (others => '0');
+      elsif valid_notiming_trg_p = '1' then
+        valid_NOtmg_trg_number <= valid_NOtmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Valid_NoTiming_Trigger_Number;
+
+-- Internal invalid trigger number counter
+  Statistics_Invalid_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        invalid_trg_number <= (others => '0');
+      elsif invalid_trg_p = '1' then
+        invalid_trg_number <= invalid_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Invalid_Trigger_Number;
+
+-- Internal multi timing trigger number counter
+  Statistics_Multi_Timing_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        multi_tmg_trg_number <= (others => '0');
+      elsif multi_tmg_trg_p = '1' then
+        multi_tmg_trg_number <= multi_tmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Multi_Timing_Trigger_Number;
+
+-- Internal spurious trigger number counter
+  Statistics_Spurious_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        spurious_trg_number <= (others => '0');
+      elsif spurious_trg_p = '1' then
+        spurious_trg_number <= spurious_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Spurious_Trigger_Number;
+
+  wrongReadoutUp : entity work.risingEdgeDetect
+    port map (
+      CLK       => CLK_100,
+      SIGNAL_IN => READOUT_RX.trg_spurious,
+      PULSE_OUT => wrong_readout_up);
+-- Number of wrong readout becasue of spurious trigger
+  Statistics_Wrong_Readout_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        wrong_readout_number <= (others => '0');
+      elsif wrong_readout_up = '1' then
+        wrong_readout_number <= wrong_readout_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Wrong_Readout_Number;
+
+-- Internal spike number counter
+  Statistics_Spike_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        spike_number <= (others => '0');
+      elsif spike_detected_p = '1' then
+        spike_number <= spike_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Spike_Number;
+
+-- Internal timeout number counter
+  Statistics_Timeout_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        timeout_number <= (others => '0');
+      elsif timeout_detected_p = '1' then
+        timeout_number <= timeout_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Timeout_Number;
+
+-- IDLE time of the TDC readout
+  Statistics_Idle_Time : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        idle_time <= (others => '0');
+      elsif idle_time_up = '1' then
+        idle_time <= idle_time + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Idle_Time;
+
+-- Readout and Wait time of the TDC readout
+  Statistics_Readout_Wait_Time : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        readout_time <= (others => '0');
+        wait_time    <= (others => '0');
+      elsif readout_time_up = '1' then
+        readout_time <= readout_time + to_unsigned(1, 1);
+      elsif wait_time_up = '1' then
+        wait_time <= wait_time + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Readout_Wait_Time;
+
+  -- Number of sent data finished
+  Statistics_Finished_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        finished_number <= (others => '0');
+      elsif data_finished = '1' then    --finished = '1' then
+        finished_number <= finished_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Finished_Number;
+
+  HistoryReadDebug : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if rd_fsm_debug_r /= rd_fsm_debug then
+        history_rd_fsm <= history_rd_fsm(27 downto 0) & rd_fsm_debug;
+      end if;
+      rd_fsm_debug_r <= rd_fsm_debug;
+    end if;
+  end process HistoryReadDebug;
+
+  HistoryWriteDebug : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if wr_fsm_debug_r /= wr_fsm_debug then
+        history_wr_fsm <= history_wr_fsm(27 downto 0) & wr_fsm_debug;
+      end if;
+      wr_fsm_debug_r <= wr_fsm_debug;
+    end if;
+  end process HistoryWriteDebug;
+
+-------------------------------------------------------------------------------
+-- STATUS REGISTERS BUS
+-------------------------------------------------------------------------------
+  -- statistics
+  STATISTICS_OUT(0)  <= std_logic_vector(trg_number);
+  STATISTICS_OUT(1)  <= std_logic_vector(valid_tmg_trg_number);
+  STATISTICS_OUT(2)  <= std_logic_vector(valid_NOtmg_trg_number);
+  STATISTICS_OUT(3)  <= std_logic_vector(invalid_trg_number);
+  STATISTICS_OUT(4)  <= std_logic_vector(multi_tmg_trg_number);
+  STATISTICS_OUT(5)  <= std_logic_vector(spurious_trg_number);
+  STATISTICS_OUT(6)  <= std_logic_vector(wrong_readout_number);
+  STATISTICS_OUT(7)  <= std_logic_vector(spike_number);
+  STATISTICS_OUT(8)  <= std_logic_vector(idle_time);
+  STATISTICS_OUT(9)  <= std_logic_vector(wait_time);
+  STATISTICS_OUT(10) <= std_logic_vector(total_empty_channel);
+  STATISTICS_OUT(11) <= std_logic_vector(release_number);
+  STATISTICS_OUT(12) <= std_logic_vector(readout_time);
+  STATISTICS_OUT(13) <= std_logic_vector(timeout_number);
+  STATISTICS_OUT(14) <= std_logic_vector(finished_number);
+  STATISTICS_OUT(15) <= (others => '0');
+
+-- readout debug history 
+  --STATUS_REGISTERS_BUS_OUT(19)              <= history_rd_fsm;
+  --STATUS_REGISTERS_BUS_OUT(20)              <= history_wr_fsm;
+
+
+-------------------------------------------------------------------------------
+-- Registering
+-------------------------------------------------------------------------------
+  ch_data_r  <= CH_DATA_IN when rising_edge(CLK_100);
+  ch_data_2r <= ch_data_r  when rising_edge(CLK_100);
+  ch_data_3r <= ch_data_2r when rising_edge(CLK_100);
+
+end behavioral;
diff --git a/releases/tdc_v2.3.1/Readout_record_noDecode.vhd b/releases/tdc_v2.3.1/Readout_record_noDecode.vhd
new file mode 100644 (file)
index 0000000..0f0cf7b
--- /dev/null
@@ -0,0 +1,982 @@
+-------------------------------------------------------------------------------
+-- Title      : Readout Entity
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : Readout_record.vhd
+-- Author     : cugur@gsi.de
+-- Created    : 2012-10-25
+-- Last update: 2016-03-23
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+-- Copyright (c) 2012 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.tdc_components.all;
+use work.version.all;
+
+entity Readout_record is
+  generic (
+    CHANNEL_NUMBER : integer range 2 to 65;
+    STATUS_REG_NR  : integer range 0 to 31);
+  port (
+    RESET_100           : in  std_logic;
+    RESET_200           : in  std_logic;
+    RESET_COUNTERS      : in  std_logic;
+    CLK_100             : in  std_logic;
+    CLK_200             : in  std_logic;
+    HIT_IN              : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+-- from the channels
+    CH_DATA_IN          : in  std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+    CH_DATA_VALID_IN    : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+    CH_ALMOST_FULL_IN   : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+    CH_EMPTY_IN         : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+-- endpoint bus
+    READOUT_RX          : in  READOUT_RX;
+    READOUT_TX          : out READOUT_TX;
+-- to the channels
+    READ_EN_OUT         : out std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+-- trigger window settings
+    TRG_WIN_PRE_IN      : in  std_logic_vector(10 downto 0);
+    TRG_WIN_POST_IN     : in  std_logic_vector(10 downto 0);
+    TRG_WIN_EN_IN       : in  std_logic;
+-- from the trigger handler
+    TRG_WIN_END_TDC_IN  : in  std_logic;
+    TRG_WIN_END_RDO_IN  : in  std_logic;
+    TRG_TDC_IN          : in  std_logic;
+    TRG_TIME_IN         : in  std_logic_vector(38 downto 0);
+    MISSING_REF_TIME_IN : in  std_logic;
+-- miscellaneous
+    LIGHT_MODE_IN       : in  std_logic;
+    DEBUG_MODE_EN_IN    : in  std_logic;
+    INFO_IN             : in  TIMERS;
+    STATISTICS_OUT      : out std_logic_vector_array_24(0 to 15);
+    READOUT_DEBUG       : out std_logic_vector(31 downto 0)
+    );
+end entity Readout_record;
+
+architecture behavioral of Readout_record is
+
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+
+  -- trigger window
+  signal trg_win_pre             : unsigned(10 downto 0);
+  signal trg_win_post            : unsigned(10 downto 0);
+  signal trg_time                : std_logic_vector(38 downto 0);
+  signal TW_pre                  : std_logic_vector(38 downto 0);
+  signal TW_post                 : std_logic_vector(38 downto 0);
+  signal trg_win_l               : std_logic;
+  signal trg_win_r               : std_logic;
+  signal start_trg_win_cnt       : std_logic := '0';
+  signal start_trg_win_cnt_200_p : std_logic;
+  signal trg_win_cnt             : std_logic_vector(11 downto 0);
+  signal trg_win_end_200         : std_logic := '0';
+  signal trg_win_end_200_p       : std_logic;
+  signal trg_win_end_100_p       : std_logic;
+  signal trg_win_end_100_r       : std_logic;
+  signal trg_win_end_100_2r      : std_logic;
+  signal trg_win_end_100_3r      : std_logic;
+  signal trg_win_end_100_4r      : std_logic;
+  -- channel signals
+  signal ch_data_r               : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_2r              : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_3r              : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_4r              : std_logic_vector(31 downto 0);
+  signal ch_hit_time             : std_logic_vector(38 downto 0);
+  signal ch_epoch_cntr           : std_logic_vector(27 downto 0);
+  signal buffer_transfer_done    : std_logic;
+  signal buffer_transfer_done_r  : std_logic;
+  signal buffer_transfer_done_2r : std_logic;
+  -- readout fsm
+  type FSM_READ is (IDLE, WAIT_FOR_TRG_WIND_END, RD_CH, WAIT_FOR_DATA_FINISHED, WAIT_FOR_LVL1_TRG_A,
+                    WAIT_FOR_LVL1_TRG_B, WAIT_FOR_LVL1_TRG_C, SEND_STATUS, SEND_TRG_RELEASE_A,
+                    SEND_TRG_RELEASE_B, SEND_TRG_RELEASE_C, SEND_TRG_RELEASE_D, WAIT_FOR_BUFFER_TRANSFER);
+  signal RD_CURRENT             : FSM_READ                          := IDLE;
+  signal RD_NEXT                : FSM_READ;
+  type FSM_WRITE is (IDLE, WR_CH, WAIT_A, WAIT_B, WAIT_C, WAIT_D);
+  signal WR_CURRENT             : FSM_WRITE                         := IDLE;
+  signal WR_NEXT                : FSM_WRITE;
+  signal start_trg_win_cnt_fsm  : std_logic;
+  signal rd_fsm_debug_fsm       : std_logic_vector(3 downto 0);
+  signal wr_fsm_debug_fsm       : std_logic_vector(3 downto 0);
+  signal rd_en_fsm              : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal data_finished_fsm      : std_logic;
+  signal wr_finished_fsm        : std_logic;
+  signal trg_release_fsm        : std_logic;
+  signal wr_header_fsm          : std_logic;
+  signal wr_trailer_fsm         : std_logic;
+  signal wr_ch_data_fsm         : std_logic;
+  signal wr_status_fsm          : std_logic;
+  signal missing_ref_time_fsm   : std_logic;
+  signal missing_ref_time       : std_logic;
+  signal invalid_trg_fsm        : std_logic;
+  signal invalid_trg            : std_logic;
+  signal unknown_trg_fsm        : std_logic;
+  signal unknown_trg            : std_logic;
+  signal fifo_nr_rd_fsm         : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_fsm         : integer range 0 to CHANNEL_NUMBER := 0;
+  signal buf_delay_fsm          : integer range 0 to 63             := 0;
+  signal buf_delay              : integer range 0 to 63             := 0;
+  signal idle_fsm               : std_logic;
+  signal readout_fsm            : std_logic;
+  signal wait_fsm               : std_logic;
+  -- fifo number
+  type Std_Logic_8_array is array (0 to 8) of std_logic_vector(3 downto 0);
+  signal empty_channels         : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal fifo_nr_rd             : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr             : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_r           : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_2r          : integer range 0 to CHANNEL_NUMBER := 0;
+  signal fifo_nr_wr_3r          : integer range 0 to CHANNEL_NUMBER := 0;
+  -- fifo read
+  signal rd_en                  : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  -- data mux
+  signal start_write            : std_logic                         := '0';
+  signal wr_header              : std_logic;
+  signal wr_ch_data             : std_logic;
+  signal wr_ch_data_r           : std_logic;
+  signal wr_status              : std_logic;
+  signal wr_trailer             : std_logic;
+  signal wr_info                : std_logic;
+  signal wr_time                : std_logic;
+  signal wr_epoch               : std_logic;
+  signal stop_status            : std_logic;
+  -- to endpoint
+  signal data_out_r             : std_logic_vector(31 downto 0);
+  signal data_wr_r              : std_logic;
+  signal data_finished          : std_logic;
+  signal wr_finished            : std_logic;
+  signal trg_release            : std_logic;
+  signal trg_statusbit          : std_logic_vector(31 downto 0)     := (others => '0');
+  -- statistics
+  signal compile_time           : std_logic_vector(31 downto 0);
+  signal trg_number             : unsigned(23 downto 0)             := (others => '0');
+  signal release_number         : unsigned(23 downto 0)             := (others => '0');
+  signal valid_tmg_trg_number   : unsigned(23 downto 0)             := (others => '0');
+  signal valid_NOtmg_trg_number : unsigned(23 downto 0)             := (others => '0');
+  signal invalid_trg_number     : unsigned(23 downto 0)             := (others => '0');
+  signal multi_tmg_trg_number   : unsigned(23 downto 0)             := (others => '0');
+  signal spurious_trg_number    : unsigned(23 downto 0)             := (others => '0');
+  signal wrong_readout_number   : unsigned(23 downto 0)             := (others => '0');
+  signal spike_number           : unsigned(23 downto 0)             := (others => '0');
+  signal timeout_number         : unsigned(23 downto 0)             := (others => '0');
+  signal total_empty_channel    : unsigned(23 downto 0)             := (others => '0');
+  signal idle_time              : unsigned(23 downto 0)             := (others => '0');
+  signal readout_time           : unsigned(23 downto 0)             := (others => '0');
+  signal wait_time              : unsigned(23 downto 0)             := (others => '0');
+  signal finished_number        : unsigned(23 downto 0)             := (others => '0');
+  signal valid_timing_trg_p     : std_logic;
+  signal valid_notiming_trg_p   : std_logic;
+  signal invalid_trg_p          : std_logic;
+  signal multi_tmg_trg_p        : std_logic;
+  signal spurious_trg_p         : std_logic;
+  signal spike_detected_p       : std_logic;
+  signal timeout_detected_p     : std_logic;
+  signal idle_time_up           : std_logic;
+  signal readout_time_up        : std_logic;
+  signal wait_time_up           : std_logic;
+  signal wrong_readout_up       : std_logic;
+  signal finished               : std_logic;
+  -- control
+  signal sync_q                 : std_logic_vector((CHANNEL_NUMBER-2)*3+2 downto 0);
+  signal isNoHit                : std_logic                         := '1';
+  signal isNoHit_r              : std_logic                         := '1';
+  signal isCalTrig              : std_logic                         := '0';
+  signal hit_in_i               : std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+  -- debug
+  signal header_error_bits      : std_logic_vector(15 downto 0);
+  signal trailer_trg_type       : std_logic_vector(3 downto 0);
+  signal trailer_trg_code       : std_logic_vector(7 downto 0);
+  signal trailer_error_bits     : std_logic_vector(15 downto 0);
+  signal rd_fsm_debug           : std_logic_vector(3 downto 0);
+  signal rd_fsm_debug_r         : std_logic_vector(3 downto 0);
+  signal history_rd_fsm         : std_logic_vector(31 downto 0)     := (others => '0');
+  signal wr_fsm_debug           : std_logic_vector(3 downto 0);
+  signal wr_fsm_debug_r         : std_logic_vector(3 downto 0);
+  signal history_wr_fsm         : std_logic_vector(31 downto 0)     := (others => '0');
+  signal any_hit                : std_logic                         := '0';
+
+begin  -- behavioral
+
+  trg_win_pre  <= unsigned(TRG_WIN_PRE_IN);
+  trg_win_post <= unsigned(TRG_WIN_POST_IN);
+
+-------------------------------------------------------------------------------
+-- Trigger window
+-------------------------------------------------------------------------------
+-- Trigger window borders
+  TrigWinCalculation : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      TW_pre  <= std_logic_vector(unsigned(trg_time)-trg_win_pre);
+      TW_post <= std_logic_vector(unsigned(trg_time)+trg_win_post);
+    end if;
+  end process TrigWinCalculation;
+
+-- Trigger Time Determination
+  DefineTriggerTime : process (CLK_200)
+  begin
+    if rising_edge(CLK_200) then
+      if RESET_200 = '1' then
+        trg_time <= (others => '0');
+      elsif TRG_TDC_IN = '1' then
+        trg_time <= TRG_TIME_IN;
+      end if;
+    end if;
+  end process DefineTriggerTime;
+
+-- Channel Hit Time Determination
+  ChannelHitTime : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31 downto 29) = "011" then
+        ch_epoch_cntr <= ch_data_r(fifo_nr_wr)(27 downto 0);
+      end if;
+
+      if ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31) = '1' then
+        ch_hit_time <= ch_epoch_cntr & ch_data_r(fifo_nr_wr)(10 downto 0);
+      elsif ch_data_r(fifo_nr_wr)(35 downto 32) = x"1" and ch_data_r(fifo_nr_wr)(31 downto 29) = "011" then
+        ch_hit_time <= (others => '0');
+      end if;
+    end if;
+  end process ChannelHitTime;
+
+-- Controls if the data coming from the channel is greater than the trigger window pre-edge
+  Check_Trigger_Win_Left : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if unsigned(TW_pre) <= unsigned(ch_hit_time) then
+        trg_win_l <= '1';
+      else
+        trg_win_l <= '0';
+      end if;
+    end if;
+  end process Check_Trigger_Win_Left;
+
+-- Controls if the data coming from the channel is smaller than the trigger window post-edge
+  Check_Trigger_Win_Right : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if unsigned(ch_hit_time) <= unsigned(TW_post) then
+        trg_win_r <= '1';
+      else
+        trg_win_r <= '0';
+      end if;
+    end if;
+  end process Check_Trigger_Win_Right;
+
+-------------------------------------------------------------------------------
+-- Readout
+-------------------------------------------------------------------------------
+-- Readout fsm
+  RD_FSM_CLK : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        RD_CURRENT       <= IDLE;
+        missing_ref_time <= '0';
+        invalid_trg      <= '0';
+        unknown_trg      <= '0';
+        fifo_nr_rd       <= 0;
+      else
+        RD_CURRENT              <= RD_NEXT;
+        rd_en                   <= rd_en_fsm;
+        wr_header               <= wr_header_fsm;
+        wr_trailer              <= wr_trailer_fsm;
+        wr_status               <= wr_status_fsm;
+        data_finished           <= data_finished_fsm;
+        trg_release             <= trg_release_fsm;
+        missing_ref_time        <= missing_ref_time_fsm;
+        buf_delay               <= buf_delay_fsm;
+        invalid_trg             <= invalid_trg_fsm;
+        unknown_trg             <= unknown_trg_fsm;
+        idle_time_up            <= idle_fsm;
+        readout_time_up         <= readout_fsm;
+        wait_time_up            <= wait_fsm;
+        fifo_nr_rd              <= fifo_nr_rd_fsm;
+        rd_fsm_debug            <= rd_fsm_debug_fsm;
+        buffer_transfer_done    <= and_all(CH_EMPTY_IN);
+        buffer_transfer_done_r  <= buffer_transfer_done;
+        buffer_transfer_done_2r <= buffer_transfer_done_r;
+      end if;
+    end if;
+  end process RD_FSM_CLK;
+  READ_EN_OUT <= rd_en;
+
+  RD_FSM_PROC : process (RD_CURRENT, READOUT_RX, stop_status, DEBUG_MODE_EN_IN, fifo_nr_rd,
+                         TRG_WIN_END_RDO_IN, buf_delay, CH_EMPTY_IN, buffer_transfer_done_2r,
+                         MISSING_REF_TIME_IN, isNoHit_r, missing_ref_time, invalid_trg, unknown_trg)
+
+  begin
+
+    RD_NEXT              <= RD_CURRENT;
+    rd_en_fsm            <= (others => '0');
+    wr_header_fsm        <= '0';
+    wr_trailer_fsm       <= '0';
+    wr_status_fsm        <= '0';
+    data_finished_fsm    <= '0';
+    trg_release_fsm      <= '0';
+    missing_ref_time_fsm <= missing_ref_time;
+    invalid_trg_fsm      <= invalid_trg;
+    unknown_trg_fsm      <= unknown_trg;
+    idle_fsm             <= '0';
+    readout_fsm          <= '0';
+    wait_fsm             <= '0';
+    buf_delay_fsm        <= 0;
+    fifo_nr_rd_fsm       <= fifo_nr_rd;
+    rd_fsm_debug_fsm     <= x"0";
+
+    case (RD_CURRENT) is
+      when IDLE =>
+        if READOUT_RX.valid_timing_trg = '1' then  -- physical trigger
+          RD_NEXT <= WAIT_FOR_TRG_WIND_END;
+        elsif READOUT_RX.valid_notiming_trg = '1' then
+          if READOUT_RX.trg_type = x"E" then       -- status trigger
+            wr_header_fsm <= '1';
+            RD_NEXT       <= SEND_STATUS;
+          elsif READOUT_RX.trg_type = x"D" then    -- tdc calibration trigger
+            RD_NEXT <= WAIT_FOR_TRG_WIND_END;
+          else                                     -- the other triggers
+            RD_NEXT <= SEND_TRG_RELEASE_A;
+          end if;
+        elsif READOUT_RX.invalid_trg = '1' then    -- invalid trigger
+          RD_NEXT         <= SEND_TRG_RELEASE_A;
+          invalid_trg_fsm <= '1';
+        end if;
+        idle_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"1";
+
+      when WAIT_FOR_TRG_WIND_END =>
+        if TRG_WIN_END_RDO_IN = '1' then
+          RD_NEXT <= WAIT_FOR_BUFFER_TRANSFER;
+          if MISSING_REF_TIME_IN = '1' or isNoHit_r = '0' then
+            wr_header_fsm <= '1';
+          end if;
+          if MISSING_REF_TIME_IN = '1' then
+            missing_ref_time_fsm <= '1';
+          end if;
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"2";
+
+      when WAIT_FOR_BUFFER_TRANSFER =>  -- the data from channel fifo is written to the buffer
+        if buffer_transfer_done_2r = '0' or buf_delay = 63 then
+          RD_NEXT <= RD_CH;
+        else
+          buf_delay_fsm <= buf_delay+ 1;
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"3";
+
+      when RD_CH =>
+        if CH_EMPTY_IN(fifo_nr_rd) = '0' then  -- read from channel if not empty
+          rd_en_fsm(fifo_nr_rd) <= '1';
+          fifo_nr_rd_fsm        <= fifo_nr_rd;
+        elsif fifo_nr_rd = CHANNEL_NUMBER-1 then  -- the last channel
+          rd_en_fsm(fifo_nr_rd) <= '0';
+          if DEBUG_MODE_EN_IN = '1' then  -- send status after channel data
+            RD_NEXT <= SEND_STATUS;
+          else
+            RD_NEXT <= WAIT_FOR_LVL1_TRG_A;
+          end if;
+        else                            -- go to the next channel
+          fifo_nr_rd_fsm <= fifo_nr_rd + 1 after 10 ps;
+        end if;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"4";
+
+      when WAIT_FOR_LVL1_TRG_A =>       -- wait for trigger data valid
+        if READOUT_RX.data_valid = '1' or READOUT_RX.trg_timeout = '1' then
+          if READOUT_RX.trg_type /= x"1" and READOUT_RX.trg_type /= x"D" then
+            unknown_trg_fsm <= '1';
+          end if;
+          RD_NEXT <= SEND_TRG_RELEASE_A;
+        end if;
+        wait_fsm         <= '1';
+        rd_fsm_debug_fsm <= x"6";
+
+        --when WAIT_FOR_LVL1_TRG_B =>
+        --  RD_NEXT          <= WAIT_FOR_LVL1_TRG_C;
+        --  wait_fsm         <= '1';
+        --  rd_fsm_debug_fsm <= x"7";
+
+        --when WAIT_FOR_LVL1_TRG_C =>
+        --  if READOUT_RX.trg_spurious = '1' then
+        --    wrong_readout_fsm <= '1';
+        --  end if;
+        --  RD_NEXT          <= SEND_TRG_RELEASE_A;
+        --  wait_fsm         <= '1';
+        --  rd_fsm_debug_fsm <= x"8";
+
+      when SEND_STATUS =>
+        if stop_status = '1' then
+          if DEBUG_MODE_EN_IN = '1' then
+            RD_NEXT <= WAIT_FOR_LVL1_TRG_A;
+          else
+            RD_NEXT <= SEND_TRG_RELEASE_A;
+          end if;
+        else
+          wr_status_fsm <= '1';
+        end if;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"9";
+
+      when SEND_TRG_RELEASE_A =>
+        RD_NEXT          <= SEND_TRG_RELEASE_B;
+        wr_trailer_fsm   <= '1';
+        fifo_nr_rd_fsm   <= 0;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"A";
+
+      when SEND_TRG_RELEASE_B =>
+        RD_NEXT          <= SEND_TRG_RELEASE_C;
+        readout_fsm      <= '1';
+        rd_fsm_debug_fsm <= x"A";
+
+      when SEND_TRG_RELEASE_C =>
+        RD_NEXT           <= SEND_TRG_RELEASE_D;
+        data_finished_fsm <= '1';
+        readout_fsm       <= '1';
+        rd_fsm_debug_fsm  <= x"B";
+
+      when SEND_TRG_RELEASE_D =>
+        RD_NEXT              <= IDLE;
+        trg_release_fsm      <= '1';
+        missing_ref_time_fsm <= '0';
+        invalid_trg_fsm      <= '0';
+        unknown_trg_fsm      <= '0';
+        readout_fsm          <= '1';
+        rd_fsm_debug_fsm     <= x"C";
+
+      when others =>
+        RD_NEXT          <= IDLE;
+        rd_fsm_debug_fsm <= x"0";
+    end case;
+  end process RD_FSM_PROC;
+
+
+  --purpose: FSM for writing data to endpoint buffer
+  WR_FSM_CLK : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_100 = '1' then
+        WR_CURRENT <= IDLE;
+      else
+        WR_CURRENT   <= WR_NEXT;
+        wr_ch_data   <= wr_ch_data_fsm;
+        fifo_nr_wr   <= fifo_nr_wr_fsm;
+        wr_finished  <= wr_finished_fsm;
+        wr_fsm_debug <= wr_fsm_debug_fsm;
+        start_write  <= or_all(CH_DATA_VALID_IN);
+      end if;
+    end if;
+  end process WR_FSM_CLK;
+
+  WR_FSM : process (WR_CURRENT, fifo_nr_wr, start_write, CH_DATA_VALID_IN, ch_data_2r,
+                    isNoHit_r)
+
+  begin
+
+    WR_NEXT          <= WR_CURRENT;
+    wr_ch_data_fsm   <= '0';
+    fifo_nr_wr_fsm   <= fifo_nr_wr;
+    wr_finished_fsm  <= '0';
+    wr_fsm_debug_fsm <= x"0";
+
+    case (WR_CURRENT) is
+      when IDLE =>
+        if start_write = '1' then
+          WR_NEXT <= WR_CH;
+        end if;
+        fifo_nr_wr_fsm   <= 0;
+        wr_fsm_debug_fsm <= x"1";
+--
+      when WR_CH =>
+        if ch_data_2r(fifo_nr_wr)(35 downto 32) /= x"f" then
+          if isNoHit_r = '1' then
+            wr_ch_data_fsm <= '0';
+          else
+            wr_ch_data_fsm <= '1';
+          end if;
+        elsif fifo_nr_wr = CHANNEL_NUMBER-1 then
+          fifo_nr_wr_fsm  <= 0;
+          wr_finished_fsm <= '1';
+          WR_NEXT         <= IDLE;
+        else
+          fifo_nr_wr_fsm <= fifo_nr_wr + 1;
+          WR_NEXT        <= WAIT_A;
+        end if;
+        wr_fsm_debug_fsm <= x"2";
+--
+      when WAIT_A =>
+        WR_NEXT          <= WAIT_B;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_B =>
+        WR_NEXT          <= WAIT_C;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_C =>
+        WR_NEXT          <= WR_CH;      --WAIT_D;
+        wr_fsm_debug_fsm <= x"3";
+--
+      when WAIT_D =>
+        WR_NEXT          <= WR_CH;
+        wr_fsm_debug_fsm <= x"3";
+--      
+      when others =>
+        WR_NEXT          <= IDLE;
+        wr_fsm_debug_fsm <= x"0";
+
+    end case;
+  end process WR_FSM;
+
+  fifo_nr_wr_r  <= fifo_nr_wr    when rising_edge(CLK_100);
+  fifo_nr_wr_2r <= fifo_nr_wr_r  when rising_edge(CLK_100);
+  fifo_nr_wr_3r <= fifo_nr_wr_2r when rising_edge(CLK_100);
+  wr_ch_data_r  <= wr_ch_data    when rising_edge(CLK_100);
+
+-------------------------------------------------------------------------------
+-- Data out mux
+-------------------------------------------------------------------------------
+  isCalibrationTrigger : process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then        -- rising clock edge
+      if trg_release = '1' then
+        isCalTrig <= '0';
+      elsif READOUT_RX.valid_notiming_trg = '1' and READOUT_RX.trg_type = x"D" then
+        isCalTrig <= '1';
+      end if;
+    end if;
+  end process isCalibrationTrigger;
+
+  -- Trigger window selection
+  TriggerWindowElimination : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if ch_data_3r(fifo_nr_wr_r)(35 downto 32) = x"1" and ch_data_3r(fifo_nr_wr_r)(31) = '1' then  --DATA word
+        if TRG_WIN_EN_IN = '1' and isCalTrig = '0' then  -- trigger window enabled
+          --elsif (TW_pre(10) = '1' and ref_time_coarse(10) = '0') or (TW_post(10) = '0' and ref_time_coarse(10) = '1') then  -- if one of the trigger window edges has an overflow
+          --  if (trg_win_l = '0' and trg_win_r = '1') or (trg_win_l = '1' and trg_win_r = '0') then
+          --    ch_data_4r <= ch_data_3r(fifo_nr);
+          --    data_wr_r  <= '1';
+          --  else
+          --    ch_data_4r <= (others => '1');
+          --    data_wr_r  <= '0';
+          --  end if;
+          if trg_win_l = '1' and trg_win_r = '1' then  -- if both of the trigger window edges are in the coarse counter boundries
+            ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+          elsif trg_win_r = '0' then  -- any hit that might come after the trigger window 
+            ch_data_4r <= (others => '0');
+          --else
+          --  ch_data_4r <= (others => '0');
+          end if;
+        else
+          ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+        end if;
+      else
+        ch_data_4r <= ch_data_3r(fifo_nr_wr_r)(31 downto 0);
+      end if;
+    end if;
+  end process TriggerWindowElimination;
+
+
+  Data_Out_MUX : process (CLK_100)
+    variable i : integer := 0;
+  begin
+    if rising_edge(CLK_100) then
+      if wr_header = '1' then
+        --data_out_r  <= "001" & "0" & READOUT_RX.trg_type & READOUT_RX.trg_code & header_error_bits;
+        data_out_r  <= "001" & "0" & x"000" & header_error_bits;
+        stop_status <= '0';
+      elsif wr_ch_data_r = '1' then
+        data_out_r  <= ch_data_4r;
+        stop_status <= '0';
+      elsif wr_status = '1' then
+        case i is
+          when 0  => data_out_r <= "010" & "00000" & std_logic_vector(trg_number);
+          when 1  => data_out_r <= "010" & "00001" & std_logic_vector(release_number);
+          when 2  => data_out_r <= "010" & "00010" & std_logic_vector(valid_tmg_trg_number);
+          when 3  => data_out_r <= "010" & "00011" & std_logic_vector(valid_NOtmg_trg_number);
+          when 4  => data_out_r <= "010" & "00100" & std_logic_vector(invalid_trg_number);
+          when 5  => data_out_r <= "010" & "00101" & std_logic_vector(multi_tmg_trg_number);
+          when 6  => data_out_r <= "010" & "00110" & std_logic_vector(spurious_trg_number);
+          when 7  => data_out_r <= "010" & "00111" & std_logic_vector(wrong_readout_number);
+          when 8  => data_out_r <= "010" & "01000" & std_logic_vector(spike_number);
+          when 9  => data_out_r <= "010" & "01001" & std_logic_vector(idle_time);
+          when 10 => data_out_r <= "010" & "01010" & std_logic_vector(wait_time);
+          when 11 => data_out_r <= "010" & "01011" & std_logic_vector(total_empty_channel);
+          when 12 => data_out_r <= "010" & "01100" & std_logic_vector(readout_time);
+          when 13 => data_out_r <= "010" & "01101" & std_logic_vector(timeout_number);
+          when 14 => data_out_r <= "010" & "01110" & x"000" & INFO_IN.temperature;
+          when 15 => data_out_r <= "010" & "01111" & x"000000";  --reserved
+          when 16 => data_out_r <= "010" & "10000" & x"00" & compile_time(15 downto 0);
+                     stop_status <= '1';  -- set always before the last word to be written
+          when 17 => data_out_r <= "010" & "10001" & x"00" & compile_time(31 downto 16);
+                     i := -1;
+          when others => null;
+        end case;
+        i := i+1;
+      elsif wr_trailer = '1' then
+        data_out_r  <= "000" & "0" & trailer_trg_type & trailer_trg_code & trailer_error_bits;
+        stop_status <= '0';
+      else
+        data_out_r  <= (others => '1');
+        stop_status <= '0';
+      end if;
+    end if;
+    compile_time <= std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32));
+  end process Data_Out_MUX;
+
+  wr_info  <= wr_header or wr_status or wr_trailer when rising_edge(CLK_100);
+  wr_time  <= wr_ch_data_r and ch_data_4r(31)      when rising_edge(CLK_100);
+  wr_epoch <= wr_ch_data_r and not data_out_r(31) and data_out_r(30) and data_out_r(29) and ch_data_4r(31);
+
+
+  READOUT_TX.data          <= data_out_r                     when rising_edge(CLK_100);
+  READOUT_TX.data_write    <= wr_info or wr_time or wr_epoch when rising_edge(CLK_100);
+  READOUT_TX.data_finished <= data_finished                  when rising_edge(CLK_100);
+  READOUT_TX.busy_release  <= trg_release                    when rising_edge(CLK_100);
+  READOUT_TX.statusbits    <= trg_statusbit                  when rising_edge(CLK_100);
+  trg_statusbit(23)        <= READOUT_RX.trg_spurious        when rising_edge(CLK_100);
+
+  READOUT_DEBUG(3 downto 0)   <= rd_fsm_debug;
+  READOUT_DEBUG(7 downto 4)   <= wr_fsm_debug;
+  READOUT_DEBUG(8)            <= data_wr_r;
+  READOUT_DEBUG(9)            <= finished;
+  READOUT_DEBUG(10)           <= trg_release;
+  READOUT_DEBUG(16 downto 11) <= data_out_r(27 downto 22);
+  READOUT_DEBUG(31 downto 17) <= (others => '0');
+
+  -- Error, warning bits set in the header
+
+  header_error_bits(0)           <= or_all(CH_ALMOST_FULL_IN);
+  header_error_bits(15 downto 1) <= (others => '0');
+
+  -- Error, warning bits set in the trailer
+  trailer_error_bits(0)           <= missing_ref_time;  -- info from the triggerhandler
+  trailer_error_bits(1)           <= READOUT_RX.trg_spurious;  -- if there is a wrong readout because of a spurious timing trigger
+  trailer_error_bits(2)           <= invalid_trg;  -- if there is an invalid trigger
+  trailer_error_bits(3)           <= READOUT_RX.trg_missing;  -- if the trigger handler detects no reference time signal
+  trailer_error_bits(4)           <= READOUT_RX.trg_multiple;  -- if there is multiple triggers
+  trailer_error_bits(5)           <= READOUT_RX.trg_spike;  -- if there is spikes
+  trailer_error_bits(6)           <= READOUT_RX.trg_timeout;  -- if there is a timeout signal from the endpoint
+  trailer_error_bits(7)           <= unknown_trg;  -- if there is an unknown timing trigger
+  trailer_error_bits(15 downto 8) <= (others => '0');
+
+  TrailerTriggerInfo : process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then        -- rising clock edge
+      if READOUT_RX.data_valid = '1' or READOUT_RX.trg_timeout = '1' then
+        trailer_trg_type <= READOUT_RX.trg_type;
+        trailer_trg_code <= READOUT_RX.trg_code;
+      end if;
+    end if;
+  end process TrailerTriggerInfo;
+
+-------------------------------------------------------------------------------
+-- Control bits
+-------------------------------------------------------------------------------
+  --purpose: Hit Signal Synchroniser
+  HitSignalSync : for i in 0 to CHANNEL_NUMBER-2 generate
+    sync_q(i*3)   <= HIT_IN(i+1) when rising_edge(CLK_100);
+    --sync_q(i*3+1) <= sync_q(i*3);       -- when rising_edge(CLK_100);
+    --sync_q(i*3+2) <= sync_q(i*3+1);     -- when rising_edge(CLK_100);
+    hit_in_i(i+1) <= HIT_IN(i+1);       --sync_q(i*3+2);
+  end generate HitSignalSync;
+
+  any_hit <= or_all(hit_in_i);
+
+  CheckHitStatus : process (CLK_100) is
+  begin
+    if rising_edge(CLK_100) then        -- rising clock edge
+      if LIGHT_MODE_IN = '0' or TRG_WIN_EN_IN = '1' then
+        isNoHit   <= '0';
+        isNoHit_r <= '0';
+      elsif READOUT_RX.valid_timing_trg = '1' then
+        isNoHit   <= '1';
+        isNoHit_r <= isNoHit;
+      elsif or_all(hit_in_i) = '1' then
+        isNoHit <= '0';
+      end if;
+    end if;
+  end process CheckHitStatus;
+-------------------------------------------------------------------------------
+-- Debug and statistics words
+-------------------------------------------------------------------------------
+
+  edge_to_pulse_1 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.valid_timing_trg,
+      pulse     => valid_timing_trg_p);
+
+  edge_to_pulse_2 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.valid_notiming_trg,
+      pulse     => valid_notiming_trg_p);
+
+  edge_to_pulse_3 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.invalid_trg,
+      pulse     => invalid_trg_p);
+
+  edge_to_pulse_4 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_multiple,
+      pulse     => multi_tmg_trg_p);
+
+  edge_to_pulse_5 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_spurious,
+      pulse     => spurious_trg_p);
+
+  edge_to_pulse_6 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_spike,
+      pulse     => spike_detected_p);
+
+  edge_to_pulse_7 : edge_to_pulse
+    port map (
+      clock     => CLK_100,
+      en_clk    => '1',
+      signal_in => READOUT_RX.trg_timeout,
+      pulse     => timeout_detected_p);
+
+-- Internal trigger number counter (only valid triggers)
+  Statistics_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        trg_number <= (others => '0');
+      elsif valid_timing_trg_p = '1' or valid_notiming_trg_p = '1' then
+        trg_number <= trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Trigger_Number;
+
+-- Internal release number counter
+  Statistics_Release_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        release_number <= (others => '0');
+      elsif trg_release = '1' then
+        release_number <= release_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Release_Number;
+
+-- Internal valid timing trigger number counter
+  Statistics_Valid_Timing_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        valid_tmg_trg_number <= (others => '0');
+      elsif valid_timing_trg_p = '1' then
+        valid_tmg_trg_number <= valid_tmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Valid_Timing_Trigger_Number;
+
+-- Internal valid NOtiming trigger number counter
+  Statistics_Valid_NoTiming_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        valid_NOtmg_trg_number <= (others => '0');
+      elsif valid_notiming_trg_p = '1' then
+        valid_NOtmg_trg_number <= valid_NOtmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Valid_NoTiming_Trigger_Number;
+
+-- Internal invalid trigger number counter
+  Statistics_Invalid_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        invalid_trg_number <= (others => '0');
+      elsif invalid_trg_p = '1' then
+        invalid_trg_number <= invalid_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Invalid_Trigger_Number;
+
+-- Internal multi timing trigger number counter
+  Statistics_Multi_Timing_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        multi_tmg_trg_number <= (others => '0');
+      elsif multi_tmg_trg_p = '1' then
+        multi_tmg_trg_number <= multi_tmg_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Multi_Timing_Trigger_Number;
+
+-- Internal spurious trigger number counter
+  Statistics_Spurious_Trigger_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        spurious_trg_number <= (others => '0');
+      elsif spurious_trg_p = '1' then
+        spurious_trg_number <= spurious_trg_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Spurious_Trigger_Number;
+
+  wrongReadoutUp : entity work.risingEdgeDetect
+    port map (
+      CLK       => CLK_100,
+      SIGNAL_IN => READOUT_RX.trg_spurious,
+      PULSE_OUT => wrong_readout_up);
+-- Number of wrong readout becasue of spurious trigger
+  Statistics_Wrong_Readout_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        wrong_readout_number <= (others => '0');
+      elsif wrong_readout_up = '1' then
+        wrong_readout_number <= wrong_readout_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Wrong_Readout_Number;
+
+-- Internal spike number counter
+  Statistics_Spike_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        spike_number <= (others => '0');
+      elsif spike_detected_p = '1' then
+        spike_number <= spike_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Spike_Number;
+
+-- Internal timeout number counter
+  Statistics_Timeout_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        timeout_number <= (others => '0');
+      elsif timeout_detected_p = '1' then
+        timeout_number <= timeout_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Timeout_Number;
+
+-- IDLE time of the TDC readout
+  Statistics_Idle_Time : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        idle_time <= (others => '0');
+      elsif idle_time_up = '1' then
+        idle_time <= idle_time + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Idle_Time;
+
+-- Readout and Wait time of the TDC readout
+  Statistics_Readout_Wait_Time : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        readout_time <= (others => '0');
+        wait_time    <= (others => '0');
+      elsif readout_time_up = '1' then
+        readout_time <= readout_time + to_unsigned(1, 1);
+      elsif wait_time_up = '1' then
+        wait_time <= wait_time + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Readout_Wait_Time;
+
+  -- Number of sent data finished
+  Statistics_Finished_Number : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if RESET_COUNTERS = '1' then
+        finished_number <= (others => '0');
+      elsif data_finished = '1' then    --finished = '1' then
+        finished_number <= finished_number + to_unsigned(1, 1);
+      end if;
+    end if;
+  end process Statistics_Finished_Number;
+
+  HistoryReadDebug : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if rd_fsm_debug_r /= rd_fsm_debug then
+        history_rd_fsm <= history_rd_fsm(27 downto 0) & rd_fsm_debug;
+      end if;
+      rd_fsm_debug_r <= rd_fsm_debug;
+    end if;
+  end process HistoryReadDebug;
+
+  HistoryWriteDebug : process (CLK_100)
+  begin
+    if rising_edge(CLK_100) then
+      if wr_fsm_debug_r /= wr_fsm_debug then
+        history_wr_fsm <= history_wr_fsm(27 downto 0) & wr_fsm_debug;
+      end if;
+      wr_fsm_debug_r <= wr_fsm_debug;
+    end if;
+  end process HistoryWriteDebug;
+
+-------------------------------------------------------------------------------
+-- STATUS REGISTERS BUS
+-------------------------------------------------------------------------------
+  -- statistics
+  STATISTICS_OUT(0)  <= std_logic_vector(trg_number);
+  STATISTICS_OUT(1)  <= std_logic_vector(valid_tmg_trg_number);
+  STATISTICS_OUT(2)  <= std_logic_vector(valid_NOtmg_trg_number);
+  STATISTICS_OUT(3)  <= std_logic_vector(invalid_trg_number);
+  STATISTICS_OUT(4)  <= std_logic_vector(multi_tmg_trg_number);
+  STATISTICS_OUT(5)  <= std_logic_vector(spurious_trg_number);
+  STATISTICS_OUT(6)  <= std_logic_vector(wrong_readout_number);
+  STATISTICS_OUT(7)  <= std_logic_vector(spike_number);
+  STATISTICS_OUT(8)  <= std_logic_vector(idle_time);
+  STATISTICS_OUT(9)  <= std_logic_vector(wait_time);
+  STATISTICS_OUT(10) <= std_logic_vector(total_empty_channel);
+  STATISTICS_OUT(11) <= std_logic_vector(release_number);
+  STATISTICS_OUT(12) <= std_logic_vector(readout_time);
+  STATISTICS_OUT(13) <= std_logic_vector(timeout_number);
+  STATISTICS_OUT(14) <= std_logic_vector(finished_number);
+  STATISTICS_OUT(15) <= (others => '0');
+
+-- readout debug history 
+  --STATUS_REGISTERS_BUS_OUT(19)              <= history_rd_fsm;
+  --STATUS_REGISTERS_BUS_OUT(20)              <= history_wr_fsm;
+
+
+-------------------------------------------------------------------------------
+-- Registering
+-------------------------------------------------------------------------------
+  ch_data_r  <= CH_DATA_IN when rising_edge(CLK_100);
+  ch_data_2r <= ch_data_r  when rising_edge(CLK_100);
+  ch_data_3r <= ch_data_2r when rising_edge(CLK_100);
+
+end behavioral;
diff --git a/releases/tdc_v2.3.1/ShiftRegisterSISO.vhd b/releases/tdc_v2.3.1/ShiftRegisterSISO.vhd
new file mode 100644 (file)
index 0000000..a82160b
--- /dev/null
@@ -0,0 +1,54 @@
+-------------------------------------------------------------------------------
+-- Title      : Register.vhd
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : Register.vhd
+-- Author     : c.ugur@gsi.de
+-- Created    : 2012-10-02
+-- Last update: 2013-03-06
+-------------------------------------------------------------------------------
+-- Description: Used to register signals n levels.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity ShiftRegisterSISO is
+  
+  generic (
+    DEPTH : integer range 1 to 32 := 1;               -- defines the number register level
+    WIDTH : integer range 1 to 32 := 1);              -- defines the register size
+
+  port (
+    CLK   : in  std_logic;                            -- register clock
+    D_IN  : in  std_logic_vector(WIDTH-1 downto 0);   -- register input
+    D_OUT : out std_logic_vector(WIDTH-1 downto 0));  -- register out
+
+end ShiftRegisterSISO;
+
+architecture Behavioral of ShiftRegisterSISO is
+
+  type   RegisterArray is array (0 to DEPTH) of std_logic_vector(WIDTH-1 downto 0);
+  signal reg : RegisterArray;
+
+  attribute syn_preserve        : boolean;
+  attribute syn_preserve of reg : signal is true;
+  
+begin  -- RTL
+
+  reg(0) <= D_IN;
+
+  GEN_Registers : for i in 1 to DEPTH generate
+    Registers : process (CLK)
+    begin
+      if rising_edge(CLK) then
+        reg(i) <= reg(i-1);
+      end if;
+    end process Registers;
+  end generate GEN_Registers;
+
+  D_OUT <= reg(DEPTH);
+
+end Behavioral;
diff --git a/releases/tdc_v2.3.1/Stretcher.vhd b/releases/tdc_v2.3.1/Stretcher.vhd
new file mode 100644 (file)
index 0000000..11bdca5
--- /dev/null
@@ -0,0 +1,62 @@
+-------------------------------------------------------------------------------
+-- Title      : Stretcher
+-- Project    : 
+-------------------------------------------------------------------------------
+-- File       : Stretcher.vhd
+-- Author     : cugur@gsi.de
+-- Created    : 2012-11-07
+-- Last update: 2015-06-10
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.tdc_components.all;
+
+entity Stretcher is
+  generic (
+    CHANNEL : integer range 1 to 64;
+    DEPTH   : integer range 1 to 10 := 3);
+  port (
+    PULSE_IN  : in  std_logic_vector(CHANNEL-1 downto 0);
+    PULSE_OUT : out std_logic_vector(CHANNEL-1 downto 0));
+
+end Stretcher;
+
+architecture behavioral of Stretcher is
+
+  signal pulse_a_in  : std_logic_vector(CHANNEL*DEPTH downto 1);
+  signal pulse_a_out : std_logic_vector(CHANNEL*DEPTH-1 downto 0);
+  signal pulse_b_in  : std_logic_vector(CHANNEL*DEPTH-1 downto 1);
+  signal pulse_b_out : std_logic_vector(CHANNEL*DEPTH-1 downto 1);
+
+begin  -- behavioral
+
+  GEN : for i in 1 to CHANNEL generate
+    pulse_a_in(DEPTH*i)                        <= PULSE_IN(i-1);
+    pulse_a_in(DEPTH*i-1 downto DEPTH*(i-1)+1) <= pulse_b_out(DEPTH*i-1 downto DEPTH*(i-1)+1);
+    pulse_b_in(DEPTH*i-1 downto DEPTH*(i-1)+1) <= pulse_a_out(DEPTH*i-1 downto DEPTH*(i-1)+1);
+    PULSE_OUT(i-1)                             <= transport not pulse_a_out(DEPTH*(i-1)) after 42.186 ns;
+  end generate GEN;
+
+  Stretcher_A_1 : entity work.Stretcher_A
+    generic map (
+      CHANNEL => CHANNEL,
+      DEPTH   => DEPTH)
+    port map (
+      PULSE_IN  => pulse_a_in,
+      PULSE_OUT => pulse_a_out);
+
+  Stretcher_B_1 : entity work.Stretcher_B
+    generic map (
+      CHANNEL => CHANNEL,
+      DEPTH   => DEPTH)
+    port map (
+      PULSE_IN  => pulse_b_in,
+      PULSE_OUT => pulse_b_out);
+
+end behavioral;
diff --git a/releases/tdc_v2.3.1/Stretcher_A.vhd b/releases/tdc_v2.3.1/Stretcher_A.vhd
new file mode 100644 (file)
index 0000000..35f54c4
--- /dev/null
@@ -0,0 +1,49 @@
+-------------------------------------------------------------------------------
+-- Title      : Stretcher_A
+-- Project    : TRB3
+-------------------------------------------------------------------------------
+-- File       : Stretcher_A.vhd
+-- Author     : Cahit Ugur  <c.ugur@gsi.de>
+-- Created    : 2014-11-24
+-- Last update: 2014-12-04
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+-- Copyright (c) 2014 
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author  Description
+-- 2014-11-24  1.0      cugur   Created
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity Stretcher_A is
+  generic (
+    CHANNEL : integer range 1 to 64;
+    DEPTH   : integer range 1 to 10 := 3);
+  port (
+    PULSE_IN  : in  std_logic_vector(CHANNEL*DEPTH downto 1);
+    PULSE_OUT : out std_logic_vector(CHANNEL*DEPTH-1 downto 0));
+
+end entity Stretcher_A;
+
+architecture behavioral of Stretcher_A is
+
+  signal pulse : std_logic_vector(CHANNEL*DEPTH downto 1);
+
+  attribute syn_keep              : boolean;
+  attribute syn_keep of pulse     : signal is true;
+  attribute syn_preserve          : boolean;
+  attribute syn_preserve of pulse : signal is true;
+  attribute NOMERGE               : string;
+  attribute NOMERGE of pulse      : signal is "KEEP";
+
+begin  -- architecture behavioral
+
+  pulse     <= PULSE_IN;
+  PULSE_OUT <= not pulse;
+
+end architecture behavioral;
diff --git a/releases/tdc_v2.3.1/Stretcher_B.vhd b/releases/tdc_v2.3.1/Stretcher_B.vhd
new file mode 100644 (file)
index 0000000..40458a2
--- /dev/null
@@ -0,0 +1,49 @@
+-------------------------------------------------------------------------------
+-- Title      : Stretcher_B
+-- Project    : TRB3
+-------------------------------------------------------------------------------
+-- File       : Stretcher_B.vhd
+-- Author     : Cahit Ugur  <c.ugur@gsi.de>
+-- Created    : 2014-11-24
+-- Last update: 2014-12-04
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+-- Copyright (c) 2014 
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author  Description
+-- 2014-11-24  1.0      cugur   Created
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity Stretcher_B is
+  generic (
+    CHANNEL : integer range 1 to 64;
+    DEPTH   : integer range 1 to 10 := 3);
+  port (
+    PULSE_IN  : in  std_logic_vector(CHANNEL*DEPTH-1 downto 1);
+    PULSE_OUT : out std_logic_vector(CHANNEL*DEPTH-1 downto 1));
+
+end entity Stretcher_B;
+
+architecture behavioral of Stretcher_B is
+
+  signal pulse : std_logic_vector(CHANNEL*DEPTH-1 downto 1);
+
+  attribute syn_keep              : boolean;
+  attribute syn_keep of pulse     : signal is true;
+  attribute syn_preserve          : boolean;
+  attribute syn_preserve of pulse : signal is true;
+  attribute NOMERGE               : string;
+  attribute NOMERGE of pulse      : signal is "KEEP";
+
+begin  -- architecture behavioral
+
+  pulse     <= PULSE_IN;
+  PULSE_OUT <= not pulse;
+
+end architecture behavioral;
diff --git a/releases/tdc_v2.3.1/TDC.vhd b/releases/tdc_v2.3.1/TDC.vhd
new file mode 100644 (file)
index 0000000..a61505a
--- /dev/null
@@ -0,0 +1,905 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+library work;
+use work.trb_net_std.all;
+use work.config.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.tdc_version.all;
+
+entity TDC is
+  generic (
+    CHANNEL_NUMBER : integer range 2 to 65 := 5;
+    STATUS_REG_NR  : integer range 0 to 31 := 21;
+    CONTROL_REG_NR : integer range 1 to 8  := 8;
+    DEBUG          : integer range 0 to 1  := c_NO;
+    SIMULATION     : integer range 0 to 1  := c_NO);
+  port (
+    RESET                 : in  std_logic;
+    CLK_TDC               : in  std_logic;
+    CLK_READOUT           : in  std_logic;
+    REFERENCE_TIME        : in  std_logic;
+    HIT_IN                : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+    HIT_CAL_IN            : in  std_logic;
+    TRG_WIN_PRE           : in  std_logic_vector(10 downto 0);
+    TRG_WIN_POST          : in  std_logic_vector(10 downto 0) := "00000001010";
+--
+    -- Trigger signals from handler
+    TRG_DATA_VALID_IN     : in  std_logic                     := '0';
+    VALID_TIMING_TRG_IN   : in  std_logic                     := '0';
+    VALID_NOTIMING_TRG_IN : in  std_logic                     := '0';
+    INVALID_TRG_IN        : in  std_logic                     := '0';
+    TMGTRG_TIMEOUT_IN     : in  std_logic                     := '0';
+    SPIKE_DETECTED_IN     : in  std_logic                     := '0';
+    MULTI_TMG_TRG_IN      : in  std_logic                     := '0';
+    SPURIOUS_TRG_IN       : in  std_logic                     := '0';
+--
+    TRG_NUMBER_IN         : in  std_logic_vector(15 downto 0) := (others => '0');
+    TRG_CODE_IN           : in  std_logic_vector(7 downto 0)  := (others => '0');
+    TRG_INFORMATION_IN    : in  std_logic_vector(23 downto 0) := (others => '0');
+    TRG_TYPE_IN           : in  std_logic_vector(3 downto 0)  := (others => '0');
+--
+    --Response to handler
+    TRG_RELEASE_OUT       : out std_logic;
+    TRG_STATUSBIT_OUT     : out std_logic_vector(31 downto 0);
+    DATA_OUT              : out std_logic_vector(31 downto 0);
+    DATA_WRITE_OUT        : out std_logic;
+    DATA_FINISHED_OUT     : out std_logic;
+--
+    --To Bus Handler
+    HCB_READ_EN_IN        : in  std_logic;
+    HCB_WRITE_EN_IN       : in  std_logic;
+    HCB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+    HCB_DATA_OUT          : out std_logic_vector(31 downto 0);
+    HCB_DATAREADY_OUT     : out std_logic;
+    HCB_UNKNOWN_ADDR_OUT  : out std_logic;
+    SRB_READ_EN_IN        : in  std_logic;
+    SRB_WRITE_EN_IN       : in  std_logic;
+    SRB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+    SRB_DATA_OUT          : out std_logic_vector(31 downto 0);
+    SRB_DATAREADY_OUT     : out std_logic;
+    SRB_UNKNOWN_ADDR_OUT  : out std_logic;
+    CDB_READ_EN_IN        : in  std_logic;
+    CDB_WRITE_EN_IN       : in  std_logic;
+    CDB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+    CDB_DATA_OUT          : out std_logic_vector(31 downto 0);
+    CDB_DATAREADY_OUT     : out std_logic;
+    CDB_UNKNOWN_ADDR_OUT  : out std_logic;
+    ESB_READ_EN_IN        : in  std_logic;
+    ESB_WRITE_EN_IN       : in  std_logic;
+    ESB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+    ESB_DATA_OUT          : out std_logic_vector(31 downto 0);
+    ESB_DATAREADY_OUT     : out std_logic;
+    ESB_UNKNOWN_ADDR_OUT  : out std_logic;
+    EFB_READ_EN_IN        : in  std_logic;
+    EFB_WRITE_EN_IN       : in  std_logic;
+    EFB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+    EFB_DATA_OUT          : out std_logic_vector(31 downto 0);
+    EFB_DATAREADY_OUT     : out std_logic;
+    EFB_UNKNOWN_ADDR_OUT  : out std_logic;
+    LHB_READ_EN_IN        : in  std_logic;
+    LHB_WRITE_EN_IN       : in  std_logic;
+    LHB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+    LHB_DATA_OUT          : out std_logic_vector(31 downto 0);
+    LHB_DATAREADY_OUT     : out std_logic;
+    LHB_UNKNOWN_ADDR_OUT  : out std_logic;
+--
+    LOGIC_ANALYSER_OUT    : out std_logic_vector(15 downto 0);
+    CONTROL_REG_IN        : in  std_logic_vector(32*CONTROL_REG_NR-1 downto 0)
+    );
+end TDC;
+
+architecture TDC of TDC is
+
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+-- Reset Signals
+  signal reset_rdo                  : std_logic;
+  signal reset_tdc_i                : std_logic;
+  signal reset_tdc                  : std_logic;
+-- Coarse counters
+  signal coarse_cntr                : std_logic_vector_array_11(0 to CHANNEL_NUMBER);
+  signal coarse_cntr_reset          : std_logic;
+  signal coarse_cntr_reset_r        : std_logic_vector(CHANNEL_NUMBER downto 0);
+  signal coarse_cntr_reset_2r       : std_logic_vector(CHANNEL_NUMBER downto 0);
+-- Slow control
+  signal logic_anal_control         : std_logic_vector(3 downto 0);
+  signal debug_mode_en              : std_logic;
+  signal light_mode_en              : std_logic;
+  signal reset_counters             : std_logic;
+  --signal run_mode                   : std_logic;  -- 1: cc reset every trigger
+  --                                                  -- 0: free running mode
+  --signal run_mode_200                 : std_logic;
+  --signal run_mode_edge_200            : std_logic;
+  signal reset_coarse_cntr          : std_logic;
+  signal reset_coarse_cntr_200      : std_logic;
+  signal reset_coarse_cntr_edge_200 : std_logic;
+  signal reset_coarse_cntr_flag     : std_logic                                   := '0';
+  signal ch_en                      : std_logic_vector(64 downto 1);
+  signal ch_invert                  : std_logic_vector(64 downto 1)               := (others => '0');
+  signal ring_buffer_full_thres     : std_logic_vector(6 downto 0);
+  signal calibration_on             : std_logic                                   := '0';  -- turns on calibration for trig type 0xD
+  signal calibration_on_r           : std_logic                                   := '0';  -- turns on calibration for trig type 0xD
+  signal calibration_on_2r          : std_logic                                   := '0';  -- turns on calibration for trig type 0xD
+  signal calibration_on_3r          : std_logic                                   := '0';  -- turns on calibration for trig type 0xD
+  signal calibration_on_4r          : std_logic                                   := '0';  -- turns on calibration for trig type 0xD
+  signal calibration_on_5r          : std_logic                                   := '0';  -- turns on calibration for trig type 0xD
+-- Logic analyser
+  signal logic_anal_data            : std_logic_vector(3*32-1 downto 0);
+-- Hit signals
+  signal hit_in_d                   : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_in_d_i                 : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_in_s                   : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_in_i                   : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_latch                  : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal hit_edge                   : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal hit_edge_r                 : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal hit_edge_2r                : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising                : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising_r              : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising_2r             : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising_3r             : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling               : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_r             : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_2r            : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_3r            : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d             : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d_r           : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d_2r          : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d_3r          : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+-- Calibration
+  signal hit_cal_cntr               : unsigned(15 downto 0)                       := (others => '0');
+  signal hit_cal_i                  : std_logic;
+  signal hit_cal                    : std_logic;
+  signal calibration_freq_select    : unsigned(3 downto 0)                        := (others => '0');
+  signal cal_cntr_start             : std_logic;
+  signal cal_cntr_start_sync        : std_logic;
+  signal cal_cntr                   : std_logic_vector(2 downto 0);
+-- To the channels
+  signal rd_en                      : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal trg_time                   : std_logic_vector(38 downto 0);
+-- From the channels
+  signal ch_data                    : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_valid              : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal ch_empty                   : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal ch_almost_full             : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal ch_lost_hit_number         : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_start_number    : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_finished_number : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+  signal ch_level_hit_number        : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_lost_hit_bus            : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_start_bus       : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_finished_bus    : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_fifo_write_number       : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+-- To the endpoint
+  signal ep_trg_release             : std_logic;
+  signal ep_trg_statusbit           : std_logic_vector(31 downto 0);
+  signal ep_data                    : std_logic_vector(31 downto 0);
+  signal ep_data_write              : std_logic;
+  signal ep_data_finished           : std_logic;
+
+-- Epoch counter
+  signal epoch_cntr         : std_logic_vector(27 downto 0);
+  signal epoch_cntr_up      : std_logic;
+  signal epoch_cntr_reset   : std_logic;
+-- Trigger Handler signals
+  signal trg_in             : std_logic;
+  signal trg_rdo            : std_logic;
+  signal trg_tdc            : std_logic;
+  signal trg_win_en         : std_logic;
+  signal trg_win_end_rdo    : std_logic;
+  signal trg_win_end_tdc    : std_logic;
+  signal trg_win_end_tdc_r  : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal missing_ref_time   : std_logic;
+  signal valid_trg_rdo      : std_logic;
+  signal valid_trg_tdc      : std_logic;
+
+-- Statistics signals
+  signal edge_rising_100    : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal edge_rising_100_r  : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal edge_rising_100_2r : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal edge_rising_100_3r : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal ch_hit_detect_cntr : unsigned_array_31(0 to CHANNEL_NUMBER-1);
+
+-- Debug signals
+  signal ch_debug                     : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_200_debug                 : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal readout_debug                : std_logic_vector(31 downto 0);
+-- Bus signals
+  signal readout_statistics           : std_logic_vector_array_24(0 to 15);
+  signal trg_handler_status_registers : std_logic_vector(31 downto 0);
+  signal status_registers_bus         : std_logic_vector_array_32(0 to STATUS_REG_NR-1);
+
+  attribute syn_keep                             : boolean;
+  attribute syn_keep of reset_tdc                : signal is true;
+  attribute syn_keep of coarse_cntr              : signal is true;
+  attribute syn_keep of coarse_cntr_reset_r      : signal is true;
+  attribute syn_keep of coarse_cntr_reset_2r     : signal is true;
+  attribute syn_keep of trg_win_end_tdc_r        : signal is true;
+  attribute syn_keep of hit_in_i                 : signal is true;
+  attribute syn_preserve                         : boolean;
+  attribute syn_preserve of coarse_cntr          : signal is true;
+  attribute syn_preserve of coarse_cntr_reset_r  : signal is true;
+  attribute syn_preserve of coarse_cntr_reset_2r : signal is true;
+  attribute syn_preserve of trg_win_end_tdc_r    : signal is true;
+  attribute syn_preserve of hit_in_i             : signal is true;
+  attribute nomerge                              : string;
+  attribute nomerge of hit_in_i                  : signal is "true";
+  
+
+begin
+
+-- Slow control signals
+  logic_anal_control      <= CONTROL_REG_IN(3 downto 0)     when rising_edge(CLK_READOUT);
+  debug_mode_en           <= CONTROL_REG_IN(4);
+  light_mode_en           <= CONTROL_REG_IN(5)              when rising_edge(CLK_READOUT);
+  reset_counters          <= CONTROL_REG_IN(8) or reset_tdc when rising_edge(CLK_TDC);
+  --run_mode              <= CONTROL_REG_IN(12);
+  --run_mode_200            <= run_mode                     when rising_edge(CLK_TDC);
+  reset_coarse_cntr       <= CONTROL_REG_IN(13)             when rising_edge(CLK_TDC);
+  reset_coarse_cntr_200   <= reset_coarse_cntr              when rising_edge(CLK_TDC);
+  calibration_freq_select <= unsigned(CONTROL_REG_IN(31 downto 28));
+
+  trg_win_en             <= CONTROL_REG_IN(1*32+31);
+  ch_en                  <= CONTROL_REG_IN(3*32+31 downto 2*32+0);
+  ring_buffer_full_thres <= CONTROL_REG_IN(4*32+6 downto 4*32+0) when rising_edge(CLK_READOUT);
+  ch_invert              <= CONTROL_REG_IN(6*32+31 downto 5*32+0);
+
+-- Reset signals
+  reset_tdc_i <= RESET       when rising_edge(CLK_TDC);
+  reset_tdc   <= reset_tdc_i when rising_edge(CLK_TDC);
+  reset_rdo   <= RESET;
+
+-------------------------------------------------------------------------------
+-- Hit Process
+-------------------------------------------------------------------------------
+
+  CalibrationHitGenerate : process (HIT_CAL_IN) is
+  begin
+    if rising_edge(HIT_CAL_IN) then     -- rising clock edge
+      if cal_cntr_start = '0' then
+        cal_cntr <= "100";
+      else
+        cal_cntr <= std_logic_vector(unsigned(cal_cntr) + to_unsigned(1, 3));
+      end if;
+      cal_cntr_start_sync <= calibration_on;
+      cal_cntr_start      <= cal_cntr_start_sync;
+    end if;
+  end process CalibrationHitGenerate;
+
+  --hit_cal <= and_all(cal_cntr);
+  hit_cal <= and_all(cal_cntr);
+-------------------------------------------------------------------------------
+
+--hit_cal <= HIT_CAL_IN;
+
+
+  calibration_on_r  <= calibration_on    when rising_edge(CLK_READOUT);
+  calibration_on_2r <= calibration_on_r  when rising_edge(CLK_READOUT);
+  calibration_on_3r <= calibration_on_2r when rising_edge(CLK_READOUT);
+  calibration_on_4r <= calibration_on_3r when rising_edge(CLK_READOUT);
+  calibration_on_5r <= calibration_on_4r when rising_edge(CLK_READOUT);
+
+  HitSelectRef : process (calibration_on, REFERENCE_TIME, hit_cal) is
+  begin
+    if calibration_on = '0' then
+      hit_in_s(0) <= REFERENCE_TIME;
+    else
+      hit_in_s(0) <= hit_cal;
+    end if;
+  end process HitSelectRef;
+
+  GEN_HitSelect : for i in 1 to CHANNEL_NUMBER-1 generate
+    Double : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 or (DOUBLE_EDGE_TYPE = 2 and (i mod 2 = 1)) generate
+      HitSelect : process (calibration_on, HIT_IN, hit_cal, ch_invert) is
+      begin
+        if calibration_on = '0' then
+          if ch_invert(i) = '0' then
+            hit_in_s(i) <= HIT_IN(i);
+          else
+            hit_in_s(i) <= not HIT_IN(i);
+          end if;
+        else
+          hit_in_s(i) <= hit_cal;
+        end if;
+      end process HitSelect;
+    end generate Double;
+    Single : if DOUBLE_EDGE_TYPE = 2 and (i mod 2 = 0) generate
+      HitSelect : process (calibration_on, HIT_IN, hit_cal, ch_invert) is
+      begin
+        if calibration_on = '0' then
+          if ch_invert(i) = '0' then
+            hit_in_s(i) <= HIT_IN(i);
+          else
+            hit_in_s(i) <= not HIT_IN(i);
+          end if;
+        else
+          hit_in_s(i) <= not hit_cal;
+        end if;
+      end process HitSelect;
+    end generate Single;
+  end generate GEN_HitSelect;
+
+
+-------------------------------------------------------------------------------
+  gen_double_withStretcher : if DOUBLE_EDGE_TYPE = 3 generate
+    The_Stretcher : entity work.Stretcher
+      generic map (
+        CHANNEL => CHANNEL_NUMBER-1,
+        DEPTH   => 4)
+      port map (
+        PULSE_IN  => edge_falling(CHANNEL_NUMBER-1 downto 1),
+        PULSE_OUT => edge_falling_d(CHANNEL_NUMBER-1 downto 1));
+  end generate gen_double_withStretcher;
+
+  gen_double_withoutStretcher : if DOUBLE_EDGE_TYPE = 1 generate
+    edge_falling_d(CHANNEL_NUMBER-1 downto 1) <= edge_falling(CHANNEL_NUMBER-1 downto 1);
+  end generate gen_double_withoutStretcher;
+
+
+  -- Blocks the input after the rising edge against short pulses
+  GEN_HitBlock : for i in 1 to CHANNEL_NUMBER-1 generate
+    gen_double : if DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+      edge_rising(i) <= '0' when edge_rising_3r(i) = '1' else
+                        --edge_rising(i) when hit_edge(i) = '1' else
+                        '1' after 2.5ns  when rising_edge(hit_in_s(i));
+      edge_rising_r(i)  <= edge_rising(i)                             when rising_edge(CLK_TDC);
+      edge_rising_2r(i) <= edge_rising_r(i)                           when rising_edge(CLK_TDC);
+      edge_rising_3r(i) <= edge_rising_r(i) and not edge_rising_2r(i) when rising_edge(CLK_TDC);
+
+      edge_falling(i) <= '0' when edge_falling_3r(i) = '1' else
+                         --edge_falling(i) when hit_edge(i) = '0' else
+                         '1' after 2ns when falling_edge(hit_in_s(i));
+      edge_falling_r(i)  <= edge_falling(i)                              when rising_edge(CLK_TDC);
+      edge_falling_2r(i) <= edge_falling_r(i)                            when rising_edge(CLK_TDC);
+      edge_falling_3r(i) <= edge_falling_r(i) and not edge_falling_2r(i) when rising_edge(CLK_TDC);
+
+      hit_latch(i) <= edge_rising(i) or edge_falling_d(i);
+
+      edge_falling_d_r(i)  <= edge_falling_d(i)                                when rising_edge(CLK_TDC);
+      edge_falling_d_2r(i) <= edge_falling_d_r(i)                              when rising_edge(CLK_TDC);
+      edge_falling_d_3r(i) <= edge_falling_d_r(i) and not edge_falling_d_2r(i) when rising_edge(CLK_TDC);
+
+      hit_edge(i) <= '0' when edge_falling_d(i) = '1' or RESET = '1' else
+                     '1' when rising_edge(edge_rising(i));
+      hit_edge_r(i)  <= hit_edge(i)    when rising_edge(CLK_TDC);
+      hit_edge_2r(i) <= hit_edge_r(i)  when rising_edge(CLK_TDC);
+    end generate gen_double;
+-------------------------------------------------------------------------------    
+    -- for single edge and double edge in alternating channel setup
+    gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 2 generate
+      edge_rising(i) <= '0' when edge_rising_3r(i) = '1' else
+                        '1' when rising_edge(hit_in_s(i));
+      edge_rising_r(i)  <= edge_rising(i)                             when rising_edge(CLK_TDC);
+      edge_rising_2r(i) <= edge_rising_r(i)                           when rising_edge(CLK_TDC);
+      edge_rising_3r(i) <= edge_rising_r(i) and not edge_rising_2r(i) when rising_edge(CLK_TDC);
+
+      hit_latch(i)   <= edge_rising(i);
+      hit_edge_2r(i) <= '1';
+    end generate gen_single;
+  end generate GEN_HitBlock;
+
+  GEN_hit_mux : for i in 1 to CHANNEL_NUMBER-1 generate
+    hit_mux_ch : hit_mux
+      port map (
+        CH_EN_IN           => ch_en(i),
+        CALIBRATION_EN_IN  => '0',      --calibration_on,
+        HIT_CALIBRATION_IN => '0',      --hit_cal,
+        HIT_PHYSICAL_IN    => hit_latch(i),
+        HIT_OUT            => hit_in_i(i));
+  end generate GEN_hit_mux;
+
+  hit_mux_ref : hit_mux
+    port map (
+      CH_EN_IN           => '1',
+      CALIBRATION_EN_IN  => '0',          --calibration_on,
+      HIT_CALIBRATION_IN => '0',          -- hit_cal,
+      HIT_PHYSICAL_IN    => hit_in_s(0),  --REFERENCE_TIME,
+      HIT_OUT            => hit_in_i(0));
+
+  CalibrationSwitch : process (CLK_READOUT)
+  begin
+    if rising_edge(CLK_READOUT) then
+      if trg_win_end_rdo = '1' then
+        calibration_on <= '0';
+      elsif VALID_NOTIMING_TRG_IN = '1' and TRG_TYPE_IN = x"D" then
+        calibration_on <= '1';
+      end if;
+    end if;
+  end process CalibrationSwitch;
+
+-------------------------------------------------------------------------------
+-- Channels
+-------------------------------------------------------------------------------
+  -- Reference Channel to measure the reference time
+  ReferenceChannel : Channel
+    generic map (
+      CHANNEL_ID => 0,
+      DEBUG      => DEBUG,
+      SIMULATION => SIMULATION,
+      REFERENCE  => c_YES)
+    port map (
+      RESET_200                 => reset_tdc,
+      RESET_100                 => reset_rdo,
+      RESET_COUNTERS            => reset_counters,
+      CLK_200                   => CLK_TDC,
+      CLK_100                   => CLK_READOUT,
+      HIT_IN                    => hit_in_i(0),
+      HIT_EDGE_IN               => '1',
+      TRG_WIN_END_TDC_IN        => trg_win_end_tdc_r(0),
+      TRG_WIN_END_RDO_IN        => trg_win_end_rdo,
+      EPOCH_COUNTER_IN          => epoch_cntr,
+      COARSE_COUNTER_IN         => coarse_cntr(0),
+      READ_EN_IN                => rd_en(0),
+      FIFO_DATA_OUT             => ch_data(0),
+      FIFO_DATA_VALID_OUT       => ch_data_valid(0),
+      FIFO_ALMOST_FULL_OUT      => ch_almost_full(0),
+      FIFO_EMPTY_OUT            => ch_empty(0),
+      RING_BUFFER_FULL_THRES_IN => ring_buffer_full_thres,
+      EPOCH_WRITE_EN_IN         => '1',
+      LOST_HIT_NUMBER           => ch_lost_hit_number(0),
+      HIT_DETECT_NUMBER         => open,  --ch_hit_detect_number(0),
+      ENCODER_START_NUMBER      => ch_encoder_start_number(0),
+      ENCODER_FINISHED_NUMBER   => ch_encoder_finished_number(0),
+      FIFO_WRITE_NUMBER         => ch_fifo_write_number(0),
+      Channel_200_DEBUG_OUT     => ch_200_debug(0),
+      Channel_DEBUG_OUT         => ch_debug(0));
+
+  -- TDC Channels
+  GEN_Channels : for i in 1 to CHANNEL_NUMBER-1 generate
+    Channels : Channel
+      generic map (
+        CHANNEL_ID => i,
+        DEBUG      => DEBUG,
+        SIMULATION => SIMULATION,
+        REFERENCE  => c_NO)
+      port map (
+        RESET_200                 => reset_tdc,
+        RESET_100                 => reset_rdo,
+        RESET_COUNTERS            => reset_counters,
+        CLK_200                   => CLK_TDC,
+        CLK_100                   => CLK_READOUT,
+        HIT_IN                    => hit_in_i(i),
+        HIT_EDGE_IN               => hit_edge_2r(i),
+        TRG_WIN_END_TDC_IN        => trg_win_end_tdc_r(i),
+        TRG_WIN_END_RDO_IN        => trg_win_end_rdo,
+        EPOCH_COUNTER_IN          => epoch_cntr,
+        COARSE_COUNTER_IN         => coarse_cntr(i),  -- coarse_cntr(integer(ceil(real(i)/real(8)))),
+        READ_EN_IN                => rd_en(i),
+        FIFO_DATA_OUT             => ch_data(i),
+        FIFO_DATA_VALID_OUT       => ch_data_valid(i),
+        FIFO_ALMOST_FULL_OUT      => ch_almost_full(i),
+        FIFO_EMPTY_OUT            => ch_empty(i),
+        RING_BUFFER_FULL_THRES_IN => ring_buffer_full_thres,
+        EPOCH_WRITE_EN_IN         => '1',
+        LOST_HIT_NUMBER           => ch_lost_hit_number(i),
+        HIT_DETECT_NUMBER         => open,  --ch_hit_detect_number(i),
+        ENCODER_START_NUMBER      => ch_encoder_start_number(i),
+        ENCODER_FINISHED_NUMBER   => ch_encoder_finished_number(i),
+        FIFO_WRITE_NUMBER         => ch_fifo_write_number(i),
+        Channel_200_DEBUG_OUT     => ch_200_debug(i),
+        Channel_DEBUG_OUT         => ch_debug(i));
+  end generate GEN_Channels;
+  ch_data(CHANNEL_NUMBER) <= (others => '1');
+
+-------------------------------------------------------------------------------
+-- Trigger
+-------------------------------------------------------------------------------
+  -- Valid Trigger Sync
+  ValidTriggerPulseSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_READOUT,
+      RESET_A_IN  => reset_rdo,
+      PULSE_A_IN  => valid_trg_rdo,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => reset_tdc,
+      PULSE_B_OUT => valid_trg_tdc);
+  valid_trg_rdo <= VALID_NOTIMING_TRG_IN or VALID_TIMING_TRG_IN;
+
+  -- Timing Trigger handler
+  TheTriggerHandler : TriggerHandler
+    generic map (
+      TRIGGER_NUM            => 1,
+      PHYSICAL_EVENT_TRG_NUM => 0)
+    port map (
+      CLK_TRG               => CLK_READOUT,
+      CLK_RDO               => CLK_READOUT,
+      CLK_TDC               => CLK_TDC,
+      RESET_TRG             => reset_rdo,
+      RESET_RDO             => reset_rdo,
+      RESET_TDC             => reset_tdc,
+      VALID_TIMING_TRG_IN   => VALID_TIMING_TRG_IN,
+      VALID_NOTIMING_TRG_IN => VALID_NOTIMING_TRG_IN,
+      TRG_TYPE_IN           => TRG_TYPE_IN,
+      TRG_RELEASE_IN        => ep_trg_release,
+      TRG_IN(0)             => trg_in,
+      TRG_RDO_OUT(0)        => trg_rdo,
+      TRG_TDC_OUT(0)        => trg_tdc,
+      TRG_WIN_EN_IN         => trg_win_en,
+      TRG_WIN_POST_IN       => unsigned(TRG_WIN_POST),
+      TRG_WIN_END_RDO_OUT   => trg_win_end_rdo,
+      TRG_WIN_END_TDC_OUT   => trg_win_end_tdc,
+      MISSING_REF_TIME_OUT  => missing_ref_time,
+      COARSE_COUNTER_IN     => coarse_cntr(CHANNEL_NUMBER),
+      EPOCH_COUNTER_IN      => epoch_cntr,
+      TRG_TIME_OUT          => trg_time,
+      DEBUG_OUT             => trg_handler_status_registers
+      );
+  trg_in <= REFERENCE_TIME;
+  GenTriggerWindowEnd : for i in 0 to CHANNEL_NUMBER-1 generate
+    trg_win_end_tdc_r(i)  <= trg_win_end_tdc      when rising_edge(CLK_TDC);
+  end generate GenTriggerWindowEnd;
+
+-------------------------------------------------------------------------------
+-- Readout
+-------------------------------------------------------------------------------
+  TheReadout : Readout
+    generic map (
+      CHANNEL_NUMBER => CHANNEL_NUMBER,
+      STATUS_REG_NR  => STATUS_REG_NR)
+    port map (
+      RESET_100             => reset_rdo,
+      RESET_200             => reset_tdc,
+      RESET_COUNTERS        => reset_counters,
+      CLK_100               => CLK_READOUT,
+      CLK_200               => CLK_TDC,
+      HIT_IN                => edge_rising_100(CHANNEL_NUMBER-1 downto 1),  --sync_qq(CHANNEL_NUMBER-1 downto 1),
+      -- from the channels
+      CH_DATA_IN            => ch_data,
+      CH_DATA_VALID_IN      => ch_data_valid,
+      CH_ALMOST_FULL_IN     => ch_almost_full,
+      CH_EMPTY_IN           => ch_empty,
+      -- from the endpoint
+      TRG_DATA_VALID_IN     => TRG_DATA_VALID_IN,
+      VALID_TIMING_TRG_IN   => VALID_TIMING_TRG_IN,
+      VALID_NOTIMING_TRG_IN => VALID_NOTIMING_TRG_IN,
+      INVALID_TRG_IN        => INVALID_TRG_IN,
+      TMGTRG_TIMEOUT_IN     => TMGTRG_TIMEOUT_IN,
+      SPIKE_DETECTED_IN     => SPIKE_DETECTED_IN,
+      MULTI_TMG_TRG_IN      => MULTI_TMG_TRG_IN,
+      SPURIOUS_TRG_IN       => SPURIOUS_TRG_IN,
+      TRG_CODE_IN           => TRG_CODE_IN,
+      TRG_INFORMATION_IN    => TRG_INFORMATION_IN,
+      TRG_TYPE_IN           => TRG_TYPE_IN,
+      -- to the endpoint
+      TRG_RELEASE_OUT       => ep_trg_release,
+      TRG_STATUSBIT_OUT     => ep_trg_statusbit,
+      DATA_OUT              => ep_data,
+      DATA_WRITE_OUT        => ep_data_write,
+      DATA_FINISHED_OUT     => ep_data_finished,
+      -- to the channels
+      READ_EN_OUT           => rd_en,
+      -- trigger window settings
+      TRG_WIN_PRE_IN        => TRG_WIN_PRE,
+      TRG_WIN_POST_IN       => TRG_WIN_POST,
+      TRG_WIN_EN_IN         => trg_win_en,
+      -- from the trigger handler
+      TRG_WIN_END_TDC_IN    => trg_win_end_tdc_r(1),
+      TRG_WIN_END_RDO_IN    => trg_win_end_rdo,
+      TRG_TDC_IN            => trg_tdc,
+      TRG_TIME_IN           => trg_time,
+      MISSING_REF_TIME_IN   => missing_ref_time,
+      -- miscellaneous
+      LIGHT_MODE_IN         => light_mode_en,
+      DEBUG_MODE_EN_IN      => debug_mode_en,
+      STATISTICS_OUT        => readout_statistics,
+      READOUT_DEBUG         => readout_debug
+      );
+
+  TRG_RELEASE_OUT   <= ep_trg_release   when rising_edge(CLK_READOUT);
+  TRG_STATUSBIT_OUT <= ep_trg_statusbit when rising_edge(CLK_READOUT);
+  DATA_OUT          <= ep_data          when rising_edge(CLK_READOUT);
+  DATA_WRITE_OUT    <= ep_data_write    when rising_edge(CLK_READOUT);
+  DATA_FINISHED_OUT <= ep_data_finished when rising_edge(CLK_READOUT);
+
+-------------------------------------------------------------------------------
+-- Coarse & Epoch Counters
+-------------------------------------------------------------------------------
+-- Coarse counter
+  GenCoarseCounter : for i in 0 to CHANNEL_NUMBER generate
+    TheCoarseCounter : up_counter
+      generic map (
+        NUMBER_OF_BITS => 11)
+      port map (
+        CLK       => CLK_TDC,
+        RESET     => coarse_cntr_reset_2r(i),
+        COUNT_OUT => coarse_cntr(i),
+        UP_IN     => '1');
+  end generate GenCoarseCounter;
+
+  Coarse_Counter_Reset : process (CLK_TDC)
+  begin
+    if rising_edge(CLK_TDC) then
+      if reset_tdc = '1' then
+        coarse_cntr_reset <= '1';
+      --elsif run_mode_200 = '0' then
+      --  coarse_cntr_reset <= trg_win_end_tdc_r(1);
+      --elsif run_mode_edge_200 = '1' then
+      --  coarse_cntr_reset <= '1';
+      elsif reset_coarse_cntr_flag = '1' and valid_trg_tdc = '1' then
+        coarse_cntr_reset <= '1';
+      else
+        coarse_cntr_reset <= '0';
+      end if;
+      if reset_coarse_cntr_edge_200 = '1' then
+        reset_coarse_cntr_flag <= '1';
+      elsif valid_trg_tdc = '1' then
+        reset_coarse_cntr_flag <= '0';
+      end if;
+    end if;
+  end process Coarse_Counter_Reset;
+
+  --Run_Mode_Edge_Detect : risingEdgeDetect
+  --  port map (
+  --    CLK       => CLK_TDC,
+  --    SIGNAL_IN => run_mode_200,
+  --    PULSE_OUT => run_mode_edge_200);
+
+  Reset_Coarse_Counter_Edge_Detect : risingEdgeDetect
+    port map (
+      CLK       => CLK_TDC,
+      SIGNAL_IN => reset_coarse_cntr_200,
+      PULSE_OUT => reset_coarse_cntr_edge_200);
+
+  GenCoarseCounterReset : for i in 0 to CHANNEL_NUMBER generate
+    coarse_cntr_reset_r(i)  <= coarse_cntr_reset      when rising_edge(CLK_TDC);
+    coarse_cntr_reset_2r(i) <= coarse_cntr_reset_r(i) when rising_edge(CLK_TDC);
+  end generate GenCoarseCounterReset;
+
+-- EPOCH counter
+  TheEpochCounter : up_counter
+    generic map (
+      NUMBER_OF_BITS => 28)
+    port map (
+      CLK       => CLK_TDC,
+      RESET     => epoch_cntr_reset,
+      COUNT_OUT => epoch_cntr,
+      UP_IN     => epoch_cntr_up);
+  epoch_cntr_up    <= and_all(coarse_cntr(CHANNEL_NUMBER));
+  epoch_cntr_reset <= coarse_cntr_reset_2r(CHANNEL_NUMBER);
+
+-------------------------------------------------------------------------------
+-- Statistics
+-------------------------------------------------------------------------------
+-- Hit Counters
+  GenHitCounter : for i in 0 to CHANNEL_NUMBER-1 generate
+    edge_rising_100(i) <= '0' when edge_rising_100_3r(i) = '1' else
+                          '1' when rising_edge(hit_in_s(i));
+    edge_rising_100_r(i)  <= edge_rising_100(i)                                 when rising_edge(CLK_READOUT);
+    edge_rising_100_2r(i) <= edge_rising_100_r(i)                               when rising_edge(CLK_READOUT);
+    edge_rising_100_3r(i) <= edge_rising_100_r(i) and not edge_rising_100_2r(i) when rising_edge(CLK_READOUT);
+
+    --purpose: Counts the detected hits
+    Hit_Detect_Counter : process (CLK_READOUT)
+    begin
+      if rising_edge(CLK_READOUT) then
+        if RESET_COUNTERS = '1' then
+          ch_hit_detect_cntr(i) <= (others => '0');
+        elsif edge_rising_100_3r(i) = '1' then
+          ch_hit_detect_cntr(i) <= ch_hit_detect_cntr(i) + to_unsigned(1, 31);
+        end if;
+      end if;
+    end process Hit_Detect_Counter;
+  end generate GenHitCounter;
+
+
+
+
+
+-------------------------------------------------------------------------------
+-- Slow Control Data Busses
+-------------------------------------------------------------------------------
+-- Hit counter
+  TheHitCounterBus : BusHandler
+    generic map (
+      BUS_LENGTH => CHANNEL_NUMBER-1)
+    port map (
+      RESET            => reset_rdo,
+      CLK              => CLK_READOUT,
+      DATA_IN          => ch_level_hit_number,
+      READ_EN_IN       => HCB_READ_EN_IN,
+      WRITE_EN_IN      => HCB_WRITE_EN_IN,
+      ADDR_IN          => HCB_ADDR_IN,
+      DATA_OUT         => HCB_DATA_OUT,
+      DATAREADY_OUT    => HCB_DATAREADY_OUT,
+      UNKNOWN_ADDR_OUT => HCB_UNKNOWN_ADDR_OUT);
+
+  ch_level_hit_number(0)(31)          <= REFERENCE_TIME                          when rising_edge(CLK_READOUT);
+  ch_level_hit_number(0)(30 downto 0) <= std_logic_vector(ch_hit_detect_cntr(0)) when rising_edge(CLK_READOUT);
+  GenHitDetectNumber : for i in 1 to CHANNEL_NUMBER-1 generate
+    ch_level_hit_number(i)(31)          <= HIT_IN(i)                               when rising_edge(CLK_READOUT);
+    ch_level_hit_number(i)(30 downto 0) <= std_logic_vector(ch_hit_detect_cntr(i)) when rising_edge(CLK_READOUT);
+  end generate GenHitDetectNumber;
+
+-- Status register
+  TheStatusRegistersBus : BusHandler
+    generic map (
+      BUS_LENGTH => STATUS_REG_NR - 1)
+    port map (
+      RESET            => reset_rdo,
+      CLK              => CLK_READOUT,
+      DATA_IN          => status_registers_bus,
+      READ_EN_IN       => SRB_READ_EN_IN,
+      WRITE_EN_IN      => SRB_WRITE_EN_IN,
+      ADDR_IN          => SRB_ADDR_IN,
+      DATA_OUT         => SRB_DATA_OUT,
+      DATAREADY_OUT    => SRB_DATAREADY_OUT,
+      UNKNOWN_ADDR_OUT => SRB_UNKNOWN_ADDR_OUT);
+
+  -- basic info
+  status_registers_bus(0)(3 downto 0)   <= readout_debug(3 downto 0);  -- rd_fsm
+  status_registers_bus(0)(7 downto 4)   <= readout_debug(7 downto 4);  -- wr_fsm
+  status_registers_bus(0)(15 downto 8)  <= std_logic_vector(to_unsigned(CHANNEL_NUMBER-1, 8));
+  status_registers_bus(0)(16)           <= REFERENCE_TIME when rising_edge(CLK_READOUT);
+  status_registers_bus(0)(27 downto 17) <= TDC_VERSION(10 downto 0);
+  status_registers_bus(0)(31 downto 28) <= TRG_TYPE_IN    when rising_edge(CLK_READOUT);
+
+  -- debug info
+  status_registers_bus(1)(3 downto 0) <= trg_handler_status_registers(23 downto 20);
+  status_registers_bus(2)             <= trg_time(31 downto 0) when (trg_rdo = '1' and rising_edge(CLK_READOUT));
+
+  -- trigger window
+  status_registers_bus(3)(10 downto 0)  <= TRG_WIN_PRE;
+  status_registers_bus(3)(15 downto 11) <= (others => '0');
+  status_registers_bus(3)(26 downto 16) <= TRG_WIN_POST;
+  status_registers_bus(3)(30 downto 27) <= (others => '0');
+  status_registers_bus(3)(31)           <= trg_win_en;
+
+  -- statistics
+  status_registers_bus(4)(23 downto 0)  <= readout_statistics(0);
+  status_registers_bus(5)(23 downto 0)  <= readout_statistics(1);
+  status_registers_bus(6)(23 downto 0)  <= readout_statistics(2);
+  status_registers_bus(7)(23 downto 0)  <= readout_statistics(3);
+  status_registers_bus(8)(23 downto 0)  <= readout_statistics(4);
+  status_registers_bus(9)(23 downto 0)  <= readout_statistics(5);
+  status_registers_bus(10)(23 downto 0) <= readout_statistics(6);
+  status_registers_bus(11)(23 downto 0) <= readout_statistics(7);
+  status_registers_bus(12)(23 downto 0) <= readout_statistics(8);
+  status_registers_bus(13)(23 downto 0) <= readout_statistics(9);
+  status_registers_bus(14)(23 downto 0) <= readout_statistics(10);
+  status_registers_bus(15)(23 downto 0) <= readout_statistics(11);
+  status_registers_bus(16)(23 downto 0) <= readout_statistics(12);
+  status_registers_bus(17)(23 downto 0) <= readout_statistics(13);
+  status_registers_bus(18)(23 downto 0) <= readout_statistics(14);
+
+
+
+
+
+-- Channel debug
+  TheChannelDebugBus : BusHandler
+    generic map (
+      BUS_LENGTH => CHANNEL_NUMBER - 1)
+    port map (
+      RESET            => reset_rdo,
+      CLK              => CLK_READOUT,
+      DATA_IN          => ch_200_debug,
+      READ_EN_IN       => CDB_READ_EN_IN,
+      WRITE_EN_IN      => CDB_WRITE_EN_IN,
+      ADDR_IN          => CDB_ADDR_IN,
+      DATA_OUT         => CDB_DATA_OUT,
+      DATAREADY_OUT    => CDB_DATAREADY_OUT,
+      UNKNOWN_ADDR_OUT => CDB_UNKNOWN_ADDR_OUT);
+
+
+  --TheLostHitBus : BusHandler
+  --  generic map (
+  --    BUS_LENGTH => CHANNEL_NUMBER-1)
+  --  port map (
+  --    RESET            => reset_rdo,
+  --    CLK              => CLK_READOUT,
+  --    DATA_IN          => ch_lost_hit_bus,
+  --    READ_EN_IN       => LHB_READ_EN_IN,
+  --    WRITE_EN_IN      => LHB_WRITE_EN_IN,
+  --    ADDR_IN          => LHB_ADDR_IN,
+  --    DATA_OUT         => LHB_DATA_OUT,
+  --    DATAREADY_OUT    => LHB_DATAREADY_OUT,
+  --    UNKNOWN_ADDR_OUT => LHB_UNKNOWN_ADDR_OUT);
+
+  --GenLostHit_In_number : for i in 1 to CHANNEL_NUMBER-1 generate
+  --  ch_lost_hit_bus(i) <= ch_encoder_start_number(i)(15 downto 0) & ch_200_debug(i)(15 downto 0) when rising_edge(CLK_READOUT);
+  --end generate GenLostHit_In_number;
+
+  LHB_DATA_OUT         <= (others => '0');
+  LHB_DATAREADY_OUT    <= '0';
+  LHB_UNKNOWN_ADDR_OUT <= '0';
+
+  --TheEncoderStartBus : BusHandler
+  --  generic map (
+  --    BUS_LENGTH => CHANNEL_NUMBER-1)
+  --  port map (
+  --    RESET            => reset_rdo,
+  --    CLK              => CLK_READOUT,
+  --    DATA_IN          => ch_encoder_start_bus,
+  --    READ_EN_IN       => ESB_READ_EN_IN,
+  --    WRITE_EN_IN      => ESB_WRITE_EN_IN,
+  --    ADDR_IN          => ESB_ADDR_IN,
+  --    DATA_OUT         => ESB_DATA_OUT,
+  --    DATAREADY_OUT    => ESB_DATAREADY_OUT,
+  --    UNKNOWN_ADDR_OUT => ESB_UNKNOWN_ADDR_OUT);
+
+  --GenEncoderStartNumber : for i in 1 to CHANNEL_NUMBER-1 generate
+  --  ch_encoder_start_bus(i) <= x"00" & ch_encoder_start_number(i) when rising_edge(CLK_READOUT);
+  --end generate GenEncoderStartNumber;
+
+  ESB_DATA_OUT         <= (others => '0');
+  ESB_DATAREADY_OUT    <= '0';
+  ESB_UNKNOWN_ADDR_OUT <= '0';
+
+  --TheEncoderFinishedBus : BusHandler
+  --  generic map (
+  --    BUS_LENGTH => CHANNEL_NUMBER-1)
+  --  port map (
+  --    RESET            => reset_rdo,
+  --    CLK              => CLK_READOUT,
+  --    DATA_IN          => ch_encoder_finished_bus,
+  --    READ_EN_IN       => EFB_READ_EN_IN,
+  --    WRITE_EN_IN      => EFB_WRITE_EN_IN,
+  --    ADDR_IN          => EFB_ADDR_IN,
+  --    DATA_OUT         => EFB_DATA_OUT,
+  --    DATAREADY_OUT    => EFB_DATAREADY_OUT,
+  --    UNKNOWN_ADDR_OUT => EFB_UNKNOWN_ADDR_OUT);
+
+  --GenFifoWriteNumber : for i in 1 to CHANNEL_NUMBER-1 generate
+  --  --ch_encoder_finished_bus(i) <= x"00" & ch_encoder_finished_number(i) when rising_edge(CLK_READOUT);
+  --  ch_encoder_finished_bus(i) <= ch_fifo_write_number(i)(15 downto 0)& ch_encoder_finished_number(i)(15 downto 0) when rising_edge(CLK_READOUT);
+  --end generate GenFifoWriteNumber;
+
+  EFB_DATA_OUT         <= (others => '0');
+  EFB_DATAREADY_OUT    <= '0';
+  EFB_UNKNOWN_ADDR_OUT <= '0';
+
+-------------------------------------------------------------------------------
+-- Debug
+-------------------------------------------------------------------------------
+-- Logic Analyser
+  --TheLogicAnalyser : LogicAnalyser
+  --  generic map (
+  --    CHANNEL_NUMBER => CHANNEL_NUMBER)
+  --  port map (
+  --    CLK        => CLK_READOUT,
+  --    RESET      => reset_rdo,
+  --    DATA_IN    => logic_anal_data,
+  --    CONTROL_IN => logic_anal_control,
+  --    DATA_OUT   => LOGIC_ANALYSER_OUT);
+
+  --logic_anal_data(7 downto 0)   <= readout_debug(7 downto 0);
+  --logic_anal_data(8)            <= REFERENCE_TIME;
+  --logic_anal_data(9)            <= VALID_TIMING_TRG_IN;
+  --logic_anal_data(10)           <= VALID_NOTIMING_TRG_IN;
+  --logic_anal_data(11)           <= INVALID_TRG_IN;
+  --logic_anal_data(12)           <= TRG_DATA_VALID_IN;
+  --logic_anal_data(13)           <= readout_debug(8);   --data_wr_r;
+  --logic_anal_data(14)           <= readout_debug(9);   --data_finished_r;
+  --logic_anal_data(15)           <= readout_debug(10);  --trg_release_r;
+  --logic_anal_data(31 downto 16) <= (others => '0');
+  --logic_anal_data(37 downto 32) <= readout_debug(16 downto 11);  --data_out_r(27 downto 22);
+  --logic_anal_data(47 downto 38) <= (others => '0');
+  --logic_anal_data(63 downto 48) <= ch_debug(1)(15 downto 0);
+  --logic_anal_data(95 downto 64) <= (others => '0');
+
+  --LOGIC_ANALYSER_OUT(0) <= REFERENCE_TIME;  -- 0  19
+  --LOGIC_ANALYSER_OUT(1) <= hit_in_s(0);     -- 1  18
+  --LOGIC_ANALYSER_OUT(2) <= hit_in_i(0);     -- 2  17
+  --LOGIC_ANALYSER_OUT(3)  <= edge_falling(1);  -- 3  16
+  --LOGIC_ANALYSER_OUT(4)  <= HIT_IN(1);        -- 4  15
+  --LOGIC_ANALYSER_OUT(5)  <= HIT_IN(2);        -- 5  14
+  --LOGIC_ANALYSER_OUT(6)  <= HIT_IN(3);        -- 6  13
+  --LOGIC_ANALYSER_OUT(7)  <= HIT_IN(4);        -- 7  12
+  --LOGIC_ANALYSER_OUT(8)  <= hit_in_i(1);      -- 8  11
+  --LOGIC_ANALYSER_OUT(9)  <= hit_in_i(2);      -- 9  10
+  --LOGIC_ANALYSER_OUT(10) <= hit_in_i(3);      -- 10 9
+  --LOGIC_ANALYSER_OUT(11) <= hit_in_i(4);      -- 11 8
+  --LOGIC_ANALYSER_OUT(12) <= hit_edge(1);      -- 12 7
+  --LOGIC_ANALYSER_OUT(13) <= hit_latch(1);     -- 13 6
+  --LOGIC_ANALYSER_OUT(14) <= hit_in_i(1);      -- 14 5
+  --LOGIC_ANALYSER_OUT(13) <= hit_in_i(1);
+  --LOGIC_ANALYSER_OUT(14) <= hit_in_i(1);
+  --LOGIC_ANALYSER_OUT(15) <= hit_in_i(1);
+
+  
+end TDC;
diff --git a/releases/tdc_v2.3.1/TDC_record.vhd b/releases/tdc_v2.3.1/TDC_record.vhd
new file mode 100644 (file)
index 0000000..2cc1213
--- /dev/null
@@ -0,0 +1,772 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+library work;
+use work.trb_net_std.all;
+use work.config.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.tdc_version.all;
+
+entity TDC_record is
+  generic (
+    CHANNEL_NUMBER : integer range 2 to 65 := 5;
+    STATUS_REG_NR  : integer range 0 to 31 := 21;
+    DEBUG          : integer range 0 to 1  := c_NO;
+    SIMULATION     : integer range 0 to 1  := c_NO);
+  port (
+    RESET              : in  std_logic;
+    CLK_TDC            : in  std_logic;
+    CLK_READOUT        : in  std_logic;
+    REFERENCE_TIME     : in  std_logic;
+    HIT_IN             : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+    HIT_CAL_IN         : in  std_logic;
+    --Readout
+    BUSRDO_RX          : in  READOUT_RX;
+    BUSRDO_TX          : out READOUT_TX;
+    --Slow Control
+    BUS_RX             : in  CTRLBUS_RX;
+    BUS_TX             : out CTRLBUS_TX;
+    --Debug
+    INFO_IN            : in  TIMERS;
+    LOGIC_ANALYSER_OUT : out std_logic_vector(15 downto 0)
+    );
+end TDC_record;
+
+architecture TDC_record of TDC_record is
+
+-------------------------------------------------------------------------------
+-- Signal Declarations
+-------------------------------------------------------------------------------
+-- Reset Signals
+  signal reset_rdo                                        : std_logic;
+  signal reset_tdc_i                                      : std_logic;
+  signal reset_tdc                                        : std_logic;
+-- Coarse counters
+  signal coarse_cntr                                      : std_logic_vector_array_11(0 to CHANNEL_NUMBER);
+  signal coarse_cntr_reset                                : std_logic;
+-- Slow control
+  signal ctrl_reg                                         : std_logic_vector_array_32(0 to 8);
+  signal logic_anal_control                               : std_logic_vector(3 downto 0);
+  signal debug_mode_en                                    : std_logic;
+  signal light_mode_en                                    : std_logic;
+  signal reset_counters                                   : std_logic;
+  --signal run_mode                   : std_logic;  -- 1: cc reset every trigger
+  --                                                  -- 0: free running mode
+  --signal run_mode_200                 : std_logic;
+  --signal run_mode_edge_200            : std_logic;
+  signal reset_coarse_cntr                                : std_logic;
+  signal reset_coarse_cntr_200                            : std_logic;
+  signal reset_coarse_cntr_edge_200                       : std_logic;
+  signal reset_coarse_cntr_flag                           : std_logic                                   := '0';
+  signal ch_en                                            : std_logic_vector(64 downto 1);
+  signal ch_invert                                        : std_logic_vector(64 downto 1)               := (others => '0');
+  signal ring_buffer_full_thres                           : std_logic_vector(6 downto 0);
+  signal calibration_on                                   : std_logic                                   := '0';  --turns on calibration for trig type 0xD
+-- Logic analyser
+  signal logic_anal_data                                  : std_logic_vector(3*32-1 downto 0);
+-- Hit signals
+  signal hit_in_d                                         : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_in_d_i                                       : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_in_s                                         : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_in_i                                         : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal hit_latch                                        : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal hit_edge                                         : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal hit_edge_r                                       : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal hit_edge_2r                                      : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising                                      : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising_r                                    : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising_2r                                   : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_rising_3r                                   : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling                                     : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_r                                   : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_2r                                  : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_3r                                  : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d                                   : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d_r                                 : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d_2r                                : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+  signal edge_falling_d_3r                                : std_logic_vector(CHANNEL_NUMBER-1 downto 1) := (others => '0');
+-- Calibration
+  signal hit_cal_cntr                                     : unsigned(15 downto 0)                       := (others => '0');
+  signal hit_cal_i                                        : std_logic;
+  signal hit_cal                                          : std_logic;
+  signal calibration_freq_select                          : unsigned(3 downto 0)                        := (others => '0');
+  signal cal_cntr_start                                   : std_logic;
+  signal cal_cntr_start_sync                              : std_logic;
+  signal cal_cntr                                         : std_logic_vector(2 downto 0);
+-- To the channels
+  signal rd_en                                            : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal trg_time                                         : std_logic_vector(38 downto 0);
+-- From the channels
+  signal ch_data                                          : std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+  signal ch_data_valid                                    : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal ch_empty                                         : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal ch_almost_full                                   : std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+  signal ch_lost_hit_number                               : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_start_number                          : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_finished_number                       : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+  signal ch_level_hit_number                              : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_lost_hit_bus                                  : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_start_bus                             : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_encoder_finished_bus                          : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_fifo_write_number                             : std_logic_vector_array_24(0 to CHANNEL_NUMBER-1);
+-- Epoch counter
+  signal epoch_cntr                                       : std_logic_vector(27 downto 0);
+  signal epoch_cntr_up                                    : std_logic;
+  signal epoch_cntr_reset                                 : std_logic;
+-- Trigger Handler signals
+  signal trg_in                                           : std_logic;
+  signal trg_rdo                                          : std_logic;
+  signal trg_tdc                                          : std_logic;
+  signal trg_win_en                                       : std_logic;
+  signal trg_win_end_rdo                                  : std_logic;
+  signal trg_win_end_tdc                                  : std_logic;
+  signal missing_ref_time                                 : std_logic;
+  signal valid_trg_rdo                                    : std_logic;
+  signal valid_trg_tdc                                    : std_logic;
+  signal trg_win_pre                                      : std_logic_vector(10 downto 0);
+  signal trg_win_post                                     : std_logic_vector(10 downto 0)               := "00000001010";
+-- Statistics signals
+  signal edge_rising_100                                  : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal edge_rising_100_r                                : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal edge_rising_100_2r                               : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal edge_rising_100_3r                               : std_logic_vector(CHANNEL_NUMBER-1 downto 0) := (others => '0');
+  signal ch_hit_detect_cntr                               : unsigned_array_31(0 to CHANNEL_NUMBER-1);
+-- Debug signals
+  signal ch_debug                                         : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal ch_200_debug                                     : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+  signal readout_debug                                    : std_logic_vector(31 downto 0);
+  signal buschdebug_data_in                               : std_logic_vector_array_32(0 to CHANNEL_NUMBER-1);
+-- Bus signals
+  signal readout_statistics                               : std_logic_vector_array_24(0 to 15);
+  signal trg_handler_status_registers                     : std_logic_vector(31 downto 0);
+  signal status_registers_bus                             : std_logic_vector_array_32(0 to STATUS_REG_NR-1);
+  signal bushit_rx, busstat_rx, buschdebug_rx, busctrl_rx : CTRLBUS_RX;
+  signal bushit_tx, busstat_tx, buschdebug_tx, busctrl_tx : CTRLBUS_TX;
+  signal busreadout_rx                                    : READOUT_RX;
+  signal busreadout_tx                                    : READOUT_TX;
+  
+  signal hit_in_reg                   : std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+  signal ref_in_reg                   : std_logic;
+
+
+  attribute syn_keep                    : boolean;
+  attribute syn_keep of reset_tdc       : signal is true;
+  attribute syn_keep of coarse_cntr     : signal is true;
+  attribute syn_keep of hit_in_i        : signal is true;
+  attribute syn_preserve                : boolean;
+  attribute syn_preserve of coarse_cntr : signal is true;
+  attribute syn_preserve of hit_in_i    : signal is true;
+  attribute nomerge                     : string;
+  attribute nomerge of hit_in_i         : signal is "true";
+
+
+begin
+
+-------------------------------------------------------------------------------
+-- Bus Handler
+-------------------------------------------------------------------------------
+  THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record
+    generic map(
+      PORT_NUMBER      => 4,
+      PORT_ADDRESSES   => (0 => x"0000", 1 => x"0100", 2 => x"0200", 3 => x"0800", others => x"0000"),
+      PORT_ADDR_MASK   => (0 => 7,       1 => 5,       2 => 7, 3 =>  3,            others => 0),
+      PORT_MASK_ENABLE => 1
+      )
+    port map(
+      CLK   => CLK_READOUT,
+      RESET => RESET,
+
+      REGIO_RX => BUS_RX,
+      REGIO_TX => BUS_TX,
+
+      BUS_RX(0) => bushit_rx,           -- hit counter bus
+      BUS_RX(1) => busstat_rx,          -- status reg bus
+      BUS_RX(2) => buschdebug_rx,       -- channel debug bus
+      BUS_RX(3) => busctrl_rx,          -- contorl reg bus
+      BUS_TX(0) => bushit_tx,
+      BUS_TX(1) => busstat_tx,
+      BUS_TX(2) => buschdebug_tx,
+      BUS_TX(3) => busctrl_tx,
+
+      STAT_DEBUG => open
+      );
+
+  busreadout_rx <= BUSRDO_RX;
+  BUSRDO_TX     <= busreadout_tx;
+
+-------------------------------------------------------------------------------
+-- Slow Control
+-------------------------------------------------------------------------------
+
+  TheSlowcontrolBus : entity work.BusHandler_record
+    generic map (
+      BUS_LENGTH => 8)
+    port map (
+      RESET    => RESET,
+      CLK      => CLK_READOUT,
+      BUS_RX   => busctrl_rx,
+      BUS_TX   => busctrl_tx,
+      DATA_IN  => ctrl_reg,
+      DATA_OUT => ctrl_reg);
+
+
+-- Slow control signals
+  logic_anal_control      <= ctrl_reg(0)(3 downto 0);
+  debug_mode_en           <= ctrl_reg(0)(4);
+  light_mode_en           <= ctrl_reg(0)(5);
+  reset_counters          <= ctrl_reg(0)(8) or reset_tdc when rising_edge(CLK_TDC);
+  --run_mode              <= ctrl_reg(0)(12);
+  --run_mode_200            <= run_mode                     when rising_edge(CLK_TDC);
+  reset_coarse_cntr       <= ctrl_reg(0)(13)             when rising_edge(CLK_TDC);
+  reset_coarse_cntr_200   <= reset_coarse_cntr           when rising_edge(CLK_TDC);
+  calibration_freq_select <= unsigned(ctrl_reg(0)(31 downto 28));
+  trg_win_pre             <= ctrl_reg(1)(10 downto 0);
+  trg_win_post            <= ctrl_reg(1)(26 downto 16);
+  trg_win_en              <= ctrl_reg(1)(31);
+  ch_en                   <= ctrl_reg(3) & ctrl_reg(2);
+  ring_buffer_full_thres  <= ctrl_reg(4)(6 downto 0);
+  ch_invert               <= ctrl_reg(6) & ctrl_reg(5);
+
+-- Reset signals
+  reset_tdc_i <= RESET       when rising_edge(CLK_TDC);
+  reset_tdc   <= reset_tdc_i when rising_edge(CLK_TDC);
+  reset_rdo   <= RESET;
+
+-------------------------------------------------------------------------------
+-- Hit Process
+-------------------------------------------------------------------------------
+
+  CalibrationHitGenerate : process (HIT_CAL_IN) is
+  begin
+    if rising_edge(HIT_CAL_IN) then     -- rising clock edge
+      if cal_cntr_start = '0' then
+        cal_cntr <= "100";
+      else
+        cal_cntr <= std_logic_vector(unsigned(cal_cntr) + to_unsigned(1, 3));
+      end if;
+      cal_cntr_start_sync <= calibration_on;
+      cal_cntr_start      <= cal_cntr_start_sync;
+    end if;
+  end process CalibrationHitGenerate;
+
+  hit_cal           <= and_all(cal_cntr);
+
+  HitSelectRef : process (calibration_on, REFERENCE_TIME, hit_cal) is
+  begin
+    if calibration_on = '0' then
+      hit_in_s(0) <= REFERENCE_TIME;
+    else
+      hit_in_s(0) <= hit_cal;
+    end if;
+  end process HitSelectRef;
+
+  GEN_HitSelect : for i in 1 to CHANNEL_NUMBER-1 generate
+    Double : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 or (DOUBLE_EDGE_TYPE = 2 and (i mod 2 = 1)) generate
+      HitSelect : process (calibration_on, HIT_IN, hit_cal, ch_invert) is
+      begin
+        if calibration_on = '0' then
+          if ch_invert(i) = '0' then
+            hit_in_s(i) <= HIT_IN(i);
+          else
+            hit_in_s(i) <= not HIT_IN(i);
+          end if;
+        else
+          hit_in_s(i) <= hit_cal;
+        end if;
+      end process HitSelect;
+    end generate Double;
+    Single : if DOUBLE_EDGE_TYPE = 2 and (i mod 2 = 0) generate
+      HitSelect : process (calibration_on, HIT_IN, hit_cal, ch_invert) is
+      begin
+        if calibration_on = '0' then
+          if ch_invert(i) = '0' then
+            hit_in_s(i) <= HIT_IN(i);
+          else
+            hit_in_s(i) <= not HIT_IN(i);
+          end if;
+        else
+          hit_in_s(i) <= not hit_cal;
+        end if;
+      end process HitSelect;
+    end generate Single;
+  end generate GEN_HitSelect;
+
+
+-------------------------------------------------------------------------------
+  gen_double_withStretcher : if DOUBLE_EDGE_TYPE = 3 generate
+    The_Stretcher : entity work.Stretcher
+      generic map (
+        CHANNEL => CHANNEL_NUMBER-1,
+        DEPTH   => 4)
+      port map (
+        PULSE_IN  => edge_falling(CHANNEL_NUMBER-1 downto 1),
+        PULSE_OUT => edge_falling_d(CHANNEL_NUMBER-1 downto 1));
+  end generate gen_double_withStretcher;
+
+  gen_double_withoutStretcher : if DOUBLE_EDGE_TYPE = 1 generate
+    edge_falling_d(CHANNEL_NUMBER-1 downto 1) <= edge_falling(CHANNEL_NUMBER-1 downto 1);
+  end generate gen_double_withoutStretcher;
+
+
+  -- Blocks the input after the rising edge against short pulses
+  GEN_HitBlock : for i in 1 to CHANNEL_NUMBER-1 generate
+    gen_double : if DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+      edge_rising(i) <= '0' when edge_rising_3r(i) = '1' else
+                        --edge_rising(i) when hit_edge(i) = '1' else
+                        '1' after 2.5 ns when rising_edge(hit_in_s(i));
+      edge_rising_r(i)  <= edge_rising(i)    when rising_edge(CLK_TDC);
+      edge_rising_2r(i) <= edge_rising_r(i)  when rising_edge(CLK_TDC);
+      edge_rising_3r(i) <= edge_rising_2r(i) when rising_edge(CLK_TDC);
+
+      edge_falling(i) <= '0' when edge_falling_3r(i) = '1' else
+                         --edge_falling(i) when hit_edge(i) = '0' else
+                         '1' after 2 ns when falling_edge(hit_in_s(i));
+      edge_falling_r(i)  <= edge_falling(i)    when rising_edge(CLK_TDC);
+      edge_falling_2r(i) <= edge_falling_r(i)  when rising_edge(CLK_TDC);
+      edge_falling_3r(i) <= edge_falling_2r(i) when rising_edge(CLK_TDC);
+
+      hit_latch(i) <= edge_rising(i) or edge_falling_d(i);
+
+      edge_falling_d_r(i)  <= edge_falling_d(i)    when rising_edge(CLK_TDC);
+      edge_falling_d_2r(i) <= edge_falling_d_r(i)  when rising_edge(CLK_TDC);
+      edge_falling_d_3r(i) <= edge_falling_d_2r(i) when rising_edge(CLK_TDC);
+
+      hit_edge(i) <= '0' when edge_falling_d(i) = '1' or RESET = '1' else
+                     '1' when rising_edge(edge_rising(i));
+      hit_edge_r(i)  <= hit_edge(i)   when rising_edge(CLK_TDC);
+      hit_edge_2r(i) <= hit_edge_r(i) when rising_edge(CLK_TDC);
+    end generate gen_double;
+-------------------------------------------------------------------------------    
+    -- for single edge and double edge in alternating channel setup
+    gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 2 generate
+      edge_rising(i) <= '0' when edge_rising_3r(i) = '1' else
+                        '1' when rising_edge(hit_in_s(i));
+      edge_rising_r(i)  <= edge_rising(i)    when rising_edge(CLK_TDC);
+      edge_rising_2r(i) <= edge_rising_r(i)  when rising_edge(CLK_TDC);
+      edge_rising_3r(i) <= edge_rising_2r(i) when rising_edge(CLK_TDC);
+
+      hit_latch(i)   <= edge_rising(i);
+      hit_edge_2r(i) <= '1';
+    end generate gen_single;
+  end generate GEN_HitBlock;
+
+  GEN_hit_mux : for i in 1 to CHANNEL_NUMBER-1 generate
+    hit_mux_ch : hit_mux
+      port map (
+        CH_EN_IN           => ch_en(i),
+        CALIBRATION_EN_IN  => '0',
+        HIT_CALIBRATION_IN => '0',
+        HIT_PHYSICAL_IN    => hit_latch(i),
+        HIT_OUT            => hit_in_i(i));
+  end generate GEN_hit_mux;
+
+  hit_mux_ref : hit_mux
+    port map (
+      CH_EN_IN           => '1',
+      CALIBRATION_EN_IN  => '0',
+      HIT_CALIBRATION_IN => '0',
+      HIT_PHYSICAL_IN    => hit_in_s(0),
+      HIT_OUT            => hit_in_i(0));
+
+  CalibrationSwitch : process (CLK_READOUT)
+  begin
+    if rising_edge(CLK_READOUT) then
+      if trg_win_end_rdo = '1' then
+        calibration_on <= '0';
+      elsif busreadout_rx.valid_notiming_trg = '1' and busreadout_rx.trg_type = x"D" then
+        calibration_on <= '1';
+      end if;
+    end if;
+  end process CalibrationSwitch;
+
+-------------------------------------------------------------------------------
+-- Channels
+-------------------------------------------------------------------------------
+  -- Reference Channel to measure the reference time
+  ReferenceChannel : Channel
+    generic map (
+      CHANNEL_ID => 0,
+      DEBUG      => DEBUG,
+      SIMULATION => SIMULATION,
+      REFERENCE  => c_YES)
+    port map (
+      RESET_200                 => reset_tdc,
+      RESET_100                 => reset_rdo,
+      RESET_COUNTERS            => reset_counters,
+      CLK_200                   => CLK_TDC,
+      CLK_100                   => CLK_READOUT,
+      HIT_IN                    => hit_in_i(0),
+      HIT_EDGE_IN               => '1',
+      TRG_WIN_END_TDC_IN        => trg_win_end_tdc,
+      TRG_WIN_END_RDO_IN        => trg_win_end_rdo,
+      EPOCH_COUNTER_IN          => epoch_cntr,
+      COARSE_COUNTER_IN         => coarse_cntr(0),
+      READ_EN_IN                => rd_en(0),
+      FIFO_DATA_OUT             => ch_data(0),
+      FIFO_DATA_VALID_OUT       => ch_data_valid(0),
+      FIFO_ALMOST_FULL_OUT      => ch_almost_full(0),
+      FIFO_EMPTY_OUT            => ch_empty(0),
+      RING_BUFFER_FULL_THRES_IN => ring_buffer_full_thres,
+      EPOCH_WRITE_EN_IN         => '1',
+      LOST_HIT_NUMBER           => ch_lost_hit_number(0),
+      HIT_DETECT_NUMBER         => open,  --ch_hit_detect_number(0),
+      ENCODER_START_NUMBER      => ch_encoder_start_number(0),
+      ENCODER_FINISHED_NUMBER   => ch_encoder_finished_number(0),
+      FIFO_WRITE_NUMBER         => ch_fifo_write_number(0),
+      Channel_200_DEBUG_OUT     => ch_200_debug(0),
+      Channel_DEBUG_OUT         => ch_debug(0));
+
+  -- TDC Channels
+  GEN_Channels : for i in 1 to CHANNEL_NUMBER-1 generate
+    Channels : Channel
+      generic map (
+        CHANNEL_ID => i,
+        DEBUG      => DEBUG,
+        SIMULATION => SIMULATION,
+        REFERENCE  => c_NO)
+      port map (
+        RESET_200                 => reset_tdc,
+        RESET_100                 => reset_rdo,
+        RESET_COUNTERS            => reset_counters,
+        CLK_200                   => CLK_TDC,
+        CLK_100                   => CLK_READOUT,
+        HIT_IN                    => hit_in_i(i),
+        HIT_EDGE_IN               => hit_edge_2r(i),
+        TRG_WIN_END_TDC_IN        => trg_win_end_tdc,
+        TRG_WIN_END_RDO_IN        => trg_win_end_rdo,
+        EPOCH_COUNTER_IN          => epoch_cntr,
+        COARSE_COUNTER_IN         => coarse_cntr(i),  -- coarse_cntr(integer(ceil(real(i)/real(8)))),
+        READ_EN_IN                => rd_en(i),
+        FIFO_DATA_OUT             => ch_data(i),
+        FIFO_DATA_VALID_OUT       => ch_data_valid(i),
+        FIFO_ALMOST_FULL_OUT      => ch_almost_full(i),
+        FIFO_EMPTY_OUT            => ch_empty(i),
+        RING_BUFFER_FULL_THRES_IN => ring_buffer_full_thres,
+        EPOCH_WRITE_EN_IN         => '1',
+        LOST_HIT_NUMBER           => ch_lost_hit_number(i),
+        HIT_DETECT_NUMBER         => open,  --ch_hit_detect_number(i),
+        ENCODER_START_NUMBER      => ch_encoder_start_number(i),
+        ENCODER_FINISHED_NUMBER   => ch_encoder_finished_number(i),
+        FIFO_WRITE_NUMBER         => ch_fifo_write_number(i),
+        Channel_200_DEBUG_OUT     => ch_200_debug(i),
+        Channel_DEBUG_OUT         => ch_debug(i));
+  end generate GEN_Channels;
+  ch_data(CHANNEL_NUMBER) <= (others => '1');
+
+-------------------------------------------------------------------------------
+-- Trigger
+-------------------------------------------------------------------------------
+  -- Valid Trigger Sync
+  ValidTriggerPulseSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_READOUT,
+      RESET_A_IN  => reset_rdo,
+      PULSE_A_IN  => valid_trg_rdo,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => reset_tdc,
+      PULSE_B_OUT => valid_trg_tdc);
+  valid_trg_rdo <= busreadout_rx.valid_notiming_trg or busreadout_rx.valid_timing_trg;
+
+  -- Timing Trigger handler
+  TheTriggerHandler : TriggerHandler
+    generic map (
+      TRIGGER_NUM            => 1,
+      PHYSICAL_EVENT_TRG_NUM => 0)
+    port map (
+      CLK_TRG               => CLK_READOUT,
+      CLK_RDO               => CLK_READOUT,
+      CLK_TDC               => CLK_TDC,
+      RESET_TRG             => reset_rdo,
+      RESET_RDO             => reset_rdo,
+      RESET_TDC             => reset_tdc,
+      VALID_TIMING_TRG_IN   => busreadout_rx.valid_timing_trg,
+      VALID_NOTIMING_TRG_IN => busreadout_rx.valid_notiming_trg,
+      TRG_TYPE_IN           => busreadout_rx.trg_type,
+      TRG_RELEASE_IN        => busreadout_tx.busy_release,
+      TRG_IN(0)             => trg_in,
+      TRG_RDO_OUT(0)        => trg_rdo,
+      TRG_TDC_OUT(0)        => trg_tdc,
+      TRG_WIN_EN_IN         => trg_win_en,
+      TRG_WIN_POST_IN       => unsigned(trg_win_post),
+      TRG_WIN_END_RDO_OUT   => trg_win_end_rdo,
+      TRG_WIN_END_TDC_OUT   => trg_win_end_tdc,
+      MISSING_REF_TIME_OUT  => missing_ref_time,
+      COARSE_COUNTER_IN     => coarse_cntr(CHANNEL_NUMBER),
+      EPOCH_COUNTER_IN      => epoch_cntr,
+      TRG_TIME_OUT          => trg_time,
+      DEBUG_OUT             => trg_handler_status_registers
+      );
+  trg_in <= REFERENCE_TIME;
+
+-------------------------------------------------------------------------------
+-- Readout
+-------------------------------------------------------------------------------
+  TheReadout : Readout_record
+    generic map (
+      CHANNEL_NUMBER => CHANNEL_NUMBER,
+      STATUS_REG_NR  => STATUS_REG_NR)
+    port map (
+      RESET_100           => reset_rdo,
+      RESET_200           => reset_tdc,
+      RESET_COUNTERS      => reset_counters,
+      CLK_100             => CLK_READOUT,
+      CLK_200             => CLK_TDC,
+      HIT_IN              => edge_rising_100(CHANNEL_NUMBER-1 downto 1),
+      -- from the channels
+      CH_DATA_IN          => ch_data,
+      CH_DATA_VALID_IN    => ch_data_valid,
+      CH_ALMOST_FULL_IN   => ch_almost_full,
+      CH_EMPTY_IN         => ch_empty,
+      -- endpoint bus
+      READOUT_RX          => busreadout_rx,
+      READOUT_TX          => busreadout_tx,
+      -- to the channels
+      READ_EN_OUT         => rd_en,
+      -- trigger window settings
+      TRG_WIN_PRE_IN      => trg_win_pre,
+      TRG_WIN_POST_IN     => trg_win_post,
+      TRG_WIN_EN_IN       => trg_win_en,
+      -- from the trigger handler
+      TRG_WIN_END_TDC_IN  => trg_win_end_tdc,
+      TRG_WIN_END_RDO_IN  => trg_win_end_rdo,
+      TRG_TDC_IN          => trg_tdc,
+      TRG_TIME_IN         => trg_time,
+      MISSING_REF_TIME_IN => missing_ref_time,
+      -- miscellaneous
+      LIGHT_MODE_IN       => light_mode_en,
+      DEBUG_MODE_EN_IN    => debug_mode_en,
+      INFO_IN             => INFO_IN,
+      STATISTICS_OUT      => readout_statistics,
+      READOUT_DEBUG       => readout_debug
+      );
+
+-------------------------------------------------------------------------------
+-- Coarse & Epoch Counters
+-------------------------------------------------------------------------------
+-- Coarse counter
+  GenCoarseCounter : for i in 0 to CHANNEL_NUMBER generate
+    TheCoarseCounter : up_counter
+      generic map (
+        NUMBER_OF_BITS => 11)
+      port map (
+        CLK       => CLK_TDC,
+        RESET     => coarse_cntr_reset,
+        COUNT_OUT => coarse_cntr(i),
+        UP_IN     => '1');
+  end generate GenCoarseCounter;
+
+  Coarse_Counter_Reset : process (CLK_TDC)
+  begin
+    if rising_edge(CLK_TDC) then
+      if reset_tdc = '1' then
+        coarse_cntr_reset <= '1';
+      --elsif run_mode_200 = '0' then
+      --  coarse_cntr_reset <= trg_win_end_tdc;
+      --elsif run_mode_edge_200 = '1' then
+      --  coarse_cntr_reset <= '1';
+      elsif reset_coarse_cntr_flag = '1' and valid_trg_tdc = '1' then
+        coarse_cntr_reset <= '1';
+      else
+        coarse_cntr_reset <= '0';
+      end if;
+      if reset_coarse_cntr_edge_200 = '1' then
+        reset_coarse_cntr_flag <= '1';
+      elsif valid_trg_tdc = '1' then
+        reset_coarse_cntr_flag <= '0';
+      end if;
+    end if;
+  end process Coarse_Counter_Reset;
+
+  --Run_Mode_Edge_Detect : risingEdgeDetect
+  --  port map (
+  --    CLK       => CLK_TDC,
+  --    SIGNAL_IN => run_mode_200,
+  --    PULSE_OUT => run_mode_edge_200);
+
+  Reset_Coarse_Counter_Edge_Detect : risingEdgeDetect
+    port map (
+      CLK       => CLK_TDC,
+      SIGNAL_IN => reset_coarse_cntr_200,
+      PULSE_OUT => reset_coarse_cntr_edge_200);
+
+-- EPOCH counter
+  TheEpochCounter : up_counter
+    generic map (
+      NUMBER_OF_BITS => 28)
+    port map (
+      CLK       => CLK_TDC,
+      RESET     => epoch_cntr_reset,
+      COUNT_OUT => epoch_cntr,
+      UP_IN     => epoch_cntr_up);
+  epoch_cntr_up    <= and_all(coarse_cntr(CHANNEL_NUMBER));
+  epoch_cntr_reset <= coarse_cntr_reset;
+
+-------------------------------------------------------------------------------
+-- Statistics
+-------------------------------------------------------------------------------
+-- Hit Counters
+  GenHitCounter : for i in 0 to CHANNEL_NUMBER-1 generate
+    edge_rising_100(i) <= '0' when edge_rising_100_3r(i) = '1' else
+                          '1' when rising_edge(hit_in_s(i));
+    edge_rising_100_r(i)  <= edge_rising_100(i)                                 when rising_edge(CLK_READOUT);
+    edge_rising_100_2r(i) <= edge_rising_100_r(i)                               when rising_edge(CLK_READOUT);
+    edge_rising_100_3r(i) <= edge_rising_100_r(i) and not edge_rising_100_2r(i) when rising_edge(CLK_READOUT);
+
+    --purpose: Counts the detected hits
+    Hit_Detect_Counter : process (CLK_READOUT)
+    begin
+      if rising_edge(CLK_READOUT) then
+        if RESET_COUNTERS = '1' then
+          ch_hit_detect_cntr(i) <= (others => '0');
+        elsif edge_rising_100_3r(i) = '1' then
+          ch_hit_detect_cntr(i) <= ch_hit_detect_cntr(i) + to_unsigned(1, 31);
+        end if;
+      end if;
+    end process Hit_Detect_Counter;
+  end generate GenHitCounter;
+
+-------------------------------------------------------------------------------
+-- Slow Control Data Busses
+-------------------------------------------------------------------------------
+-- Hit counter
+  TheHitCounterBus : entity work.BusHandler_record
+    generic map (
+      BUS_LENGTH => CHANNEL_NUMBER-1)
+    port map (
+      RESET    => reset_rdo,
+      CLK      => CLK_READOUT,
+      BUS_RX   => bushit_rx,
+      BUS_TX   => bushit_tx,
+      DATA_IN  => ch_level_hit_number,
+      DATA_OUT => open);
+
+  ch_level_hit_number(0)(31)          <= ref_in_reg                          when rising_edge(CLK_READOUT);
+  ch_level_hit_number(0)(30 downto 0) <= std_logic_vector(ch_hit_detect_cntr(0)) when rising_edge(CLK_READOUT);
+  GenHitDetectNumber : for i in 1 to CHANNEL_NUMBER-1 generate
+    ch_level_hit_number(i)(31)          <= hit_in_reg(i)                               when rising_edge(CLK_READOUT);
+    ch_level_hit_number(i)(30 downto 0) <= std_logic_vector(ch_hit_detect_cntr(i)) when rising_edge(CLK_READOUT);
+  end generate GenHitDetectNumber;
+
+  hit_in_reg <= HIT_IN         when rising_edge(CLK_READOUT);
+  ref_in_reg <= REFERENCE_TIME when rising_edge(CLK_READOUT);
+  
+  
+-- Status register
+  TheStatusRegisterBus : entity work.BusHandler_record
+    generic map (
+      BUS_LENGTH => STATUS_REG_NR-1)
+    port map (
+      RESET    => reset_rdo,
+      CLK      => CLK_READOUT,
+      BUS_RX   => busstat_rx,
+      BUS_TX   => busstat_tx,
+      DATA_IN  => status_registers_bus,
+      DATA_OUT => open);
+
+  -- basic info
+  status_registers_bus(0)(3 downto 0)   <= readout_debug(3 downto 0);  -- rd_fsm
+  status_registers_bus(0)(7 downto 4)   <= readout_debug(7 downto 4);  -- wr_fsm
+  status_registers_bus(0)(15 downto 8)  <= std_logic_vector(to_unsigned(CHANNEL_NUMBER-1, 8));
+  status_registers_bus(0)(16)           <= REFERENCE_TIME         when rising_edge(CLK_READOUT);
+  status_registers_bus(0)(27 downto 17) <= TDC_VERSION(10 downto 0);
+  status_registers_bus(0)(31 downto 28) <= busreadout_rx.trg_type when rising_edge(CLK_READOUT);
+
+  -- debug info
+  status_registers_bus(1)(3 downto 0) <= trg_handler_status_registers(23 downto 20);
+  status_registers_bus(2)             <= trg_time(31 downto 0) when (trg_rdo = '1' and rising_edge(CLK_READOUT));
+
+  -- trigger window
+  status_registers_bus(3)(10 downto 0)  <= trg_win_pre;
+  status_registers_bus(3)(15 downto 11) <= (others => '0');
+  status_registers_bus(3)(26 downto 16) <= trg_win_post;
+  status_registers_bus(3)(30 downto 27) <= (others => '0');
+  status_registers_bus(3)(31)           <= trg_win_en;
+
+  -- statistics
+  status_registers_bus(4)(23 downto 0)  <= readout_statistics(0);
+  status_registers_bus(5)(23 downto 0)  <= readout_statistics(1);
+  status_registers_bus(6)(23 downto 0)  <= readout_statistics(2);
+  status_registers_bus(7)(23 downto 0)  <= readout_statistics(3);
+  status_registers_bus(8)(23 downto 0)  <= readout_statistics(4);
+  status_registers_bus(9)(23 downto 0)  <= readout_statistics(5);
+  status_registers_bus(10)(23 downto 0) <= readout_statistics(6);
+  status_registers_bus(11)(23 downto 0) <= readout_statistics(7);
+  status_registers_bus(12)(23 downto 0) <= readout_statistics(8);
+  status_registers_bus(13)(23 downto 0) <= readout_statistics(9);
+  status_registers_bus(14)(23 downto 0) <= readout_statistics(10);
+  status_registers_bus(15)(23 downto 0) <= readout_statistics(11);
+  status_registers_bus(16)(23 downto 0) <= readout_statistics(12);
+  status_registers_bus(17)(23 downto 0) <= readout_statistics(13);
+  status_registers_bus(18)(23 downto 0) <= readout_statistics(14);
+
+-- Channel debug
+  TheChannelDebugBus : entity work.BusHandler_record
+    generic map (
+      BUS_LENGTH => CHANNEL_NUMBER-1)
+    port map (
+      RESET    => reset_rdo,
+      CLK      => CLK_READOUT,
+      BUS_RX   => buschdebug_rx,
+      BUS_TX   => buschdebug_tx,
+      DATA_IN  => buschdebug_data_in,
+      DATA_OUT => open);
+
+  buschdebug_data_in(0) <= ch_200_debug(0);
+  GEN_BUSCHDEBUG : for i in 1 to CHANNEL_NUMBER-1 generate
+    buschdebug_data_in(i) <= ch_200_debug(i)(31 downto 2) & edge_rising_2r(i) & ch_200_debug(i)(0);
+  end generate GEN_BUSCHDEBUG;
+
+
+-------------------------------------------------------------------------------
+-- Debug
+-------------------------------------------------------------------------------
+-- Logic Analyser
+  --TheLogicAnalyser : LogicAnalyser
+  --  generic map (
+  --    CHANNEL_NUMBER => CHANNEL_NUMBER)
+  --  port map (
+  --    CLK        => CLK_READOUT,
+  --    RESET      => reset_rdo,
+  --    DATA_IN    => logic_anal_data,
+  --    CONTROL_IN => logic_anal_control,
+  --    DATA_OUT   => LOGIC_ANALYSER_OUT);
+
+  --logic_anal_data(7 downto 0)   <= readout_debug(7 downto 0);
+  --logic_anal_data(8)            <= REFERENCE_TIME;
+  --logic_anal_data(9)            <= READOUT_RX.valid_timing_trg;
+  --logic_anal_data(10)           <= READOUT_RX.valid_notiming_trg;
+  --logic_anal_data(11)           <= READOUT_RX.invalid_trg;
+  --logic_anal_data(12)           <= READOUT_RX.data_valid;
+  --logic_anal_data(13)           <= readout_debug(8);   --data_wr_r;
+  --logic_anal_data(14)           <= readout_debug(9);   --data_finished_r;
+  --logic_anal_data(15)           <= readout_debug(10);  --trg_release_r;
+  --logic_anal_data(31 downto 16) <= (others => '0');
+  --logic_anal_data(37 downto 32) <= readout_debug(16 downto 11);  --data_out_r(27 downto 22);
+  --logic_anal_data(47 downto 38) <= (others => '0');
+  --logic_anal_data(63 downto 48) <= ch_debug(1)(15 downto 0);
+  --logic_anal_data(95 downto 64) <= (others => '0');
+
+  --LOGIC_ANALYSER_OUT(0) <= REFERENCE_TIME;  -- 0  19
+  --LOGIC_ANALYSER_OUT(1) <= hit_in_s(0);     -- 1  18
+  --LOGIC_ANALYSER_OUT(2) <= hit_in_i(0);     -- 2  17
+  --LOGIC_ANALYSER_OUT(3)  <= edge_falling(1);  -- 3  16
+  --LOGIC_ANALYSER_OUT(4)  <= HIT_IN(1);        -- 4  15
+  --LOGIC_ANALYSER_OUT(5)  <= HIT_IN(2);        -- 5  14
+  --LOGIC_ANALYSER_OUT(6)  <= HIT_IN(3);        -- 6  13
+  --LOGIC_ANALYSER_OUT(7)  <= HIT_IN(4);        -- 7  12
+  --LOGIC_ANALYSER_OUT(8)  <= hit_in_i(1);      -- 8  11
+  --LOGIC_ANALYSER_OUT(9)  <= hit_in_i(2);      -- 9  10
+  --LOGIC_ANALYSER_OUT(10) <= hit_in_i(3);      -- 10 9
+  --LOGIC_ANALYSER_OUT(11) <= hit_in_i(4);      -- 11 8
+  --LOGIC_ANALYSER_OUT(12) <= hit_edge(1);      -- 12 7
+  --LOGIC_ANALYSER_OUT(13) <= hit_latch(1);     -- 13 6
+  --LOGIC_ANALYSER_OUT(14) <= hit_in_i(1);      -- 14 5
+  --LOGIC_ANALYSER_OUT(13) <= hit_in_i(1);
+  --LOGIC_ANALYSER_OUT(14) <= hit_in_i(1);
+  --LOGIC_ANALYSER_OUT(15) <= hit_in_i(1);
+
+
+end TDC_record;
diff --git a/releases/tdc_v2.3.1/TriggerHandler.vhd b/releases/tdc_v2.3.1/TriggerHandler.vhd
new file mode 100644 (file)
index 0000000..7ea901f
--- /dev/null
@@ -0,0 +1,319 @@
+-------------------------------------------------------------------------------
+-- Title      : TriggerHandler
+-------------------------------------------------------------------------------
+-- File       : TriggerHandler.vhd
+-- Author     : Cahit Ugur  c.ugur@gsi.de
+-- Created    : 2013-03-13
+-- Last update: 2015-12-10
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+
+entity TriggerHandler is
+  generic (
+    TRIGGER_NUM            : integer := 2;   -- number of trigger signals sent
+    PHYSICAL_EVENT_TRG_NUM : integer := 0);  -- physical event trigger input number for the trigger window calculations
+  port (
+    CLK_TRG               : in  std_logic;   -- trigger clock domain
+    CLK_RDO               : in  std_logic;   -- readout clock domain
+    CLK_TDC               : in  std_logic;   -- tdc clock domain
+    RESET_TRG             : in  std_logic;
+    RESET_RDO             : in  std_logic;
+    RESET_TDC             : in  std_logic;
+    VALID_TIMING_TRG_IN   : in  std_logic;
+    VALID_NOTIMING_TRG_IN : in  std_logic;
+    TRG_TYPE_IN           : in  std_logic_vector(3 downto 0);
+    TRG_RELEASE_IN        : in  std_logic;
+    TRG_IN                : in  std_logic_vector(TRIGGER_NUM-1 downto 0);
+    TRG_RDO_OUT           : out std_logic_vector(TRIGGER_NUM-1 downto 0);
+    TRG_TDC_OUT           : out std_logic_vector(TRIGGER_NUM-1 downto 0);
+    TRG_WIN_EN_IN         : in  std_logic;
+    TRG_WIN_POST_IN       : in  unsigned(10 downto 0);
+    TRG_WIN_END_RDO_OUT   : out std_logic;
+    TRG_WIN_END_TDC_OUT   : out std_logic;
+    MISSING_REF_TIME_OUT  : out std_logic;
+    COARSE_COUNTER_IN     : in  std_logic_vector(10 downto 0);
+    EPOCH_COUNTER_IN      : in  std_logic_vector(27 downto 0);
+    TRG_TIME_OUT          : out std_logic_vector(38 downto 0) := (others => '0');
+    DEBUG_OUT             : out std_logic_vector(31 downto 0)
+    );
+
+end entity TriggerHandler;
+
+architecture behavioral of TriggerHandler is
+  -- Placer Directives
+  attribute HGROUP               : string;
+  -- for whole architecture
+  attribute HGROUP of Behavioral : architecture is "TriggerHandler_group";
+
+  -- trigger signals
+  signal trg_in_r           : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_in_2r          : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_in_3r          : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_pulse_trg      : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_pulse_rdo      : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_pulse_tdc      : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_length         : unsigned_array_5(TRIGGER_NUM-1 downto 0);
+  signal trg_release_200    : std_logic;
+  signal valid_timing_200   : std_logic;
+  signal valid_notiming_200 : std_logic;
+  signal valid_trigger_flag : std_logic := '0';
+  -- trigger window signals
+  type TrgWinCounter_FSM is (IDLE, COUNT, COUNT_CALIBRATION, VALIDATE_TRIGGER, WIN_END,
+                             MISSING_REFERENCE_TIME, WAIT_NEXT_TRIGGER);
+  signal STATE_TW_CURRENT      : TrgWinCounter_FSM;
+  signal STATE_TW_NEXT         : TrgWinCounter_FSM;
+  signal trg_win_cnt_f         : unsigned(11 downto 0);
+  signal trg_win_cnt           : unsigned(11 downto 0);
+  signal trg_win_end_f         : std_logic;
+  signal trg_win_end_tdc       : std_logic;
+  signal trg_win_end_rdo       : std_logic;
+  signal missing_ref_time_f    : std_logic;
+  signal missing_ref_time_tdc  : std_logic;
+  signal missing_ref_time_rdo  : std_logic;
+  signal trg_time              : std_logic_vector(38 downto 0) := (others => '0');
+  signal trg_win_state_debug_f : std_logic_vector(3 downto 0);
+
+
+begin  -- architecture behavioral
+
+  -- the trigger signals have to be synced
+  trg_in_r  <= TRG_IN    when rising_edge(CLK_TDC);
+  trg_in_2r <= trg_in_r  when rising_edge(CLK_TDC);
+  trg_in_3r <= trg_in_2r when rising_edge(CLK_TDC);
+
+  GEN_TRIGGER : for i in 0 to TRIGGER_NUM-1 generate
+    Validation : process (CLK_TDC)
+    begin
+      if rising_edge(CLK_TDC) then
+
+        -- calculate trigger length
+        if trg_in_3r(i) = '0' then
+          trg_length(i) <= (others => '0');
+        else
+          trg_length(i) <= trg_length(i) + to_unsigned(1, 5);
+        end if;
+
+        -- accept trigger if it is longer than 100 ns
+        if RESET_TDC = '1' then
+          trg_pulse_tdc(i) <= '0';
+        elsif trg_length(i) = to_unsigned(20, 5) then
+          trg_pulse_tdc(i) <= '1';
+        else
+          trg_pulse_tdc(i) <= '0';
+        end if;
+
+      end if;
+    end process Validation;
+  end generate GEN_TRIGGER;
+
+  -- sync the strobes to the readout clock domain
+  GEN_TDC : for i in 0 to TRIGGER_NUM-1 generate
+    ThePulseSync : pulse_sync
+      port map (
+        CLK_A_IN    => CLK_TDC,
+        RESET_A_IN  => RESET_TDC,
+        PULSE_A_IN  => trg_pulse_tdc(i),
+        CLK_B_IN    => CLK_RDO,
+        RESET_B_IN  => RESET_RDO,
+        PULSE_B_OUT => trg_pulse_rdo(i));
+  end generate GEN_TDC;
+
+  TRG_RDO_OUT <= trg_pulse_rdo when rising_edge(CLK_RDO);
+  TRG_TDC_OUT <= trg_pulse_tdc when rising_edge(CLK_TDC);
+
+  ValidateTrigger : process (CLK_TDC) is
+  begin
+    if rising_edge(CLK_TDC) then        -- rising clock edge
+      if RESET_TDC = '1' then
+        valid_trigger_flag <= '0';
+      elsif valid_timing_200 = '1' then
+        valid_trigger_flag <= '1';
+      elsif trg_release_200 = '1' then
+        valid_trigger_flag <= '0';
+      end if;
+    end if;
+  end process ValidateTrigger;
+
+  TriggerReleaseSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_RDO,
+      RESET_A_IN  => RESET_RDO,
+      PULSE_A_IN  => TRG_RELEASE_IN,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => RESET_TDC,
+      PULSE_B_OUT => trg_release_200);
+
+  ValidTriggerSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_RDO,
+      RESET_A_IN  => RESET_RDO,
+      PULSE_A_IN  => VALID_TIMING_TRG_IN,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => RESET_TDC,
+      PULSE_B_OUT => valid_timing_200);
+
+  ValidNoTriggerSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_RDO,
+      RESET_A_IN  => RESET_RDO,
+      PULSE_A_IN  => VALID_NOTIMING_TRG_IN,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => RESET_TDC,
+      PULSE_B_OUT => valid_notiming_200);
+
+-------------------------------------------------------------------------------
+-- Trigger Window State Machine
+-------------------------------------------------------------------------------
+  FSM_TRIGGER_WINDOW_SEQUENTIAL : process (CLK_TDC) is
+  begin
+    -- Outputs to be registered
+    if rising_edge(CLK_TDC) then        -- rising clock edge
+      if RESET_TDC = '1' then
+        STATE_TW_CURRENT <= IDLE;
+      else
+        STATE_TW_CURRENT     <= STATE_TW_NEXT;
+        trg_win_cnt          <= trg_win_cnt_f;
+        trg_win_end_tdc      <= trg_win_end_f;
+        missing_ref_time_tdc <= missing_ref_time_f;
+      end if;
+    end if;
+  -- Outputs not to be registered
+  end process FSM_TRIGGER_WINDOW_SEQUENTIAL;
+  DEBUG_OUT(19 downto 0)  <= (others => '0');
+  DEBUG_OUT(23 downto 20) <= trg_win_state_debug_f when rising_edge(CLK_RDO);
+  DEBUG_OUT(31 downto 24) <= (others => '0');
+
+  FSM_TRIGGER_WINDOW_COMBINATIONAL : process (STATE_TW_CURRENT, trg_in_3r, TRG_WIN_EN_IN,
+                                              valid_notiming_200, TRG_TYPE_IN, trg_win_cnt,
+                                              TRG_WIN_POST_IN, valid_trigger_flag, trg_release_200) is
+  begin
+    -- Default values
+    STATE_TW_NEXT         <= STATE_TW_CURRENT;
+    trg_win_cnt_f         <= x"00a";
+    trg_win_end_f         <= '0';
+    missing_ref_time_f    <= '0';
+    trg_win_state_debug_f <= x"0";
+
+    case STATE_TW_CURRENT is
+      when IDLE =>
+        if trg_in_3r(0) = '1' then
+          if TRG_WIN_EN_IN = '1' then
+            STATE_TW_NEXT <= COUNT;
+          else
+            STATE_TW_NEXT <= VALIDATE_TRIGGER;
+          end if;
+        elsif valid_notiming_200 = '1' then
+          if TRG_TYPE_IN = x"D" then
+            STATE_TW_NEXT <= COUNT_CALIBRATION;
+          else
+            STATE_TW_NEXT <= WAIT_NEXT_TRIGGER;
+          end if;
+        elsif valid_timing_200 = '1' then
+          STATE_TW_NEXT <= MISSING_REFERENCE_TIME;
+        else
+          STATE_TW_NEXT <= IDLE;
+        end if;
+        trg_win_state_debug_f <= x"1";
+
+      when COUNT =>
+        if trg_win_cnt(10 downto 0) = TRG_WIN_POST_IN then
+          STATE_TW_NEXT <= VALIDATE_TRIGGER;
+        else
+          STATE_TW_NEXT <= COUNT;
+        end if;
+        trg_win_cnt_f         <= trg_win_cnt + to_unsigned(1, 12);
+        trg_win_state_debug_f <= x"3";
+
+      when COUNT_CALIBRATION =>
+        if trg_win_cnt(6) = '1' then
+          STATE_TW_NEXT <= WIN_END;
+        else
+          STATE_TW_NEXT <= COUNT_CALIBRATION;
+        end if;
+        trg_win_cnt_f         <= trg_win_cnt + to_unsigned(1, 12);
+        trg_win_state_debug_f <= x"4";
+
+      when VALIDATE_TRIGGER =>
+        if valid_trigger_flag = '1' then
+          STATE_TW_NEXT <= WIN_END;
+        else
+          STATE_TW_NEXT <= VALIDATE_TRIGGER;
+        end if;
+        trg_win_end_f         <= '0';
+        trg_win_state_debug_f <= x"5";
+
+      when WIN_END =>
+        STATE_TW_NEXT         <= WAIT_NEXT_TRIGGER;
+        trg_win_end_f         <= '1';
+        trg_win_state_debug_f <= x"6";
+
+      when MISSING_REFERENCE_TIME =>
+        STATE_TW_NEXT         <= WAIT_NEXT_TRIGGER;
+        trg_win_end_f         <= '1';
+        missing_ref_time_f    <= '1';
+        trg_win_state_debug_f <= x"7";
+
+      when WAIT_NEXT_TRIGGER =>
+        if trg_release_200 = '1' then
+          STATE_TW_NEXT <= IDLE;
+        else
+          STATE_TW_NEXT <= WAIT_NEXT_TRIGGER;
+        end if;
+        trg_win_end_f         <= '0';
+        trg_win_state_debug_f <= x"8";
+
+      when others =>
+        STATE_TW_NEXT         <= IDLE;
+        trg_win_state_debug_f <= x"0";
+    end case;
+  end process FSM_TRIGGER_WINDOW_COMBINATIONAL;
+
+  -- syn trg window end strobe to readout clock domain
+  TrgWinEndPulseSync : pulse_sync
+    port map (
+      CLK_A_IN    => CLK_TDC,
+      RESET_A_IN  => RESET_TDC,
+      PULSE_A_IN  => trg_win_end_tdc,
+      CLK_B_IN    => CLK_RDO,
+      RESET_B_IN  => RESET_RDO,
+      PULSE_B_OUT => trg_win_end_rdo);
+
+  TRG_WIN_END_TDC_OUT <= trg_win_end_tdc;
+  TRG_WIN_END_RDO_OUT <= trg_win_end_rdo;
+
+  -- syn missing reference time strobe to readout clock domain
+  MissRefTimePulseSync : pulse_sync
+    port map (
+      CLK_A_IN    => CLK_TDC,
+      RESET_A_IN  => RESET_TDC,
+      PULSE_A_IN  => missing_ref_time_tdc,
+      CLK_B_IN    => CLK_RDO,
+      RESET_B_IN  => RESET_RDO,
+      PULSE_B_OUT => missing_ref_time_rdo);
+
+  MISSING_REF_TIME_OUT <= missing_ref_time_rdo;
+
+  TriggerTime : process (CLK_TDC)
+  begin
+    if rising_edge(CLK_TDC) then
+      if trg_in_2r(0) = '1' and trg_in_3r(0) = '0' then
+        trg_time <= EPOCH_COUNTER_IN & COARSE_COUNTER_IN;
+      end if;
+      if trg_pulse_tdc(0) = '1' then
+        TRG_TIME_OUT <= trg_time;  --std_logic_vector(unsigned(trg_time) - to_unsigned(2, 39));
+      end if;
+    end if;
+  end process TriggerTime;
+
+
+end architecture behavioral;
diff --git a/releases/tdc_v2.3.1/TriggerHandler_noDecode.vhd b/releases/tdc_v2.3.1/TriggerHandler_noDecode.vhd
new file mode 100644 (file)
index 0000000..2c3a00e
--- /dev/null
@@ -0,0 +1,320 @@
+-------------------------------------------------------------------------------
+-- Title      : TriggerHandler
+-------------------------------------------------------------------------------
+-- File       : TriggerHandler.vhd
+-- Author     : Cahit Ugur  c.ugur@gsi.de
+-- Created    : 2013-03-13
+-- Last update: 2016-03-07
+-------------------------------------------------------------------------------
+-- Description: 
+-------------------------------------------------------------------------------
+
+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+
+entity TriggerHandler is
+  generic (
+    TRIGGER_NUM            : integer := 2;   -- number of trigger signals sent
+    PHYSICAL_EVENT_TRG_NUM : integer := 0);  -- physical event trigger input number for the trigger window calculations
+  port (
+    CLK_TRG               : in  std_logic;   -- trigger clock domain
+    CLK_RDO               : in  std_logic;   -- readout clock domain
+    CLK_TDC               : in  std_logic;   -- tdc clock domain
+    RESET_TRG             : in  std_logic;
+    RESET_RDO             : in  std_logic;
+    RESET_TDC             : in  std_logic;
+    VALID_TIMING_TRG_IN   : in  std_logic;
+    VALID_NOTIMING_TRG_IN : in  std_logic;
+    TRG_TYPE_IN           : in  std_logic_vector(3 downto 0);
+    TRG_RELEASE_IN        : in  std_logic;
+    TRG_IN                : in  std_logic_vector(TRIGGER_NUM-1 downto 0);
+    TRG_RDO_OUT           : out std_logic_vector(TRIGGER_NUM-1 downto 0);
+    TRG_TDC_OUT           : out std_logic_vector(TRIGGER_NUM-1 downto 0);
+    TRG_WIN_EN_IN         : in  std_logic;
+    TRG_WIN_POST_IN       : in  unsigned(10 downto 0);
+    TRG_WIN_END_RDO_OUT   : out std_logic;
+    TRG_WIN_END_TDC_OUT   : out std_logic;
+    MISSING_REF_TIME_OUT  : out std_logic;
+    COARSE_COUNTER_IN     : in  std_logic_vector(10 downto 0);
+    EPOCH_COUNTER_IN      : in  std_logic_vector(27 downto 0);
+    TRG_TIME_OUT          : out std_logic_vector(38 downto 0) := (others => '0');
+    DEBUG_OUT             : out std_logic_vector(31 downto 0)
+    );
+
+end entity TriggerHandler;
+
+architecture behavioral of TriggerHandler is
+  -- Placer Directives
+  attribute HGROUP               : string;
+  -- for whole architecture
+  attribute HGROUP of Behavioral : architecture is "TriggerHandler_group";
+
+  -- trigger signals
+  signal trg_in_r           : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_in_2r          : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_in_3r          : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_pulse_trg      : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_pulse_rdo      : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_pulse_tdc      : std_logic_vector(TRIGGER_NUM-1 downto 0);
+  signal trg_length         : unsigned_array_5(TRIGGER_NUM-1 downto 0);
+  signal trg_release_200    : std_logic;
+  signal valid_timing_200   : std_logic;
+  signal valid_notiming_200 : std_logic;
+  signal valid_trigger_flag : std_logic := '0';
+  -- trigger window signals
+  type TrgWinCounter_FSM is (IDLE, COUNT, COUNT_CALIBRATION, VALIDATE_TRIGGER, WIN_END,
+                             MISSING_REFERENCE_TIME, WAIT_NEXT_TRIGGER);
+  signal STATE_TW_CURRENT      : TrgWinCounter_FSM;
+  signal STATE_TW_NEXT         : TrgWinCounter_FSM;
+  signal trg_win_cnt_f         : unsigned(11 downto 0);
+  signal trg_win_cnt           : unsigned(11 downto 0);
+  signal trg_win_end_f         : std_logic;
+  signal trg_win_end_tdc       : std_logic;
+  signal trg_win_end_rdo       : std_logic;
+  signal missing_ref_time_f    : std_logic;
+  signal missing_ref_time_tdc  : std_logic;
+  signal missing_ref_time_rdo  : std_logic;
+  signal trg_time              : std_logic_vector(38 downto 0) := (others => '0');
+  signal trg_win_state_debug_f : std_logic_vector(3 downto 0);
+
+
+begin  -- architecture behavioral
+
+  -- the trigger signals have to be synced
+  trg_in_r  <= TRG_IN    when rising_edge(CLK_TDC);
+  trg_in_2r <= trg_in_r  when rising_edge(CLK_TDC);
+  trg_in_3r <= trg_in_2r when rising_edge(CLK_TDC);
+
+  GEN_TRIGGER : for i in 0 to TRIGGER_NUM-1 generate
+    Validation : process (CLK_TDC)
+    begin
+      if rising_edge(CLK_TDC) then
+
+        -- calculate trigger length
+        if trg_in_3r(i) = '0' then
+          trg_length(i) <= (others => '0');
+        else
+          trg_length(i) <= trg_length(i) + to_unsigned(1, 5);
+        end if;
+
+        -- accept trigger if it is longer than 100 ns
+        if RESET_TDC = '1' then
+          trg_pulse_tdc(i) <= '0';
+        elsif trg_length(i) = to_unsigned(20, 5) then
+          trg_pulse_tdc(i) <= '1';
+        else
+          trg_pulse_tdc(i) <= '0';
+        end if;
+
+      end if;
+    end process Validation;
+  end generate GEN_TRIGGER;
+
+  -- sync the strobes to the readout clock domain
+  GEN_TDC : for i in 0 to TRIGGER_NUM-1 generate
+    ThePulseSync : pulse_sync
+      port map (
+        CLK_A_IN    => CLK_TDC,
+        RESET_A_IN  => RESET_TDC,
+        PULSE_A_IN  => trg_pulse_tdc(i),
+        CLK_B_IN    => CLK_RDO,
+        RESET_B_IN  => RESET_RDO,
+        PULSE_B_OUT => trg_pulse_rdo(i));
+  end generate GEN_TDC;
+
+  TRG_RDO_OUT <= trg_pulse_rdo when rising_edge(CLK_RDO);
+  TRG_TDC_OUT <= trg_pulse_tdc when rising_edge(CLK_TDC);
+
+  ValidateTrigger : process (CLK_TDC) is
+  begin
+    if rising_edge(CLK_TDC) then        -- rising clock edge
+      if RESET_TDC = '1' then
+        valid_trigger_flag <= '0';
+      elsif valid_timing_200 = '1' then
+        valid_trigger_flag <= '1';
+      elsif trg_release_200 = '1' then
+        valid_trigger_flag <= '0';
+      end if;
+    end if;
+  end process ValidateTrigger;
+
+  TriggerReleaseSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_RDO,
+      RESET_A_IN  => RESET_RDO,
+      PULSE_A_IN  => TRG_RELEASE_IN,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => RESET_TDC,
+      PULSE_B_OUT => trg_release_200);
+
+  ValidTriggerSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_RDO,
+      RESET_A_IN  => RESET_RDO,
+      PULSE_A_IN  => VALID_TIMING_TRG_IN,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => RESET_TDC,
+      PULSE_B_OUT => valid_timing_200);
+
+  ValidNoTriggerSync : entity work.pulse_sync
+    port map (
+      CLK_A_IN    => CLK_RDO,
+      RESET_A_IN  => RESET_RDO,
+      PULSE_A_IN  => VALID_NOTIMING_TRG_IN,
+      CLK_B_IN    => CLK_TDC,
+      RESET_B_IN  => RESET_TDC,
+      PULSE_B_OUT => valid_notiming_200);
+
+-------------------------------------------------------------------------------
+-- Trigger Window State Machine
+-------------------------------------------------------------------------------
+  FSM_TRIGGER_WINDOW_SEQUENTIAL : process (CLK_TDC) is
+  begin
+    -- Outputs to be registered
+    if rising_edge(CLK_TDC) then        -- rising clock edge
+      if RESET_TDC = '1' then
+        STATE_TW_CURRENT <= IDLE;
+      else
+        STATE_TW_CURRENT     <= STATE_TW_NEXT;
+        trg_win_cnt          <= trg_win_cnt_f;
+        trg_win_end_tdc      <= trg_win_end_f;
+        missing_ref_time_tdc <= missing_ref_time_f;
+      end if;
+    end if;
+  -- Outputs not to be registered
+  end process FSM_TRIGGER_WINDOW_SEQUENTIAL;
+  DEBUG_OUT(19 downto 0)  <= (others => '0');
+  DEBUG_OUT(23 downto 20) <= trg_win_state_debug_f when rising_edge(CLK_RDO);
+  DEBUG_OUT(31 downto 24) <= (others => '0');
+
+  FSM_TRIGGER_WINDOW_COMBINATIONAL : process (STATE_TW_CURRENT, trg_in_3r, TRG_WIN_EN_IN,
+                                              valid_notiming_200, TRG_TYPE_IN, trg_win_cnt,
+                                              TRG_WIN_POST_IN, valid_trigger_flag, trg_release_200) is
+  begin
+    -- Default values
+    STATE_TW_NEXT         <= STATE_TW_CURRENT;
+    trg_win_cnt_f         <= x"00a";
+    trg_win_end_f         <= '0';
+    missing_ref_time_f    <= '0';
+    trg_win_state_debug_f <= x"0";
+
+    case STATE_TW_CURRENT is
+      when IDLE =>
+        if trg_in_3r(0) = '1' then
+          if TRG_WIN_EN_IN = '1' then
+            STATE_TW_NEXT <= COUNT;
+          else
+            STATE_TW_NEXT <= COUNT;
+--            STATE_TW_NEXT <= VALIDATE_TRIGGER;
+          end if;
+        elsif valid_notiming_200 = '1' then
+          if TRG_TYPE_IN = x"D" then
+            STATE_TW_NEXT <= COUNT_CALIBRATION;
+          else
+            STATE_TW_NEXT <= WAIT_NEXT_TRIGGER;
+          end if;
+        elsif valid_timing_200 = '1' then
+          STATE_TW_NEXT <= MISSING_REFERENCE_TIME;
+        else
+          STATE_TW_NEXT <= IDLE;
+        end if;
+        trg_win_state_debug_f <= x"1";
+
+      when COUNT =>
+        if trg_win_cnt(10 downto 0) = TRG_WIN_POST_IN then
+          STATE_TW_NEXT <= VALIDATE_TRIGGER;
+        else
+          STATE_TW_NEXT <= COUNT;
+        end if;
+        trg_win_cnt_f         <= trg_win_cnt + to_unsigned(1, 12);
+        trg_win_state_debug_f <= x"3";
+
+      when COUNT_CALIBRATION =>
+        if trg_win_cnt(6) = '1' then
+          STATE_TW_NEXT <= WIN_END;
+        else
+          STATE_TW_NEXT <= COUNT_CALIBRATION;
+        end if;
+        trg_win_cnt_f         <= trg_win_cnt + to_unsigned(1, 12);
+        trg_win_state_debug_f <= x"4";
+
+      when VALIDATE_TRIGGER =>
+        if valid_trigger_flag = '1' then
+          STATE_TW_NEXT <= WIN_END;
+        else
+          STATE_TW_NEXT <= VALIDATE_TRIGGER;
+        end if;
+        trg_win_end_f         <= '0';
+        trg_win_state_debug_f <= x"5";
+
+      when WIN_END =>
+        STATE_TW_NEXT         <= WAIT_NEXT_TRIGGER;
+        trg_win_end_f         <= '1';
+        trg_win_state_debug_f <= x"6";
+
+      when MISSING_REFERENCE_TIME =>
+        STATE_TW_NEXT         <= WAIT_NEXT_TRIGGER;
+        trg_win_end_f         <= '1';
+        missing_ref_time_f    <= '1';
+        trg_win_state_debug_f <= x"7";
+
+      when WAIT_NEXT_TRIGGER =>
+        if trg_release_200 = '1' then
+          STATE_TW_NEXT <= IDLE;
+        else
+          STATE_TW_NEXT <= WAIT_NEXT_TRIGGER;
+        end if;
+        trg_win_end_f         <= '0';
+        trg_win_state_debug_f <= x"8";
+
+      when others =>
+        STATE_TW_NEXT         <= IDLE;
+        trg_win_state_debug_f <= x"0";
+    end case;
+  end process FSM_TRIGGER_WINDOW_COMBINATIONAL;
+
+  -- syn trg window end strobe to readout clock domain
+  TrgWinEndPulseSync : pulse_sync
+    port map (
+      CLK_A_IN    => CLK_TDC,
+      RESET_A_IN  => RESET_TDC,
+      PULSE_A_IN  => trg_win_end_tdc,
+      CLK_B_IN    => CLK_RDO,
+      RESET_B_IN  => RESET_RDO,
+      PULSE_B_OUT => trg_win_end_rdo);
+
+  TRG_WIN_END_TDC_OUT <= trg_win_end_tdc;
+  TRG_WIN_END_RDO_OUT <= trg_win_end_rdo;
+
+  -- syn missing reference time strobe to readout clock domain
+  MissRefTimePulseSync : pulse_sync
+    port map (
+      CLK_A_IN    => CLK_TDC,
+      RESET_A_IN  => RESET_TDC,
+      PULSE_A_IN  => missing_ref_time_tdc,
+      CLK_B_IN    => CLK_RDO,
+      RESET_B_IN  => RESET_RDO,
+      PULSE_B_OUT => missing_ref_time_rdo);
+
+  MISSING_REF_TIME_OUT <= missing_ref_time_rdo;
+
+  TriggerTime : process (CLK_TDC)
+  begin
+    if rising_edge(CLK_TDC) then
+      if trg_in_2r(0) = '1' and trg_in_3r(0) = '0' then
+        trg_time <= EPOCH_COUNTER_IN & COARSE_COUNTER_IN;
+      end if;
+      if trg_pulse_tdc(0) = '1' then
+        TRG_TIME_OUT <= trg_time;  --std_logic_vector(unsigned(trg_time) - to_unsigned(2, 39));
+      end if;
+    end if;
+  end process TriggerTime;
+
+
+end architecture behavioral;
diff --git a/releases/tdc_v2.3.1/bit_sync.vhd b/releases/tdc_v2.3.1/bit_sync.vhd
new file mode 100644 (file)
index 0000000..ba9adb2
--- /dev/null
@@ -0,0 +1,60 @@
+--synchronizes a single bit to a different clock domain
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity bit_sync is
+  generic(
+    DEPTH : integer := 3
+    );
+  port(
+    RESET : in  std_logic;  --Reset is neceessary to avoid optimization to shift register
+    CLK0  : in  std_logic;              --clock for first FF
+    CLK1  : in  std_logic;              --Clock for other FF
+    D_IN  : in  std_logic;              --Data input
+    D_OUT : out std_logic               --Data output
+    );
+end entity;
+
+architecture behavioral of bit_sync is
+
+  signal sync_q : std_logic_vector(DEPTH downto 0);
+
+  attribute syn_preserve           : boolean;
+  attribute syn_keep               : boolean;
+  attribute syn_keep of sync_q     : signal is true;
+  attribute syn_preserve of sync_q : signal is true;
+
+
+begin
+  sync_q(0) <= D_IN;
+  D_OUT     <= sync_q(DEPTH);
+
+  process(CLK0)
+  begin
+    if rising_edge(CLK0) then
+      if RESET = '1' then
+        sync_q(1) <= '0';
+      else
+        sync_q(1) <= sync_q(0);
+      end if;
+    end if;
+  end process;
+
+  gen_others : if DEPTH > 1 generate
+    gen_flipflops : for i in 2 to DEPTH generate
+      process(CLK1)
+      begin
+        if rising_edge(CLK1) then
+          if RESET = '1' then
+            sync_q(i) <= '0';
+          else
+            sync_q(i) <= sync_q(i-1);
+          end if;
+        end if;
+      end process;
+    end generate;
+  end generate;
+
+end architecture;
diff --git a/releases/tdc_v2.3.1/cbmtof.vhd b/releases/tdc_v2.3.1/cbmtof.vhd
new file mode 100644 (file)
index 0000000..eeb83bb
--- /dev/null
@@ -0,0 +1,819 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.config.all;
+use work.version.all;
+
+
+
+entity cbmtof is
+  port(
+    --Clocks
+    CLK_OSC : in std_logic;  --for tdc measurements --200MHz
+    CLK_CM  : in std_logic_vector(8 downto 1);  --from clock manager   --125MHz
+    CLK_EXT : in std_logic;             --from CK_IN1 connection
+
+    --Serdes
+    --CLK_SERDES_INT_RIGHT : in    std_logic;
+    SERDES_TX    : out   std_logic_vector(1 downto 0);
+    SERDES_RX    : in    std_logic_vector(1 downto 0);
+    SFP_TXDIS    : out   std_logic;
+    SFP_MOD      : inout std_logic_vector(2 downto 0);
+    SFP_LOS      : in    std_logic;
+    SFP_RATE_SEL : out   std_logic;     -- doesn't exist in cbmrich
+    SFP_TXFAULT  : out   std_logic;     -- doesn't exist in cbmrich
+
+    --Connections
+    SPARE_LINE : inout std_logic_vector(2 downto 0);
+    LVDS       : inout std_logic_vector(2 downto 1);
+    INPUT      : in    std_logic_vector(32 downto 1);
+    OR_IN      : in    std_logic;
+
+    --Flash ROM & Reboot
+    FLASH_CLK  : out std_logic;
+    FLASH_CS   : out std_logic;
+    FLASH_DIN  : out std_logic;
+    FLASH_DOUT : in  std_logic;
+    PROGRAMN   : out std_logic;         --reboot FPGA
+
+    --DAC
+    DAC_SDO : in  std_logic;
+    DAC_SDI : out std_logic;
+    DAC_SCK : out std_logic;
+    DAC_CS  : out std_logic;
+    DAC_CLR : out std_logic;
+
+    --Misc
+    TEMPSENS      : inout std_logic;    --Temperature Sensor
+    LED_GREEN     : out   std_logic;
+    LED_ORANGE    : out   std_logic;
+    LED_RED       : out   std_logic;
+    LED_YELLOW    : out   std_logic;
+    LED_CLK_GREEN : out   std_logic;
+    LED_CLK_RED   : out   std_logic;
+    LED_SFP_GREEN : out   std_logic;
+    LED_SFP_RED   : out   std_logic;
+
+    CLK_MNGR_USER : inout std_logic_vector(3 downto 0);
+
+    --Test Connectors
+    TEST_LINE : out std_logic_vector(31 downto 0)
+    );
+
+
+  attribute syn_useioff                  : boolean;
+  --no IO-FF for LEDs relaxes timing constraints
+  attribute syn_useioff of LED_GREEN     : signal is false;
+  attribute syn_useioff of LED_ORANGE    : signal is false;
+  attribute syn_useioff of LED_RED       : signal is false;
+  attribute syn_useioff of LED_YELLOW    : signal is false;
+  attribute syn_useioff of LED_CLK_GREEN : signal is false;
+  attribute syn_useioff of LED_CLK_RED   : signal is false;
+  attribute syn_useioff of LED_SFP_RED   : signal is false;
+  attribute syn_useioff of LED_SFP_GREEN : signal is false;
+  attribute syn_useioff of TEMPSENS      : signal is false;
+  attribute syn_useioff of PROGRAMN      : signal is false;
+  attribute syn_useioff of INPUT         : signal is false;
+  attribute syn_useioff of CLK_CM        : signal is false;
+  attribute syn_useioff of SPARE_LINE    : signal is false;
+
+  --important signals _with_ IO-FF
+  attribute syn_useioff of DAC_SCK    : signal is true;
+  attribute syn_useioff of DAC_CS     : signal is true;
+  attribute syn_useioff of DAC_SDI    : signal is true;
+  attribute syn_useioff of DAC_SDO    : signal is true;
+  attribute syn_useioff of DAC_CLR    : signal is true;
+  attribute syn_useioff of FLASH_CLK  : signal is true;
+  attribute syn_useioff of FLASH_CS   : signal is true;
+  attribute syn_useioff of FLASH_DIN  : signal is true;
+  attribute syn_useioff of FLASH_DOUT : signal is true;
+  attribute syn_useioff of TEST_LINE  : signal is true;
+  attribute syn_useioff of LVDS       : signal is true;
+  attribute syn_useioff of OR_IN      : signal is true;
+
+
+end entity;
+
+architecture cbmtof_arch of cbmtof is
+  --Constants
+  constant REGIO_NUM_STAT_REGS : integer := 5;
+  constant REGIO_NUM_CTRL_REGS : integer := 3;
+
+  attribute syn_keep     : boolean;
+  attribute syn_preserve : boolean;
+  --attribute NOM_FREQ             : string;
+  --attribute NOM_FREQ of OSCinst0 : label is "20.0";
+
+
+  --Clock / Reset
+  signal clk_100_i                : std_logic;  --clock for main logic, 100 MHz, via Clock Manager and internal PLL
+  signal clk_200_i                : std_logic;  --clock for logic at 200 MHz, via Clock Manager and bypassed PLL
+  signal clk_tdc_i                : std_logic;  --clock for the TDC
+  signal clk_osc_int              : std_logic;  -- clock for calibrating the tdc, 2.5 MHz, via internal osscilator
+  signal clk_100_osc              : std_logic;
+  signal rx_clock_100             : std_logic;
+  signal rx_clock_200             : std_logic;
+  signal clk_cal                  : std_logic;  -- clock for calibrating the tdc, 100 MHz, via pll
+  signal pll_lock                 : std_logic;  --Internal PLL locked. E.g. used to reset all internal logic.
+  signal pll_lock_1               : std_logic;  --Internal PLL locked. E.g. used to reset all internal logic.
+  signal pll_lock_2               : std_logic;  --Internal PLL locked. E.g. used to reset all internal logic.
+  signal clear_i                  : std_logic;
+  signal reset_i                  : std_logic;
+  signal GSR_N                    : std_logic;
+  attribute syn_keep of GSR_N     : signal is true;
+  attribute syn_preserve of GSR_N : signal is true;
+
+  --Media Interface
+  signal med_stat_op        : std_logic_vector (1*16-1 downto 0);
+  signal med_ctrl_op        : std_logic_vector (1*16-1 downto 0);
+  signal med_stat_debug     : std_logic_vector (1*64-1 downto 0);
+  signal med_ctrl_debug     : std_logic_vector (1*64-1 downto 0);
+  signal med_data_out       : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_out : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_out  : std_logic;
+  signal med_read_out       : std_logic;
+  signal med_data_in        : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_in  : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_in   : std_logic;
+  signal med_read_in        : std_logic;
+
+  --LVL1 channel
+  signal timing_trg_received_i : std_logic;
+
+  --READOUT
+  signal readout_rx : READOUT_RX;
+  signal readout_tx : readout_tx_array_t(0 to 0);
+
+  --Slow Control channel
+  signal common_stat_reg        : std_logic_vector(std_COMSTATREG*32-1 downto 0);
+  signal common_ctrl_reg        : std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+  signal stat_reg               : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg               : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0);
+  signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0);
+  signal stat_reg_strobe        : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg_strobe        : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal timer                  : TIMERS;
+
+  --RegIO
+  signal my_address             : std_logic_vector (15 downto 0);
+  signal regio_addr_out         : std_logic_vector (15 downto 0);
+  signal regio_read_enable_out  : std_logic;
+  signal regio_write_enable_out : std_logic;
+  signal regio_data_out         : std_logic_vector (31 downto 0);
+  signal regio_data_in          : std_logic_vector (31 downto 0);
+  signal regio_dataready_in     : std_logic;
+  signal regio_no_more_data_in  : std_logic;
+  signal regio_write_ack_in     : std_logic;
+  signal regio_unknown_addr_in  : std_logic;
+  signal regio_timeout_out      : std_logic;
+
+  --Timer
+  signal global_time         : std_logic_vector(31 downto 0);
+  signal local_time          : std_logic_vector(7 downto 0);
+  signal time_since_last_trg : std_logic_vector(31 downto 0);
+  signal timer_ticks         : std_logic_vector(1 downto 0);
+
+  --Flash
+  signal spimem_read_en          : std_logic;
+  signal spimem_write_en         : std_logic;
+  signal spimem_data_in          : std_logic_vector(31 downto 0);
+  signal spimem_addr             : std_logic_vector(8 downto 0);
+  signal spimem_data_out         : std_logic_vector(31 downto 0);
+  signal spimem_dataready_out    : std_logic;
+  signal spimem_no_more_data_out : std_logic;
+  signal spimem_unknown_addr_out : std_logic;
+  signal spimem_write_ack_out    : std_logic;
+
+  signal dac_read_en  : std_logic;
+  signal dac_write_en : std_logic;
+  signal dac_data_in  : std_logic_vector(31 downto 0);
+  signal dac_addr     : std_logic_vector(4 downto 0);
+  signal dac_data_out : std_logic_vector(31 downto 0);
+  signal dac_ack      : std_logic;
+  signal dac_busy     : std_logic;
+
+  signal spi_bram_addr : std_logic_vector(7 downto 0);
+  signal spi_bram_wr_d : std_logic_vector(7 downto 0);
+  signal spi_bram_rd_d : std_logic_vector(7 downto 0);
+  signal spi_bram_we   : std_logic;
+
+  signal trig_out   : std_logic_vector(3 downto 0);
+  signal trig_din   : std_logic_vector(31 downto 0);
+  signal trig_dout  : std_logic_vector(31 downto 0);
+  signal trig_write : std_logic                     := '0';
+  signal trig_read  : std_logic                     := '0';
+  signal trig_ack   : std_logic                     := '0';
+  signal trig_nack  : std_logic                     := '0';
+  signal trig_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal stat_out   : std_logic_vector(3 downto 0);
+  signal stat_din   : std_logic_vector(31 downto 0);
+  signal stat_dout  : std_logic_vector(31 downto 0);
+  signal stat_write : std_logic                     := '0';
+  signal stat_read  : std_logic                     := '0';
+  signal stat_ack   : std_logic                     := '0';
+  signal stat_nack  : std_logic                     := '0';
+  signal stat_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal sed_error            : std_logic;
+  signal bussed_rx, bustdc_rx : CTRLBUS_RX;
+  signal bussed_tx, bustdc_tx : CTRLBUS_TX;
+
+  --FPGA Test
+  signal time_counter   : unsigned(31 downto 0);
+  signal time_counter_2 : unsigned(31 downto 0);
+
+  --TDC
+  signal hit_in_i         : std_logic_vector(64 downto 1);
+  signal logic_analyser_i : std_logic_vector(15 downto 0);
+  
+begin
+---------------------------------------------------------------------------
+-- Reset Generation
+---------------------------------------------------------------------------
+
+  pll_lock <= pll_lock_1;               -- or pll_lock_2;
+  GSR_N    <= pll_lock;
+
+  THE_RESET_HANDLER : trb_net_reset_handler
+    generic map(
+      RESET_DELAY => x"FEEE"
+      )
+    port map(
+      CLEAR_IN      => '0',              -- reset input (high active, async)
+      CLEAR_N_IN    => '1',              -- reset input (low active, async)
+      CLK_IN        => clk_200_i,        -- raw master clock, NOT from PLL/DLL!
+      SYSCLK_IN     => clk_100_osc,      -- PLL/DLL remastered clock
+      PLL_LOCKED_IN => pll_lock,         -- master PLL lock signal (async)
+      RESET_IN      => '0',              -- general reset signal (SYSCLK)
+      TRB_RESET_IN  => med_stat_op(13),  -- TRBnet reset signal (SYSCLK)
+      CLEAR_OUT     => clear_i,          -- async reset out, USE WITH CARE!
+      RESET_OUT     => reset_i,          -- synchronous reset out (SYSCLK)
+      DEBUG_OUT     => open
+      );  
+
+
+---------------------------------------------------------------------------
+-- Clock Handling
+---------------------------------------------------------------------------
+
+  THE_MAIN_PLL : entity work.pll_in200_out100
+    port map (
+      CLK   => CLK_OSC,
+      RESET => '0',
+      CLKOP => clk_100_osc,             -- 100 MHz        
+      CLKOK => clk_200_i,               -- 200 MHz, bypass
+      LOCK  => pll_lock_1);
+
+
+  clk_cal <= clk_100_i;
+
+  TDC_Clock_Int : if USE_EXTERNALCLOCK = 0 and USE_RXCLOCK = 0 generate
+    clk_tdc_i <= CLK_OSC;  -- Oscillator used for the time measurement
+  end generate TDC_Clock_Int;
+
+  TDC_Clock_Ext : if USE_EXTERNALCLOCK = 1 and USE_RXCLOCK = 0 generate
+    clk_tdc_i <= CLK_EXT;  -- External Clock used for the time measurement
+  end generate TDC_Clock_Ext;
+
+  TDC_Clock_Rx : if USE_EXTERNALCLOCK = 0 and USE_RXCLOCK = 1 generate
+    clk_tdc_i <= rx_clock_200;  -- Recovered Clock used for the time measurement
+  end generate;
+
+---------------------------------------------------------------------------
+-- The TrbNet media interface (to other FPGA)
+---------------------------------------------------------------------------
+  gen_norm_uplink : if USE_RXCLOCK = c_NO generate
+    THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp
+      generic map(
+        SERDES_NUM  => 0,               --number of serdes in quad
+        EXT_CLOCK   => c_NO,            --use internal clock
+        USE_200_MHZ => c_YES,           --run on 200 MHz clock
+        USE_125_MHZ => c_NO,
+        USE_CTC     => c_YES,           --CTC required
+        USE_SLAVE   => c_NO
+        )
+      port map(
+        CLK                => clk_200_i,
+        SYSCLK             => clk_100_i,
+        RESET              => reset_i,
+        CLEAR              => clear_i,
+        CLK_EN             => '1',
+        --Internal Connection
+        MED_DATA_IN        => med_data_out,
+        MED_PACKET_NUM_IN  => med_packet_num_out,
+        MED_DATAREADY_IN   => med_dataready_out,
+        MED_READ_OUT       => med_read_in,
+        MED_DATA_OUT       => med_data_in,
+        MED_PACKET_NUM_OUT => med_packet_num_in,
+        MED_DATAREADY_OUT  => med_dataready_in,
+        MED_READ_IN        => med_read_out,
+        REFCLK2CORE_OUT    => open,
+        --SFP Connection
+        SD_RXD_P_IN        => SERDES_RX(0),
+        SD_RXD_N_IN        => SERDES_RX(1),
+        SD_TXD_P_OUT       => SERDES_TX(0),
+        SD_TXD_N_OUT       => SERDES_TX(1),
+        SD_REFCLK_P_IN     => open,
+        SD_REFCLK_N_IN     => open,
+        SD_PRSNT_N_IN      => SFP_MOD(0),
+        SD_LOS_IN          => SFP_LOS,
+        SD_TXDIS_OUT       => SFP_TXDIS,
+        -- Status and control port
+        STAT_OP            => med_stat_op,
+        CTRL_OP            => med_ctrl_op,
+        STAT_DEBUG         => med_stat_debug,
+        CTRL_DEBUG         => (others => '0')
+        );
+    clk_100_i <= clk_100_osc;
+  end generate;
+
+  gen_sync_uplink : if USE_RXCLOCK = c_YES generate
+    THE_MEDIA_UPLINK : med_ecp3_sfp_sync
+      generic map(
+        SERDES_NUM    => 0,             --number of serdes in quad
+        IS_SYNC_SLAVE => c_YES
+        )
+      port map(
+        CLK                => clk_200_i,
+        SYSCLK             => clk_100_i,
+        RESET              => reset_i,
+        CLEAR              => clear_i,
+        --Internal Connection for TrbNet data -> not used a.t.m.
+        MED_DATA_IN        => med_data_out,
+        MED_PACKET_NUM_IN  => med_packet_num_out,
+        MED_DATAREADY_IN   => med_dataready_out,
+        MED_READ_OUT       => med_read_in,
+        MED_DATA_OUT       => med_data_in,
+        MED_PACKET_NUM_OUT => med_packet_num_in,
+        MED_DATAREADY_OUT  => med_dataready_in,
+        MED_READ_IN        => med_read_out,
+        CLK_RX_HALF_OUT    => rx_clock_100,
+        CLK_RX_FULL_OUT    => rx_clock_200,
+
+        RX_DLM         => open,
+        RX_DLM_WORD    => open,
+        TX_DLM         => '0',
+        TX_DLM_WORD    => (others => '0'),
+        --SFP Connection
+        SD_RXD_P_IN    => SERDES_RX(0),
+        SD_RXD_N_IN    => SERDES_RX(1),
+        SD_TXD_P_OUT   => SERDES_TX(0),
+        SD_TXD_N_OUT   => SERDES_TX(1),
+        SD_REFCLK_P_IN => open,
+        SD_REFCLK_N_IN => open,
+        SD_PRSNT_N_IN  => SFP_MOD(0),
+        SD_LOS_IN      => SFP_LOS,
+        SD_TXDIS_OUT   => SFP_TXDIS,
+
+        SCI_DATA_IN  => (others => '0'),
+        SCI_DATA_OUT => open,
+        SCI_ADDR     => (others => '0'),
+        SCI_READ     => '0',
+        SCI_WRITE    => '0',
+        SCI_ACK      => open,
+        SCI_NACK     => open,
+        -- Status and control port
+        STAT_OP      => med_stat_op,
+        CTRL_OP      => med_ctrl_op,
+        STAT_DEBUG   => med_stat_debug,
+        CTRL_DEBUG   => (others => '0')
+        ); 
+    clk_100_i <= rx_clock_100;
+  end generate;
+
+
+---------------------------------------------------------------------------
+-- Endpoint
+---------------------------------------------------------------------------
+
+  THE_ENDPOINT : trb_net16_endpoint_hades_full_handler
+    generic map(
+      REGIO_NUM_STAT_REGS       => REGIO_NUM_STAT_REGS,
+      REGIO_NUM_CTRL_REGS       => REGIO_NUM_CTRL_REGS,
+      ADDRESS_MASK              => x"FFFF",
+      BROADCAST_BITMASK         => x"FF",
+      BROADCAST_SPECIAL_ADDR    => BROADCAST_SPECIAL_ADDR,
+      REGIO_COMPILE_TIME        => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)),
+      REGIO_HARDWARE_VERSION    => HARDWARE_INFO,
+      REGIO_INCLUDED_FEATURES   => INCLUDED_FEATURES,
+      REGIO_INIT_ADDRESS        => INIT_ADDRESS,
+      REGIO_USE_VAR_ENDPOINT_ID => c_YES,
+      CLOCK_FREQUENCY           => CLOCK_FREQUENCY,
+      TIMING_TRIGGER_RAW        => c_YES,
+      --Configure data handler
+      DATA_INTERFACE_NUMBER     => 1,
+      DATA_BUFFER_DEPTH         => EVENT_BUFFER_SIZE,
+      DATA_BUFFER_WIDTH         => 32,
+      DATA_BUFFER_FULL_THRESH   => 2**EVENT_BUFFER_SIZE-EVENT_MAX_SIZE,
+      TRG_RELEASE_AFTER_DATA    => c_YES,
+      HEADER_BUFFER_DEPTH       => 9,
+      HEADER_BUFFER_FULL_THRESH => 2**9-16
+      )
+    port map(
+      CLK                => clk_100_i,
+      RESET              => reset_i,
+      CLK_EN             => '1',
+      MED_DATAREADY_OUT  => med_dataready_out,  -- open, --
+      MED_DATA_OUT       => med_data_out,  -- open, --
+      MED_PACKET_NUM_OUT => med_packet_num_out,  -- open, --
+      MED_READ_IN        => med_read_in,
+      MED_DATAREADY_IN   => med_dataready_in,
+      MED_DATA_IN        => med_data_in,
+      MED_PACKET_NUM_IN  => med_packet_num_in,
+      MED_READ_OUT       => med_read_out,  -- open, --
+      MED_STAT_OP_IN     => med_stat_op,
+      MED_CTRL_OP_OUT    => med_ctrl_op,
+
+      --Timing trigger in
+      TRG_TIMING_TRG_RECEIVED_IN  => timing_trg_received_i,
+      --LVL1 trigger to FEE
+      LVL1_TRG_DATA_VALID_OUT     => readout_rx.data_valid,
+      LVL1_VALID_TIMING_TRG_OUT   => readout_rx.valid_timing_trg,
+      LVL1_VALID_NOTIMING_TRG_OUT => readout_rx.valid_notiming_trg,
+      LVL1_INVALID_TRG_OUT        => readout_rx.invalid_trg,
+
+      LVL1_TRG_TYPE_OUT        => readout_rx.trg_type,
+      LVL1_TRG_NUMBER_OUT      => readout_rx.trg_number,
+      LVL1_TRG_CODE_OUT        => readout_rx.trg_code,
+      LVL1_TRG_INFORMATION_OUT => readout_rx.trg_information,
+      LVL1_INT_TRG_NUMBER_OUT  => readout_rx.trg_int_number,
+
+      --Information about trigger handler errors
+      TRG_MULTIPLE_TRG_OUT     => readout_rx.trg_multiple,
+      TRG_TIMEOUT_DETECTED_OUT => readout_rx.trg_timeout,
+      TRG_SPURIOUS_TRG_OUT     => readout_rx.trg_spurious,
+      TRG_MISSING_TMG_TRG_OUT  => readout_rx.trg_missing,
+      TRG_SPIKE_DETECTED_OUT   => readout_rx.trg_spike,
+
+      --Response from FEE
+      FEE_TRG_RELEASE_IN(0)       => readout_tx(0).busy_release,
+      FEE_TRG_STATUSBITS_IN       => readout_tx(0).statusbits,
+      FEE_DATA_IN                 => readout_tx(0).data,
+      FEE_DATA_WRITE_IN(0)        => readout_tx(0).data_write,
+      FEE_DATA_FINISHED_IN(0)     => readout_tx(0).data_finished,
+      FEE_DATA_ALMOST_FULL_OUT(0) => readout_rx.buffer_almost_full,
+
+      -- Slow Control Data Port
+      REGIO_COMMON_STAT_REG_IN     => common_stat_reg,  --0x00
+      REGIO_COMMON_CTRL_REG_OUT    => common_ctrl_reg,  --0x20
+      REGIO_COMMON_STAT_STROBE_OUT => common_stat_reg_strobe,
+      REGIO_COMMON_CTRL_STROBE_OUT => common_ctrl_reg_strobe,
+      REGIO_STAT_REG_IN            => stat_reg,         --start 0x80
+      REGIO_CTRL_REG_OUT           => ctrl_reg,         --start 0xc0
+      REGIO_STAT_STROBE_OUT        => stat_reg_strobe,
+      REGIO_CTRL_STROBE_OUT        => ctrl_reg_strobe,
+      REGIO_VAR_ENDPOINT_ID        => (others => '0'),
+
+      BUS_ADDR_OUT         => regio_addr_out,
+      BUS_READ_ENABLE_OUT  => regio_read_enable_out,
+      BUS_WRITE_ENABLE_OUT => regio_write_enable_out,
+      BUS_DATA_OUT         => regio_data_out,
+      BUS_DATA_IN          => regio_data_in,
+      BUS_DATAREADY_IN     => regio_dataready_in,
+      BUS_NO_MORE_DATA_IN  => regio_no_more_data_in,
+      BUS_WRITE_ACK_IN     => regio_write_ack_in,
+      BUS_UNKNOWN_ADDR_IN  => regio_unknown_addr_in,
+      BUS_TIMEOUT_OUT      => regio_timeout_out,
+      ONEWIRE_INOUT        => TEMPSENS,
+      ONEWIRE_MONITOR_OUT  => open,
+
+      TIME_GLOBAL_OUT         => global_time,
+      TIME_LOCAL_OUT          => local_time,
+      TIME_SINCE_LAST_TRG_OUT => time_since_last_trg,
+      TIME_TICKS_OUT          => timer_ticks,
+      TEMPERATURE_OUT         => timer.temperature,
+
+      STAT_DEBUG_IPU              => open,
+      STAT_DEBUG_1                => open,
+      STAT_DEBUG_2                => open,
+      STAT_DEBUG_DATA_HANDLER_OUT => open,
+      STAT_DEBUG_IPU_HANDLER_OUT  => open,
+      STAT_TRIGGER_OUT            => open,
+      CTRL_MPLEX                  => (others => '0'),
+      IOBUF_CTRL_GEN              => (others => '0'),
+      STAT_ONEWIRE                => open,
+      STAT_ADDR_DEBUG             => open,
+      DEBUG_LVL1_HANDLER_OUT      => open
+      );
+
+---------------------------------------------------------------------------
+-- I/O
+---------------------------------------------------------------------------
+  Reference_Time_Direct : if USE_CLK_MANAGER_REF_TIME = 0 generate
+    timing_trg_received_i <= SPARE_LINE(0);  -- reference time from the 2nd pair
+                                             --  on the external clock port
+  end generate Reference_Time_Direct;
+
+  Reference_Time_Clock_Manager : if USE_CLK_MANAGER_REF_TIME = 1 generate
+    timing_trg_received_i <= CLK_CM(3);  -- reference time from the clock manager
+  end generate Reference_Time_Clock_Manager;
+
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+  THE_BUS_HANDLER : trb_net16_regio_bus_handler
+    generic map(
+      PORT_NUMBER      => 6,
+      PORT_ADDRESSES   => (0 => x"d000", 1 => x"d400", 2 => x"c000", 3 => x"cf00",
+                           4 => x"cf80", 5 => x"d500", others => x"0000"),
+      PORT_ADDR_MASK   => (0 => 9, 1 => 5, 2 => 12, 3 => 6,
+                           4 => 7, 5 => 4, others => 0),
+      PORT_MASK_ENABLE => 1
+      )
+    port map(
+      CLK   => clk_100_i,
+      RESET => reset_i,
+
+      DAT_ADDR_IN          => regio_addr_out,
+      DAT_DATA_IN          => regio_data_out,
+      DAT_DATA_OUT         => regio_data_in,
+      DAT_READ_ENABLE_IN   => regio_read_enable_out,
+      DAT_WRITE_ENABLE_IN  => regio_write_enable_out,
+      DAT_TIMEOUT_IN       => regio_timeout_out,
+      DAT_DATAREADY_OUT    => regio_dataready_in,
+      DAT_WRITE_ACK_OUT    => regio_write_ack_in,
+      DAT_NO_MORE_DATA_OUT => regio_no_more_data_in,
+      DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in,
+
+      --Bus Handler (SPI Flash control)
+      BUS_READ_ENABLE_OUT(0)              => spimem_read_en,
+      BUS_WRITE_ENABLE_OUT(0)             => spimem_write_en,
+      BUS_DATA_OUT(0*32+31 downto 0*32)   => spimem_data_in,
+      BUS_ADDR_OUT(0*16+8 downto 0*16)    => spimem_addr,
+      BUS_ADDR_OUT(0*16+15 downto 0*16+9) => open,
+      BUS_TIMEOUT_OUT(0)                  => open,
+      BUS_DATA_IN(0*32+31 downto 0*32)    => spimem_data_out,
+      BUS_DATAREADY_IN(0)                 => spimem_dataready_out,
+      BUS_WRITE_ACK_IN(0)                 => spimem_write_ack_out,
+      BUS_NO_MORE_DATA_IN(0)              => spimem_no_more_data_out,
+      BUS_UNKNOWN_ADDR_IN(0)              => spimem_unknown_addr_out,
+      --DAC
+      BUS_READ_ENABLE_OUT(1)              => dac_read_en,
+      BUS_WRITE_ENABLE_OUT(1)             => dac_write_en,
+      BUS_DATA_OUT(1*32+31 downto 1*32)   => dac_data_in,
+      BUS_ADDR_OUT(1*16+4 downto 1*16)    => dac_addr,
+      BUS_ADDR_OUT(1*16+15 downto 1*16+5) => open,
+      BUS_TIMEOUT_OUT(1)                  => open,
+      BUS_DATA_IN(1*32+31 downto 1*32)    => dac_data_out,
+      BUS_DATAREADY_IN(1)                 => dac_ack,
+      BUS_WRITE_ACK_IN(1)                 => dac_ack,
+      BUS_NO_MORE_DATA_IN(1)              => dac_busy,
+      BUS_UNKNOWN_ADDR_IN(1)              => '0',
+      --TDC
+      BUS_READ_ENABLE_OUT(2)              => bustdc_rx.read,
+      BUS_WRITE_ENABLE_OUT(2)             => bustdc_rx.write,
+      BUS_DATA_OUT(2*32+31 downto 2*32)   => bustdc_rx.data,
+      BUS_ADDR_OUT(2*16+11 downto 2*16)   => bustdc_rx.addr(11 downto 0),
+      BUS_TIMEOUT_OUT(2)                  => bustdc_rx.timeout,
+      BUS_DATA_IN(2*32+31 downto 2*32)    => bustdc_tx.data,
+      BUS_DATAREADY_IN(2)                 => bustdc_tx.ack,
+      BUS_WRITE_ACK_IN(2)                 => bustdc_tx.ack,
+      BUS_NO_MORE_DATA_IN(2)              => bustdc_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(2)              => bustdc_tx.unknown,
+      --Trigger logic registers
+      BUS_READ_ENABLE_OUT(3)              => trig_read,
+      BUS_WRITE_ENABLE_OUT(3)             => trig_write,
+      BUS_DATA_OUT(3*32+31 downto 3*32)   => trig_din,
+      BUS_ADDR_OUT(3*16+15 downto 3*16)   => trig_addr,
+      BUS_TIMEOUT_OUT(3)                  => open,
+      BUS_DATA_IN(3*32+31 downto 3*32)    => trig_dout,
+      BUS_DATAREADY_IN(3)                 => trig_ack,
+      BUS_WRITE_ACK_IN(3)                 => trig_ack,
+      BUS_NO_MORE_DATA_IN(3)              => '0',
+      BUS_UNKNOWN_ADDR_IN(3)              => trig_nack,
+      --Input statistics
+      BUS_READ_ENABLE_OUT(4)              => stat_read,
+      BUS_WRITE_ENABLE_OUT(4)             => stat_write,
+      BUS_DATA_OUT(4*32+31 downto 4*32)   => stat_din,
+      BUS_ADDR_OUT(4*16+15 downto 4*16)   => stat_addr,
+      BUS_TIMEOUT_OUT(4)                  => open,
+      BUS_DATA_IN(4*32+31 downto 4*32)    => stat_dout,
+      BUS_DATAREADY_IN(4)                 => stat_ack,
+      BUS_WRITE_ACK_IN(4)                 => stat_ack,
+      BUS_NO_MORE_DATA_IN(4)              => '0',
+      BUS_UNKNOWN_ADDR_IN(4)              => stat_nack,
+      --SEU Detection
+      BUS_READ_ENABLE_OUT(5)              => bussed_rx.read,
+      BUS_WRITE_ENABLE_OUT(5)             => bussed_rx.write,
+      BUS_DATA_OUT(5*32+31 downto 5*32)   => bussed_rx.data,
+      BUS_ADDR_OUT(5*16+15 downto 5*16)   => bussed_rx.addr,
+      BUS_TIMEOUT_OUT(5)                  => bussed_rx.timeout,
+      BUS_DATA_IN(5*32+31 downto 5*32)    => bussed_tx.data,
+      BUS_DATAREADY_IN(5)                 => bussed_tx.ack,
+      BUS_WRITE_ACK_IN(5)                 => bussed_tx.ack,
+      BUS_NO_MORE_DATA_IN(5)              => bussed_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(5)              => bussed_tx.unknown,
+
+      STAT_DEBUG => open
+      );
+
+---------------------------------------------------------------------------
+-- SPI / Flash
+---------------------------------------------------------------------------
+
+  THE_SPI_RELOAD : entity work.spi_flash_and_fpga_reload
+    port map(
+      CLK_IN   => clk_100_i,
+      RESET_IN => reset_i,
+
+      BUS_ADDR_IN          => spimem_addr,
+      BUS_READ_IN          => spimem_read_en,
+      BUS_WRITE_IN         => spimem_write_en,
+      BUS_DATAREADY_OUT    => spimem_dataready_out,
+      BUS_WRITE_ACK_OUT    => spimem_write_ack_out,
+      BUS_UNKNOWN_ADDR_OUT => spimem_unknown_addr_out,
+      BUS_NO_MORE_DATA_OUT => spimem_no_more_data_out,
+      BUS_DATA_IN          => spimem_data_in,
+      BUS_DATA_OUT         => spimem_data_out,
+
+      DO_REBOOT_IN => common_ctrl_reg(15),
+      PROGRAMN     => PROGRAMN,
+
+      SPI_CS_OUT  => FLASH_CS,
+      SPI_SCK_OUT => FLASH_CLK,
+      SPI_SDO_OUT => FLASH_DIN,
+      SPI_SDI_IN  => FLASH_DOUT
+      );
+
+---------------------------------------------------------------------------
+-- DAC
+---------------------------------------------------------------------------      
+  gen_SPI : if INCLUDE_SPI = 1 generate
+    THE_DAC_SPI : spi_ltc2600
+      generic map (
+        BITS       => 16,
+        WAITCYCLES => 15)
+      port map(
+        CLK_IN         => clk_100_i,
+        RESET_IN       => reset_i,
+        -- Slave bus
+        BUS_ADDR_IN    => dac_addr,
+        BUS_READ_IN    => dac_read_en,
+        BUS_WRITE_IN   => dac_write_en,
+        BUS_ACK_OUT    => dac_ack,
+        BUS_BUSY_OUT   => dac_busy,
+        BUS_DATA_IN    => dac_data_in,
+        BUS_DATA_OUT   => dac_data_out,
+        -- SPI connections
+        SPI_CS_OUT(0)  => DAC_CS,
+        SPI_SDI_IN     => DAC_SDO,
+        SPI_SDO_OUT    => DAC_SDI,
+        SPI_SCK_OUT    => DAC_SCK,
+        SPI_CLR_OUT(0) => DAC_CLR
+        );
+  end generate;
+
+---------------------------------------------------------------------------
+-- Trigger logic
+---------------------------------------------------------------------------
+  gen_TRIGGER_LOGIC : if INCLUDE_TRIGGER_LOGIC = 1 generate
+    THE_TRIG_LOGIC : input_to_trigger_logic
+      generic map(
+        INPUTS  => PHYSICAL_INPUTS,
+        OUTPUTS => 4
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT  => INPUT(PHYSICAL_INPUTS downto 1),
+        OUTPUT => trig_out,
+
+        DATA_IN  => trig_din,
+        DATA_OUT => trig_dout,
+        WRITE_IN => trig_write,
+        READ_IN  => trig_read,
+        ACK_OUT  => trig_ack,
+        NACK_OUT => trig_nack,
+        ADDR_IN  => trig_addr
+        );
+--    FPGA5_COMM(10 downto 7) <= trig_out;
+  end generate;
+
+---------------------------------------------------------------------------
+-- Input Statistics
+---------------------------------------------------------------------------
+  gen_STATISTICS : if INCLUDE_STATISTICS = 1 generate
+
+    THE_STAT_LOGIC : entity work.input_statistics
+      generic map(
+        INPUTS           => PHYSICAL_INPUTS,
+        SINGLE_FIFO_ONLY => USE_SINGLE_FIFO
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT => INPUT(PHYSICAL_INPUTS downto 1),
+
+        DATA_IN  => stat_din,
+        DATA_OUT => stat_dout,
+        WRITE_IN => stat_write,
+        READ_IN  => stat_read,
+        ACK_OUT  => stat_ack,
+        NACK_OUT => stat_nack,
+        ADDR_IN  => stat_addr
+        );
+  end generate;
+
+---------------------------------------------------------------------------
+-- SED Detection
+---------------------------------------------------------------------------
+  THE_SED : entity work.sedcheck
+    port map(
+      CLK       => clk_100_i,
+      ERROR_OUT => sed_error,
+      BUS_RX    => bussed_rx,
+      BUS_TX    => bussed_tx
+      );  
+
+---------------------------------------------------------------------------
+-- LED
+---------------------------------------------------------------------------
+  --LED_GREEN     <= not time_counter(26);
+  --LED_ORANGE    <= not time_counter(27);
+  LED_RED       <= not time_counter_2(29);
+  LED_YELLOW    <= not time_counter(29);
+  LED_SFP_GREEN <= not med_stat_op(9);
+  LED_SFP_RED   <= not (med_stat_op(10) or med_stat_op(11));
+
+---------------------------------------------------------------------------
+-- Test Connector
+---------------------------------------------------------------------------    
+  --TEST_LINE(0)            <= OR_IN;
+  --TEST_LINE(8 downto 1)   <= CLK_CM(8 downto 1);
+  --TEST_LINE(9)            <= CLK_EXT;
+  --TEST_LINE(11 downto 10) <= SFP_MOD(2 downto 1);
+  --TEST_LINE(13 downto 12) <= SPARE_LINE(2 downto 1);
+  --TEST_LINE(31 downto 14) <= time_counter(31 downto 14);
+  TEST_LINE(15 downto 0) <= logic_analyser_i;
+
+
+  LVDS(1) <= OR_IN;                     --or_all(INPUT);
+  LVDS(2) <= not OR_IN;                 -- timing_trg_received_i;
+  --CLK_MNGR_USER(3 downto 0) <= (others => '0') ;
+
+---------------------------------------------------------------------------
+-- Test Circuits
+---------------------------------------------------------------------------
+  process
+  begin
+    wait until rising_edge(CLK_CM(1));  --(clk_100_i);
+    time_counter <= time_counter + 1;
+  end process;
+
+  process
+  begin
+    wait until rising_edge(clk_osc_int);   --(clk_100_i);
+    time_counter_2 <= time_counter_2 + 1;
+  end process;
+-------------------------------------------------------------------------------
+-- TDC
+-------------------------------------------------------------------------------
+  THE_TDC : TDC_record
+    generic map (
+      CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
+      STATUS_REG_NR  => 21,             -- Number of status regs
+      DEBUG          => c_YES,
+      SIMULATION     => c_NO)
+    port map (
+      RESET              => reset_i,
+      CLK_TDC            => clk_tdc_i,
+      CLK_READOUT        => clk_100_i,  -- Clock for the readout
+      REFERENCE_TIME     => timing_trg_received_i,  -- Reference time input
+      HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
+      HIT_CAL_IN         => clk_cal,    -- Hits for calibrating the TDC
+      -- Trigger signals from handler
+      BUSRDO_RX          => readout_rx,
+      BUSRDO_TX          => readout_tx(0),
+      -- Slow control bus
+      BUS_RX             => bustdc_rx,
+      BUS_TX             => bustdc_tx,
+      -- Dubug signals
+      INFO_IN            => timer,
+      LOGIC_ANALYSER_OUT => logic_analyser_i
+      );
+
+
+
+  -- For single edge measurements
+  gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+    hit_in_i(32 downto 1) <= INPUT;
+  end generate;
+
+  -- For ToT Measurements
+  gen_double : if DOUBLE_EDGE_TYPE = 2 generate
+    Gen_Hit_In_Signals : for i in 1 to 32 generate
+      hit_in_i(i*2-1) <= INPUT(i);
+      hit_in_i(i*2)   <= not INPUT(i);
+    end generate Gen_Hit_In_Signals;
+  end generate;
+
+end architecture;
diff --git a/releases/tdc_v2.3.1/dirich.vhd b/releases/tdc_v2.3.1/dirich.vhd
new file mode 100644 (file)
index 0000000..5cace1b
--- /dev/null
@@ -0,0 +1,406 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.version.all;
+use work.config.all;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.med_sync_define.all;
+
+entity dirich is
+  port(
+    CLOCK_IN        : in    std_logic; --Main Oscillator
+    TRIG_IN         : in    std_logic; --Reference Time
+    CLOCK_CAL       : in    std_logic; --on-board calibration oscillator
+    
+    INPUT                : in    std_logic_vector(32 downto 1);
+    PWM                  : out   std_logic_vector(32 downto 1);
+    
+    --Additional IO
+    SIG                  : inout std_logic_vector( 5 downto 1); 
+    --1:master ready, 2: slave ready, 3-4 trigger, 5 spare
+    --LED
+    LED_GREEN            : out   std_logic;
+    LED_YELLOW           : out   std_logic;
+    LED_ORANGE           : out   std_logic;
+    LED_RED              : out   std_logic;
+    --ADC
+    ADC_SCLK             : out   std_logic;
+    ADC_CS               : out   std_logic;
+    ADC_DIN              : out   std_logic;
+    ADC_DOUT             : in    std_logic;
+    --Flash, 1-wire, Reload
+    FLASH_CLK            : out   std_logic;
+    FLASH_CS             : out   std_logic;
+    FLASH_IN             : out   std_logic;
+    FLASH_OUT            : in    std_logic;
+    PROGRAMN             : out   std_logic;
+    TEMP_LINE            : inout std_logic;
+    
+    --Test Connectors
+    TEST_LINE            : out std_logic_vector(14 downto 1)
+    );
+
+
+  attribute syn_useioff                  : boolean;
+  attribute syn_useioff of FLASH_CLK  : signal is true;
+  attribute syn_useioff of FLASH_CS   : signal is true;
+  attribute syn_useioff of FLASH_IN   : signal is true;
+  attribute syn_useioff of FLASH_OUT  : signal is true;
+  
+end entity;
+
+architecture dirich_arch of dirich is
+  attribute syn_keep     : boolean;
+  attribute syn_preserve : boolean;
+  
+  signal clk_sys, clk_full, clk_full_osc   : std_logic;
+  signal GSR_N       : std_logic;
+  signal reset_i     : std_logic;
+  signal clear_i     : std_logic;
+  
+  signal time_counter      : unsigned(31 downto 0) := (others => '0');
+  signal debug_clock_reset : std_logic_vector(31 downto 0);
+  signal debug_tools       : std_logic_vector(31 downto 0);
+
+  --Media Interface
+  signal med2int           : med2int_array_t(0 to 0);
+  signal int2med           : int2med_array_t(0 to 0);
+  signal med_stat_debug    : std_logic_vector (1*64-1  downto 0);
+  signal link_stat_in, link_stat_out : std_logic;
+  --READOUT
+  signal readout_rx        : READOUT_RX;
+  signal readout_tx        : readout_tx_array_t(0 to 0);
+
+  signal ctrlbus_tx, bustdc_tx, bussci_tx, bustools_tx, bustc_tx, busthresh_tx, bus_master_in   : CTRLBUS_TX;
+  signal ctrlbus_rx, bustdc_rx, bussci_rx, bustools_rx, bustc_rx, busthresh_rx, bus_master_out  : CTRLBUS_RX;
+  
+  signal common_stat_reg   : std_logic_vector(std_COMSTATREG*32-1 downto 0) := (others => '0');
+  signal common_ctrl_reg   : std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+  
+  signal sed_error_i       : std_logic;
+  signal clock_select      : std_logic;
+  signal bus_master_active : std_logic;
+  signal flash_clk_i       : std_logic;
+  
+  signal spi_cs, spi_mosi, spi_miso, spi_clk : std_logic_vector(15 downto 0);
+
+  signal pwm_i            : std_logic_vector(31 downto 0);
+  signal timer            : TIMERS;
+  signal lcd_data         : std_logic_vector(511 downto 0);
+  signal hdr_io           : std_logic_vector(9 downto 0);
+  signal led_off          : std_logic;
+  --TDC
+  signal hit_in_i         : std_logic_vector(32 downto 1);
+  signal logic_analyser_i : std_logic_vector(16 downto 1);
+
+  attribute syn_keep of GSR_N     : signal is true;
+  attribute syn_preserve of GSR_N : signal is true;  
+
+
+  component usrmclk
+    port(
+      USRMCLKI : in std_ulogic;
+      USRMCLKTS : in std_ulogic
+      );
+  end component;
+  
+  
+begin
+
+---------------------------------------------------------------------------
+-- Clock & Reset Handling
+---------------------------------------------------------------------------
+THE_CLOCK_RESET :  entity work.clock_reset_handler
+  port map(
+    CLOCK_IN        => CLOCK_IN,
+    RESET_FROM_NET  => med2int(0).stat_op(13),
+    
+    BUS_RX          => bustc_rx,
+    BUS_TX          => bustc_tx,
+
+    RESET_OUT       => reset_i,
+    CLEAR_OUT       => clear_i,
+    GSR_OUT         => GSR_N,
+    
+    REF_CLK_OUT     => clk_full,
+    SYS_CLK_OUT     => clk_sys,
+    RAW_CLK_OUT     => clk_full_osc,
+    
+    DEBUG_OUT       => debug_clock_reset
+    );
+
+
+---------------------------------------------------------------------------
+-- TrbNet Uplink
+---------------------------------------------------------------------------
+
+  THE_MEDIA_INTERFACE : entity work.med_ecp5_sfp_sync
+    generic map(
+      SERDES_NUM    => 0,
+      IS_SYNC_SLAVE => c_YES
+      )
+    port map(
+      CLK_REF_FULL       => med2int(0).clk_full,
+      CLK_INTERNAL_FULL  => clk_full_osc,
+      SYSCLK        => clk_sys,
+      RESET         => reset_i,
+      CLEAR         => clear_i,
+      --Internal Connection
+      MEDIA_MED2INT => med2int(0),
+      MEDIA_INT2MED => int2med(0),
+
+      --Sync operation
+      RX_DLM      => open,
+      RX_DLM_WORD => open,
+      TX_DLM      => open,
+      TX_DLM_WORD => open,
+
+      --SFP Connection
+      SD_PRSNT_N_IN  => link_stat_in,
+      SD_LOS_IN      => link_stat_in,
+      SD_TXDIS_OUT   => link_stat_out,
+      --Control Interface
+      BUS_RX         => bussci_rx,
+      BUS_TX         => bussci_tx,
+      -- Status and control port
+      STAT_DEBUG     => med_stat_debug(63 downto 0),
+      CTRL_DEBUG     => open
+      );
+
+SIG(2) <= '1' when link_stat_out = '1' else '0';
+link_stat_in <= SIG(1);
+      
+---------------------------------------------------------------------------
+-- Endpoint
+---------------------------------------------------------------------------
+THE_ENDPOINT : entity work.trb_net16_endpoint_hades_full_handler_record
+  generic map (
+    ADDRESS_MASK                 => x"FFFF",
+    BROADCAST_BITMASK            => x"FF",
+    REGIO_INIT_ENDPOINT_ID       => x"0001",
+    TIMING_TRIGGER_RAW           => c_YES,
+    --Configure data handler
+    DATA_INTERFACE_NUMBER        => 1,
+    DATA_BUFFER_DEPTH            => 10,
+    DATA_BUFFER_WIDTH            => 32,
+    DATA_BUFFER_FULL_THRESH      => 2**8,
+    TRG_RELEASE_AFTER_DATA       => c_YES,
+    HEADER_BUFFER_DEPTH          => 9,
+    HEADER_BUFFER_FULL_THRESH    => 2**8
+    )
+
+  port map(
+    --  Misc
+    CLK                          => clk_sys,
+    RESET                        => reset_i,
+    CLK_EN                       => '1',
+
+    --  Media direction port
+    MEDIA_MED2INT                => med2int(0),
+    MEDIA_INT2MED                => int2med(0),
+
+    --Timing trigger in
+    TRG_TIMING_TRG_RECEIVED_IN   => TRIG_IN,
+    
+    READOUT_RX                   => readout_rx,
+    READOUT_TX                   => readout_tx,
+
+    --Slow Control Port
+    REGIO_COMMON_STAT_REG_IN     => common_stat_reg,  --0x00
+    REGIO_COMMON_CTRL_REG_OUT    => common_ctrl_reg,  --0x20
+    BUS_RX                       => ctrlbus_rx,
+    BUS_TX                       => ctrlbus_tx,
+    BUS_MASTER_IN                => bus_master_in,
+    BUS_MASTER_OUT               => bus_master_out,
+    BUS_MASTER_ACTIVE            => bus_master_active,
+    
+    ONEWIRE_INOUT                => TEMP_LINE,
+    --Timing registers
+    TIMERS_OUT                   => timer
+    );
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+
+
+  THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record
+    generic map(
+      PORT_NUMBER      => 5,
+      PORT_ADDRESSES   => (0 => x"d000", 1 => x"b000", 2 => x"d300", 3 => x"a000", 4 => x"c000", others => x"0000"),
+      PORT_ADDR_MASK   => (0 => 12,      1 => 9,       2 => 1,       3 => 8,       4 => 12,      others => 0),
+      PORT_MASK_ENABLE => 1
+      )
+    port map(
+      CLK   => clk_sys,
+      RESET => reset_i,
+
+      REGIO_RX  => ctrlbus_rx,
+      REGIO_TX  => ctrlbus_tx,
+      
+      BUS_RX(0) => bustools_rx, --Flash, SPI, UART, ADC, SED
+      BUS_RX(1) => bussci_rx,   --SCI Serdes
+      BUS_RX(2) => bustc_rx,    --Clock switch
+      BUS_RX(3) => busthresh_rx,
+      BUS_RX(4) => bustdc_rx,
+      BUS_TX(0) => bustools_tx,
+      BUS_TX(1) => bussci_tx,
+      BUS_TX(2) => bustc_tx,
+      BUS_TX(3) => busthresh_tx,
+      BUS_TX(4) => bustdc_tx,
+      
+      STAT_DEBUG => open
+      );
+
+---------------------------------------------------------------------------
+-- Control Tools
+---------------------------------------------------------------------------
+  THE_TOOLS: entity work.trb3sc_tools 
+    port map(
+      CLK         => clk_sys,
+      RESET       => reset_i,
+      
+      --Flash & Reload
+      FLASH_CS          => FLASH_CS,
+      FLASH_CLK         => flash_clk_i,
+      FLASH_IN          => FLASH_OUT,
+      FLASH_OUT         => FLASH_IN,
+      PROGRAMN          => PROGRAMN,
+      REBOOT_IN         => common_ctrl_reg(15),
+      --SPI
+      SPI_CS_OUT        => open,
+      SPI_MOSI_OUT      => open,
+      SPI_MISO_IN       => open,
+      SPI_CLK_OUT       => open,
+      --Header
+      HEADER_IO         => hdr_io,
+      ADDITIONAL_REG(0) => led_off,
+      --LCD
+      LCD_DATA_IN       => lcd_data,
+      --ADC
+      ADC_CS            => ADC_CS,
+      ADC_MOSI          => ADC_DIN,
+      ADC_MISO          => ADC_DOUT,
+      ADC_CLK           => ADC_SCLK,
+      --Trigger & Monitor 
+      MONITOR_INPUTS    => INPUT,
+      TRIG_GEN_INPUTS   => INPUT,
+      TRIG_GEN_OUTPUTS  => SIG(4 downto 3),
+      --SED
+      SED_ERROR_OUT     => sed_error_i,
+      --Slowcontrol
+      BUS_RX            => bustools_rx,
+      BUS_TX            => bustools_tx,
+      --Control master for default settings
+      BUS_MASTER_IN     => bus_master_in,
+      BUS_MASTER_OUT    => bus_master_out,
+      BUS_MASTER_ACTIVE => bus_master_active,
+      DEBUG_OUT         => debug_tools
+      );
+
+      
+THE_FLASH_CLOCK : usrmclk
+  port map(
+    USRMCLKI  => flash_clk_i,
+    USRMCLKTS => '0'
+    );
+      
+---------------------------------------------------------------------------
+-- PWM / Thresh
+---------------------------------------------------------------------------  
+
+THE_PWM_GEN : entity work.pwm_generator
+  port map(
+    CLK        => clk_sys,
+    BUS_RX     => busthresh_rx,
+    BUS_TX     => busthresh_tx,
+    TEMP_IN    => timer.temperature,
+    PWM        => pwm_i
+    );
+      
+
+
+---------------------------------------------------------------------------
+-- I/O
+---------------------------------------------------------------------------
+  TEST_LINE(10 downto 1)  <= hdr_io;
+  TEST_LINE(14 downto 11) <= time_counter(31 downto 28);
+  
+---------------------------------------------------------------------------
+-- LCD Data to display
+---------------------------------------------------------------------------  
+  lcd_data(15 downto 0)    <= timer.network_address;
+  lcd_data(47 downto 16)   <= timer.microsecond;
+  lcd_data(79 downto 48)   <= std_logic_vector(to_unsigned(VERSION_NUMBER_TIME,32));
+  lcd_data(91 downto 80)   <= timer.temperature;
+  lcd_data(95 downto 92)   <= x"0";
+  lcd_data(159 downto 96)  <= timer.uid;
+  lcd_data(511 downto 160) <= (others => '0');  
+  
+---------------------------------------------------------------------------
+-- LED
+---------------------------------------------------------------------------
+  LED_GREEN            <= '0' or led_off;   
+  LED_ORANGE           <= '0' or led_off;
+  LED_RED              <= '0' or led_off;
+  LED_YELLOW           <= '0' or led_off;
+
+---------------------------------------------------------------------------
+-- Test Circuits
+---------------------------------------------------------------------------
+  process begin
+    wait until rising_edge(clk_sys);
+    time_counter <= time_counter + 1; 
+    if reset_i = '1' then
+      time_counter <= (others => '0');
+    end if;
+  end process;  
+
+-------------------------------------------------------------------------------
+-- TDC
+-------------------------------------------------------------------------------
+  THE_TDC : entity work.TDC_record
+    generic map (
+      CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
+      STATUS_REG_NR  => 21,             -- Number of status regs
+      DEBUG          => c_YES,
+      SIMULATION     => c_NO)
+    port map (
+      RESET              => reset_i,
+      CLK_TDC            => CLOCK_IN,
+      CLK_READOUT        => clk_sys,  -- Clock for the readout
+      REFERENCE_TIME     => TRIG_IN,  -- Reference time input
+      HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
+      HIT_CAL_IN         => CLOCK_CAL,    -- Hits for calibrating the TDC
+      -- Trigger signals from handler
+      BUSRDO_RX          => readout_rx,
+      BUSRDO_TX          => readout_tx(0),
+      -- Slow control bus
+      BUS_RX             => bustdc_rx,
+      BUS_TX             => bustdc_tx,
+      -- Dubug signals
+      INFO_IN            => timer,
+      LOGIC_ANALYSER_OUT => logic_analyser_i
+      );
+
+  -- For single edge measurements
+  gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+    hit_in_i <= INPUT;
+  end generate;
+
+  -- For ToT Measurements
+  gen_double : if DOUBLE_EDGE_TYPE = 2 generate
+    Gen_Hit_In_Signals : for i in 1 to 16 generate
+      hit_in_i(i*2-1) <= INPUT(i);
+      hit_in_i(i*2)   <= not INPUT(i);
+    end generate Gen_Hit_In_Signals;
+  end generate;
+
+end architecture;
+
+
+
diff --git a/releases/tdc_v2.3.1/dirich_tdc_constraints.lpf b/releases/tdc_v2.3.1/dirich_tdc_constraints.lpf
new file mode 100644 (file)
index 0000000..e93f3c9
--- /dev/null
@@ -0,0 +1,605 @@
+#################################################################
+# TDC Constraints
+#################################################################
+##############################################################################
+##                 DELAY LINE and HIT BUFFER PLACEMENTS                    ##
+##############################################################################
+##############################################################################
+UGROUP "Ref_Ch" BBOX 1 36
+       BLKNAME THE_TDC/ReferenceChannel/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "Ref_Ch" SITE "R8C44D" ;
+UGROUP "hitBuf_ref" BBOX 1 1 
+       BLKNAME THE_TDC/hit_mux_ref
+       ;
+LOCATE UGROUP "hitBuf_ref" SITE "R9C45D" ;
+UGROUP "Ref_ff_en" BBOX 1 1 
+       BLKNAME THE_TDC/ReferenceChannel/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "Ref_ff_en" SITE "R9C62D" ;
+#
+UGROUP "FC_1" BBOX 1 36
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_1" SITE "R11C2D" ;
+UGROUP "hitBuf_1" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.1.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_1" SITE "R12C3D" ;
+UGROUP "ff_en_1" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_1" SITE "R12C20D" ;
+#
+UGROUP "FC_2" BBOX 1 36
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_2" SITE "R13C2D" ;
+UGROUP "hitBuf_2" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.2.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_2" SITE "R14C3D" ;
+UGROUP "ff_en_2" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_2" SITE "R14C20D" ;
+#
+UGROUP "FC_3" BBOX 1 36
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_3" SITE "R30C2D" ;
+UGROUP "hitBuf_3" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.3.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_3" SITE "R31C3D" ;
+UGROUP "ff_en_3" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_3" SITE "R31C20D" ;
+#
+UGROUP "FC_4" BBOX 1 36
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_4" SITE "R32C2D" ;
+UGROUP "hitBuf_4" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.4.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_4" SITE "R33C3D" ;
+UGROUP "ff_en_4" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_4" SITE "R33C20D" ;
+#
+UGROUP "FC_5" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_5" SITE "R35C2D" ;
+UGROUP "hitBuf_5" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.5.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_5" SITE "R36C3D" ;
+UGROUP "ff_en_5" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_5" SITE "R36C20D" ;
+#
+UGROUP "FC_6" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_6" SITE "R37C2D" ;
+UGROUP "hitBuf_6" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.6.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_6" SITE "R38C3D" ;
+UGROUP "ff_en_6" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_6" SITE "R38C20D" ;
+#
+UGROUP "FC_7" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_7" SITE "R54C2D" ;
+UGROUP "hitBuf_7" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.7.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_7" SITE "R55C3D" ;
+UGROUP "ff_en_7" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_7" SITE "R55C20D" ;
+#
+UGROUP "FC_8" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_8" SITE "R56C2D" ;
+UGROUP "hitBuf_8" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.8.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_8" SITE "R57C3D" ;
+UGROUP "ff_en_8" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_8" SITE "R57C20D" ;
+#
+UGROUP "FC_9" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_9" SITE "R59C2D" ;
+UGROUP "hitBuf_9" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.9.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_9" SITE "R60C3D" ;
+UGROUP "ff_en_9" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_9" SITE "R60C20D" ;
+#
+UGROUP "FC_10" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_10" SITE "R61C2D" ;
+UGROUP "hitBuf_10" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.10.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_10" SITE "R62C3D" ;
+UGROUP "ff_en_10" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_10" SITE "R62C20D" ;
+#
+UGROUP "FC_11" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_11" SITE "R78C2D" ;
+UGROUP "hitBuf_11" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.11.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_11" SITE "R79C3D" ;
+UGROUP "ff_en_11" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_11" SITE "R79C20D" ;
+#
+UGROUP "FC_12" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_12" SITE "R80C2D" ;
+UGROUP "hitBuf_12" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.12.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_12" SITE "R81C3D" ;
+UGROUP "ff_en_12" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_12" SITE "R81C20D" ;
+#
+UGROUP "FC_13" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_13" SITE "R90C2D" ;
+UGROUP "hitBuf_13" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.13.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_13" SITE "R91C3D" ;
+UGROUP "ff_en_13" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_13" SITE "R91C20D" ;
+#
+UGROUP "FC_14" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_14" SITE "R92C2D" ;
+UGROUP "hitBuf_14" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.14.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_14" SITE "R93C3D" ;
+UGROUP "ff_en_14" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_14" SITE "R93C20D" ;
+#
+UGROUP "FC_15" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_15" SITE "R90C86D" ;
+UGROUP "hitBuf_15" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.15.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_15" SITE "R91C87D" ;
+UGROUP "ff_en_15" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_15" SITE "R91C104D" ;
+#
+UGROUP "FC_16" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_16" SITE "R92C86D" ;
+UGROUP "hitBuf_16" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.16.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_16" SITE "R93C87D" ;
+UGROUP "ff_en_16" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_16" SITE "R93C104D" ;
+#
+UGROUP "FC_17" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_17" SITE "R11C86D" ;
+UGROUP "hitBuf_17" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.17.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_17" SITE "R12C87D" ;
+UGROUP "ff_en_17" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_17" SITE "R12C104D" ;
+#
+UGROUP "FC_18" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_18" SITE "R13C86D" ;
+UGROUP "hitBuf_18" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.18.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_18" SITE "R14C87D" ;
+UGROUP "ff_en_18" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_18" SITE "R14C104D" ;
+#
+UGROUP "FC_19" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_19" SITE "R30C86D" ;
+UGROUP "hitBuf_19" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.19.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_19" SITE "R31C87D" ;
+UGROUP "ff_en_19" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_19" SITE "R31C104D" ;
+#
+UGROUP "FC_20" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_20" SITE "R32C86D" ;
+UGROUP "hitBuf_20" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.20.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_20" SITE "R33C87D" ;
+UGROUP "ff_en_20" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_20" SITE "R33C104D" ;
+#
+UGROUP "FC_21" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_21" SITE "R35C86D" ;
+UGROUP "hitBuf_21" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.21.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_21" SITE "R36C87D" ;
+UGROUP "ff_en_21" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_21" SITE "R36C104D" ;
+#
+UGROUP "FC_22" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_22" SITE "R37C86D" ;
+UGROUP "hitBuf_22" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.22.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_22" SITE "R38C87D" ;
+UGROUP "ff_en_22" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_22" SITE "R38C104D" ;
+#
+UGROUP "FC_23" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_23" SITE "R54C86D" ;
+UGROUP "hitBuf_23" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.23.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_23" SITE "R55C87D" ;
+UGROUP "ff_en_23" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_23" SITE "R55C104D" ;
+#
+UGROUP "FC_24" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_24" SITE "R56C86D" ;
+UGROUP "hitBuf_24" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.24.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_24" SITE "R57C87D" ;
+UGROUP "ff_en_24" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_24" SITE "R57C104D" ;
+#
+UGROUP "FC_25" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_25" SITE "R59C86D" ;
+UGROUP "hitBuf_25" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.25.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_25" SITE "R60C87D" ;
+UGROUP "ff_en_25" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_25" SITE "R60C104D" ;
+#
+UGROUP "FC_26" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_26" SITE "R61C86D" ;
+UGROUP "hitBuf_26" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.26.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_26" SITE "R62C87D" ;
+UGROUP "ff_en_26" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_26" SITE "R62C104D" ;
+#
+UGROUP "FC_27" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_27" SITE "R78C86D" ;
+UGROUP "hitBuf_27" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.27.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_27" SITE "R79C87D" ;
+UGROUP "ff_en_27" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_27" SITE "R79C104D" ;
+#
+UGROUP "FC_28" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_28" SITE "R80C86D" ;
+UGROUP "hitBuf_28" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.28.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_28" SITE "R81C87D" ;
+UGROUP "ff_en_28" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_28" SITE "R81C104D" ;
+#
+UGROUP "FC_29" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_29" SITE "R11C44D" ;
+UGROUP "hitBuf_29" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.29.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_29" SITE "R12C45D" ;
+UGROUP "ff_en_29" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_29" SITE "R12C62D" ;
+#
+UGROUP "FC_30" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_30" SITE "R13C44D" ;
+UGROUP "hitBuf_30" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.30.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_30" SITE "R14C45D" ;
+UGROUP "ff_en_30" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_30" SITE "R14C62D" ;
+#
+UGROUP "FC_31" BBOX 1 36 
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_31" SITE "R90C44D" ;
+UGROUP "hitBuf_31" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.31.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_31" SITE "R91C45D" ;
+UGROUP "ff_en_31" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_31" SITE "R91C62D" ;
+#
+UGROUP "FC_32" BBOX 1 36
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_32" SITE "R92C44D" ;
+UGROUP "hitBuf_32" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_hit_mux.32.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_32" SITE "R93C45D" ;
+UGROUP "ff_en_32" BBOX 1 1 
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_32" SITE "R93C62D" ;
+##############################################################################
+##                          CHANNEL PLACEMENTS                             ##
+##############################################################################
+UGROUP "EF_LT1" BBOX 23 42 
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LT1" SITE "R11C2D" ;
+UGROUP "EF_LT2" BBOX 23 42 
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LT2" SITE "R35C2D" ;
+UGROUP "EF_LB2" BBOX 23 42
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LB2" SITE "R59C2D" ;
+UGROUP "EF_LB1" BBOX 13 42 
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LB1" SITE "R81C2D" ;
+UGROUP "EF_RT1" BBOX 23 42 
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RT1" SITE "R11C83D" ;
+UGROUP "EF_RT2" BBOX 23 42 
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RT2" SITE "R35C83D" ;
+UGROUP "EF_RB2" BBOX 23 42 
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RB2" SITE "R59C83D" ;
+UGROUP "EF_RB1" BBOX 13 42 
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RB1" SITE "R81C83D" ;
+UGROUP "EF_CB1" BBOX 13 39 
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Buffer_32.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Buffer_32.The_Buffer
+       ;
+LOCATE UGROUP "EF_CB1" SITE "R81C44D" ;
+UGROUP "EF_CT1" BBOX 21 39 
+       BLKNAME THE_TDC/ReferenceChannel/Channel200
+       BLKNAME THE_TDC/ReferenceChannel/Buffer_32.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Buffer_32.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Buffer_32.The_Buffer
+       ;
+LOCATE UGROUP "EF_CT1" SITE "R2C44D" ;
+#############################################################################
+## Stretcher
+#############################################################################
+UGROUP "Stretcher_A" BBOX 6 8 
+       BLKNAME THE_TDC/gen_double_withStretcher.The_Stretcher/Stretcher_A_1;
+LOCATE UGROUP "Stretcher_A" SITE "R2C117D" ;
+UGROUP "Stretcher_B" BBOX 6 8 
+       BLKNAME THE_TDC/gen_double_withStretcher.The_Stretcher/Stretcher_B_1;
+LOCATE UGROUP "Stretcher_B" SITE "R2C2D" ;
+#############################################################################
+## Coarse counter register placement
+#############################################################################
+
+#############################################################################
+## Other Logic Placements
+#############################################################################
+
+#############################################################################
+##                         Unimportant Data Lines                          ##
+#############################################################################
+
+#MULTICYCLE TO CELL "THE_TDC/ReferenceChannel/sync_q*" 4.000000 X ;
+#MULTICYCLE TO CELL "THE_TDC/GEN_Channels*Channels/sync_q*" 4.000000 X ;
+#MULTICYCLE FROM CELL "THE_TDC/ReferenceChannel/Channel200/RingBuffer*FIFO/FF*" TO CELL "THE_TDC/ReferenceChannel/Channel200/ringBuffer_almost_full_sync*" 2.000000 X ;
+#MULTICYCLE FROM CELL "THE_TDC/GEN_Channels*Channels/Channel200/RingBuffer*FIFO/FF*" TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/ringBuffer_almost_full_sync*" 2.000000 X ;
+#BLOCK NET "THE_TDC/pulse[*]" ;
+#BLOCK NET "THE_TDC/hit_in_s*" ;
+#BLOCK NET "THE_TDC/edge_rising[*]" ;
+#BLOCK NET "THE_TDC/edge_falling[*]" ;
+# MULTICYCLE FROM CELL "PROC_TDC_CTRL_REG*tdc_ctrl_reg*" 4x;
+# MULTICYCLE TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/SimAdderNo*FC/FF*" 4x;
+# MULTICYCLE TO CELL "THE_TDC/ReferenceChannel/Channel200/SimAdderNo*FC/FF*" 4x;
+## Maybe effective
+# MULTICYCLE FROM CELL "THE_TDC/GEN_Channels*Channels/The_Buffer/*" TO CELL "THE_TDC/TheReadout/rd_en*" 2 X;
+# # BLOCK NET "THE_TDC/reset_tdc*" ;
+# # BLOCK NET "THE_TDC/reset_rdo*" ;
+# # #BLOCK NET "THE_TDC/hit_in_*" ;
+# # BLOCK NET "THE_TDC/hit_latch*" ;
+# # BLOCK NET "THE_TDC/reset_counters*" ;
+
+USE PRIMARY NET "THE_TDC/coarse_cntr_reset" ;
+USE PRIMARY NET "THE_TDC/trg_win_end_tdc" ;
+
+BLOCK PATH FROM CLKNET "THE_TDC/hit_in_s*" ;
+BLOCK PATH FROM CLKNET "TRIG_IN_c" ;
+BLOCK PATH FROM CLKNET "THE_TDC/edge_rising[*]" ;
+BLOCK PATH FROM CLKNET "CLOCK_CAL_c" ;
+BLOCK PATH FROM GROUP "INP_group" ;
+BLOCK PATH TO GROUP "LED_group" ;
+BLOCK NET "THE_TDC/edge_falling_3r[*]" ;
+BLOCK NET "THE_TDC/edge_rising_3r[*]" ;
+BLOCK NET "TRIG_IN_c" ;
+BLOCK PATH FROM CELL "THE_TDC/calibration_on*" TO CELL "THE_TDC/ReferenceChannel/Channel200/SimAdderNo.FC/FF*" ;
+BLOCK PATH FROM CELL "THE_TDC/calibration_on*" TO CELL "THE_TDC/GEN_Channels.*.Channels/Channel200/SimAdderNo.FC/FF*" ;
+
+MULTICYCLE FROM CELL "THE_TDC/reset_counters" 30.000000 ns ;
+MULTICYCLE FROM CELL "THE_TDC/reset_tdc*" TO CLKNET "CLOCK_IN_c" 4.000000 X ;
+MULTICYCLE TO CELL "THE_TDC/TheReadout/TW_pre*" 4.000000 X ;
+MULTICYCLE TO CELL "THE_TDC/TheReadout/TW_post*" 4.000000 X ;
+MULTICYCLE FROM CELL "THE_TDC/TheSlowcontrolBus/DATA_OUT*" 20.000000 ns ;
+MULTICYCLE TO CELL "THE_TDC/TheHitCounterBus/BUS_TX[data][*]" 20.000000 ns ;
+MULTICYCLE TO CELL "THE_TDC/TheStatusRegisterBus/BUS_TX[data][*]" 20.000000 ns ;
+MULTICYCLE TO CELL "THE_TDC/TheChannelDebugBus/BUS_TX[data][*]" 20.000000 ns ;
+MULTICYCLE FROM CELL "THE_TDC/TheTriggerHandler/TRG_TIME_OUT[*]" TO CELL "THE_TDC/status_registers_bus[*]" 2.000000 X ;
+MULTICYCLE FROM CELL "THE_TDC/TheEpochCounter/counter*" TO CELL "THE_TDC/ReferenceChannel/Channel200/epoch_cntr*" 3.000000 X ;
+MULTICYCLE FROM CELL "THE_TDC/TheEpochCounter/counter*" TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/epoch_cntr*" 3.000000 X ;
+MULTICYCLE FROM CELL "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.gentrgapi.the_trigger_apl/reg_TRG_TYPE_OUT[*]" TO CELL "THE_TDC/TheTriggerHandler/STATE_TW_CURRENT[*]" 2.000000 X ;
+#MULTICYCLE FROM CELL "THE_TDC/calibration_on*" TO CELL "THE_TDC/ReferenceChannel/Channel200/SimAdderNo.FC/FF*" 3.000000 X ;
+#MULTICYCLE FROM CELL "THE_TDC/calibration_on*" TO CELL "THE_TDC/GEN_Channels.*.Channels/Channel200/SimAdderNo.FC/FF*" 3.000000 X ;
+
+MAXDELAY NET "THE_TDC/hit_in_i*" 1.000000 nS ;
diff --git a/releases/tdc_v2.3.1/dirich_trbnet_constraints.lpf b/releases/tdc_v2.3.1/dirich_trbnet_constraints.lpf
new file mode 100644 (file)
index 0000000..1d5dc0d
--- /dev/null
@@ -0,0 +1,51 @@
+#################################################################
+# Reset Nets
+#################################################################  
+GSR_NET NET "reset_i";  
+
+#################################################################
+# Locate Serdes and media interfaces
+#################################################################
+
+MULTICYCLE TO CELL "THE_MEDIA_DOWNLINK/SCI_DATA_OUT*" 50 ns;
+MULTICYCLE TO CELL "THE_MEDIA_UPLINK/SCI_DATA_OUT*" 50 ns;
+MULTICYCLE TO CELL "THE_CLOCK_RESET/THE_RESET_HANDLER/final_reset*" 30.000000 ns ;
+MULTICYCLE TO CELL "gen_SPI_DAC_SPI_*io*" 20 ns;
+MULTICYCLE TO CELL "THE_SPI_MASTER_THE_SPI_SLIM_tx_sreg_oregio*" 20 ns;
+
+BLOCK PATH TO CELL "gen_TRIGGER_LOGIC_THE_TRIG_LOGIC/out_*";
+
+#Jan: Placement of TrbNet components (at least, most of them)
+
+MULTICYCLE FROM CELL "THE_CLOCK_RESET/THE_RESET_HANDLER/final_reset*" 30.000000 ns ;
+
+
+
+REGION "REGION_SPI" "R21C60D"  8 18 DEVSIZE;
+LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MASTER/SPI_group" REGION "REGION_SPI";
+LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MEMORY/SPI_group" REGION "REGION_SPI";
+
+
+
+REGION "REGION_TRBNET" "R23C44D"  46 39 DEVSIZE;
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/MPLEX/MUX_group" REGION "REGION_TRBNET";
+
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.gen_api.DAT_PASSIVE_API/API_group" REGION "REGION_TRBNET";
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_api.DAT_PASSIVE_API/API_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.2.gentermbuf.termbuf/TRMBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_regio.regIO/the_addresses/HUBLOGIC_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_regio.regIO/RegIO_group" REGION "REGION_TRBNET";
+
+LOCATE UGROUP "THE_BUS_HANDLER/Bus_handler_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_INTERNAL_BUS_HANDLER/Bus_handler_group" REGION "REGION_TRBNET";
+
diff --git a/releases/tdc_v2.3.1/fallingEdgeDetect.vhd b/releases/tdc_v2.3.1/fallingEdgeDetect.vhd
new file mode 100644 (file)
index 0000000..f413d0b
--- /dev/null
@@ -0,0 +1,17 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+entity fallingEdgeDetect is
+  port (CLK       : in  std_logic;
+        SIGNAL_IN : in  std_logic;
+        PULSE_OUT : out std_logic);
+end fallingEdgeDetect;
+
+architecture Behavioral of fallingEdgeDetect is
+  
+  signal signal_d : std_logic;
+  
+begin
+  signal_d  <= SIGNAL_IN                    when rising_edge(CLK);
+  PULSE_OUT <= (not SIGNAL_IN) and signal_d when rising_edge(CLK);
+end Behavioral;
diff --git a/releases/tdc_v2.3.1/hit_mux.vhd b/releases/tdc_v2.3.1/hit_mux.vhd
new file mode 100644 (file)
index 0000000..bb61b83
--- /dev/null
@@ -0,0 +1,81 @@
+-------------------------------------------------------------------------------
+-- Title      : Hit Multiplexer
+-- Project    : FPGA TDC
+-------------------------------------------------------------------------------
+-- File       : hit_mux.vhd
+-- Author     : Cahit Ugur  <c.ugur@gsi.de>
+-- Created    : 2014-03-26
+-- Last update: 2014-12-04
+-------------------------------------------------------------------------------
+-- Description: Entity to decide the hit for the channels between physical or
+-- calibration hits.
+-------------------------------------------------------------------------------
+-- Copyright (c) 2014 
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author  Description
+-- 2014-03-26  1.0      cugur   Created
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity hit_mux is
+  
+  port (
+    CH_EN_IN           : in  std_logic;  -- channel enable signal
+    CALIBRATION_EN_IN  : in  std_logic;  -- calibration enable signal
+    HIT_CALIBRATION_IN : in  std_logic;  -- hit signal for calibration purposes
+    HIT_PHYSICAL_IN    : in  std_logic;  -- physical hit signal
+    HIT_OUT            : out std_logic);  -- hit signal to the delay lines
+end entity hit_mux;
+
+architecture behavioral of hit_mux is
+
+  signal ch_en           : std_logic;
+  signal calibration_en  : std_logic;
+  signal hit_calibration : std_logic;
+  signal hit_physical    : std_logic;
+  signal hit             : std_logic;
+
+  attribute syn_keep                    : boolean;
+  attribute syn_keep of ch_en           : signal is true;
+  attribute syn_keep of calibration_en  : signal is true;
+  attribute syn_keep of hit_calibration : signal is true;
+  attribute syn_keep of hit_physical    : signal is true;
+  attribute syn_keep of hit             : signal is true;
+  --attribute syn_preserve                        : boolean;
+  --attribute syn_preserve of coarse_cntr         : signal is true;
+  attribute nomerge                     : string;
+  attribute nomerge of ch_en            : signal is "true";
+  attribute nomerge of calibration_en   : signal is "true";
+  attribute nomerge of hit_calibration  : signal is "true";
+  attribute nomerge of hit_physical     : signal is "true";
+  attribute nomerge of hit              : signal is "true";
+
+  
+begin  -- architecture behavioral
+
+  ch_en           <= CH_EN_IN;
+  calibration_en  <= CALIBRATION_EN_IN;
+  hit_calibration <= HIT_CALIBRATION_IN;
+  hit_physical    <= HIT_PHYSICAL_IN;
+
+  process (ch_en, calibration_en, hit_calibration, hit_physical)
+  begin
+    if ch_en = '1' then
+      if calibration_en = '1' then
+        hit <= hit_calibration;
+      else
+        hit <= hit_physical;
+      end if;
+    else
+      hit <= '0';
+    end if;
+  end process;
+
+  HIT_OUT <= hit;
+
+end architecture behavioral;
diff --git a/releases/tdc_v2.3.1/risingEdgeDetect.vhd b/releases/tdc_v2.3.1/risingEdgeDetect.vhd
new file mode 100644 (file)
index 0000000..fad9f7e
--- /dev/null
@@ -0,0 +1,17 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+
+entity risingEdgeDetect is
+  port (CLK       : in  std_logic;
+        SIGNAL_IN : in  std_logic;
+        PULSE_OUT : out std_logic);
+end risingEdgeDetect;
+
+architecture Behavioral of risingEdgeDetect is
+  
+  signal signal_d : std_logic;
+  
+begin
+  signal_d  <= SIGNAL_IN                    when rising_edge(CLK);
+  PULSE_OUT <= (not signal_d) and SIGNAL_IN when rising_edge(CLK);
+end Behavioral;
diff --git a/releases/tdc_v2.3.1/tdc_components.vhd b/releases/tdc_v2.3.1/tdc_components.vhd
new file mode 100644 (file)
index 0000000..9aabf2a
--- /dev/null
@@ -0,0 +1,669 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library work;
+use work.trb_net_std.all;
+use work.config.all;
+
+package tdc_components is
+
+  --type CH_RX is record
+  --  data        : std_logic_vector_array_36(0 to NUM_TDC_CHANNELS);
+  --  data_valid  : std_logic_vector(NUM_TDC_CHANNELS-1 downto 0);
+  --  almost_full : std_logic_vector(NUM_TDC_CHANNELS-1 downto 0);
+  --  empty       : std_logic_vector(NUM_TDC_CHANNELS-1 downto 0);
+  --end record;
+
+  --type CH_TX is record
+  --  read_en : std_logic_vector(NUM_TDC_CHANNELS-1 downto 0);
+  --end record;
+
+  component TDC_record is
+    generic (
+      CHANNEL_NUMBER : integer range 2 to 65;
+      STATUS_REG_NR  : integer range 0 to 31;
+      DEBUG          : integer range 0 to 1;
+      SIMULATION     : integer range 0 to 1);
+    port (
+      RESET              : in  std_logic;
+      CLK_TDC            : in  std_logic;
+      CLK_READOUT        : in  std_logic;
+      REFERENCE_TIME     : in  std_logic;
+      HIT_IN             : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+      HIT_CAL_IN         : in  std_logic;
+      BUSRDO_RX          : in  READOUT_RX;
+      BUSRDO_TX          : out READOUT_TX;
+      BUS_RX             : in  CTRLBUS_RX;
+      BUS_TX             : in  CTRLBUS_TX;
+      INFO_IN            : in  TIMERS;
+      LOGIC_ANALYSER_OUT : out std_logic_vector(15 downto 0));
+  end component TDC_record;
+
+  component TDC is
+    generic (
+      CHANNEL_NUMBER : integer range 2 to 65;
+      STATUS_REG_NR  : integer range 0 to 31;
+      CONTROL_REG_NR : integer range 1 to 8;
+      DEBUG          : integer range 0 to 1 := c_YES;
+      SIMULATION     : integer range 0 to 1 := c_NO);
+    port (
+      RESET                 : in  std_logic;
+      CLK_TDC               : in  std_logic;
+      CLK_READOUT           : in  std_logic;
+      REFERENCE_TIME        : in  std_logic;
+      HIT_IN                : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+      HIT_CAL_IN            : in  std_logic;
+      TRG_WIN_PRE           : in  std_logic_vector(10 downto 0);
+      TRG_WIN_POST          : in  std_logic_vector(10 downto 0);
+      TRG_DATA_VALID_IN     : in  std_logic                     := '0';
+      VALID_TIMING_TRG_IN   : in  std_logic                     := '0';
+      VALID_NOTIMING_TRG_IN : in  std_logic                     := '0';
+      INVALID_TRG_IN        : in  std_logic                     := '0';
+      TMGTRG_TIMEOUT_IN     : in  std_logic                     := '0';
+      SPIKE_DETECTED_IN     : in  std_logic                     := '0';
+      MULTI_TMG_TRG_IN      : in  std_logic                     := '0';
+      SPURIOUS_TRG_IN       : in  std_logic                     := '0';
+      TRG_NUMBER_IN         : in  std_logic_vector(15 downto 0) := (others => '0');
+      TRG_CODE_IN           : in  std_logic_vector(7 downto 0)  := (others => '0');
+      TRG_INFORMATION_IN    : in  std_logic_vector(23 downto 0) := (others => '0');
+      TRG_TYPE_IN           : in  std_logic_vector(3 downto 0)  := (others => '0');
+      TRG_RELEASE_OUT       : out std_logic;
+      TRG_STATUSBIT_OUT     : out std_logic_vector(31 downto 0);
+      DATA_OUT              : out std_logic_vector(31 downto 0);
+      DATA_WRITE_OUT        : out std_logic;
+      DATA_FINISHED_OUT     : out std_logic;
+      HCB_READ_EN_IN        : in  std_logic;
+      HCB_WRITE_EN_IN       : in  std_logic;
+      HCB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+      HCB_DATA_OUT          : out std_logic_vector(31 downto 0);
+      HCB_DATAREADY_OUT     : out std_logic;
+      HCB_UNKNOWN_ADDR_OUT  : out std_logic;
+      SRB_READ_EN_IN        : in  std_logic;
+      SRB_WRITE_EN_IN       : in  std_logic;
+      SRB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+      SRB_DATA_OUT          : out std_logic_vector(31 downto 0);
+      SRB_DATAREADY_OUT     : out std_logic;
+      SRB_UNKNOWN_ADDR_OUT  : out std_logic;
+      CDB_READ_EN_IN        : in  std_logic;
+      CDB_WRITE_EN_IN       : in  std_logic;
+      CDB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+      CDB_DATA_OUT          : out std_logic_vector(31 downto 0);
+      CDB_DATAREADY_OUT     : out std_logic;
+      CDB_UNKNOWN_ADDR_OUT  : out std_logic;
+      ESB_READ_EN_IN        : in  std_logic;
+      ESB_WRITE_EN_IN       : in  std_logic;
+      ESB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+      ESB_DATA_OUT          : out std_logic_vector(31 downto 0);
+      ESB_DATAREADY_OUT     : out std_logic;
+      ESB_UNKNOWN_ADDR_OUT  : out std_logic;
+      EFB_READ_EN_IN        : in  std_logic;
+      EFB_WRITE_EN_IN       : in  std_logic;
+      EFB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+      EFB_DATA_OUT          : out std_logic_vector(31 downto 0);
+      EFB_DATAREADY_OUT     : out std_logic;
+      EFB_UNKNOWN_ADDR_OUT  : out std_logic;
+      LHB_READ_EN_IN        : in  std_logic;
+      LHB_WRITE_EN_IN       : in  std_logic;
+      LHB_ADDR_IN           : in  std_logic_vector(6 downto 0);
+      LHB_DATA_OUT          : out std_logic_vector(31 downto 0);
+      LHB_DATAREADY_OUT     : out std_logic;
+      LHB_UNKNOWN_ADDR_OUT  : out std_logic;
+      LOGIC_ANALYSER_OUT    : out std_logic_vector(15 downto 0);
+      CONTROL_REG_IN        : in  std_logic_vector(32*CONTROL_REG_NR-1 downto 0));
+  end component TDC;
+
+  component Channel
+    generic (
+      CHANNEL_ID : integer range 0 to 64;
+      DEBUG      : integer range 0 to 1;
+      SIMULATION : integer range 0 to 1;
+      REFERENCE  : integer range 0 to 1);
+    port (
+      RESET_200                 : in  std_logic;
+      RESET_100                 : in  std_logic;
+      RESET_COUNTERS            : in  std_logic;
+      CLK_200                   : in  std_logic;
+      CLK_100                   : in  std_logic;
+      HIT_IN                    : in  std_logic;
+      HIT_EDGE_IN               : in  std_logic;
+      TRG_WIN_END_TDC_IN        : in  std_logic;
+      TRG_WIN_END_RDO_IN        : in  std_logic;
+      READ_EN_IN                : in  std_logic;
+      FIFO_DATA_OUT             : out std_logic_vector(35 downto 0);
+      FIFO_DATA_VALID_OUT       : out std_logic;
+      FIFO_ALMOST_FULL_OUT      : out std_logic;
+      FIFO_EMPTY_OUT            : out std_logic;
+      RING_BUFFER_FULL_THRES_IN : in  std_logic_vector(6 downto 0);
+      COARSE_COUNTER_IN         : in  std_logic_vector(10 downto 0);
+      EPOCH_COUNTER_IN          : in  std_logic_vector(27 downto 0);
+      EPOCH_WRITE_EN_IN         : in  std_logic;
+      LOST_HIT_NUMBER           : out std_logic_vector(23 downto 0);
+      HIT_DETECT_NUMBER         : out std_logic_vector(30 downto 0);
+      ENCODER_START_NUMBER      : out std_logic_vector(23 downto 0);
+      ENCODER_FINISHED_NUMBER   : out std_logic_vector(23 downto 0);
+      FIFO_WRITE_NUMBER         : out std_logic_vector(23 downto 0);
+      Channel_200_DEBUG_OUT     : out std_logic_vector(31 downto 0);
+      Channel_DEBUG_OUT         : out std_logic_vector(31 downto 0));
+  end component;
+
+  component Channel_200 is
+    generic (
+      CHANNEL_ID : integer range 0 to 64;
+      DEBUG      : integer range 0 to 1;
+      SIMULATION : integer range 0 to 1;
+      REFERENCE  : integer range 0 to 1);
+    port (
+      CLK_200                   : in  std_logic;
+      RESET_200                 : in  std_logic;
+      CLK_100                   : in  std_logic;
+      RESET_100                 : in  std_logic;
+      HIT_IN                    : in  std_logic;
+      HIT_EDGE_IN               : in  std_logic;
+      TRG_WIN_END_TDC_IN        : in  std_logic;
+      TRG_WIN_END_RDO_IN        : in  std_logic;
+      EPOCH_COUNTER_IN          : in  std_logic_vector(27 downto 0);
+      COARSE_COUNTER_IN         : in  std_logic_vector(10 downto 0);
+      FIFO_DATA_OUT             : out std_logic_vector(35 downto 0);
+      FIFO_DATA_VALID_OUT       : out std_logic;
+      FIFO_ALMOST_FULL_OUT      : out std_logic;
+      RING_BUFFER_FULL_THRES_IN : in  std_logic_vector(6 downto 0);
+      EPOCH_WRITE_EN_IN         : in  std_logic;
+      ENCODER_START_OUT         : out std_logic;
+      ENCODER_FINISHED_OUT      : out std_logic;
+      FIFO_WRITE_OUT            : out std_logic;
+      CHANNEL_200_DEBUG_OUT     : out std_logic_vector(31 downto 0));
+  end component Channel_200;
+
+  component Readout_Header is
+    port (
+      RESET_100             : in  std_logic;
+      CLK_100               : in  std_logic;
+      VALID_TIMING_TRG_IN   : in  std_logic;
+      VALID_NOTIMING_TRG_IN : in  std_logic;
+      INVALID_TRG_IN        : in  std_logic;
+      TRG_CODE_IN           : in  std_logic_vector(7 downto 0);
+      TRG_TYPE_IN           : in  std_logic_vector(3 downto 0);
+      TRG_RELEASE_OUT       : out std_logic;
+      TRG_STATUSBIT_OUT     : out std_logic_vector(31 downto 0);
+      DATA_OUT              : out std_logic_vector(31 downto 0);
+      DATA_WRITE_OUT        : out std_logic;
+      DATA_FINISHED_OUT     : out std_logic);
+  end component Readout_Header;
+
+  component Readout_record is
+    generic (
+      CHANNEL_NUMBER : integer range 2 to 65;
+      STATUS_REG_NR  : integer range 0 to 31);
+    port (
+      RESET_100           : in  std_logic;
+      RESET_200           : in  std_logic;
+      RESET_COUNTERS      : in  std_logic;
+      CLK_100             : in  std_logic;
+      CLK_200             : in  std_logic;
+      HIT_IN              : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+      CH_DATA_IN          : in  std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+      CH_DATA_VALID_IN    : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      CH_ALMOST_FULL_IN   : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      CH_EMPTY_IN         : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      READOUT_RX          : in  READOUT_RX;
+      READOUT_TX          : out READOUT_TX;
+      READ_EN_OUT         : out std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      TRG_WIN_PRE_IN      : in  std_logic_vector(10 downto 0);
+      TRG_WIN_POST_IN     : in  std_logic_vector(10 downto 0);
+      TRG_WIN_EN_IN       : in  std_logic;
+      TRG_WIN_END_TDC_IN  : in  std_logic;
+      TRG_WIN_END_RDO_IN  : in  std_logic;
+      TRG_TDC_IN          : in  std_logic;
+      TRG_TIME_IN         : in  std_logic_vector(38 downto 0);
+      MISSING_REF_TIME_IN : in  std_logic;
+      LIGHT_MODE_IN       : in  std_logic;
+      DEBUG_MODE_EN_IN    : in  std_logic;
+      INFO_IN             : in  TIMERS;
+      STATISTICS_OUT      : out std_logic_vector_array_24(0 to 15);
+      READOUT_DEBUG       : out std_logic_vector(31 downto 0));
+  end component Readout_record;
+
+  component Readout is
+    generic (
+      CHANNEL_NUMBER : integer range 2 to 65;
+      STATUS_REG_NR  : integer range 0 to 31);
+    port (
+      RESET_100             : in  std_logic;
+      RESET_200             : in  std_logic;
+      RESET_COUNTERS        : in  std_logic;
+      CLK_100               : in  std_logic;
+      CLK_200               : in  std_logic;
+      HIT_IN                : in  std_logic_vector(CHANNEL_NUMBER-1 downto 1);
+      CH_DATA_IN            : in  std_logic_vector_array_36(0 to CHANNEL_NUMBER);
+      CH_DATA_VALID_IN      : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      CH_ALMOST_FULL_IN     : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      CH_EMPTY_IN           : in  std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      TRG_DATA_VALID_IN     : in  std_logic;
+      VALID_TIMING_TRG_IN   : in  std_logic;
+      VALID_NOTIMING_TRG_IN : in  std_logic;
+      INVALID_TRG_IN        : in  std_logic;
+      TMGTRG_TIMEOUT_IN     : in  std_logic;
+      SPIKE_DETECTED_IN     : in  std_logic;
+      MULTI_TMG_TRG_IN      : in  std_logic;
+      SPURIOUS_TRG_IN       : in  std_logic;
+      TRG_CODE_IN           : in  std_logic_vector(7 downto 0);
+      TRG_INFORMATION_IN    : in  std_logic_vector(23 downto 0);
+      TRG_TYPE_IN           : in  std_logic_vector(3 downto 0);
+      TRG_RELEASE_OUT       : out std_logic;
+      TRG_STATUSBIT_OUT     : out std_logic_vector(31 downto 0);
+      DATA_OUT              : out std_logic_vector(31 downto 0);
+      DATA_WRITE_OUT        : out std_logic;
+      DATA_FINISHED_OUT     : out std_logic;
+      READ_EN_OUT           : out std_logic_vector(CHANNEL_NUMBER-1 downto 0);
+      TRG_WIN_PRE_IN        : in  std_logic_vector(10 downto 0);
+      TRG_WIN_POST_IN       : in  std_logic_vector(10 downto 0);
+      TRG_WIN_EN_IN         : in  std_logic;
+      TRG_WIN_END_TDC_IN    : in  std_logic;
+      TRG_WIN_END_RDO_IN    : in  std_logic;
+      TRG_TDC_IN            : in  std_logic;
+      TRG_TIME_IN           : in  std_logic_vector(38 downto 0);
+      MISSING_REF_TIME_IN   : in  std_logic;
+      LIGHT_MODE_IN         : in  std_logic;
+      DEBUG_MODE_EN_IN      : in  std_logic;
+      STATISTICS_OUT        : out std_logic_vector_array_24(0 to 15);
+      READOUT_DEBUG         : out std_logic_vector(31 downto 0));
+  end component Readout;
+
+  component TriggerHandler is
+    generic (
+      TRIGGER_NUM            : integer;
+      PHYSICAL_EVENT_TRG_NUM : integer);
+    port (
+      CLK_TRG               : in  std_logic;
+      CLK_RDO               : in  std_logic;
+      CLK_TDC               : in  std_logic;
+      RESET_TRG             : in  std_logic;
+      RESET_RDO             : in  std_logic;
+      RESET_TDC             : in  std_logic;
+      VALID_TIMING_TRG_IN   : in  std_logic;
+      VALID_NOTIMING_TRG_IN : in  std_logic;
+      TRG_TYPE_IN           : in  std_logic_vector(3 downto 0);
+      TRG_RELEASE_IN        : in  std_logic;
+      TRG_IN                : in  std_logic_vector(TRIGGER_NUM-1 downto 0);
+      TRG_RDO_OUT           : out std_logic_vector(TRIGGER_NUM-1 downto 0);
+      TRG_TDC_OUT           : out std_logic_vector(TRIGGER_NUM-1 downto 0);
+      TRG_WIN_EN_IN         : in  std_logic;
+      TRG_WIN_POST_IN       : in  unsigned(10 downto 0);
+      TRG_WIN_END_RDO_OUT   : out std_logic;
+      TRG_WIN_END_TDC_OUT   : out std_logic;
+      MISSING_REF_TIME_OUT  : out std_logic;
+      COARSE_COUNTER_IN     : in  std_logic_vector(10 downto 0);
+      EPOCH_COUNTER_IN      : in  std_logic_vector(27 downto 0);
+      TRG_TIME_OUT          : out std_logic_vector(38 downto 0) := (others => '0');
+      DEBUG_OUT             : out std_logic_vector(31 downto 0));
+  end component TriggerHandler;
+
+  component LogicAnalyser
+    generic (
+      CHANNEL_NUMBER : integer range 2 to 65);
+    port (
+      CLK        : in  std_logic;
+      RESET      : in  std_logic;
+      DATA_IN    : in  std_logic_vector(3*32-1 downto 0);
+      CONTROL_IN : in  std_logic_vector(3 downto 0);
+      DATA_OUT   : out std_logic_vector(15 downto 0));
+  end component;
+
+  component BusHandler_record is
+    generic (
+      BUS_LENGTH : integer range 0 to 64);
+    port (
+      RESET    : in  std_logic;
+      CLK      : in  std_logic;
+      BUS_RX   : in  CTRLBUS_RX;
+      BUS_TX   : out CTRLBUS_TX;
+      DATA_IN  : in  std_logic_vector_array_32(0 to BUS_LENGTH);
+      DATA_OUT : out std_logic_vector_array_32(0 to BUS_LENGTH));
+  end component BusHandler_record;
+
+  component BusHandler
+    generic (
+      BUS_LENGTH : integer range 0 to 64 := 2);
+    port (
+      RESET            : in  std_logic;
+      CLK              : in  std_logic;
+      DATA_IN          : in  std_logic_vector_array_32(0 to BUS_LENGTH);
+      READ_EN_IN       : in  std_logic;
+      WRITE_EN_IN      : in  std_logic;
+      ADDR_IN          : in  std_logic_vector(6 downto 0);
+      DATA_OUT         : out std_logic_vector(31 downto 0);
+      DATAREADY_OUT    : out std_logic;
+      UNKNOWN_ADDR_OUT : out std_logic);
+  end component;
+
+  component ROM_FIFO
+    port (
+      Address    : in  std_logic_vector(7 downto 0);
+      OutClock   : in  std_logic;
+      OutClockEn : in  std_logic;
+      Reset      : in  std_logic;
+      Q          : out std_logic_vector(3 downto 0));
+  end component;
+
+  component Stretcher is
+    generic (
+      CHANNEL : integer range 1 to 64;
+      DEPTH   : integer range 1 to 10);
+    port (
+      PULSE_IN  : in  std_logic_vector(CHANNEL-1 downto 0);
+      PULSE_OUT : out std_logic_vector(CHANNEL-1 downto 0));
+  end component Stretcher;
+
+  component Stretcher_A is
+    generic (
+      CHANNEL : integer range 1 to 64;
+      DEPTH   : integer range 1 to 10);
+    port (
+      PULSE_IN  : in  std_logic_vector(CHANNEL*DEPTH downto 1);
+      PULSE_OUT : out std_logic_vector(CHANNEL*DEPTH-1 downto 0));
+  end component Stretcher_A;
+
+  component Stretcher_B is
+    generic (
+      CHANNEL : integer range 1 to 64;
+      DEPTH   : integer range 1 to 10);
+    port (
+      PULSE_IN  : in  std_logic_vector(CHANNEL*DEPTH-1 downto 1);
+      PULSE_OUT : out std_logic_vector(CHANNEL*DEPTH-1 downto 1));
+  end component Stretcher_B;
+
+  component up_counter
+    generic (
+      NUMBER_OF_BITS : positive);
+    port (
+      CLK       : in  std_logic;
+      RESET     : in  std_logic;
+      COUNT_OUT : out std_logic_vector(NUMBER_OF_BITS-1 downto 0);
+      UP_IN     : in  std_logic);
+  end component;
+
+  component Adder_304
+    port (
+      CLK    : in  std_logic;
+      RESET  : in  std_logic;
+      DataA  : in  std_logic_vector(303 downto 0);
+      DataB  : in  std_logic_vector(303 downto 0);
+      ClkEn  : in  std_logic;
+      Result : out std_logic_vector(303 downto 0));
+  end component;
+
+  component Adder_288 is
+    port (
+      DataA  : in  std_logic_vector(287 downto 0);
+      DataB  : in  std_logic_vector(287 downto 0);
+      Clk    : in  std_logic;
+      Reset  : in  std_logic;
+      ClkEn  : in  std_logic;
+      Result : out std_logic_vector(287 downto 0)); 
+  end component Adder_288;
+
+  component Encoder_304_Bit is
+    port (
+      RESET            : in  std_logic;
+      CLK              : in  std_logic;
+      START_IN         : in  std_logic;
+      THERMOCODE_IN    : in  std_logic_vector(303 downto 0);
+      FINISHED_OUT     : out std_logic;
+      DECIMAL_CODE_OUT : out std_logic_vector(9 downto 0);
+      ENCODER_INFO_OUT : out std_logic_vector(1 downto 0);
+      ENCODER_DEBUG    : out std_logic_vector(31 downto 0));
+  end component Encoder_304_Bit;
+
+  component Encoder_288_Bit is
+    port (
+      RESET            : in  std_logic;
+      CLK              : in  std_logic;
+      START_IN         : in  std_logic;
+      THERMOCODE_IN    : in  std_logic_vector(287 downto 0);
+      FINISHED_OUT     : out std_logic;
+      DECIMAL_CODE_OUT : out std_logic_vector(9 downto 0);
+      ENCODER_INFO_OUT : out std_logic;
+      ENCODER_DEBUG    : out std_logic_vector(31 downto 0);
+      CHAIN_VALID_OUT  : out std_logic;
+      CHAIN_DATA_OUT   : out std_logic_vector(15 downto 0));
+  end component Encoder_288_Bit;
+
+  component hit_mux is
+    port (
+      CH_EN_IN           : in  std_logic;
+      CALIBRATION_EN_IN  : in  std_logic;
+      HIT_CALIBRATION_IN : in  std_logic;
+      HIT_PHYSICAL_IN    : in  std_logic;
+      HIT_OUT            : out std_logic);
+  end component hit_mux;
+
+  component ROM_encoder_3
+    port (
+      Address    : in  std_logic_vector(9 downto 0);
+      OutClock   : in  std_logic;
+      OutClockEn : in  std_logic;
+      Reset      : in  std_logic;
+      Q          : out std_logic_vector(7 downto 0));
+  end component;
+
+  component ROM4_Encoder is
+    port (
+      Address    : in  std_logic_vector(9 downto 0);
+      OutClock   : in  std_logic;
+      OutClockEn : in  std_logic;
+      Reset      : in  std_logic;
+      Q          : out std_logic_vector(7 downto 0));
+  end component ROM4_Encoder;
+
+  component FIFO_36x128_OutReg is
+    port (
+      Data  : in  std_logic_vector(35 downto 0);
+      Clock : in  std_logic;
+      WrEn  : in  std_logic;
+      RdEn  : in  std_logic;
+      Reset : in  std_logic;
+      Q     : out std_logic_vector(35 downto 0);
+      Empty : out std_logic;
+      Full  : out std_logic);
+  end component FIFO_36x128_OutReg;
+
+  component FIFO_36x64_OutReg is
+    port (
+      Data  : in  std_logic_vector(35 downto 0);
+      Clock : in  std_logic;
+      WrEn  : in  std_logic;
+      RdEn  : in  std_logic;
+      Reset : in  std_logic;
+      Q     : out std_logic_vector(35 downto 0);
+      Empty : out std_logic;
+      Full  : out std_logic);
+  end component;
+
+  component FIFO_36x32_OutReg is
+    port (
+      Data  : in  std_logic_vector(35 downto 0);
+      Clock : in  std_logic;
+      WrEn  : in  std_logic;
+      RdEn  : in  std_logic;
+      Reset : in  std_logic;
+      Q     : out std_logic_vector(35 downto 0);
+      Empty : out std_logic;
+      Full  : out std_logic);
+  end component FIFO_36x32_OutReg;
+
+  component FIFO_36x16_OutReg is
+    port (
+      Data  : in  std_logic_vector(35 downto 0);
+      Clock : in  std_logic;
+      WrEn  : in  std_logic;
+      RdEn  : in  std_logic;
+      Reset : in  std_logic;
+      Q     : out std_logic_vector(35 downto 0);
+      Empty : out std_logic;
+      Full  : out std_logic);
+  end component;
+
+  component FIFO_DC_36x128_DynThr_OutReg is
+    port (
+      Data         : in  std_logic_vector(35 downto 0);
+      WrClock      : in  std_logic;
+      RdClock      : in  std_logic;
+      WrEn         : in  std_logic;
+      RdEn         : in  std_logic;
+      Reset        : in  std_logic;
+      RPReset      : in  std_logic;
+      AmFullThresh : in  std_logic_vector(6 downto 0);
+      Q            : out std_logic_vector(35 downto 0);
+      Empty        : out std_logic;
+      Full         : out std_logic;
+      AlmostFull   : out std_logic);
+  end component FIFO_DC_36x128_DynThr_OutReg;
+
+  component FIFO_DC_36x128_OutReg is
+    port (
+      Data       : in  std_logic_vector(35 downto 0);
+      WrClock    : in  std_logic;
+      RdClock    : in  std_logic;
+      WrEn       : in  std_logic;
+      RdEn       : in  std_logic;
+      Reset      : in  std_logic;
+      RPReset    : in  std_logic;
+      Q          : out std_logic_vector(35 downto 0);
+      Empty      : out std_logic;
+      Full       : out std_logic;
+      AlmostFull : out std_logic);
+  end component FIFO_DC_36x128_OutReg;
+
+  component FIFO_DC_36x64_DynThr_OutReg is
+    port (
+      Data         : in  std_logic_vector(35 downto 0);
+      WrClock      : in  std_logic;
+      RdClock      : in  std_logic;
+      WrEn         : in  std_logic;
+      RdEn         : in  std_logic;
+      Reset        : in  std_logic;
+      RPReset      : in  std_logic;
+      AmFullThresh : in  std_logic_vector(5 downto 0);
+      Q            : out std_logic_vector(35 downto 0);
+      Empty        : out std_logic;
+      Full         : out std_logic;
+      AlmostFull   : out std_logic);
+  end component FIFO_DC_36x64_DynThr_OutReg;
+
+  component FIFO_DC_36x64_OutReg is
+    port (
+      Data       : in  std_logic_vector(35 downto 0);
+      WrClock    : in  std_logic;
+      RdClock    : in  std_logic;
+      WrEn       : in  std_logic;
+      RdEn       : in  std_logic;
+      Reset      : in  std_logic;
+      RPReset    : in  std_logic;
+      Q          : out std_logic_vector(35 downto 0);
+      Empty      : out std_logic;
+      Full       : out std_logic;
+      AlmostFull : out std_logic);
+  end component FIFO_DC_36x64_OutReg;
+
+  component FIFO_DC_36x32_OutReg is
+    port (
+      Data       : in  std_logic_vector(35 downto 0);
+      WrClock    : in  std_logic;
+      RdClock    : in  std_logic;
+      WrEn       : in  std_logic;
+      RdEn       : in  std_logic;
+      Reset      : in  std_logic;
+      RPReset    : in  std_logic;
+      Q          : out std_logic_vector(35 downto 0);
+      Empty      : out std_logic;
+      Full       : out std_logic;
+      AlmostFull : out std_logic);
+  end component;
+
+  component FIFO_DC_36x16_OutReg is
+    port (
+      Data       : in  std_logic_vector(35 downto 0);
+      WrClock    : in  std_logic;
+      RdClock    : in  std_logic;
+      WrEn       : in  std_logic;
+      RdEn       : in  std_logic;
+      Reset      : in  std_logic;
+      RPReset    : in  std_logic;
+      Q          : out std_logic_vector(35 downto 0);
+      Empty      : out std_logic;
+      Full       : out std_logic;
+      AlmostFull : out std_logic);
+  end component;
+
+  component bit_sync
+    generic (
+      DEPTH : integer);
+    port (
+      RESET : in  std_logic;
+      CLK0  : in  std_logic;
+      CLK1  : in  std_logic;
+      D_IN  : in  std_logic;
+      D_OUT : out std_logic);
+  end component;
+
+  component edge_to_pulse
+    port (
+      clock     : in  std_logic;
+      en_clk    : in  std_logic;
+      signal_in : in  std_logic;
+      pulse     : out std_logic);
+  end component;
+
+  component risingEdgeDetect is
+    port (
+      CLK       : in  std_logic;
+      SIGNAL_IN : in  std_logic;
+      PULSE_OUT : out std_logic);
+  end component risingEdgeDetect;
+
+  component fallingEdgeDetect is
+    port (
+      CLK       : in  std_logic;
+      SIGNAL_IN : in  std_logic;
+      PULSE_OUT : out std_logic);
+  end component fallingEdgeDetect;
+
+  component ShiftRegisterSISO
+    generic (
+      DEPTH : integer range 1 to 32;
+      WIDTH : integer range 1 to 32);
+    port (
+      CLK   : in  std_logic;
+      D_IN  : in  std_logic_vector(WIDTH-1 downto 0);
+      D_OUT : out std_logic_vector(WIDTH-1 downto 0));
+  end component;
+
+  component pll_in20_out100 is
+    port (
+      CLK   : in  std_logic;
+      CLKOP : out std_logic;
+      LOCK  : out std_logic);
+  end component pll_in20_out100;
+
+  component pll_in125_out100 is
+    port (
+      CLK   : in  std_logic;
+      CLKOP : out std_logic;
+      LOCK  : out std_logic);
+  end component pll_in125_out100;
+
+  component pll_in125_out333 is
+    port (
+      CLK   : in  std_logic;
+      CLKOP : out std_logic;
+      LOCK  : out std_logic);
+  end component pll_in125_out333;
+
+  component pll_in125_out33 is
+    port (
+      CLK   : in  std_logic;
+      CLKOP : out std_logic;
+      LOCK  : out std_logic);
+  end component pll_in125_out33;
+
+end package tdc_components;
diff --git a/releases/tdc_v2.3.1/tdc_constraints_64.lpf b/releases/tdc_v2.3.1/tdc_constraints_64.lpf
new file mode 100644 (file)
index 0000000..62bd08e
--- /dev/null
@@ -0,0 +1,1068 @@
+#################################################################
+# TDC Constraints
+#################################################################
+##############################################################################
+##                 DELAY LINE and HIT BUFFER PLACEMENTS                    ##
+##############################################################################
+##############################################################################
+UGROUP "Ref_Ch" BBOX 1 48 
+       BLKNAME THE_TDC/ReferenceChannel/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "Ref_Ch" SITE "R32C2D" ;
+UGROUP "hitBuf_ref" BBOX 1 1
+       BLKNAME THE_TDC/hit_mux_ref
+       ;
+LOCATE UGROUP "hitBuf_ref" SITE "R33C3D" ;
+UGROUP "Ref_ff_en"  BBOX 1 1
+       BLKNAME THE_TDC/ReferenceChannel/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "Ref_ff_en" SITE "R32C26D" ;
+#
+UGROUP "FC_1" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_1" SITE "R30C2D" ;
+UGROUP "hitBuf_1" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.1.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_1" SITE "R31C3D" ;
+UGROUP "ff_en_1" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_1" SITE "R30C26D" ;
+#
+UGROUP "FC_2" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_2" SITE "R48C2D" ;
+UGROUP "hitBuf_2" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.2.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_2" SITE "R49C3D" ;
+UGROUP "ff_en_2" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_2" SITE "R48C26D" ;
+#
+UGROUP "FC_3" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_3" SITE "R35C2D" ;
+UGROUP "hitBuf_3" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.3.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_3" SITE "R36C3D" ;
+UGROUP "ff_en_3" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_3" SITE "R35C26D" ;
+#
+UGROUP "FC_4" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_4" SITE "R37C2D" ;
+UGROUP "hitBuf_4" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.4.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_4" SITE "R38C3D" ;
+UGROUP "ff_en_4" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_4" SITE "R37C26D" ;
+#
+UGROUP "FC_5" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_5" SITE "R50C2D" ;
+UGROUP "hitBuf_5" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.5.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_5" SITE "R51C3D" ;
+UGROUP "ff_en_5" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_5" SITE "R50C26D" ;
+#
+UGROUP "FC_6" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_6" SITE "R71C2D" ;
+UGROUP "hitBuf_6" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.6.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_6" SITE "R72C3D" ;
+UGROUP "ff_en_6" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_6" SITE "R71C26D" ;
+#
+UGROUP "FC_7" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_7" SITE "R86C2D" ;
+UGROUP "hitBuf_7" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.7.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_7" SITE "R87C3D" ;
+UGROUP "ff_en_7" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_7" SITE "R86C26D" ;
+#
+UGROUP "FC_8" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_8" SITE "R84C2D" ;
+UGROUP "hitBuf_8" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.8.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_8" SITE "R85C3D" ;
+UGROUP "ff_en_8" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_8" SITE "R84C26D" ;
+#
+UGROUP "FC_9" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_9" SITE "R73C2D" ;
+UGROUP "hitBuf_9" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.9.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_9" SITE "R74C3D" ;
+UGROUP "ff_en_9" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_9" SITE "R73C26D" ;
+#
+UGROUP "FC_10" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_10" SITE "R102C2D" ;
+UGROUP "hitBuf_10" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.10.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_10" SITE "R103C3D" ;
+UGROUP "ff_en_10" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_10" SITE "R102C26D" ;
+#
+UGROUP "FC_11" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_11" SITE "R104C2D" ;
+UGROUP "hitBuf_11" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.11.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_11" SITE "R105C3D" ;
+UGROUP "ff_en_11" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_11" SITE "R104C26D" ;
+#
+UGROUP "FC_12" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_12" SITE "R91C2D" ;
+UGROUP "hitBuf_12" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.12.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_12" SITE "R92C3D" ;
+UGROUP "ff_en_12" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_12" SITE "R91C26D" ;
+#
+UGROUP "FC_13" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_13" SITE "R8C2D" ;
+UGROUP "hitBuf_13" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.13.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_13" SITE "R9C3D" ;
+UGROUP "ff_en_13" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_13" SITE "R8C26D" ;
+#
+UGROUP "FC_14" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_14" SITE "R10C2D" ;
+UGROUP "hitBuf_14" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.14.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_14" SITE "R11C3D" ;
+UGROUP "ff_en_14" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_14" SITE "R10C26D" ;
+#
+UGROUP "FC_15" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_15" SITE "R21C2D" ;
+UGROUP "hitBuf_15" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.15.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_15" SITE "R22C3D" ;
+UGROUP "ff_en_15" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_15" SITE "R21C26D" ;
+#
+UGROUP "FC_16" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_16" SITE "R23C2D" ;
+UGROUP "hitBuf_16" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.16.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_16" SITE "R24C3D" ;
+UGROUP "ff_en_16" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_16" SITE "R23C26D" ;
+#
+UGROUP "FC_17" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_17" SITE "R104C58D" ;
+UGROUP "hitBuf_17" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.17.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_17" SITE "R105C59D" ;
+UGROUP "ff_en_17" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_17" SITE "R104C82D" ;
+#
+UGROUP "FC_18" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_18" SITE "R89C58D" ;
+UGROUP "hitBuf_18" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.18.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_18" SITE "R90C59D" ;
+UGROUP "ff_en_18" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_18" SITE "R89C82D" ;
+#
+UGROUP "FC_19" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_19" SITE "R91C58D" ;
+UGROUP "hitBuf_19" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.19.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_19" SITE "R92C59D" ;
+UGROUP "ff_en_19" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_19" SITE "R91C82D" ;
+#
+UGROUP "FC_20" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_20" SITE "R102C58D" ;
+UGROUP "hitBuf_20" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.20.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_20" SITE "R103C59D" ;
+UGROUP "ff_en_20" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_20" SITE "R102C82D" ;
+#
+UGROUP "FC_21" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_21" SITE "R111C58D" ;
+UGROUP "hitBuf_21" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.21.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_21" SITE "R112C59D" ;
+UGROUP "ff_en_21" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_21" SITE "R111C82D" ;
+#
+UGROUP "FC_22" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_22" SITE "R113C58D" ;
+UGROUP "hitBuf_22" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.22.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_22" SITE "R114C59D" ;
+UGROUP "ff_en_22" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_22" SITE "R113C82D" ;
+#
+UGROUP "FC_23" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_23" SITE "R68C2D" ;
+UGROUP "hitBuf_23" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.23.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_23" SITE "R69C3D" ;
+UGROUP "ff_en_23" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_23" SITE "R68C26D" ;
+#
+UGROUP "FC_24" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_24" SITE "R55C2D" ;
+UGROUP "hitBuf_24" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.24.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_24" SITE "R56C3D" ;
+UGROUP "ff_en_24" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_24" SITE "R55C26D" ;
+#
+UGROUP "FC_25" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_25" SITE "R53C2D" ;
+UGROUP "hitBuf_25" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.25.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_25" SITE "R54C3D" ;
+UGROUP "ff_en_25" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_25" SITE "R53C26D" ;
+#
+UGROUP "FC_26" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_26" SITE "R66C2D" ;
+UGROUP "hitBuf_26" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.26.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_26" SITE "R67C3D" ;
+UGROUP "ff_en_26" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_26" SITE "R66C26D" ;
+#
+UGROUP "FC_27" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_27" SITE "R111C2D" ;
+UGROUP "hitBuf_27" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.27.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_27" SITE "R112C3D" ;
+UGROUP "ff_en_27" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_27" SITE "R111C26D" ;
+#
+UGROUP "FC_28" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_28" SITE "R113C2D" ;
+UGROUP "hitBuf_28" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.28.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_28" SITE "R114C3D" ;
+UGROUP "ff_en_28" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_28" SITE "R113C26D" ;
+#
+UGROUP "FC_29" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_29" SITE "R8C58D" ;
+UGROUP "hitBuf_29" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.29.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_29" SITE "R9C59D" ;
+UGROUP "ff_en_29" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_29" SITE "R8C82D" ;
+#
+UGROUP "FC_30" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_30" SITE "R10C58D" ;
+UGROUP "hitBuf_30" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.30.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_30" SITE "R11C59D" ;
+UGROUP "ff_en_30" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_30" SITE "R10C82D" ;
+#
+UGROUP "FC_31" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_31" SITE "R21C58D" ;
+UGROUP "hitBuf_31" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.31.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_31" SITE "R22C59D" ;
+UGROUP "ff_en_31" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_31" SITE "R21C82D" ;
+#
+UGROUP "FC_32" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_32" SITE "R23C58D" ;
+UGROUP "hitBuf_32" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.32.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_32" SITE "R24C59D" ;
+UGROUP "ff_en_32" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_32" SITE "R23C82D" ;
+#
+UGROUP "FC_33" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.33.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_33" SITE "R30C58D" ;
+UGROUP "hitBuf_33" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.33.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_33" SITE "R31C59D" ;
+UGROUP "ff_en_33" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.33.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_33" SITE "R30C82D" ;
+#
+UGROUP "FC_34" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.34.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_34" SITE "R32C58D" ;
+UGROUP "hitBuf_34" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.34.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_34" SITE "R33C59D" ;
+UGROUP "ff_en_34" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.34.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_34" SITE "R32C82D" ;
+#
+UGROUP "FC_35" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.35.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_35" SITE "R35C58D" ;
+UGROUP "hitBuf_35" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.35.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_35" SITE "R35C59D" ;
+UGROUP "ff_en_35" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.35.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_35" SITE "R35C82D" ;
+#
+UGROUP "FC_36" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.36.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_36" SITE "R37C58D" ;
+UGROUP "hitBuf_36" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.36.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_36" SITE "R38C59D" ;
+UGROUP "ff_en_36" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.36.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_36" SITE "R37C82D" ;
+#
+UGROUP "FC_37" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.37.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_37" SITE "R48C58D" ;
+UGROUP "hitBuf_37" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.37.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_37" SITE "R49C59D" ;
+UGROUP "ff_en_37" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.37.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_37" SITE "R48C82D" ;
+#
+UGROUP "FC_38" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.38.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_38" SITE "R50C58D" ;
+UGROUP "hitBuf_38" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.38.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_38" SITE "R51C59D" ;
+UGROUP "ff_en_38" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.38.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_38" SITE "R50C82D" ;
+#
+UGROUP "FC_39" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.39.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_39" SITE "R89C131D" ;
+UGROUP "hitBuf_39" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.39.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_39" SITE "R90C132D" ;
+UGROUP "ff_en_39" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.39.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_39" SITE "R89C155D" ;
+#
+UGROUP "FC_40" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.40.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_40" SITE "R91C131D" ;
+UGROUP "hitBuf_40" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.40.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_40" SITE "R92C132D" ;
+UGROUP "ff_en_40" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.40.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_40" SITE "R91C155D" ;
+#
+UGROUP "FC_41" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.41.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_41" SITE "R102C131D" ;
+UGROUP "hitBuf_41" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.41.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_41" SITE "R103C132D" ;
+UGROUP "ff_en_41" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.41.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_41" SITE "R102C155D" ;
+#
+UGROUP "FC_42" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.42.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_42" SITE "R104C131D" ;
+UGROUP "hitBuf_42" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.42.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_42" SITE "R105C132D" ;
+UGROUP "ff_en_42" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.42.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_42" SITE "R104C155D" ;
+#
+UGROUP "FC_43" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.43.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_43" SITE "R86C131D" ;
+UGROUP "hitBuf_43"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.43.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_43" SITE "R87C132D" ;
+UGROUP "ff_en_43" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.43.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_43" SITE "R86C155D" ;
+#
+UGROUP "FC_44" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.44.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_44" SITE "R84C131D" ;
+UGROUP "hitBuf_44"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.44.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_44" SITE "R85C132D" ;
+UGROUP "ff_en_44" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.44.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_44" SITE "R84C155D" ;
+#
+UGROUP "FC_45" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.45.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_45" SITE "R73C131D" ;
+UGROUP "hitBuf_45"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.45.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_45" SITE "R74C132D" ;
+UGROUP "ff_en_45" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.45.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_45" SITE "R73C155D" ;
+#
+UGROUP "FC_46" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.46.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_46" SITE "R71C131D" ;
+UGROUP "hitBuf_46"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.46.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_46" SITE "R72C132D" ;
+UGROUP "ff_en_46" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.46.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_46" SITE "R71C155D" ;
+#
+UGROUP "FC_47" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.47.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_47" SITE "R111C131D" ;
+UGROUP "hitBuf_47" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.47.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_47" SITE "R112C132D" ;
+UGROUP "ff_en_47" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.47.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_47" SITE "R111C155D" ;
+#
+UGROUP "FC_48" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.48.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_48" SITE "R113C131D" ;
+UGROUP "hitBuf_48" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.48.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_48" SITE "R114C132D" ;
+UGROUP "ff_en_48" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.48.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_48" SITE "R113C155D" ;
+#
+UGROUP "FC_49" BBOX 1 48
+       BLKNAME THE_TDC/GEN_Channels.49.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_49" SITE "R8C131D" ;
+UGROUP "hitBuf_49" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.49.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_49" SITE "R9C132D" ;
+UGROUP "ff_en_49"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.49.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_49" SITE "R8C155D" ;
+#
+UGROUP "FC_50" BBOX 1 48
+       BLKNAME THE_TDC/GEN_Channels.50.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_50" SITE "R10C131D" ;
+UGROUP "hitBuf_50" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.50.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_50" SITE "R11C132D" ;
+UGROUP "ff_en_50"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.50.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_50" SITE "R10C155D" ;
+#
+UGROUP "FC_51" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.51.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_51" SITE "R21C131D" ;
+UGROUP "hitBuf_51"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.51.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_51" SITE "R22C132D" ;
+UGROUP "ff_en_51" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.51.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_51" SITE "R21C155D" ;
+#
+UGROUP "FC_52" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.52.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_52" SITE "R23C131D" ;
+UGROUP "hitBuf_52"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.52.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_52" SITE "R24C132D" ;
+UGROUP "ff_en_52" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.52.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_52" SITE "R23C155D" ;
+#
+UGROUP "FC_53" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.53.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_53" SITE "R30C131D" ;
+UGROUP "hitBuf_53"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.53.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_53" SITE "R31C132D" ;
+UGROUP "ff_en_53" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.53.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_53" SITE "R30C155D" ;
+#
+UGROUP "FC_54" BBOX 1 48 
+      BLKNAME THE_TDC/GEN_Channels.54.Channels/Channel200/SimAdderNo.FC
+      ;
+LOCATE UGROUP "FC_54" SITE "R32C131D" ;
+UGROUP "hitBuf_54"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.54.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_54" SITE "R33C132D" ;
+UGROUP "ff_en_54" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.54.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_54" SITE "R32C155D" ;
+#
+UGROUP "FC_55" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.55.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_55" SITE "R35C131D" ;
+UGROUP "hitBuf_55"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.55.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_55" SITE "R36C132D" ;
+UGROUP "ff_en_55" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.55.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_55" SITE "R35C155D" ;
+#
+UGROUP "FC_56" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.56.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_56" SITE "R37C131D" ;
+UGROUP "hitBuf_56"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.56.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_56" SITE "R38C132D" ;
+UGROUP "ff_en_56" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.56.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_56" SITE "R37C155D" ;
+#
+UGROUP "FC_57" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.57.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_57" SITE "R48C131D" ;
+UGROUP "hitBuf_57"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.57.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_57" SITE "R49C132D" ;
+UGROUP "ff_en_57" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.57.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_57" SITE "R48C155D" ;
+#
+UGROUP "FC_58" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.58.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_58" SITE "R50C131D" ;
+UGROUP "hitBuf_58"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.58.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_58" SITE "R51C132D" ;
+UGROUP "ff_en_58" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.58.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_58" SITE "R50C155D" ;
+#
+UGROUP "FC_59" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.59.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_59" SITE "R53C131D" ;
+UGROUP "hitBuf_59"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.59.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_59" SITE "R54C132D" ;
+UGROUP "ff_en_59" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.59.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_59" SITE "R53C155D" ;
+#
+UGROUP "FC_60" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.60.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_60" SITE "R55C131D" ;
+UGROUP "hitBuf_60" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.60.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_60" SITE "R56C132D" ;
+UGROUP "ff_en_60" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.60.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_60" SITE "R55C155D" ;
+#
+UGROUP "FC_61" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.61.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_61" SITE "R66C131D" ;
+UGROUP "hitBuf_61"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.61.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_61" SITE "R67C132D" ;
+UGROUP "ff_en_61" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.61.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_61" SITE "R66C155D" ;
+#
+UGROUP "FC_62" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.62.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_62" SITE "R68C131D" ;
+UGROUP "hitBuf_62"  BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.62.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_62" SITE "R69C132D" ;
+UGROUP "ff_en_62" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.62.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_62" SITE "R68C155D" ;
+#
+UGROUP "FC_63" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.63.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_63" SITE "R86C58D" ;
+UGROUP "hitBuf_63" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.63.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_63" SITE "R87C59D" ;
+UGROUP "ff_en_63" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.63.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_63" SITE "R86C82D" ;
+#
+UGROUP "FC_64" BBOX 1 48 
+       BLKNAME THE_TDC/GEN_Channels.64.Channels/Channel200/SimAdderNo.FC
+       ;
+LOCATE UGROUP "FC_64" SITE "R84C58D" ;
+UGROUP "hitBuf_64" BBOX 1 1
+       BLKNAME THE_TDC/GEN_hit_mux.64.hit_mux_ch
+       ;
+LOCATE UGROUP "hitBuf_64" SITE "R85C59D" ;
+UGROUP "ff_en_64" BBOX 1 1
+       BLKNAME THE_TDC/GEN_Channels.64.Channels/Channel200/ff_array_en_1_i
+       ;
+LOCATE UGROUP "ff_en_64" SITE "R84C82D" ;
+#
+
+
+##############################################################################
+##                          CHANNEL PLACEMENTS                             ##
+##############################################################################
+UGROUP "EF_LT2" BBOX 10 49
+       BLKNAME THE_TDC/ReferenceChannel/Channel200
+       BLKNAME THE_TDC/ReferenceChannel/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.1.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LT2" SITE "R24C2D" ;
+UGROUP "EF_LC1" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.2.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.3.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.4.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.5.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LC1" SITE "R35C2D" ;
+UGROUP "EF_LC3" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.6.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.7.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.8.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.9.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LC3" SITE "R71C2D" ;
+UGROUP "EF_LB1" BBOX 16 49
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.10.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.11.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.12.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LB1" SITE "R89C2D" ;
+UGROUP "EF_LT1" BBOX 16 49
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.13.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.14.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.15.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.16.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LT1" SITE "R8C2D" ;
+UGROUP "EF_CB1" BBOX 16 49
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.17.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.18.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.19.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.20.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_CB1" SITE "R89C58D" ;
+UGROUP "EF_CB2" BBOX 10 49
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.21.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.22.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_CB2" SITE "R105C58D" ;
+UGROUP "EF_LC2" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.23.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.24.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.25.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.26.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LC2" SITE "R53C2D" ;
+UGROUP "EF_LB2" BBOX 10 49
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.27.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.28.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_LB2" SITE "R105C2D" ;
+UGROUP "EF_CT1" BBOX 16 49
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.29.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.30.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.31.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.32.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_CT1" SITE "R8C58D" ;
+UGROUP "EF_CT2" BBOX 10 49
+       BLKNAME THE_TDC/GEN_Channels.33.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.33.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.34.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.34.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_CT2" SITE "R24C58D" ;
+UGROUP "EF_CC1" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.35.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.35.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.36.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.36.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.37.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.37.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.38.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.38.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_CC1" SITE "R35C58D" ;
+UGROUP "EF_RB1" BBOX 16 49
+       BLKNAME THE_TDC/GEN_Channels.39.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.39.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.40.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.40.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.41.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.41.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.42.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.42.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RB1" SITE "R89C131D" ;
+UGROUP "EF_RC3" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.43.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.43.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.44.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.44.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.45.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.45.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.46.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.46.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RC3" SITE "R71C131D" ;
+UGROUP "EF_RB2" BBOX 10 49
+       BLKNAME THE_TDC/GEN_Channels.47.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.47.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.48.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.48.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RB2" SITE "R105C131D" ;
+UGROUP "EF_RT1" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.49.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.49.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.50.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.50.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.51.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.51.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.52.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.52.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RT1" SITE "R8C131D" ;
+UGROUP "EF_RT2" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.53.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.53.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.54.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.54.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RT2" SITE "R24C131D" ;
+UGROUP "EF_RC1" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.55.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.55.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.56.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.56.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.57.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.57.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.58.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.58.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RC1" SITE "R35C131D" ;
+UGROUP "EF_RC2" BBOX 17 49
+       BLKNAME THE_TDC/GEN_Channels.59.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.59.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.60.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.60.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.61.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.61.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.62.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.62.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_RC2" SITE "R53C131D" ;
+UGROUP "EF_CC3" BBOX 10 49
+       BLKNAME THE_TDC/GEN_Channels.63.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.64.Channels/Channel200
+       BLKNAME THE_TDC/GEN_Channels.63.Channels/Buffer_128.The_Buffer
+       BLKNAME THE_TDC/GEN_Channels.64.Channels/Buffer_128.The_Buffer
+       ;
+LOCATE UGROUP "EF_CC3" SITE "R78C58D" ;
+
+#############################################################################
+## Stretcher
+#############################################################################
+UGROUP "Stretcher_A" BBOX 6 8
+        BLKNAME THE_TDC/gen_double_withStretcher.The_Stretcher/Stretcher_A_1
+;
+LOCATE UGROUP "Stretcher_A" SITE "R2C174D";
+
+UGROUP "Stretcher_B" BBOX 6 8
+        BLKNAME THE_TDC/gen_double_withStretcher.The_Stretcher/Stretcher_B_1
+;
+LOCATE UGROUP "Stretcher_B" SITE "R2C2D";
+
+#############################################################################
+## Coarse counter register placement
+#############################################################################
+
+#############################################################################
+## Other Logic Placements
+#############################################################################
diff --git a/releases/tdc_v2.3.1/tdc_version.vhd b/releases/tdc_v2.3.1/tdc_version.vhd
new file mode 100644 (file)
index 0000000..8cbea6f
--- /dev/null
@@ -0,0 +1,9 @@
+library ieee;
+use IEEE.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package tdc_version is
+
+  constant TDC_VERSION             : std_logic_vector(11 downto 0) := x"231";
+
+end;
diff --git a/releases/tdc_v2.3.1/trb3_periph_32PinAddOn.vhd b/releases/tdc_v2.3.1/trb3_periph_32PinAddOn.vhd
new file mode 100644 (file)
index 0000000..0d2ba52
--- /dev/null
@@ -0,0 +1,444 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.config.all;
+use work.tdc_version.all;
+use work.version.all;
+
+
+entity trb3_periph_32PinAddOn is
+  port(
+    --Clocks
+    CLK_GPLL_LEFT        : in    std_logic;  --Clock Manager 1/(2468), 125 MHz
+    CLK_GPLL_RIGHT       : in    std_logic;  --Clock Manager 2/(2468), 200 MHz  <-- MAIN CLOCK for FPGA
+    CLK_PCLK_LEFT        : in    std_logic;  --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right!
+    CLK_PCLK_RIGHT       : in    std_logic;  --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right!
+    --Trigger
+    TRIGGER_LEFT         : in    std_logic;  --left side trigger input from fan-out
+    TRIGGER_RIGHT        : in    std_logic;  --right side trigger input from fan-out
+    --Serdes
+    CLK_SERDES_INT_LEFT  : in    std_logic;  --Clock Manager 1/(1357), off, 125 MHz possible
+    CLK_SERDES_INT_RIGHT : in    std_logic;  --Clock Manager 2/(1357), 200 MHz, only in case of problems
+    SERDES_INT_TX        : out   std_logic_vector(3 downto 0);
+    SERDES_INT_RX        : in    std_logic_vector(3 downto 0);
+    --Inter-FPGA Communication
+    FPGA5_COMM           : inout std_logic_vector(11 downto 0);
+                                        --Bit 0/1 input, serial link RX active
+                                        --Bit 2/3 output, serial link TX active
+    --Connection to ADA AddOn
+    SPARE_LINE           : inout std_logic_vector(3 downto 0);  --inputs only
+    INP                  : in    std_logic_vector(63 downto 0);
+    --DAC
+    DAC_IN_SDI           : in    std_logic;
+    DAC_OUT_SDO          : out   std_logic;
+    DAC_OUT_SCK          : out   std_logic;
+    DAC_OUT_CS           : out   std_logic;
+    DAC_OUT_CLR          : out   std_logic;
+
+    --Flash ROM & Reboot
+    FLASH_CLK  : out   std_logic;
+    FLASH_CS   : out   std_logic;
+    FLASH_DIN  : out   std_logic;
+    FLASH_DOUT : in    std_logic;
+    PROGRAMN   : out   std_logic;       --reboot FPGA
+    --Misc
+    TEMPSENS   : inout std_logic;       --Temperature Sensor
+    CODE_LINE  : in    std_logic_vector(1 downto 0);
+    LED_GREEN  : out   std_logic;
+    LED_ORANGE : out   std_logic;
+    LED_RED    : out   std_logic;
+    LED_YELLOW : out   std_logic;
+    SUPPL      : in    std_logic;       --terminated diff pair, PCLK, Pads
+    --Test Connectors
+    TEST_LINE  : inout std_logic_vector(15 downto 0)
+    );
+  attribute syn_useioff                  : boolean;
+  --no IO-FF for LEDs relaxes timing constraints
+  attribute syn_useioff of LED_GREEN     : signal is false;
+  attribute syn_useioff of LED_ORANGE    : signal is false;
+  attribute syn_useioff of LED_RED       : signal is false;
+  attribute syn_useioff of LED_YELLOW    : signal is false;
+  attribute syn_useioff of TEMPSENS      : signal is false;
+  attribute syn_useioff of PROGRAMN      : signal is false;
+  attribute syn_useioff of CODE_LINE     : signal is false;
+  attribute syn_useioff of TRIGGER_LEFT  : signal is false;
+  attribute syn_useioff of TRIGGER_RIGHT : signal is false;
+  --important signals
+  attribute syn_useioff of FLASH_CLK     : signal is true;
+  attribute syn_useioff of FLASH_CS      : signal is true;
+  attribute syn_useioff of FLASH_DIN     : signal is true;
+  attribute syn_useioff of FLASH_DOUT    : signal is true;
+  attribute syn_useioff of FPGA5_COMM    : signal is true;
+  attribute syn_useioff of TEST_LINE     : signal is true;
+  attribute syn_useioff of INP           : signal is false;
+  attribute syn_useioff of SPARE_LINE    : signal is true;
+  attribute syn_useioff of DAC_IN_SDI    : signal is true;
+  attribute syn_useioff of DAC_OUT_SDO   : signal is true;
+  attribute syn_useioff of DAC_OUT_SCK   : signal is true;
+  attribute syn_useioff of DAC_OUT_CS    : signal is true;
+  attribute syn_useioff of DAC_OUT_CLR   : signal is true;
+
+
+end entity;
+
+
+architecture trb3_periph_32PinAddOn_arch of trb3_periph_32PinAddOn is
+  attribute syn_keep     : boolean;
+  attribute syn_preserve : boolean;
+
+  --Clock / Reset
+  signal clk_100_i                : std_logic;  --clock for main logic, 100 MHz, via Clock Manager and internal PLL
+  signal clk_200_i                : std_logic;  --clock for logic at 200 MHz, via Clock Manager and bypassed PLL
+  signal osc_int                  : std_logic;  -- clock for calibrating the tdc, 2.5 MHz, via internal osscilator
+  signal pll_lock                 : std_logic;  --Internal PLL locked. E.g. used to reset all internal logic.
+  signal clear_i                  : std_logic;
+  signal reset_i                  : std_logic;
+  signal GSR_N                    : std_logic;
+  attribute syn_keep of GSR_N     : signal is true;
+  attribute syn_preserve of GSR_N : signal is true;
+
+  --Media Interface
+  signal med_stat_debug : std_logic_vector (1*64-1 downto 0);
+  signal med2int        : med2int_array_t(0 to 0);
+  signal int2med        : int2med_array_t(0 to 0);
+
+  signal timing_trg_received_i : std_logic;
+
+  --READOUT
+  signal readout_rx : READOUT_RX;
+  signal readout_tx : readout_tx_array_t(0 to 0);
+
+  --Slow Control channel
+  signal common_ctrl_reg : std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+
+  signal ctrlbus_rx, bustdc_rx, bustools_rx, bus_master_out : CTRLBUS_RX;
+  signal ctrlbus_tx, bustdc_tx, bustools_tx, bus_master_in  : CTRLBUS_TX;
+  signal bus_master_active                                  : std_logic;
+  signal timer                                              : TIMERS;
+  signal lcd_data                                           : std_logic_vector(511 downto 0);
+  signal lcd_out                                            : std_logic_vector(4 downto 0);
+  signal feature_outputs_i                                  : std_logic_vector(15 downto 0);
+  signal spi_cs, spi_mosi, spi_miso, spi_clk, spi_clr       : std_logic_vector(15 downto 0);
+  signal uart_rx, uart_tx, debug_rx, debug_tx               : std_logic;
+  signal trig_gen_out_i                                     : std_logic_vector(3 downto 0);
+  signal sed_error_i                                        : std_logic;
+  --TDC
+  signal hit_in_i                                           : std_logic_vector(64 downto 1);
+
+begin
+---------------------------------------------------------------------------
+-- Reset Generation
+---------------------------------------------------------------------------
+
+  GSR_N <= pll_lock;
+
+  THE_RESET_HANDLER : trb_net_reset_handler
+    generic map(
+      RESET_DELAY => x"FEEE"
+      )
+    port map(
+      CLEAR_IN      => '0',             -- reset input (high active, async)
+      CLEAR_N_IN    => '1',             -- reset input (low active, async)
+      CLK_IN        => clk_200_i,       -- raw master clock, NOT from PLL/DLL!
+      SYSCLK_IN     => clk_100_i,       -- PLL/DLL remastered clock
+      PLL_LOCKED_IN => pll_lock,        -- master PLL lock signal (async)
+      RESET_IN      => '0',             -- general reset signal (SYSCLK)
+      TRB_RESET_IN  => med2int(0).stat_op(13),  -- TRBnet reset signal (SYSCLK)
+      CLEAR_OUT     => clear_i,         -- async reset out, USE WITH CARE!
+      RESET_OUT     => reset_i,         -- synchronous reset out (SYSCLK)
+      DEBUG_OUT     => open
+      );
+
+
+---------------------------------------------------------------------------
+-- Clock Handling
+---------------------------------------------------------------------------
+  THE_MAIN_PLL : pll_in200_out100
+    port map(
+      CLK   => CLK_GPLL_RIGHT,
+      RESET => '0',
+      CLKOP => clk_100_i,
+      CLKOK => clk_200_i,
+      LOCK  => pll_lock
+      );
+
+  pll_calibration : entity work.pll_in125_out33
+    port map (
+      CLK   => CLK_GPLL_LEFT,
+      CLKOP => osc_int,
+      LOCK  => open);
+
+---------------------------------------------------------------------------
+-- The TrbNet media interface (to other FPGA)
+---------------------------------------------------------------------------
+  THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp
+    generic map(
+      SERDES_NUM  => 1,                 --number of serdes in quad
+      EXT_CLOCK   => c_NO,              --use internal clock
+      USE_200_MHZ => c_YES,             --run on 200 MHz clock
+      USE_125_MHZ => c_NO,
+      USE_CTC     => c_NO
+      )
+    port map(
+      CLK                => clk_200_i,
+      SYSCLK             => clk_100_i,
+      RESET              => reset_i,
+      CLEAR              => clear_i,
+      CLK_EN             => '1',
+      --Internal Connection
+      MED_DATA_IN        => int2med(0).data,
+      MED_PACKET_NUM_IN  => int2med(0).packet_num,
+      MED_DATAREADY_IN   => int2med(0).dataready,
+      MED_READ_OUT       => med2int(0).tx_read,
+      MED_DATA_OUT       => med2int(0).data,
+      MED_PACKET_NUM_OUT => med2int(0).packet_num,
+      MED_DATAREADY_OUT  => med2int(0).dataready,
+      MED_READ_IN        => '1',
+      REFCLK2CORE_OUT    => open,
+      --SFP Connection
+      SD_RXD_P_IN        => SERDES_INT_RX(2),
+      SD_RXD_N_IN        => SERDES_INT_RX(3),
+      SD_TXD_P_OUT       => SERDES_INT_TX(2),
+      SD_TXD_N_OUT       => SERDES_INT_TX(3),
+      SD_REFCLK_P_IN     => open,
+      SD_REFCLK_N_IN     => open,
+      SD_PRSNT_N_IN      => FPGA5_COMM(0),
+      SD_LOS_IN          => FPGA5_COMM(0),
+      SD_TXDIS_OUT       => FPGA5_COMM(2),
+      -- Status and control port
+      STAT_OP            => med2int(0).stat_op,
+      CTRL_OP            => int2med(0).ctrl_op,
+      STAT_DEBUG         => med_stat_debug,
+      CTRL_DEBUG         => (others => '0')
+      );
+
+---------------------------------------------------------------------------
+-- Endpoint
+---------------------------------------------------------------------------
+  THE_ENDPOINT : entity work.trb_net16_endpoint_hades_full_handler_record
+    generic map (
+      ADDRESS_MASK              => x"FFFF",
+      BROADCAST_BITMASK         => x"FF",
+      REGIO_INIT_ENDPOINT_ID    => x"0001",
+      TIMING_TRIGGER_RAW        => c_YES,
+      REGIO_USE_VAR_ENDPOINT_ID => c_YES,
+      --Configure data handler
+      DATA_INTERFACE_NUMBER     => 1,
+      DATA_BUFFER_DEPTH         => EVENT_BUFFER_SIZE,
+      DATA_BUFFER_WIDTH         => 32,
+      DATA_BUFFER_FULL_THRESH   => 2**EVENT_BUFFER_SIZE-EVENT_MAX_SIZE,
+      TRG_RELEASE_AFTER_DATA    => c_YES,
+      HEADER_BUFFER_DEPTH       => 9,
+      HEADER_BUFFER_FULL_THRESH => 2**9-16
+      )
+
+    port map(
+      --  Misc
+      CLK    => clk_100_i,
+      RESET  => reset_i,
+      CLK_EN => '1',
+
+      --  Media direction port
+      MEDIA_MED2INT => med2int(0),
+      MEDIA_INT2MED => int2med(0),
+
+      --Timing trigger in
+      TRG_TIMING_TRG_RECEIVED_IN => timing_trg_received_i,
+
+      READOUT_RX => readout_rx,
+      READOUT_TX => readout_tx,
+
+      --Slow Control Port
+      REGIO_COMMON_CTRL_REG_OUT => common_ctrl_reg,  --0x20
+      BUS_RX                    => ctrlbus_rx,
+      BUS_TX                    => ctrlbus_tx,
+      BUS_MASTER_IN             => bus_master_in,
+      BUS_MASTER_OUT            => bus_master_out,
+      BUS_MASTER_ACTIVE         => bus_master_active,
+
+      REGIO_VAR_ENDPOINT_ID(1 downto 0)  => CODE_LINE,
+      REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'),
+      ONEWIRE_INOUT                      => TEMPSENS,
+      --Timing registers
+      TIMERS_OUT                         => timer
+      );
+
+
+  timing_trg_received_i <= TRIGGER_LEFT;
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+  THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record
+    generic map(
+      PORT_NUMBER      => 2,
+      PORT_ADDRESSES   => (0 => x"d000", 1 => x"c000", others => x"0000"),
+      PORT_ADDR_MASK   => (0 => 12, 1 => 12, others => 0),
+      PORT_MASK_ENABLE => 1
+      )
+    port map(
+      CLK   => clk_100_i,
+      RESET => reset_i,
+
+      REGIO_RX => ctrlbus_rx,
+      REGIO_TX => ctrlbus_tx,
+
+      BUS_RX(0) => bustools_rx,         --Flash, SPI, UART, ADC, SED
+      BUS_RX(1) => bustdc_rx,           --TDC config
+      BUS_TX(0) => bustools_tx,
+      BUS_TX(1) => bustdc_tx,
+
+      STAT_DEBUG => open
+      );
+
+---------------------------------------------------------------------------
+-- Control Tools
+---------------------------------------------------------------------------
+  THE_TOOLS : entity work.trb3_tools
+    port map(
+      CLK   => clk_100_i,
+      RESET => reset_i,
+
+      --Flash & Reload
+      FLASH_CS     => FLASH_CS,
+      FLASH_CLK    => FLASH_CLK,
+      FLASH_IN     => FLASH_DOUT,
+      FLASH_OUT    => FLASH_DIN,
+      PROGRAMN     => PROGRAMN,
+      REBOOT_IN    => common_ctrl_reg(15),
+      --SPI
+      SPI_CS_OUT   => spi_cs,
+      SPI_MOSI_OUT => spi_mosi,
+      SPI_MISO_IN  => spi_miso,
+      SPI_CLK_OUT  => spi_clk,
+      SPI_CLR_OUT  => spi_clr,
+      --LCD
+      LCD_DATA_IN  => lcd_data,
+      UART_RX_IN   => uart_rx,
+      UART_TX_OUT  => uart_tx,
+      DEBUG_RX_IN  => debug_rx,
+      DEBUG_TX_OUT => debug_tx,
+
+      --Trigger & Monitor
+      MONITOR_INPUTS(31 downto 0)  => INP(31 downto 0),
+      MONITOR_INPUTS(35 downto 32) => trig_gen_out_i,
+      TRIG_GEN_INPUTS              => INP(31 downto 0),
+      TRIG_GEN_OUTPUTS             => trig_gen_out_i,
+      LCD_OUT                      => lcd_out,
+      --SED
+      SED_ERROR_OUT                => sed_error_i,
+      --Slowcontrol
+      BUS_RX                       => bustools_rx,
+      BUS_TX                       => bustools_tx,
+      --Control master for default settings
+      BUS_MASTER_IN                => bus_master_in,
+      BUS_MASTER_OUT               => bus_master_out,
+      BUS_MASTER_ACTIVE            => bus_master_active,
+      DEBUG_OUT                    => open
+      );
+
+---------------------------------------------------------------------------
+-- Feature I/O
+---------------------------------------------------------------------------
+  gen_SPI : if INCLUDE_SPI = 1 generate
+    DAC_OUT_CS  <= spi_cs(0);
+    DAC_OUT_SDO <= spi_mosi(0);
+    DAC_OUT_SCK <= spi_clk(0);
+    DAC_OUT_CLR <= spi_clr(0);
+    spi_miso(0) <= DAC_IN_SDI;
+  end generate;
+  gen_NO_SPI : if INCLUDE_SPI = 0 generate
+    DAC_OUT_SDO <= trig_gen_out_i(0);
+    DAC_OUT_SCK <= trig_gen_out_i(1);
+    DAC_OUT_CS  <= trig_gen_out_i(2);
+    DAC_OUT_CLR <= trig_gen_out_i(3);
+  end generate;
+
+
+  FPGA5_COMM(10 downto 7) <= trig_gen_out_i;
+  FPGA5_COMM(6 downto 3)  <= (others => 'Z');
+  FPGA5_COMM(1)           <= 'Z';
+
+  feature_outputs_i(0)  <= uart_rx;
+  feature_outputs_i(1)  <= uart_tx;
+  feature_outputs_i(2)  <= spi_cs(1);
+  feature_outputs_i(3)  <= spi_mosi(1);
+  feature_outputs_i(4)  <= spi_clk(1);
+  spi_miso(1)           <= TEST_LINE(5);
+  feature_outputs_i(7)  <= lcd_out(4);  --lcd_cs
+  feature_outputs_i(8)  <= lcd_out(0);  --lcd_rst
+  feature_outputs_i(9)  <= lcd_out(3);  --lcd_dc
+  feature_outputs_i(10) <= lcd_out(2);  --lcd_mosi
+  feature_outputs_i(11) <= lcd_out(1);  --lcd_sck
+  --12 is LCD MISO, but not used
+  feature_outputs_i(14) <= debug_rx;
+  feature_outputs_i(15) <= debug_tx;
+
+---------------------------------------------------------------------------
+-- LCD Data to display
+---------------------------------------------------------------------------
+  lcd_data(15 downto 0)   <= timer.network_address;
+  lcd_data(47 downto 16)  <= timer.microsecond;
+  lcd_data(79 downto 48)  <= std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32));
+  lcd_data(511 downto 80) <= (others => '0');
+
+---------------------------------------------------------------------------
+-- LED
+---------------------------------------------------------------------------
+  LED_GREEN  <= not med2int(0).stat_op(9);
+  LED_ORANGE <= not med2int(0).stat_op(10);
+  LED_RED    <= '1';
+  LED_YELLOW <= not med2int(0).stat_op(11);
+
+---------------------------------------------------------------------------
+-- Test Connector - Additional Features
+---------------------------------------------------------------------------
+--   TEST_LINE <= feature_outputs_i;
+
+-------------------------------------------------------------------------------
+-- TDC
+-------------------------------------------------------------------------------
+  THE_TDC : entity work.TDC_record
+    generic map (
+      CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
+      STATUS_REG_NR  => 21,             -- Number of status regs
+      DEBUG          => c_YES,
+      SIMULATION     => c_NO)
+    port map (
+      RESET              => reset_i,
+      CLK_TDC            => CLK_PCLK_LEFT,
+      CLK_READOUT        => clk_100_i,  -- Clock for the readout
+      REFERENCE_TIME     => timing_trg_received_i,  -- Reference time input
+      HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
+      HIT_CAL_IN         => osc_int,    -- Hits for calibrating the TDC
+      -- Trigger signals from handler
+      BUSRDO_RX          => readout_rx,
+      BUSRDO_TX          => readout_tx(0),
+      -- Slow control bus
+      BUS_RX             => bustdc_rx,
+      BUS_TX             => bustdc_tx,
+      -- Dubug signals
+      INFO_IN            => timer,
+      LOGIC_ANALYSER_OUT => TEST_LINE
+      );
+
+  -- For single edge measurements
+  gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+    hit_in_i <= INP;
+  end generate;
+
+  -- For ToT Measurements
+  gen_double : if DOUBLE_EDGE_TYPE = 2 generate
+    Gen_Hit_In_Signals : for i in 1 to 32 generate
+      hit_in_i(i*2-1) <= INP(i-1);
+      hit_in_i(i*2)   <= not INP(i-1);
+    end generate Gen_Hit_In_Signals;
+  end generate;
+
+end architecture;
diff --git a/releases/tdc_v2.3.1/trb3_periph_ADA.vhd b/releases/tdc_v2.3.1/trb3_periph_ADA.vhd
new file mode 100644 (file)
index 0000000..b9c039f
--- /dev/null
@@ -0,0 +1,728 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.config.all;
+use work.tdc_version.all;
+use work.version.all;
+
+
+entity trb3_periph_ADA is
+  port(
+    --Clocks
+    CLK_GPLL_LEFT        : in    std_logic;  --Clock Manager 1/(2468), 125 MHz
+    CLK_GPLL_RIGHT       : in    std_logic;  --Clock Manager 2/(2468), 200 MHz  <-- MAIN CLOCK for FPGA
+    CLK_PCLK_LEFT        : in    std_logic;  --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right!
+    CLK_PCLK_RIGHT       : in    std_logic;  --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right!
+    --Trigger
+    TRIGGER_LEFT         : in    std_logic;  --left side trigger input from fan-out
+    TRIGGER_RIGHT        : in    std_logic;  --right side trigger input from fan-out
+    --Serdes
+    CLK_SERDES_INT_LEFT  : in    std_logic;  --Clock Manager 1/(1357), off, 125 MHz possible
+    CLK_SERDES_INT_RIGHT : in    std_logic;  --Clock Manager 2/(1357), 200 MHz, only in case of problems
+    SERDES_INT_TX        : out   std_logic_vector(3 downto 0);
+    SERDES_INT_RX        : in    std_logic_vector(3 downto 0);
+    SERDES_ADDON_TX      : out   std_logic_vector(11 downto 0);
+    SERDES_ADDON_RX      : in    std_logic_vector(11 downto 0);
+    --Inter-FPGA Communication
+    FPGA5_COMM           : inout std_logic_vector(11 downto 0);
+                                        --Bit 0/1 input, serial link RX active
+                                        --Bit 2/3 output, serial link TX active
+    --Connection to ADA AddOn
+    SPARE_LINE           : inout std_logic_vector(3 downto 0);  --inputs only
+    INP                  : in    std_logic_vector(63 downto 0);
+    --DAC
+    DAC_IN_SDI           : in    std_logic;
+    DAC_OUT_SDO          : out   std_logic;
+    DAC_OUT_SCK          : out   std_logic;
+    DAC_OUT_CS           : out   std_logic_vector(4 downto 1);
+    DAC_OUT_CLR          : out   std_logic;
+    --Flash ROM & Reboot
+    FLASH_CLK            : out   std_logic;
+    FLASH_CS             : out   std_logic;
+    FLASH_DIN            : out   std_logic;
+    FLASH_DOUT           : in    std_logic;
+    PROGRAMN             : out   std_logic;  --reboot FPGA
+    --Misc
+    TEMPSENS             : inout std_logic;  --Temperature Sensor
+    CODE_LINE            : in    std_logic_vector(1 downto 0);
+    LED_GREEN            : out   std_logic;
+    LED_ORANGE           : out   std_logic;
+    LED_RED              : out   std_logic;
+    LED_YELLOW           : out   std_logic;
+    SUPPL                : in    std_logic;  --terminated diff pair, PCLK, Pads
+    --Test Connectors
+    TEST_LINE            : out   std_logic_vector(15 downto 0)
+    );
+  attribute syn_useioff                  : boolean;
+  --no IO-FF for LEDs relaxes timing constraints
+  attribute syn_useioff of LED_GREEN     : signal is false;
+  attribute syn_useioff of LED_ORANGE    : signal is false;
+  attribute syn_useioff of LED_RED       : signal is false;
+  attribute syn_useioff of LED_YELLOW    : signal is false;
+  attribute syn_useioff of TEMPSENS      : signal is false;
+  attribute syn_useioff of PROGRAMN      : signal is false;
+  attribute syn_useioff of CODE_LINE     : signal is false;
+  attribute syn_useioff of TRIGGER_LEFT  : signal is false;
+  attribute syn_useioff of TRIGGER_RIGHT : signal is false;
+  --important signals
+  attribute syn_useioff of FLASH_CLK     : signal is true;
+  attribute syn_useioff of FLASH_CS      : signal is true;
+  attribute syn_useioff of FLASH_DIN     : signal is true;
+  attribute syn_useioff of FLASH_DOUT    : signal is true;
+  attribute syn_useioff of FPGA5_COMM    : signal is true;
+  attribute syn_useioff of TEST_LINE     : signal is true;
+  attribute syn_useioff of INP           : signal is false;
+  attribute syn_useioff of SPARE_LINE    : signal is true;
+  attribute syn_useioff of DAC_IN_SDI    : signal is true;
+  attribute syn_useioff of DAC_OUT_SDO   : signal is true;
+  attribute syn_useioff of DAC_OUT_SCK   : signal is true;
+  attribute syn_useioff of DAC_OUT_CS    : signal is true;
+  attribute syn_useioff of DAC_OUT_CLR   : signal is true;
+
+end entity;
+
+
+architecture trb3_periph_ADA_arch of trb3_periph_ADA is
+  --Constants
+  constant REGIO_NUM_STAT_REGS : integer := 3;
+  constant REGIO_NUM_CTRL_REGS : integer := 3;
+
+  attribute syn_keep     : boolean;
+  attribute syn_preserve : boolean;
+
+  --Clock / Reset
+  signal clk_100_i                : std_logic;  --clock for main logic, 100 MHz, via Clock Manager and internal PLL
+  signal clk_200_i                : std_logic;  --clock for logic at 200 MHz, via Clock Manager and bypassed PLL
+  signal clk_20                   : std_logic;  --clock for calibration at 20 MHz, via PLL
+  signal osc_int                  : std_logic;  --clock for calibration at 20 MHz, via internal osscilator
+  signal pll_lock                 : std_logic;  --Internal PLL locked. E.g. used to reset all internal logic.
+  signal pll_lock2                : std_logic;  --Internal PLL locked.
+  signal clear_i                  : std_logic;
+  signal reset_i                  : std_logic;
+  signal GSR_N                    : std_logic;
+  attribute syn_keep of GSR_N     : signal is true;
+  attribute syn_preserve of GSR_N : signal is true;
+
+  --Media Interface
+  signal med_stat_op        : std_logic_vector (1*16-1 downto 0);
+  signal med_ctrl_op        : std_logic_vector (1*16-1 downto 0);
+  signal med_stat_debug     : std_logic_vector (1*64-1 downto 0);
+  signal med_data_out       : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_out : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_out  : std_logic;
+  signal med_read_out       : std_logic;
+  signal med_data_in        : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_in  : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_in   : std_logic;
+  signal med_read_in        : std_logic;
+
+  --LVL1 channel
+  signal timing_trg_received_i  : std_logic;
+
+  --READOUT
+  signal readout_rx : READOUT_RX;
+  signal readout_tx : readout_tx_array_t(0 to 0);
+
+  --Slow Control channel
+  signal common_stat_reg        : std_logic_vector(std_COMSTATREG*32-1 downto 0);
+  signal common_ctrl_reg        : std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+  signal stat_reg               : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg               : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0);
+  signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0);
+  signal stat_reg_strobe        : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg_strobe        : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal timer                  : TIMERS;
+
+  --RegIO
+  signal regio_addr_out         : std_logic_vector (15 downto 0);
+  signal regio_read_enable_out  : std_logic;
+  signal regio_write_enable_out : std_logic;
+  signal regio_data_out         : std_logic_vector (31 downto 0);
+  signal regio_data_in          : std_logic_vector (31 downto 0);
+  signal regio_dataready_in     : std_logic;
+  signal regio_no_more_data_in  : std_logic;
+  signal regio_write_ack_in     : std_logic;
+  signal regio_unknown_addr_in  : std_logic;
+  signal regio_timeout_out      : std_logic;
+
+  --Timer
+  signal global_time         : std_logic_vector(31 downto 0);
+  signal local_time          : std_logic_vector(7 downto 0);
+  signal time_since_last_trg : std_logic_vector(31 downto 0);
+  signal timer_ticks         : std_logic_vector(1 downto 0);
+
+  --Flash
+  signal spimem_read_en          : std_logic;
+  signal spimem_write_en         : std_logic;
+  signal spimem_data_in          : std_logic_vector(31 downto 0);
+  signal spimem_addr             : std_logic_vector(8 downto 0);
+  signal spimem_data_out         : std_logic_vector(31 downto 0);
+  signal spimem_dataready_out    : std_logic;
+  signal spimem_no_more_data_out : std_logic;
+  signal spimem_unknown_addr_out : std_logic;
+  signal spimem_write_ack_out    : std_logic;
+
+  signal spidac_read_en   : std_logic;
+  signal spidac_write_en  : std_logic;
+  signal spidac_data_in   : std_logic_vector(31 downto 0);
+  signal spidac_addr      : std_logic_vector(4 downto 0);
+  signal spidac_data_out  : std_logic_vector(31 downto 0);
+  signal spidac_ack       : std_logic;
+  signal spidac_busy      : std_logic;
+
+  signal spi_bram_addr : std_logic_vector(7 downto 0);
+  signal spi_bram_wr_d : std_logic_vector(7 downto 0);
+  signal spi_bram_rd_d : std_logic_vector(7 downto 0);
+  signal spi_bram_we   : std_logic;
+
+  signal trig_out   : std_logic_vector(3 downto 0);
+  signal trig_din   : std_logic_vector(31 downto 0);
+  signal trig_dout  : std_logic_vector(31 downto 0);
+  signal trig_write : std_logic                     := '0';
+  signal trig_read  : std_logic                     := '0';
+  signal trig_ack   : std_logic                     := '0';
+  signal trig_nack  : std_logic                     := '0';
+  signal trig_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal stat_din   : std_logic_vector(31 downto 0);
+  signal stat_dout  : std_logic_vector(31 downto 0);
+  signal stat_write : std_logic                     := '0';
+  signal stat_read  : std_logic                     := '0';
+  signal stat_ack   : std_logic                     := '0';
+  signal stat_nack  : std_logic                     := '0';
+  signal stat_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal sed_error : std_logic;
+  signal bussed_rx, bustdc_rx : CTRLBUS_RX;
+  signal bussed_tx, bustdc_tx : CTRLBUS_TX;
+
+  --TDC
+  signal hit_in_i         : std_logic_vector(64 downto 1);
+  signal logic_analyser_i : std_logic_vector(15 downto 0);
+
+begin
+---------------------------------------------------------------------------
+-- Reset Generation
+---------------------------------------------------------------------------
+
+  GSR_N <= pll_lock;
+
+  THE_RESET_HANDLER : trb_net_reset_handler
+    generic map(
+      RESET_DELAY => x"FEEE"
+      )
+    port map(
+      CLEAR_IN      => '0',              -- reset input (high active, async)
+      CLEAR_N_IN    => '1',              -- reset input (low active, async)
+      CLK_IN        => clk_200_i,        -- raw master clock, NOT from PLL/DLL!
+      SYSCLK_IN     => clk_100_i,        -- PLL/DLL remastered clock
+      PLL_LOCKED_IN => pll_lock,         -- master PLL lock signal (async)
+      RESET_IN      => '0',              -- general reset signal (SYSCLK)
+      TRB_RESET_IN  => med_stat_op(13),  -- TRBnet reset signal (SYSCLK)
+      CLEAR_OUT     => clear_i,          -- async reset out, USE WITH CARE!
+      RESET_OUT     => reset_i,          -- synchronous reset out (SYSCLK)
+      DEBUG_OUT     => open
+      );
+
+
+---------------------------------------------------------------------------
+-- Clock Handling
+---------------------------------------------------------------------------
+  THE_MAIN_PLL : entity work.pll_in200_out100
+    port map (
+      CLK   => CLK_GPLL_RIGHT,
+      RESET => '0',
+      CLKOP => clk_100_i,               -- 100 MHz        
+      CLKOK => clk_200_i,               -- 200 MHz, bypass
+      LOCK  => pll_lock);
+
+
+  --pll_calibration: entity work.pll_in125_out100
+  --  port map (
+  --    CLK   => CLK_GPLL_LEFT,
+  --    CLKOP => osc_int,
+  --    LOCK  => open);
+  
+  pll_calibration: entity work.pll_in125_out33
+    port map (
+      CLK   => CLK_GPLL_LEFT,
+      CLKOP => osc_int,
+      LOCK  => open);
+
+---------------------------------------------------------------------------
+-- The TrbNet media interface (to other FPGA)
+---------------------------------------------------------------------------
+  THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp
+    generic map(
+      SERDES_NUM  => 1,                 --number of serdes in quad
+      EXT_CLOCK   => c_NO,              --use internal clock
+      USE_200_MHZ => c_YES,             --run on 200 MHz clock
+      USE_125_MHZ => c_NO,
+      USE_CTC     => c_NO
+      )
+    port map(
+      CLK                => clk_200_i,
+      SYSCLK             => clk_100_i,
+      RESET              => reset_i,
+      CLEAR              => clear_i,
+      CLK_EN             => '1',
+      --Internal Connection
+      MED_DATA_IN        => med_data_out,
+      MED_PACKET_NUM_IN  => med_packet_num_out,
+      MED_DATAREADY_IN   => med_dataready_out,
+      MED_READ_OUT       => med_read_in,
+      MED_DATA_OUT       => med_data_in,
+      MED_PACKET_NUM_OUT => med_packet_num_in,
+      MED_DATAREADY_OUT  => med_dataready_in,
+      MED_READ_IN        => med_read_out,
+      REFCLK2CORE_OUT    => open,
+      --SFP Connection
+      SD_RXD_P_IN        => SERDES_INT_RX(2),
+      SD_RXD_N_IN        => SERDES_INT_RX(3),
+      SD_TXD_P_OUT       => SERDES_INT_TX(2),
+      SD_TXD_N_OUT       => SERDES_INT_TX(3),
+      SD_REFCLK_P_IN     => open,
+      SD_REFCLK_N_IN     => open,
+      SD_PRSNT_N_IN      => FPGA5_COMM(0),
+      SD_LOS_IN          => FPGA5_COMM(0),
+      SD_TXDIS_OUT       => FPGA5_COMM(2),
+      -- Status and control port
+      STAT_OP            => med_stat_op,
+      CTRL_OP            => med_ctrl_op,
+      STAT_DEBUG         => med_stat_debug,
+      CTRL_DEBUG         => (others => '0')
+      );
+
+---------------------------------------------------------------------------
+-- Endpoint
+---------------------------------------------------------------------------
+  
+  THE_ENDPOINT : trb_net16_endpoint_hades_full_handler
+    generic map(
+      REGIO_NUM_STAT_REGS       => REGIO_NUM_STAT_REGS,
+      REGIO_NUM_CTRL_REGS       => REGIO_NUM_CTRL_REGS,
+      ADDRESS_MASK              => x"FFFF",
+      BROADCAST_BITMASK         => x"FF",
+      BROADCAST_SPECIAL_ADDR    => BROADCAST_SPECIAL_ADDR,
+      REGIO_COMPILE_TIME        => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)),
+      REGIO_HARDWARE_VERSION    => HARDWARE_INFO,
+      REGIO_INCLUDED_FEATURES   => INCLUDED_FEATURES,
+      REGIO_INIT_ADDRESS        => INIT_ADDRESS,
+      REGIO_USE_VAR_ENDPOINT_ID => c_YES,
+      CLOCK_FREQUENCY           => CLOCK_FREQUENCY,
+      TIMING_TRIGGER_RAW        => c_YES,
+      --Configure data handler
+      DATA_INTERFACE_NUMBER     => 1,
+      DATA_BUFFER_DEPTH         => EVENT_BUFFER_SIZE,
+      DATA_BUFFER_WIDTH         => 32,
+      DATA_BUFFER_FULL_THRESH   => 2**EVENT_BUFFER_SIZE-EVENT_MAX_SIZE,
+      TRG_RELEASE_AFTER_DATA    => c_YES,
+      HEADER_BUFFER_DEPTH       => 9,
+      HEADER_BUFFER_FULL_THRESH => 2**9-16
+      )
+    port map(
+      CLK                => clk_100_i,
+      RESET              => reset_i,
+      CLK_EN             => '1',
+      MED_DATAREADY_OUT  => med_dataready_out,  -- open,  --
+      MED_DATA_OUT       => med_data_out,  -- open,  --
+      MED_PACKET_NUM_OUT => med_packet_num_out,  -- open,  --
+      MED_READ_IN        => med_read_in,
+      MED_DATAREADY_IN   => med_dataready_in,
+      MED_DATA_IN        => med_data_in,
+      MED_PACKET_NUM_IN  => med_packet_num_in,
+      MED_READ_OUT       => med_read_out,  -- open,  --
+      MED_STAT_OP_IN     => med_stat_op,
+      MED_CTRL_OP_OUT    => med_ctrl_op,
+
+      --Timing trigger in
+      TRG_TIMING_TRG_RECEIVED_IN  => timing_trg_received_i,
+      LVL1_TRG_DATA_VALID_OUT     => readout_rx.data_valid,
+      LVL1_VALID_TIMING_TRG_OUT   => readout_rx.valid_timing_trg,
+      LVL1_VALID_NOTIMING_TRG_OUT => readout_rx.valid_notiming_trg,
+      LVL1_INVALID_TRG_OUT        => readout_rx.invalid_trg,
+
+      LVL1_TRG_TYPE_OUT        => readout_rx.trg_type,
+      LVL1_TRG_NUMBER_OUT      => readout_rx.trg_number,
+      LVL1_TRG_CODE_OUT        => readout_rx.trg_code,
+      LVL1_TRG_INFORMATION_OUT => readout_rx.trg_information,
+      LVL1_INT_TRG_NUMBER_OUT  => readout_rx.trg_int_number,
+
+      --Information about trigger handler errors
+      TRG_MULTIPLE_TRG_OUT     => readout_rx.trg_multiple,
+      TRG_TIMEOUT_DETECTED_OUT => readout_rx.trg_timeout,
+      TRG_SPURIOUS_TRG_OUT     => readout_rx.trg_spurious,
+      TRG_MISSING_TMG_TRG_OUT  => readout_rx.trg_missing,
+      TRG_SPIKE_DETECTED_OUT   => readout_rx.trg_spike,
+
+      --Response from FEE
+      FEE_TRG_RELEASE_IN(0)       => readout_tx(0).busy_release,
+      FEE_TRG_STATUSBITS_IN       => readout_tx(0).statusbits,
+      FEE_DATA_IN                 => readout_tx(0).data,
+      FEE_DATA_WRITE_IN(0)        => readout_tx(0).data_write,
+      FEE_DATA_FINISHED_IN(0)     => readout_tx(0).data_finished,
+      FEE_DATA_ALMOST_FULL_OUT(0) => readout_rx.buffer_almost_full,
+
+      -- Slow Control Data Port
+      REGIO_COMMON_STAT_REG_IN           => common_stat_reg,  --0x00
+      REGIO_COMMON_CTRL_REG_OUT          => common_ctrl_reg,  --0x20
+      REGIO_COMMON_STAT_STROBE_OUT       => common_stat_reg_strobe,
+      REGIO_COMMON_CTRL_STROBE_OUT       => common_ctrl_reg_strobe,
+      REGIO_STAT_REG_IN                  => stat_reg,         --start 0x80
+      REGIO_CTRL_REG_OUT                 => ctrl_reg,         --start 0xc0
+      REGIO_STAT_STROBE_OUT              => stat_reg_strobe,
+      REGIO_CTRL_STROBE_OUT              => ctrl_reg_strobe,
+      REGIO_VAR_ENDPOINT_ID(1 downto 0)  => CODE_LINE,
+      REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'),
+
+      BUS_ADDR_OUT         => regio_addr_out,
+      BUS_READ_ENABLE_OUT  => regio_read_enable_out,
+      BUS_WRITE_ENABLE_OUT => regio_write_enable_out,
+      BUS_DATA_OUT         => regio_data_out,
+      BUS_DATA_IN          => regio_data_in,
+      BUS_DATAREADY_IN     => regio_dataready_in,
+      BUS_NO_MORE_DATA_IN  => regio_no_more_data_in,
+      BUS_WRITE_ACK_IN     => regio_write_ack_in,
+      BUS_UNKNOWN_ADDR_IN  => regio_unknown_addr_in,
+      BUS_TIMEOUT_OUT      => regio_timeout_out,
+      ONEWIRE_INOUT        => TEMPSENS,
+      ONEWIRE_MONITOR_OUT  => open,
+
+      TIME_GLOBAL_OUT         => global_time,
+      TIME_LOCAL_OUT          => local_time,
+      TIME_SINCE_LAST_TRG_OUT => time_since_last_trg,
+      TIME_TICKS_OUT          => timer_ticks,
+      TEMPERATURE_OUT         => timer.temperature,
+
+      STAT_DEBUG_IPU              => open,
+      STAT_DEBUG_1                => open,
+      STAT_DEBUG_2                => open,
+      STAT_DEBUG_DATA_HANDLER_OUT => open,
+      STAT_DEBUG_IPU_HANDLER_OUT  => open,
+      STAT_TRIGGER_OUT            => open,
+      CTRL_MPLEX                  => (others => '0'),
+      IOBUF_CTRL_GEN              => (others => '0'),
+      STAT_ONEWIRE                => open,
+      STAT_ADDR_DEBUG             => open,
+      DEBUG_LVL1_HANDLER_OUT      => open
+      );
+
+  timing_trg_received_i <= TRIGGER_LEFT;  --TRIGGER_RIGHT;  --
+  common_stat_reg       <= (others => '0');
+  stat_reg              <= (others => '0');
+
+---------------------------------------------------------------------------
+-- AddOn
+---------------------------------------------------------------------------
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+  THE_BUS_HANDLER : trb_net16_regio_bus_handler
+    generic map(
+      PORT_NUMBER    => 9,
+      PORT_ADDRESSES => (0 => x"d000", 1 => x"cf80", 2 => x"d400", 3 => x"c000",
+                         4 => x"cf00", 5 => x"d500", others => x"0000"),
+      PORT_ADDR_MASK => (0 => 9, 1 => 7, 2 => 5, 3 => 12,
+                         4 => 6, 5 => 4, others => 0)
+      )
+    port map(
+      CLK   => clk_100_i,
+      RESET => reset_i,
+
+      DAT_ADDR_IN          => regio_addr_out,
+      DAT_DATA_IN          => regio_data_out,
+      DAT_DATA_OUT         => regio_data_in,
+      DAT_READ_ENABLE_IN   => regio_read_enable_out,
+      DAT_WRITE_ENABLE_IN  => regio_write_enable_out,
+      DAT_TIMEOUT_IN       => regio_timeout_out,
+      DAT_DATAREADY_OUT    => regio_dataready_in,
+      DAT_WRITE_ACK_OUT    => regio_write_ack_in,
+      DAT_NO_MORE_DATA_OUT => regio_no_more_data_in,
+      DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in,
+
+      --Bus Handler (SPI Flash control)
+      BUS_READ_ENABLE_OUT(0)              => spimem_read_en,
+      BUS_WRITE_ENABLE_OUT(0)             => spimem_write_en,
+      BUS_DATA_OUT(0*32+31 downto 0*32)   => spimem_data_in,
+      BUS_ADDR_OUT(0*16+8 downto 0*16)    => spimem_addr,
+      BUS_ADDR_OUT(0*16+15 downto 0*16+9) => open,
+      BUS_TIMEOUT_OUT(0)                  => open,
+      BUS_DATA_IN(0*32+31 downto 0*32)    => spimem_data_out,
+      BUS_DATAREADY_IN(0)                 => spimem_dataready_out,
+      BUS_WRITE_ACK_IN(0)                 => spimem_write_ack_out,
+      BUS_NO_MORE_DATA_IN(0)              => spimem_no_more_data_out,
+      BUS_UNKNOWN_ADDR_IN(0)              => spimem_unknown_addr_out,
+      --Input statistics
+      BUS_READ_ENABLE_OUT(1)              => stat_read,
+      BUS_WRITE_ENABLE_OUT(1)             => stat_write,
+      BUS_DATA_OUT(1*32+31 downto 1*32)   => stat_din,
+      BUS_ADDR_OUT(1*16+15 downto 1*16)   => stat_addr,
+      BUS_TIMEOUT_OUT(1)                  => open,
+      BUS_DATA_IN(1*32+31 downto 1*32)    => stat_dout,
+      BUS_DATAREADY_IN(1)                 => stat_ack,
+      BUS_WRITE_ACK_IN(1)                 => stat_ack,
+      BUS_NO_MORE_DATA_IN(1)              => '0',
+      BUS_UNKNOWN_ADDR_IN(1)              => stat_nack,
+      --Bus Handler (SPI DAC)
+      BUS_READ_ENABLE_OUT(2)              => spidac_read_en,
+      BUS_WRITE_ENABLE_OUT(2)             => spidac_write_en,
+      BUS_DATA_OUT(2*32+31 downto 2*32)   => spidac_data_in,
+      BUS_ADDR_OUT(2*16+4 downto 2*16)    => spidac_addr,
+      BUS_ADDR_OUT(2*16+15 downto 2*16+5) => open,
+      BUS_TIMEOUT_OUT(2)                  => open,
+      BUS_DATA_IN(2*32+31 downto 2*32)    => spidac_data_out,
+      BUS_DATAREADY_IN(2)                 => spidac_ack,
+      BUS_WRITE_ACK_IN(2)                 => spidac_ack,
+      BUS_NO_MORE_DATA_IN(2)              => spidac_busy,
+      BUS_UNKNOWN_ADDR_IN(2)              => '0',
+      --TDC
+      BUS_READ_ENABLE_OUT(3)              => bustdc_rx.read,
+      BUS_WRITE_ENABLE_OUT(3)             => bustdc_rx.write,
+      BUS_DATA_OUT(3*32+31 downto 3*32)   => bustdc_rx.data,
+      BUS_ADDR_OUT(3*16+15 downto 3*16)   => bustdc_rx.addr,
+      BUS_TIMEOUT_OUT(3)                  => bustdc_rx.timeout,
+      BUS_DATA_IN(3*32+31 downto 3*32)    => bustdc_tx.data,
+      BUS_DATAREADY_IN(3)                 => bustdc_tx.ack,
+      BUS_WRITE_ACK_IN(3)                 => bustdc_tx.ack,
+      BUS_NO_MORE_DATA_IN(3)              => bustdc_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(3)              => bustdc_tx.unknown,
+      --Trigger logic registers
+      BUS_READ_ENABLE_OUT(4)              => trig_read,
+      BUS_WRITE_ENABLE_OUT(4)             => trig_write,
+      BUS_DATA_OUT(4*32+31 downto 4*32)   => trig_din,
+      BUS_ADDR_OUT(4*16+15 downto 4*16)   => trig_addr,
+      BUS_TIMEOUT_OUT(4)                  => open,
+      BUS_DATA_IN(4*32+31 downto 4*32)    => trig_dout,
+      BUS_DATAREADY_IN(4)                 => trig_ack,
+      BUS_WRITE_ACK_IN(4)                 => trig_ack,
+      BUS_NO_MORE_DATA_IN(4)              => '0',
+      BUS_UNKNOWN_ADDR_IN(4)              => trig_nack,
+      --SEU Detection
+      BUS_READ_ENABLE_OUT(5)              => bussed_rx.read,
+      BUS_WRITE_ENABLE_OUT(5)             => bussed_rx.write,
+      BUS_DATA_OUT(5*32+31 downto 5*32)   => bussed_rx.data,
+      BUS_ADDR_OUT(5*16+15 downto 5*16)   => bussed_rx.addr,
+      BUS_TIMEOUT_OUT(5)                  => bussed_rx.timeout,
+      BUS_DATA_IN(5*32+31 downto 5*32)    => bussed_tx.data,
+      BUS_DATAREADY_IN(5)                 => bussed_tx.ack,
+      BUS_WRITE_ACK_IN(5)                 => bussed_tx.ack,
+      BUS_NO_MORE_DATA_IN(5)              => bussed_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(5)              => bussed_tx.unknown,
+
+      STAT_DEBUG => open
+      );
+
+---------------------------------------------------------------------------
+-- SPI / Flash
+---------------------------------------------------------------------------
+    THE_SPI_RELOAD : entity spi_flash_and_fpga_reload
+    port map(
+      CLK_IN   => clk_100_i,
+      RESET_IN => reset_i,
+
+      BUS_ADDR_IN          => spimem_addr,
+      BUS_READ_IN          => spimem_read_en,
+      BUS_WRITE_IN         => spimem_write_en,
+      BUS_DATAREADY_OUT    => spimem_dataready_out,
+      BUS_WRITE_ACK_OUT    => spimem_write_ack_out,
+      BUS_UNKNOWN_ADDR_OUT => spimem_unknown_addr_out,
+      BUS_NO_MORE_DATA_OUT => spimem_no_more_data_out,
+      BUS_DATA_IN          => spimem_data_in,
+      BUS_DATA_OUT         => spimem_data_out,
+
+      DO_REBOOT_IN => common_ctrl_reg(15),
+      PROGRAMN     => PROGRAMN,
+
+      SPI_CS_OUT  => FLASH_CS,
+      SPI_SCK_OUT => FLASH_CLK,
+      SPI_SDO_OUT => FLASH_DIN,
+      SPI_SDI_IN  => FLASH_DOUT
+      );
+
+-------------------------------------------------------------------------------
+-- SPI
+-------------------------------------------------------------------------------
+  gen_SPI : if INCLUDE_SPI = 1 and SPI_FOR_PADI = 1 generate
+    THE_DAC_SPI : spi_ltc2600
+      generic map (
+        BITS       => 16,
+        WAITCYCLES => 15)
+      port map(
+        CLK_IN         => clk_100_i,
+        RESET_IN       => reset_i,
+        -- Slave bus
+        BUS_ADDR_IN    => spidac_addr,
+        BUS_READ_IN    => spidac_read_en,
+        BUS_WRITE_IN   => spidac_write_en,
+        BUS_ACK_OUT    => spidac_ack,
+        BUS_BUSY_OUT   => spidac_busy,
+        BUS_DATA_IN    => spidac_data_in,
+        BUS_DATA_OUT   => spidac_data_out,
+        -- SPI connections
+        SPI_CS_OUT(0)  => DAC_OUT_CS(1),
+        SPI_SDI_IN     => DAC_IN_SDI,
+        SPI_SDO_OUT    => DAC_OUT_SDO,
+        SPI_SCK_OUT    => DAC_OUT_SCK,
+        SPI_CLR_OUT(0) => DAC_OUT_CLR
+        );
+  end generate;
+
+  gen_ADA_SPI : if INCLUDE_SPI = 1 and SPI_FOR_PADI = 0 generate
+    THE_DAC_SPI : spi_ltc2600
+      port map (
+        CLK_IN                 => clk_100_i,
+        RESET_IN               => reset_i,
+        -- Slave bus
+        BUS_READ_IN            => spidac_read_en,
+        BUS_WRITE_IN           => spidac_write_en,
+        BUS_BUSY_OUT           => spidac_busy,
+        BUS_ACK_OUT            => spidac_ack,
+        BUS_ADDR_IN            => spidac_addr,
+        BUS_DATA_IN            => spidac_data_in,
+        BUS_DATA_OUT           => spidac_data_out,
+        -- SPI connections
+        SPI_CS_OUT(3 downto 0) => DAC_OUT_CS,
+        SPI_SDI_IN             => '0',
+        SPI_SDO_OUT            => DAC_IN_SDI,
+        SPI_SCK_OUT            => DAC_OUT_SCK,
+        SPI_CLR_OUT            => open);
+  end generate;
+
+---------------------------------------------------------------------------
+-- Trigger logic
+---------------------------------------------------------------------------
+  gen_TRIGGER_LOGIC : if INCLUDE_TRIGGER_LOGIC = 1 generate
+    THE_TRIG_LOGIC : entity input_to_trigger_logic
+      generic map(
+        INPUTS  => PHYSICAL_INPUTS,
+        OUTPUTS => 4
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT  => INP(PHYSICAL_INPUTS-1 downto 0),
+        OUTPUT => trig_out,
+
+        DATA_IN  => trig_din,
+        DATA_OUT => trig_dout,
+        WRITE_IN => trig_write,
+        READ_IN  => trig_read,
+        ACK_OUT  => trig_ack,
+        NACK_OUT => trig_nack,
+        ADDR_IN  => trig_addr
+        );
+    -- Trigger on a TDC Channel
+    FPGA5_COMM(10 downto 7) <= trig_out;
+    FPGA5_COMM(6 downto 3)  <= (others => 'Z');
+    FPGA5_COMM(1)           <= 'Z';
+  end generate;
+
+---------------------------------------------------------------------------
+-- Reboot FPGA
+---------------------------------------------------------------------------
+  --THE_FPGA_REBOOT : fpga_reboot
+  --  port map(
+  --    CLK       => clk_100_i,
+  --    RESET     => reset_i,
+  --    DO_REBOOT => common_ctrl_reg(15),
+  --    PROGRAMN  => PROGRAMN
+  --    );
+
+---------------------------------------------------------------------------
+-- Input Statistics
+---------------------------------------------------------------------------
+  gen_STATISTICS : if INCLUDE_STATISTICS = 1 generate
+
+    THE_STAT_LOGIC : entity input_statistics
+      generic map(
+        INPUTS => PHYSICAL_INPUTS
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT => INP(PHYSICAL_INPUTS-1 downto 0),
+
+        DATA_IN  => stat_din,
+        DATA_OUT => stat_dout,
+        WRITE_IN => stat_write,
+        READ_IN  => stat_read,
+        ACK_OUT  => stat_ack,
+        NACK_OUT => stat_nack,
+        ADDR_IN  => stat_addr
+        );
+  end generate;
+
+---------------------------------------------------------------------------
+-- SED Detection
+---------------------------------------------------------------------------
+  THE_SED : entity sedcheck
+    port map(
+      CLK       => clk_100_i,
+      ERROR_OUT => sed_error,
+      BUS_RX    => bussed_rx,
+      BUS_TX    => bussed_tx
+      );  
+
+---------------------------------------------------------------------------
+-- LED
+---------------------------------------------------------------------------
+  LED_GREEN  <= not med_stat_op(9);
+  LED_ORANGE <= not med_stat_op(10);
+  LED_RED    <= not INP(0);
+  LED_YELLOW <= not med_stat_op(11);
+
+---------------------------------------------------------------------------
+-- Test Connector - Logic Analyser
+---------------------------------------------------------------------------
+
+  TEST_LINE <= logic_analyser_i;
+
+-------------------------------------------------------------------------------
+-- TDC
+-------------------------------------------------------------------------------
+  THE_TDC : TDC_record
+    generic map (
+      CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
+      STATUS_REG_NR  => 21,             -- Number of status regs
+      DEBUG          => c_YES,
+      SIMULATION     => c_NO)
+    port map (
+      RESET              => reset_i,
+      CLK_TDC            => CLK_PCLK_LEFT,
+      CLK_READOUT        => clk_100_i,  -- Clock for the readout
+      REFERENCE_TIME     => timing_trg_received_i,  -- Reference time input
+      HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
+      HIT_CAL_IN         => osc_int,    -- Hits for calibrating the TDC
+      -- Trigger signals from handler
+      BUSRDO_RX          => readout_rx,
+      BUSRDO_TX          => readout_tx(0),
+      -- Slow control bus
+      BUS_RX             => bustdc_rx,
+      BUS_TX             => bustdc_tx,
+      -- Dubug signals
+      INFO_IN            => timer,
+      LOGIC_ANALYSER_OUT => logic_analyser_i
+      );
+
+  -- For single edge measurements
+  gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+    hit_in_i <= INP;
+  end generate;
+
+  -- For ToT Measurements
+  gen_double : if DOUBLE_EDGE_TYPE = 2 generate
+    Gen_Hit_In_Signals : for i in 1 to 32 generate
+      hit_in_i(i*2-1) <= INP(i-1);
+      hit_in_i(i*2)   <= not INP(i-1);
+    end generate Gen_Hit_In_Signals;
+  end generate;
+
+end architecture;
diff --git a/releases/tdc_v2.3.1/trb3_periph_gpin.vhd b/releases/tdc_v2.3.1/trb3_periph_gpin.vhd
new file mode 100644 (file)
index 0000000..a18d554
--- /dev/null
@@ -0,0 +1,697 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.config.all;
+use work.version.all;
+
+
+entity trb3_periph_gpin is
+  generic(
+    SYNC_MODE : integer range 0 to 1 := c_NO  --use the RX clock for internal logic and transmission.
+    );
+  port(
+    --Clocks
+    CLK_GPLL_LEFT  : in std_logic;      --Clock Manager 6
+    CLK_GPLL_RIGHT : in std_logic;  --Clock Manager 4  <-- MAIN CLOCK for FPGA
+    CLK_PCLK_LEFT  : in std_logic;      --Clock Manager 3
+    CLK_PCLK_RIGHT : in std_logic;      --Clock Manager 1
+    --CLK_PCLK_RIGHT is the only clock with external termination !?
+    CLK_EXTERNAL   : in std_logic;      --Clock Manager 9
+
+
+    --Trigger
+    TRIGGER_LEFT : in std_logic;        --left side trigger input from fan-out
+--     TRIGGER_RIGHT : in std_logic;       --right side trigger input from fan-out
+
+    --Serdes
+    CLK_SERDES_INT_RIGHT : in  std_logic;  --Clock Manager 0, not used
+    SERDES_TX            : out std_logic_vector(3 downto 2);
+    SERDES_RX            : in  std_logic_vector(3 downto 2);
+
+    FPGA5_COMM : inout std_logic_vector(11 downto 0);
+                                        --Bit 0/1 input, serial link RX active
+                                        --Bit 2/3 output, serial link TX active
+    --Connections
+    INP  : in  std_logic_vector(23 downto 0);
+    LEDR : out std_logic_vector(4 downto 1);
+    LEDG : out std_logic_vector(7 downto 1);
+
+    --Flash ROM & Reboot
+    FLASH_CLK  : out std_logic;
+    FLASH_CS   : out std_logic;
+    FLASH_DIN  : out std_logic;
+    FLASH_DOUT : in  std_logic;
+    PROGRAMN   : out std_logic;         --reboot FPGA
+
+    --Misc
+    TEMPSENS   : inout std_logic;       --Temperature Sensor
+    CODE_LINE  : in    std_logic_vector(1 downto 0);
+    LED_GREEN  : out   std_logic;
+    LED_ORANGE : out   std_logic;
+    LED_RED    : out   std_logic;
+    LED_YELLOW : out   std_logic;
+
+    --Test Connectors
+    TEST_LINE : out std_logic_vector(15 downto 0)
+    );
+
+
+  attribute syn_useioff               : boolean;
+  --no IO-FF for LEDs relaxes timing constraints
+  attribute syn_useioff of LED_GREEN  : signal is false;
+  attribute syn_useioff of LED_ORANGE : signal is false;
+  attribute syn_useioff of LED_RED    : signal is false;
+  attribute syn_useioff of LED_YELLOW : signal is false;
+  attribute syn_useioff of LEDR       : signal is false;
+  attribute syn_useioff of LEDG       : signal is false;
+  attribute syn_useioff of TEMPSENS   : signal is false;
+  attribute syn_useioff of PROGRAMN   : signal is false;
+
+  --important signals _with_ IO-FF
+  attribute syn_useioff of FLASH_CLK  : signal is true;
+  attribute syn_useioff of FLASH_CS   : signal is true;
+  attribute syn_useioff of FLASH_DIN  : signal is true;
+  attribute syn_useioff of FLASH_DOUT : signal is true;
+  attribute syn_useioff of TEST_LINE  : signal is true;
+  attribute syn_useioff of INP        : signal is false;
+
+
+end entity;
+
+architecture trb3_periph_gpin_arch of trb3_periph_gpin is
+  --Constants
+  constant REGIO_NUM_STAT_REGS : integer := 0;
+  constant REGIO_NUM_CTRL_REGS : integer := 2;
+
+  attribute syn_keep     : boolean;
+  attribute syn_preserve : boolean;
+
+  --Clock / Reset
+  signal clk_100_i                : std_logic;  --clock for main logic, 100 MHz, via Clock Manager and internal PLL
+  signal clk_200_i                : std_logic;  --clock for logic at 200 MHz, via Clock Manager and bypassed PLL
+  signal clk_cal                  : std_logic;  -- clock for calibrating the tdc, 2.5 MHz, via internal osscilator
+  signal pll_lock                 : std_logic;  --Internal PLL locked. E.g. used to reset all internal logic.
+  signal clear_i                  : std_logic;
+  signal reset_i                  : std_logic;
+  signal GSR_N                    : std_logic;
+  attribute syn_keep of GSR_N     : signal is true;
+  attribute syn_preserve of GSR_N : signal is true;
+  signal rx_clock_100             : std_logic;
+  signal rx_clock_200             : std_logic;
+  signal time_counter             : unsigned(31 downto 0);
+  --Media Interface
+  signal med_stat_op              : std_logic_vector (1*16-1 downto 0);
+  signal med_ctrl_op              : std_logic_vector (1*16-1 downto 0);
+  signal med_stat_debug           : std_logic_vector (1*64-1 downto 0);
+  signal med_ctrl_debug           : std_logic_vector (1*64-1 downto 0);
+  signal med_data_out             : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_out       : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_out        : std_logic;
+  signal med_read_out             : std_logic;
+  signal med_data_in              : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_in        : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_in         : std_logic;
+  signal med_read_in              : std_logic;
+
+  --LVL1 channel
+  signal timing_trg_received_i : std_logic;
+
+  --READOUT
+  signal readout_rx : READOUT_RX;
+  signal readout_tx : readout_tx_array_t(0 to 0);
+
+  --Slow Control channel
+  signal common_stat_reg        : std_logic_vector(std_COMSTATREG*32-1 downto 0);
+  signal common_ctrl_reg        : std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+  signal stat_reg               : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg               : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0);
+  signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0);
+  signal stat_reg_strobe        : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg_strobe        : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal timer                  : TIMERS;
+
+  --RegIO
+  signal my_address             : std_logic_vector (15 downto 0);
+  signal regio_addr_out         : std_logic_vector (15 downto 0);
+  signal regio_read_enable_out  : std_logic;
+  signal regio_write_enable_out : std_logic;
+  signal regio_data_out         : std_logic_vector (31 downto 0);
+  signal regio_data_in          : std_logic_vector (31 downto 0);
+  signal regio_dataready_in     : std_logic;
+  signal regio_no_more_data_in  : std_logic;
+  signal regio_write_ack_in     : std_logic;
+  signal regio_unknown_addr_in  : std_logic;
+  signal regio_timeout_out      : std_logic;
+
+  --Timer
+  signal global_time         : std_logic_vector(31 downto 0);
+  signal local_time          : std_logic_vector(7 downto 0);
+  signal time_since_last_trg : std_logic_vector(31 downto 0);
+  signal timer_ticks         : std_logic_vector(1 downto 0);
+
+  --Flash
+  signal spimem_read_en          : std_logic;
+  signal spimem_write_en         : std_logic;
+  signal spimem_data_in          : std_logic_vector(31 downto 0);
+  signal spimem_addr             : std_logic_vector(8 downto 0);
+  signal spimem_data_out         : std_logic_vector(31 downto 0);
+  signal spimem_dataready_out    : std_logic;
+  signal spimem_no_more_data_out : std_logic;
+  signal spimem_unknown_addr_out : std_logic;
+  signal spimem_write_ack_out    : std_logic;
+
+  signal spi_bram_addr : std_logic_vector(7 downto 0);
+  signal spi_bram_wr_d : std_logic_vector(7 downto 0);
+  signal spi_bram_rd_d : std_logic_vector(7 downto 0);
+  signal spi_bram_we   : std_logic;
+
+  signal sci1_ack      : std_logic;
+  signal sci1_write    : std_logic;
+  signal sci1_read     : std_logic;
+  signal sci1_data_in  : std_logic_vector(7 downto 0);
+  signal sci1_data_out : std_logic_vector(7 downto 0);
+  signal sci1_addr     : std_logic_vector(8 downto 0);
+
+  signal trig_out   : std_logic_vector(3 downto 0);
+  signal trig_din   : std_logic_vector(31 downto 0);
+  signal trig_dout  : std_logic_vector(31 downto 0);
+  signal trig_write : std_logic                     := '0';
+  signal trig_read  : std_logic                     := '0';
+  signal trig_ack   : std_logic                     := '0';
+  signal trig_nack  : std_logic                     := '0';
+  signal trig_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal stat_out   : std_logic_vector(3 downto 0);
+  signal stat_din   : std_logic_vector(31 downto 0);
+  signal stat_dout  : std_logic_vector(31 downto 0);
+  signal stat_write : std_logic                     := '0';
+  signal stat_read  : std_logic                     := '0';
+  signal stat_ack   : std_logic                     := '0';
+  signal stat_nack  : std_logic                     := '0';
+  signal stat_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal sed_error            : std_logic;
+  signal bussed_rx, bustdc_rx : CTRLBUS_RX;
+  signal bussed_tx, bustdc_tx : CTRLBUS_TX;
+
+  --TDC
+  signal hit_in_i         : std_logic_vector(48 downto 1);
+  signal logic_analyser_i : std_logic_vector(15 downto 0);
+
+begin
+---------------------------------------------------------------------------
+-- Reset Generation
+---------------------------------------------------------------------------
+
+  GSR_N <= pll_lock;
+
+  THE_RESET_HANDLER : trb_net_reset_handler
+    generic map(
+      RESET_DELAY => x"FEEE"
+      )
+    port map(
+      CLEAR_IN      => '0',              -- reset input (high active, async)
+      CLEAR_N_IN    => '1',              -- reset input (low active, async)
+      CLK_IN        => clk_200_i,        -- raw master clock, NOT from PLL/DLL!
+      SYSCLK_IN     => clk_100_i,        -- PLL/DLL remastered clock
+      PLL_LOCKED_IN => pll_lock,         -- master PLL lock signal (async)
+      RESET_IN      => '0',              -- general reset signal (SYSCLK)
+      TRB_RESET_IN  => med_stat_op(13),  -- TRBnet reset signal (SYSCLK)
+      CLEAR_OUT     => clear_i,          -- async reset out, USE WITH CARE!
+      RESET_OUT     => reset_i,          -- synchronous reset out (SYSCLK)
+      DEBUG_OUT     => open
+      );  
+
+
+---------------------------------------------------------------------------
+-- Clock Handling
+---------------------------------------------------------------------------
+
+  THE_MAIN_PLL : pll_in200_out100
+    port map(
+      CLK   => CLK_GPLL_RIGHT,
+      RESET => '0',
+      CLKOP => clk_100_i,
+      CLKOK => clk_200_i,
+      LOCK  => pll_lock
+      );
+
+  pll_calibration : entity work.pll_in125_out33
+    port map (
+      CLK   => CLK_GPLL_LEFT,
+      CLKOP => clk_cal,
+      LOCK  => open);
+
+---------------------------------------------------------------------------
+-- The TrbNet media interface (to other FPGA)
+---------------------------------------------------------------------------
+  THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp
+    generic map(
+      SERDES_NUM  => 1,                 --number of serdes in quad
+      EXT_CLOCK   => c_NO,              --use internal clock
+      USE_200_MHZ => c_YES,             --run on 200 MHz clock
+      USE_CTC     => c_NO,
+      USE_SLAVE   => SYNC_MODE
+      )      
+    port map(
+      CLK                => clk_200_i,
+      SYSCLK             => clk_100_i,
+      RESET              => reset_i,
+      CLEAR              => clear_i,
+      CLK_EN             => '1',
+      --Internal Connection
+      MED_DATA_IN        => med_data_out,
+      MED_PACKET_NUM_IN  => med_packet_num_out,
+      MED_DATAREADY_IN   => med_dataready_out,
+      MED_READ_OUT       => med_read_in,
+      MED_DATA_OUT       => med_data_in,
+      MED_PACKET_NUM_OUT => med_packet_num_in,
+      MED_DATAREADY_OUT  => med_dataready_in,
+      MED_READ_IN        => med_read_out,
+      REFCLK2CORE_OUT    => open,
+      CLK_RX_HALF_OUT    => rx_clock_100,
+      CLK_RX_FULL_OUT    => rx_clock_200,
+
+      --SFP Connection
+      SD_RXD_P_IN    => SERDES_RX(2),
+      SD_RXD_N_IN    => SERDES_RX(3),
+      SD_TXD_P_OUT   => SERDES_TX(2),
+      SD_TXD_N_OUT   => SERDES_TX(3),
+      SD_REFCLK_P_IN => open,
+      SD_REFCLK_N_IN => open,
+      SD_PRSNT_N_IN  => FPGA5_COMM(0),
+      SD_LOS_IN      => FPGA5_COMM(0),
+      SD_TXDIS_OUT   => FPGA5_COMM(2),
+
+      SCI_DATA_IN  => sci1_data_in,
+      SCI_DATA_OUT => sci1_data_out,
+      SCI_ADDR     => sci1_addr,
+      SCI_READ     => sci1_read,
+      SCI_WRITE    => sci1_write,
+      SCI_ACK      => sci1_ack,
+      -- Status and control port
+      STAT_OP      => med_stat_op,
+      CTRL_OP      => med_ctrl_op,
+      STAT_DEBUG   => med_stat_debug,
+      CTRL_DEBUG   => (others => '0')
+      );
+
+
+---------------------------------------------------------------------------
+-- Endpoint
+---------------------------------------------------------------------------
+  
+  THE_ENDPOINT : trb_net16_endpoint_hades_full_handler
+    generic map(
+      REGIO_NUM_STAT_REGS       => REGIO_NUM_STAT_REGS,
+      REGIO_NUM_CTRL_REGS       => REGIO_NUM_CTRL_REGS,
+      ADDRESS_MASK              => x"FFFF",
+      BROADCAST_BITMASK         => x"FF",
+      BROADCAST_SPECIAL_ADDR    => BROADCAST_SPECIAL_ADDR,
+      REGIO_COMPILE_TIME        => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)),
+      REGIO_HARDWARE_VERSION    => HARDWARE_INFO,
+      REGIO_INCLUDED_FEATURES   => INCLUDED_FEATURES,
+      REGIO_INIT_ADDRESS        => INIT_ADDRESS,
+      REGIO_USE_VAR_ENDPOINT_ID => c_YES,
+      CLOCK_FREQUENCY           => CLOCK_FREQUENCY,
+      TIMING_TRIGGER_RAW        => c_YES,
+      --Configure data handler
+      DATA_INTERFACE_NUMBER     => 1,   --NUM_TDC_MODULES,
+      DATA_BUFFER_DEPTH         => EVENT_BUFFER_SIZE,
+      DATA_BUFFER_WIDTH         => 32,
+      DATA_BUFFER_FULL_THRESH   => 2**EVENT_BUFFER_SIZE-EVENT_MAX_SIZE,
+      TRG_RELEASE_AFTER_DATA    => c_YES,
+      HEADER_BUFFER_DEPTH       => 9,
+      HEADER_BUFFER_FULL_THRESH => 2**9-16
+      )
+    port map(
+      CLK                => clk_100_i,
+      RESET              => reset_i,
+      CLK_EN             => '1',
+      MED_DATAREADY_OUT  => med_dataready_out,  -- open, --
+      MED_DATA_OUT       => med_data_out,  -- open, --
+      MED_PACKET_NUM_OUT => med_packet_num_out,  -- open, --
+      MED_READ_IN        => med_read_in,
+      MED_DATAREADY_IN   => med_dataready_in,
+      MED_DATA_IN        => med_data_in,
+      MED_PACKET_NUM_IN  => med_packet_num_in,
+      MED_READ_OUT       => med_read_out,  -- open, --
+      MED_STAT_OP_IN     => med_stat_op,
+      MED_CTRL_OP_OUT    => med_ctrl_op,
+
+      --Timing trigger in
+      TRG_TIMING_TRG_RECEIVED_IN  => timing_trg_received_i,
+      --LVL1 trigger to FEE
+      LVL1_TRG_DATA_VALID_OUT     => readout_rx.data_valid,
+      LVL1_VALID_TIMING_TRG_OUT   => readout_rx.valid_timing_trg,
+      LVL1_VALID_NOTIMING_TRG_OUT => readout_rx.valid_notiming_trg,
+      LVL1_INVALID_TRG_OUT        => readout_rx.invalid_trg,
+
+      LVL1_TRG_TYPE_OUT        => readout_rx.trg_type,
+      LVL1_TRG_NUMBER_OUT      => readout_rx.trg_number,
+      LVL1_TRG_CODE_OUT        => readout_rx.trg_code,
+      LVL1_TRG_INFORMATION_OUT => readout_rx.trg_information,
+      LVL1_INT_TRG_NUMBER_OUT  => readout_rx.trg_int_number,
+
+      --Information about trigger handler errors
+      TRG_MULTIPLE_TRG_OUT     => readout_rx.trg_multiple,
+      TRG_TIMEOUT_DETECTED_OUT => readout_rx.trg_timeout,
+      TRG_SPURIOUS_TRG_OUT     => readout_rx.trg_spurious,
+      TRG_MISSING_TMG_TRG_OUT  => readout_rx.trg_missing,
+      TRG_SPIKE_DETECTED_OUT   => readout_rx.trg_spike,
+
+      --Response from FEE
+      FEE_TRG_RELEASE_IN(0)       => readout_tx(0).busy_release,
+      FEE_TRG_STATUSBITS_IN       => readout_tx(0).statusbits,
+      FEE_DATA_IN                 => readout_tx(0).data,
+      FEE_DATA_WRITE_IN(0)        => readout_tx(0).data_write,
+      FEE_DATA_FINISHED_IN(0)     => readout_tx(0).data_finished,
+      FEE_DATA_ALMOST_FULL_OUT(0) => readout_rx.buffer_almost_full,
+
+      -- Slow Control Data Port
+      REGIO_COMMON_STAT_REG_IN           => common_stat_reg,  --0x00
+      REGIO_COMMON_CTRL_REG_OUT          => common_ctrl_reg,  --0x20
+      REGIO_COMMON_STAT_STROBE_OUT       => common_stat_reg_strobe,
+      REGIO_COMMON_CTRL_STROBE_OUT       => common_ctrl_reg_strobe,
+      REGIO_STAT_REG_IN                  => stat_reg,         --start 0x80
+      REGIO_CTRL_REG_OUT                 => ctrl_reg,         --start 0xc0
+      REGIO_STAT_STROBE_OUT              => stat_reg_strobe,
+      REGIO_CTRL_STROBE_OUT              => ctrl_reg_strobe,
+      REGIO_VAR_ENDPOINT_ID(1 downto 0)  => CODE_LINE,
+      REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'),
+
+      BUS_ADDR_OUT         => regio_addr_out,
+      BUS_READ_ENABLE_OUT  => regio_read_enable_out,
+      BUS_WRITE_ENABLE_OUT => regio_write_enable_out,
+      BUS_DATA_OUT         => regio_data_out,
+      BUS_DATA_IN          => regio_data_in,
+      BUS_DATAREADY_IN     => regio_dataready_in,
+      BUS_NO_MORE_DATA_IN  => regio_no_more_data_in,
+      BUS_WRITE_ACK_IN     => regio_write_ack_in,
+      BUS_UNKNOWN_ADDR_IN  => regio_unknown_addr_in,
+      BUS_TIMEOUT_OUT      => regio_timeout_out,
+      ONEWIRE_INOUT        => TEMPSENS,
+      ONEWIRE_MONITOR_OUT  => open,
+
+      TIME_GLOBAL_OUT         => global_time,
+      TIME_LOCAL_OUT          => local_time,
+      TIME_SINCE_LAST_TRG_OUT => time_since_last_trg,
+      TIME_TICKS_OUT          => timer_ticks,
+      TEMPERATURE_OUT         => timer.temperature,
+
+      STAT_DEBUG_IPU              => open,
+      STAT_DEBUG_1                => open,
+      STAT_DEBUG_2                => open,
+      STAT_DEBUG_DATA_HANDLER_OUT => open,
+      STAT_DEBUG_IPU_HANDLER_OUT  => open,
+      STAT_TRIGGER_OUT            => open,
+      CTRL_MPLEX                  => (others => '0'),
+      IOBUF_CTRL_GEN              => (others => '0'),
+      STAT_ONEWIRE                => open,
+      STAT_ADDR_DEBUG             => open,
+      DEBUG_LVL1_HANDLER_OUT      => open
+      );
+
+---------------------------------------------------------------------------
+-- I/O
+---------------------------------------------------------------------------
+  timing_trg_received_i <= TRIGGER_LEFT;
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+  THE_BUS_HANDLER : trb_net16_regio_bus_handler
+    generic map(
+      PORT_NUMBER      => 6,
+      PORT_ADDRESSES   => (0 => x"d000", 1 => x"c000", 2 => x"cf00", 3 => x"cf80",
+                           4 => x"d500", 5 => x"b000", others => x"0000"),
+      PORT_ADDR_MASK   => (0 => 9,       1 => 12,      2 => 6,       3 => 7,
+                           4 => 4,       5 => 9,       others => 0),
+      PORT_MASK_ENABLE => 1
+      )
+    port map(
+      CLK   => clk_100_i,
+      RESET => reset_i,
+
+      DAT_ADDR_IN          => regio_addr_out,
+      DAT_DATA_IN          => regio_data_out,
+      DAT_DATA_OUT         => regio_data_in,
+      DAT_READ_ENABLE_IN   => regio_read_enable_out,
+      DAT_WRITE_ENABLE_IN  => regio_write_enable_out,
+      DAT_TIMEOUT_IN       => regio_timeout_out,
+      DAT_DATAREADY_OUT    => regio_dataready_in,
+      DAT_WRITE_ACK_OUT    => regio_write_ack_in,
+      DAT_NO_MORE_DATA_OUT => regio_no_more_data_in,
+      DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in,
+
+      --Bus Handler (SPI Flash control)
+      BUS_READ_ENABLE_OUT(0)              => spimem_read_en,
+      BUS_WRITE_ENABLE_OUT(0)             => spimem_write_en,
+      BUS_DATA_OUT(0*32+31 downto 0*32)   => spimem_data_in,
+      BUS_ADDR_OUT(0*16+8 downto 0*16)    => spimem_addr,
+      BUS_ADDR_OUT(0*16+15 downto 0*16+9) => open,
+      BUS_TIMEOUT_OUT(0)                  => open,
+      BUS_DATA_IN(0*32+31 downto 0*32)    => spimem_data_out,
+      BUS_DATAREADY_IN(0)                 => spimem_dataready_out,
+      BUS_WRITE_ACK_IN(0)                 => spimem_write_ack_out,
+      BUS_NO_MORE_DATA_IN(0)              => spimem_no_more_data_out,
+      BUS_UNKNOWN_ADDR_IN(0)              => spimem_unknown_addr_out,
+      --TDC
+      BUS_READ_ENABLE_OUT(1)              => bustdc_rx.read,
+      BUS_WRITE_ENABLE_OUT(1)             => bustdc_rx.write,
+      BUS_DATA_OUT(1*32+31 downto 1*32)   => bustdc_rx.data,
+      BUS_ADDR_OUT(1*16+11 downto 1*16)   => bustdc_rx.addr(11 downto 0),
+      BUS_TIMEOUT_OUT(1)                  => bustdc_rx.timeout,
+      BUS_DATA_IN(1*32+31 downto 1*32)    => bustdc_tx.data,
+      BUS_DATAREADY_IN(1)                 => bustdc_tx.ack,
+      BUS_WRITE_ACK_IN(1)                 => bustdc_tx.ack,
+      BUS_NO_MORE_DATA_IN(1)              => bustdc_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(1)              => bustdc_tx.unknown,
+      --Trigger logic registers
+      BUS_READ_ENABLE_OUT(2)              => trig_read,
+      BUS_WRITE_ENABLE_OUT(2)             => trig_write,
+      BUS_DATA_OUT(2*32+31 downto 2*32)   => trig_din,
+      BUS_ADDR_OUT(2*16+15 downto 2*16)   => trig_addr,
+      BUS_TIMEOUT_OUT(2)                  => open,
+      BUS_DATA_IN(2*32+31 downto 2*32)    => trig_dout,
+      BUS_DATAREADY_IN(2)                 => trig_ack,
+      BUS_WRITE_ACK_IN(2)                 => trig_ack,
+      BUS_NO_MORE_DATA_IN(2)              => '0',
+      BUS_UNKNOWN_ADDR_IN(2)              => trig_nack,
+      --Input statistics
+      BUS_READ_ENABLE_OUT(3)              => stat_read,
+      BUS_WRITE_ENABLE_OUT(3)             => stat_write,
+      BUS_DATA_OUT(3*32+31 downto 3*32)   => stat_din,
+      BUS_ADDR_OUT(3*16+15 downto 3*16)   => stat_addr,
+      BUS_TIMEOUT_OUT(3)                  => open,
+      BUS_DATA_IN(3*32+31 downto 3*32)    => stat_dout,
+      BUS_DATAREADY_IN(3)                 => stat_ack,
+      BUS_WRITE_ACK_IN(3)                 => stat_ack,
+      BUS_NO_MORE_DATA_IN(3)              => '0',
+      BUS_UNKNOWN_ADDR_IN(3)              => stat_nack,
+      --SEU Detection
+      BUS_READ_ENABLE_OUT(4)              => bussed_rx.read,
+      BUS_WRITE_ENABLE_OUT(4)             => bussed_rx.write,
+      BUS_DATA_OUT(4*32+31 downto 4*32)   => bussed_rx.data,
+      BUS_ADDR_OUT(4*16+15 downto 4*16)   => bussed_rx.addr,
+      BUS_TIMEOUT_OUT(4)                  => bussed_rx.timeout,
+      BUS_DATA_IN(4*32+31 downto 4*32)    => bussed_tx.data,
+      BUS_DATAREADY_IN(4)                 => bussed_tx.ack,
+      BUS_WRITE_ACK_IN(4)                 => bussed_tx.ack,
+      BUS_NO_MORE_DATA_IN(4)              => bussed_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(4)              => bussed_tx.unknown,
+      --SCI first Media Interface
+      BUS_READ_ENABLE_OUT(5)              => sci1_read,
+      BUS_WRITE_ENABLE_OUT(5)             => sci1_write,
+      BUS_DATA_OUT(5*32+7 downto 5*32)    => sci1_data_in,
+      BUS_DATA_OUT(5*32+31 downto 5*32+8) => open,
+      BUS_ADDR_OUT(5*16+8 downto 5*16)    => sci1_addr,
+      BUS_ADDR_OUT(5*16+15 downto 5*16+9) => open,
+      BUS_TIMEOUT_OUT(5)                  => open,
+      BUS_DATA_IN(5*32+7 downto 5*32)     => sci1_data_out,
+      BUS_DATAREADY_IN(5)                 => sci1_ack,
+      BUS_WRITE_ACK_IN(5)                 => sci1_ack,
+      BUS_NO_MORE_DATA_IN(5)              => '0',
+      BUS_UNKNOWN_ADDR_IN(5)              => '0',
+
+      STAT_DEBUG => open
+      );
+
+---------------------------------------------------------------------------
+-- SPI / Flash
+---------------------------------------------------------------------------
+
+  THE_SPI_RELOAD : entity work.spi_flash_and_fpga_reload
+    port map(
+      CLK_IN   => clk_100_i,
+      RESET_IN => reset_i,
+
+      BUS_ADDR_IN          => spimem_addr,
+      BUS_READ_IN          => spimem_read_en,
+      BUS_WRITE_IN         => spimem_write_en,
+      BUS_DATAREADY_OUT    => spimem_dataready_out,
+      BUS_WRITE_ACK_OUT    => spimem_write_ack_out,
+      BUS_UNKNOWN_ADDR_OUT => spimem_unknown_addr_out,
+      BUS_NO_MORE_DATA_OUT => spimem_no_more_data_out,
+      BUS_DATA_IN          => spimem_data_in,
+      BUS_DATA_OUT         => spimem_data_out,
+
+      DO_REBOOT_IN => common_ctrl_reg(15),
+      PROGRAMN     => PROGRAMN,
+
+      SPI_CS_OUT  => FLASH_CS,
+      SPI_SCK_OUT => FLASH_CLK,
+      SPI_SDO_OUT => FLASH_DIN,
+      SPI_SDI_IN  => FLASH_DOUT
+      );
+
+---------------------------------------------------------------------------
+-- Trigger logic
+---------------------------------------------------------------------------
+  gen_TRIGGER_LOGIC : if INCLUDE_TRIGGER_LOGIC = 1 generate
+    THE_TRIG_LOGIC : input_to_trigger_logic
+      generic map(
+        INPUTS  => PHYSICAL_INPUTS,
+        OUTPUTS => 4
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT  => INP(PHYSICAL_INPUTS-1 downto 0),
+        OUTPUT => trig_out,
+
+        DATA_IN  => trig_din,
+        DATA_OUT => trig_dout,
+        WRITE_IN => trig_write,
+        READ_IN  => trig_read,
+        ACK_OUT  => trig_ack,
+        NACK_OUT => trig_nack,
+        ADDR_IN  => trig_addr
+        );
+    FPGA5_COMM(10 downto 7) <= trig_out;
+  end generate;
+
+---------------------------------------------------------------------------
+-- Input Statistics
+---------------------------------------------------------------------------
+  gen_STATISTICS : if INCLUDE_STATISTICS = 1 generate
+
+    THE_STAT_LOGIC : entity work.input_statistics
+      generic map(
+        INPUTS => PHYSICAL_INPUTS
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT => INP(PHYSICAL_INPUTS-1 downto 0),
+
+        DATA_IN  => stat_din,
+        DATA_OUT => stat_dout,
+        WRITE_IN => stat_write,
+        READ_IN  => stat_read,
+        ACK_OUT  => stat_ack,
+        NACK_OUT => stat_nack,
+        ADDR_IN  => stat_addr
+        );
+  end generate;
+
+---------------------------------------------------------------------------
+-- SED Detection
+---------------------------------------------------------------------------
+  THE_SED : entity work.sedcheck
+    port map(
+      CLK       => clk_100_i,
+      ERROR_OUT => sed_error,
+      BUS_RX    => bussed_rx,
+      BUS_TX    => bussed_tx
+      );
+
+---------------------------------------------------------------------------
+-- LED
+---------------------------------------------------------------------------
+  LED_ORANGE <= not reset_i when rising_edge(clk_100_i);
+  LED_YELLOW <= '1';
+  LED_GREEN  <= not med_stat_op(9);
+  LED_RED    <= not (med_stat_op(10) or med_stat_op(11));
+
+-------------------------------------------------------------------------------
+-- LED ADDON
+-------------------------------------------------------------------------------
+  LEDR(2 downto 1) <= INP(1 downto 0)                when rising_edge(clk_100_i);
+  LEDR(3)          <= or_all(INP(3 downto 2))        when rising_edge(clk_100_i);
+  LEDR(4)          <= or_all(INP(7 downto 4))        when rising_edge(clk_100_i);
+  LEDG(4 downto 1) <= not(INP(11 downto 8))          when rising_edge(clk_100_i);
+  LEDG(5)          <= not(or_all(INP(15 downto 12))) when rising_edge(clk_100_i);
+  LEDG(6)          <= not(or_all(INP(19 downto 16))) when rising_edge(clk_100_i);
+  LEDG(7)          <= not(or_all(INP(23 downto 20))) when rising_edge(clk_100_i);
+
+---------------------------------------------------------------------------
+-- Test Connector
+---------------------------------------------------------------------------    
+--  TEST_LINE(15 downto 0) <= (others => '0');
+  TEST_LINE(15 downto 0) <= logic_analyser_i;
+
+---------------------------------------------------------------------------
+-- Test Circuits
+---------------------------------------------------------------------------
+  --process
+  --begin
+  --  wait until rising_edge(clk_100_i);
+  --  time_counter <= time_counter + 1;
+  --end process;
+
+-------------------------------------------------------------------------------
+-- TDC
+-------------------------------------------------------------------------------
+  THE_TDC : TDC_record
+    generic map (
+      CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
+      STATUS_REG_NR  => 21,             -- Number of status regs
+      DEBUG          => c_YES,
+      SIMULATION     => c_NO)
+    port map (
+      RESET              => reset_i,
+      CLK_TDC            => CLK_PCLK_LEFT,
+      CLK_READOUT        => clk_100_i,  -- Clock for the readout
+      REFERENCE_TIME     => timing_trg_received_i,  -- Reference time input
+      HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
+      HIT_CAL_IN         => clk_cal,    -- Hits for calibrating the TDC
+      -- Trigger signals from handler
+      BUSRDO_RX          => readout_rx,
+      BUSRDO_TX          => readout_tx(0),
+      -- Slow control bus
+      BUS_RX             => bustdc_rx,
+      BUS_TX             => bustdc_tx,
+      -- Dubug signals
+      INFO_IN            => timer,
+      LOGIC_ANALYSER_OUT => logic_analyser_i
+      );
+
+
+  -- For single edge measurements
+  gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+    hit_in_i(8 downto 1)  <= INP(7 downto 0);
+    hit_in_i(24 downto 9) <= not INP(23 downto 8);
+  end generate;
+
+  -- For ToT Measurements
+  gen_double : if DOUBLE_EDGE_TYPE = 2 generate
+    Gen_Hit_In_Signals : for i in 1 to 8 generate
+      hit_in_i(i*2-1) <= INP(i-1);
+      hit_in_i(i*2)   <= not INP(i-1);
+    end generate Gen_Hit_In_Signals;
+    Gen_Hit_In_Signals : for i in 9 to 24 generate
+      hit_in_i(i*2-1) <= not INP(i-1);
+      hit_in_i(i*2)   <= INP(i-1);
+    end generate Gen_Hit_In_Signals;
+  end generate;
+
+
+end architecture;
diff --git a/releases/tdc_v2.3.1/trb3_periph_padiwa.vhd b/releases/tdc_v2.3.1/trb3_periph_padiwa.vhd
new file mode 100644 (file)
index 0000000..d02e501
--- /dev/null
@@ -0,0 +1,765 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.tdc_components.all;
+use work.config.all;
+use work.tdc_version.all;
+use work.version.all;
+
+
+entity trb3_periph_padiwa is
+  generic(
+    SYNC_MODE : integer range 0 to 1 := c_NO  --use the RX clock for internal logic and transmission.
+    );
+  port(
+    --Clocks
+    CLK_GPLL_LEFT  : in std_logic;      --Clock Manager 6
+    CLK_GPLL_RIGHT : in std_logic;  --Clock Manager 4  <-- MAIN CLOCK for FPGA
+    CLK_PCLK_LEFT  : in std_logic;      --Clock Manager 3
+    CLK_PCLK_RIGHT : in std_logic;      --Clock Manager 1
+    --CLK_PCLK_RIGHT is the only clock with external termination !?
+    CLK_EXTERNAL   : in std_logic;      --Clock Manager 9
+
+
+--     --Trigger
+    TRIGGER_LEFT : in std_logic;        --left side trigger input from fan-out
+--     TRIGGER_RIGHT : in std_logic;       --right side trigger input from fan-out
+
+    --Serdes
+    CLK_SERDES_INT_RIGHT : in  std_logic;  --Clock Manager 0, not used
+    SERDES_TX            : out std_logic_vector(3 downto 2);
+    SERDES_RX            : in  std_logic_vector(3 downto 2);
+
+    FPGA5_COMM : inout std_logic_vector(11 downto 0);
+                                        --Bit 0/1 input, serial link RX active
+                                        --Bit 2/3 output, serial link TX active
+
+
+    --Connections
+    SPARE_LINE : inout std_logic_vector(3 downto 0);
+    INP        : in    std_logic_vector(63 downto 0);
+
+    --Flash ROM & Reboot
+    FLASH_CLK  : out std_logic;
+    FLASH_CS   : out std_logic;
+    FLASH_DIN  : out std_logic;
+    FLASH_DOUT : in  std_logic;
+    PROGRAMN   : out std_logic;         --reboot FPGA
+
+    --DAC
+    OUT_SDO    : out   std_logic_vector(4 downto 1);
+    IN_SDI     : in    std_logic_vector(4 downto 1);
+    OUT_SCK    : out   std_logic_vector(4 downto 1);
+    OUT_CS     : out   std_logic_vector(4 downto 1);
+    --Misc
+    TEMPSENS   : inout std_logic;       --Temperature Sensor
+    CODE_LINE  : in    std_logic_vector(1 downto 0);
+    LED_GREEN  : out   std_logic;
+    LED_ORANGE : out   std_logic;
+    LED_RED    : out   std_logic;
+    LED_YELLOW : out   std_logic;
+
+    --Test Connectors
+    TEST_LINE : out std_logic_vector(15 downto 0)
+    );
+
+
+  attribute syn_useioff               : boolean;
+  --no IO-FF for LEDs relaxes timing constraints
+  attribute syn_useioff of LED_GREEN  : signal is false;
+  attribute syn_useioff of LED_ORANGE : signal is false;
+  attribute syn_useioff of LED_RED    : signal is false;
+  attribute syn_useioff of LED_YELLOW : signal is false;
+  attribute syn_useioff of TEMPSENS   : signal is false;
+  attribute syn_useioff of PROGRAMN   : signal is false;
+
+  --important signals _with_ IO-FF
+  attribute syn_useioff of OUT_SCK    : signal is true;
+  attribute syn_useioff of OUT_CS     : signal is true;
+  attribute syn_useioff of OUT_SDO    : signal is true;
+  attribute syn_useioff of FLASH_CLK  : signal is true;
+  attribute syn_useioff of FLASH_CS   : signal is true;
+  attribute syn_useioff of FLASH_DIN  : signal is true;
+  attribute syn_useioff of FLASH_DOUT : signal is true;
+  attribute syn_useioff of TEST_LINE  : signal is true;
+  attribute syn_useioff of SPARE_LINE : signal is true;
+  attribute syn_useioff of INP        : signal is false;
+
+
+end entity;
+
+architecture trb3_periph_padiwa_arch of trb3_periph_padiwa is
+  --Constants
+  constant REGIO_NUM_STAT_REGS : integer := 0;
+  constant REGIO_NUM_CTRL_REGS : integer := 2;
+
+  attribute syn_keep     : boolean;
+  attribute syn_preserve : boolean;
+
+  --Clock / Reset
+  signal clk_100_i                   : std_logic;  --clock for main logic, 100 MHz, via Clock Manager and internal PLL
+  signal clk_200_i                   : std_logic;  --clock for logic at 200 MHz, via Clock Manager and bypassed PLL
+  signal osc_int                     : std_logic;  -- clock for calibrating the tdc, 2.5 MHz, via internal osscilator
+  signal pll_lock                    : std_logic;  --Internal PLL locked. E.g. used to reset all internal logic.
+  signal clear_i                     : std_logic;
+  signal reset_i                     : std_logic;
+  signal GSR_N                       : std_logic;
+  attribute syn_keep of GSR_N        : signal is true;
+  attribute syn_preserve of GSR_N    : signal is true;
+  signal clk_100_internal            : std_logic;
+  signal clk_200_internal            : std_logic;
+  signal rx_clock_100                : std_logic;
+  signal rx_clock_200                : std_logic;
+  signal clk_tdc                     : std_logic;
+  signal time_counter, time_counter2 : unsigned(31 downto 0);
+  --Media Interface
+  signal med_stat_op                 : std_logic_vector (1*16-1 downto 0);
+  signal med_ctrl_op                 : std_logic_vector (1*16-1 downto 0);
+  signal med_stat_debug              : std_logic_vector (1*64-1 downto 0);
+  signal med_ctrl_debug              : std_logic_vector (1*64-1 downto 0);
+  signal med_data_out                : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_out          : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_out           : std_logic;
+  signal med_read_out                : std_logic;
+  signal med_data_in                 : std_logic_vector (1*16-1 downto 0);
+  signal med_packet_num_in           : std_logic_vector (1*3-1 downto 0);
+  signal med_dataready_in            : std_logic;
+  signal med_read_in                 : std_logic;
+
+  --LVL1 channel
+  signal timing_trg_received_i : std_logic;
+
+  --READOUT
+  signal readout_rx : READOUT_RX;
+  signal readout_tx : readout_tx_array_t(0 to 0);
+
+  --Slow Control channel
+  signal common_stat_reg        : std_logic_vector(std_COMSTATREG*32-1 downto 0);
+  signal common_ctrl_reg        : std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+  signal stat_reg               : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg               : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0);
+  signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0);
+  signal stat_reg_strobe        : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0);
+  signal ctrl_reg_strobe        : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0);
+  signal timer                  : TIMERS;
+
+  --RegIO
+  signal my_address             : std_logic_vector (15 downto 0);
+  signal regio_addr_out         : std_logic_vector (15 downto 0);
+  signal regio_read_enable_out  : std_logic;
+  signal regio_write_enable_out : std_logic;
+  signal regio_data_out         : std_logic_vector (31 downto 0);
+  signal regio_data_in          : std_logic_vector (31 downto 0);
+  signal regio_dataready_in     : std_logic;
+  signal regio_no_more_data_in  : std_logic;
+  signal regio_write_ack_in     : std_logic;
+  signal regio_unknown_addr_in  : std_logic;
+  signal regio_timeout_out      : std_logic;
+
+  --Timer
+  signal global_time         : std_logic_vector(31 downto 0);
+  signal local_time          : std_logic_vector(7 downto 0);
+  signal time_since_last_trg : std_logic_vector(31 downto 0);
+  signal timer_ticks         : std_logic_vector(1 downto 0);
+
+  --Flash
+  signal spimem_read_en          : std_logic;
+  signal spimem_write_en         : std_logic;
+  signal spimem_data_in          : std_logic_vector(31 downto 0);
+  signal spimem_addr             : std_logic_vector(8 downto 0);
+  signal spimem_data_out         : std_logic_vector(31 downto 0);
+  signal spimem_dataready_out    : std_logic;
+  signal spimem_no_more_data_out : std_logic;
+  signal spimem_unknown_addr_out : std_logic;
+  signal spimem_write_ack_out    : std_logic;
+
+  signal dac_read_en  : std_logic;
+  signal dac_write_en : std_logic;
+  signal dac_data_in  : std_logic_vector(31 downto 0);
+  signal dac_addr     : std_logic_vector(4 downto 0);
+  signal dac_data_out : std_logic_vector(31 downto 0);
+  signal dac_ack      : std_logic;
+  signal dac_busy     : std_logic;
+
+  signal spi_bram_addr : std_logic_vector(7 downto 0);
+  signal spi_bram_wr_d : std_logic_vector(7 downto 0);
+  signal spi_bram_rd_d : std_logic_vector(7 downto 0);
+  signal spi_bram_we   : std_logic;
+
+  signal sci1_ack      : std_logic;
+  signal sci1_write    : std_logic;
+  signal sci1_read     : std_logic;
+  signal sci1_data_in  : std_logic_vector(7 downto 0);
+  signal sci1_data_out : std_logic_vector(7 downto 0);
+  signal sci1_addr     : std_logic_vector(8 downto 0);
+
+  signal padiwa_cs  : std_logic_vector(3 downto 0);
+  signal padiwa_sck : std_logic;
+  signal padiwa_sdi : std_logic;
+  signal padiwa_sdo : std_logic;
+
+  signal trig_out   : std_logic_vector(3 downto 0);
+  signal trig_din   : std_logic_vector(31 downto 0);
+  signal trig_dout  : std_logic_vector(31 downto 0);
+  signal trig_write : std_logic                     := '0';
+  signal trig_read  : std_logic                     := '0';
+  signal trig_ack   : std_logic                     := '0';
+  signal trig_nack  : std_logic                     := '0';
+  signal trig_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal stat_out   : std_logic_vector(3 downto 0);
+  signal stat_din   : std_logic_vector(31 downto 0);
+  signal stat_dout  : std_logic_vector(31 downto 0);
+  signal stat_write : std_logic                     := '0';
+  signal stat_read  : std_logic                     := '0';
+  signal stat_ack   : std_logic                     := '0';
+  signal stat_nack  : std_logic                     := '0';
+  signal stat_addr  : std_logic_vector(15 downto 0) := (others => '0');
+
+  signal sed_error            : std_logic;
+  signal bussed_rx, bustdc_rx : CTRLBUS_RX;
+  signal bussed_tx, bustdc_tx : CTRLBUS_TX;
+
+  --TDC
+  signal hit_in_i : std_logic_vector(64 downto 1);
+  signal input_i  : std_logic_vector(64 downto 1);
+
+begin
+---------------------------------------------------------------------------
+-- Reset Generation
+---------------------------------------------------------------------------
+
+  GSR_N <= pll_lock;
+
+  THE_RESET_HANDLER : trb_net_reset_handler
+    generic map(
+      RESET_DELAY => x"FEEE"
+      )
+    port map(
+      CLEAR_IN      => '0',              -- reset input (high active, async)
+      CLEAR_N_IN    => '1',              -- reset input (low active, async)
+      CLK_IN        => clk_200_i,        -- raw master clock, NOT from PLL/DLL!
+      SYSCLK_IN     => clk_100_i,        -- PLL/DLL remastered clock
+      PLL_LOCKED_IN => pll_lock,         -- master PLL lock signal (async)
+      RESET_IN      => '0',              -- general reset signal (SYSCLK)
+      TRB_RESET_IN  => med_stat_op(13),  -- TRBnet reset signal (SYSCLK)
+      CLEAR_OUT     => clear_i,          -- async reset out, USE WITH CARE!
+      RESET_OUT     => reset_i,          -- synchronous reset out (SYSCLK)
+      DEBUG_OUT     => open
+      );  
+
+
+---------------------------------------------------------------------------
+-- Clock Handling
+---------------------------------------------------------------------------
+
+  THE_MAIN_PLL : pll_in200_out100
+    port map(
+      CLK   => CLK_GPLL_RIGHT,
+      RESET => '0',
+      CLKOP => clk_100_internal,
+      CLKOK => clk_200_internal,
+      LOCK  => pll_lock
+      );
+
+  pll_calibration: entity work.pll_in125_out33
+    port map (
+      CLK   => CLK_GPLL_LEFT,
+      CLKOP => osc_int,
+      LOCK  => open);
+
+  gen_sync_clocks : if SYNC_MODE = c_YES generate
+    clk_100_i <= rx_clock_100;
+    clk_200_i <= rx_clock_200;
+    clk_tdc   <= rx_clock_200;
+  end generate;
+
+  gen_local_clocks : if SYNC_MODE = c_NO generate
+    clk_100_i <= clk_100_internal;
+    clk_200_i <= clk_200_internal;
+    clk_tdc   <= CLK_PCLK_LEFT;
+  end generate;
+
+---------------------------------------------------------------------------
+-- The TrbNet media interface (to other FPGA)
+---------------------------------------------------------------------------
+  THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp
+    generic map(
+      SERDES_NUM  => 1,                 --number of serdes in quad
+      EXT_CLOCK   => c_NO,              --use internal clock
+      USE_200_MHZ => c_YES,             --run on 200 MHz clock
+      USE_CTC     => c_NO,
+      USE_SLAVE   => SYNC_MODE
+      )      
+    port map(
+      CLK                => clk_200_i,
+      SYSCLK             => clk_100_i,
+      RESET              => reset_i,
+      CLEAR              => clear_i,
+      CLK_EN             => '1',
+      --Internal Connection
+      MED_DATA_IN        => med_data_out,
+      MED_PACKET_NUM_IN  => med_packet_num_out,
+      MED_DATAREADY_IN   => med_dataready_out,
+      MED_READ_OUT       => med_read_in,
+      MED_DATA_OUT       => med_data_in,
+      MED_PACKET_NUM_OUT => med_packet_num_in,
+      MED_DATAREADY_OUT  => med_dataready_in,
+      MED_READ_IN        => med_read_out,
+      REFCLK2CORE_OUT    => open,
+      CLK_RX_HALF_OUT    => rx_clock_100,
+      CLK_RX_FULL_OUT    => rx_clock_200,
+
+      --SFP Connection
+      SD_RXD_P_IN    => SERDES_RX(2),
+      SD_RXD_N_IN    => SERDES_RX(3),
+      SD_TXD_P_OUT   => SERDES_TX(2),
+      SD_TXD_N_OUT   => SERDES_TX(3),
+      SD_REFCLK_P_IN => open,
+      SD_REFCLK_N_IN => open,
+      SD_PRSNT_N_IN  => FPGA5_COMM(0),
+      SD_LOS_IN      => FPGA5_COMM(0),
+      SD_TXDIS_OUT   => FPGA5_COMM(2),
+
+      SCI_DATA_IN  => sci1_data_in,
+      SCI_DATA_OUT => sci1_data_out,
+      SCI_ADDR     => sci1_addr,
+      SCI_READ     => sci1_read,
+      SCI_WRITE    => sci1_write,
+      SCI_ACK      => sci1_ack,
+      -- Status and control port
+      STAT_OP      => med_stat_op,
+      CTRL_OP      => med_ctrl_op,
+      STAT_DEBUG   => med_stat_debug,
+      CTRL_DEBUG   => (others => '0')
+      );
+
+
+---------------------------------------------------------------------------
+-- Endpoint
+---------------------------------------------------------------------------
+  
+  THE_ENDPOINT : trb_net16_endpoint_hades_full_handler
+    generic map(
+      REGIO_NUM_STAT_REGS       => REGIO_NUM_STAT_REGS,
+      REGIO_NUM_CTRL_REGS       => REGIO_NUM_CTRL_REGS,
+      ADDRESS_MASK              => x"FFFF",
+      BROADCAST_BITMASK         => x"FF",
+      BROADCAST_SPECIAL_ADDR    => BROADCAST_SPECIAL_ADDR,
+      REGIO_COMPILE_TIME        => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)),
+      REGIO_HARDWARE_VERSION    => HARDWARE_INFO,
+      REGIO_INCLUDED_FEATURES   => INCLUDED_FEATURES,
+      REGIO_INIT_ADDRESS        => INIT_ADDRESS,
+      REGIO_USE_VAR_ENDPOINT_ID => c_YES,
+      CLOCK_FREQUENCY           => CLOCK_FREQUENCY,
+      TIMING_TRIGGER_RAW        => c_YES,
+      --Configure data handler
+      DATA_INTERFACE_NUMBER     => 1,
+      DATA_BUFFER_DEPTH         => EVENT_BUFFER_SIZE,
+      DATA_BUFFER_WIDTH         => 32,
+      DATA_BUFFER_FULL_THRESH   => 2**EVENT_BUFFER_SIZE-EVENT_MAX_SIZE,
+      TRG_RELEASE_AFTER_DATA    => c_YES,
+      HEADER_BUFFER_DEPTH       => 9,
+      HEADER_BUFFER_FULL_THRESH => 2**9-16
+      )
+    port map(
+      CLK                => clk_100_i,
+      RESET              => reset_i,
+      CLK_EN             => '1',
+      MED_DATAREADY_OUT  => med_dataready_out,  -- open, --
+      MED_DATA_OUT       => med_data_out,  -- open, --
+      MED_PACKET_NUM_OUT => med_packet_num_out,  -- open, --
+      MED_READ_IN        => med_read_in,
+      MED_DATAREADY_IN   => med_dataready_in,
+      MED_DATA_IN        => med_data_in,
+      MED_PACKET_NUM_IN  => med_packet_num_in,
+      MED_READ_OUT       => med_read_out,  -- open, --
+      MED_STAT_OP_IN     => med_stat_op,
+      MED_CTRL_OP_OUT    => med_ctrl_op,
+
+      --Timing trigger in
+      TRG_TIMING_TRG_RECEIVED_IN  => timing_trg_received_i,
+      --LVL1 trigger to FEE
+      LVL1_TRG_DATA_VALID_OUT     => readout_rx.data_valid,
+      LVL1_VALID_TIMING_TRG_OUT   => readout_rx.valid_timing_trg,
+      LVL1_VALID_NOTIMING_TRG_OUT => readout_rx.valid_notiming_trg,
+      LVL1_INVALID_TRG_OUT        => readout_rx.invalid_trg,
+
+      LVL1_TRG_TYPE_OUT        => readout_rx.trg_type,
+      LVL1_TRG_NUMBER_OUT      => readout_rx.trg_number,
+      LVL1_TRG_CODE_OUT        => readout_rx.trg_code,
+      LVL1_TRG_INFORMATION_OUT => readout_rx.trg_information,
+      LVL1_INT_TRG_NUMBER_OUT  => readout_rx.trg_int_number,
+
+      --Information about trigger handler errors
+      TRG_MULTIPLE_TRG_OUT     => readout_rx.trg_multiple,
+      TRG_TIMEOUT_DETECTED_OUT => readout_rx.trg_timeout,
+      TRG_SPURIOUS_TRG_OUT     => readout_rx.trg_spurious,
+      TRG_MISSING_TMG_TRG_OUT  => readout_rx.trg_missing,
+      TRG_SPIKE_DETECTED_OUT   => readout_rx.trg_spike,
+
+      --Response from FEE
+      FEE_TRG_RELEASE_IN(0)       => readout_tx(0).busy_release,
+      FEE_TRG_STATUSBITS_IN       => readout_tx(0).statusbits,
+      FEE_DATA_IN                 => readout_tx(0).data,
+      FEE_DATA_WRITE_IN(0)        => readout_tx(0).data_write,
+      FEE_DATA_FINISHED_IN(0)     => readout_tx(0).data_finished,
+      FEE_DATA_ALMOST_FULL_OUT(0) => readout_rx.buffer_almost_full,
+
+      -- Slow Control Data Port
+      REGIO_COMMON_STAT_REG_IN           => common_stat_reg,  --0x00
+      REGIO_COMMON_CTRL_REG_OUT          => common_ctrl_reg,  --0x20
+      REGIO_COMMON_STAT_STROBE_OUT       => common_stat_reg_strobe,
+      REGIO_COMMON_CTRL_STROBE_OUT       => common_ctrl_reg_strobe,
+      REGIO_STAT_REG_IN                  => stat_reg,         --start 0x80
+      REGIO_CTRL_REG_OUT                 => ctrl_reg,         --start 0xc0
+      REGIO_STAT_STROBE_OUT              => stat_reg_strobe,
+      REGIO_CTRL_STROBE_OUT              => ctrl_reg_strobe,
+      REGIO_VAR_ENDPOINT_ID(1 downto 0)  => CODE_LINE,
+      REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'),
+
+      BUS_ADDR_OUT         => regio_addr_out,
+      BUS_READ_ENABLE_OUT  => regio_read_enable_out,
+      BUS_WRITE_ENABLE_OUT => regio_write_enable_out,
+      BUS_DATA_OUT         => regio_data_out,
+      BUS_DATA_IN          => regio_data_in,
+      BUS_DATAREADY_IN     => regio_dataready_in,
+      BUS_NO_MORE_DATA_IN  => regio_no_more_data_in,
+      BUS_WRITE_ACK_IN     => regio_write_ack_in,
+      BUS_UNKNOWN_ADDR_IN  => regio_unknown_addr_in,
+      BUS_TIMEOUT_OUT      => regio_timeout_out,
+      ONEWIRE_INOUT        => TEMPSENS,
+      ONEWIRE_MONITOR_OUT  => open,
+
+      TIME_GLOBAL_OUT         => global_time,
+      TIME_LOCAL_OUT          => local_time,
+      TIME_SINCE_LAST_TRG_OUT => time_since_last_trg,
+      TIME_TICKS_OUT          => timer_ticks,
+      TEMPERATURE_OUT         => timer.temperature,
+
+      STAT_DEBUG_IPU              => open,
+      STAT_DEBUG_1                => open,
+      STAT_DEBUG_2                => open,
+      STAT_DEBUG_DATA_HANDLER_OUT => open,
+      STAT_DEBUG_IPU_HANDLER_OUT  => open,
+      STAT_TRIGGER_OUT            => open,
+      CTRL_MPLEX                  => (others => '0'),
+      IOBUF_CTRL_GEN              => (others => '0'),
+      STAT_ONEWIRE                => open,
+      STAT_ADDR_DEBUG             => open,
+      DEBUG_LVL1_HANDLER_OUT      => open
+      );
+
+
+---------------------------------------------------------------------------
+-- I/O
+---------------------------------------------------------------------------
+  timing_trg_received_i <= TRIGGER_LEFT;
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+  THE_BUS_HANDLER : trb_net16_regio_bus_handler
+    generic map(
+      PORT_NUMBER      => 7,
+      PORT_ADDRESSES   => (0 => x"d000", 1 => x"d400", 2 => x"c000", 3 => x"b000",
+                           4 => x"cf00", 5 => x"cf80", 6 => x"d500", others => x"0000"),
+      PORT_ADDR_MASK   => (0 => 9, 1 => 5, 2 => 12, 3 => 9,
+                           4 => 6, 5 => 7, 6 => 4,  others => 0),
+      PORT_MASK_ENABLE => 1
+      )
+    port map(
+      CLK   => clk_100_i,
+      RESET => reset_i,
+
+      DAT_ADDR_IN          => regio_addr_out,
+      DAT_DATA_IN          => regio_data_out,
+      DAT_DATA_OUT         => regio_data_in,
+      DAT_READ_ENABLE_IN   => regio_read_enable_out,
+      DAT_WRITE_ENABLE_IN  => regio_write_enable_out,
+      DAT_TIMEOUT_IN       => regio_timeout_out,
+      DAT_DATAREADY_OUT    => regio_dataready_in,
+      DAT_WRITE_ACK_OUT    => regio_write_ack_in,
+      DAT_NO_MORE_DATA_OUT => regio_no_more_data_in,
+      DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in,
+
+      --Bus Handler (SPI Flash control)
+      BUS_READ_ENABLE_OUT(0)              => spimem_read_en,
+      BUS_WRITE_ENABLE_OUT(0)             => spimem_write_en,
+      BUS_DATA_OUT(0*32+31 downto 0*32)   => spimem_data_in,
+      BUS_ADDR_OUT(0*16+8 downto 0*16)    => spimem_addr,
+      BUS_ADDR_OUT(0*16+15 downto 0*16+9) => open,
+      BUS_TIMEOUT_OUT(0)                  => open,
+      BUS_DATA_IN(0*32+31 downto 0*32)    => spimem_data_out,
+      BUS_DATAREADY_IN(0)                 => spimem_dataready_out,
+      BUS_WRITE_ACK_IN(0)                 => spimem_write_ack_out,
+      BUS_NO_MORE_DATA_IN(0)              => spimem_no_more_data_out,
+      BUS_UNKNOWN_ADDR_IN(0)              => spimem_unknown_addr_out,
+      --DAC
+      BUS_READ_ENABLE_OUT(1)              => dac_read_en,
+      BUS_WRITE_ENABLE_OUT(1)             => dac_write_en,
+      BUS_DATA_OUT(1*32+31 downto 1*32)   => dac_data_in,
+      BUS_ADDR_OUT(1*16+4 downto 1*16)    => dac_addr,
+      BUS_ADDR_OUT(1*16+15 downto 1*16+5) => open,
+      BUS_TIMEOUT_OUT(1)                  => open,
+      BUS_DATA_IN(1*32+31 downto 1*32)    => dac_data_out,
+      BUS_DATAREADY_IN(1)                 => dac_ack,
+      BUS_WRITE_ACK_IN(1)                 => dac_ack,
+      BUS_NO_MORE_DATA_IN(1)              => dac_busy,
+      BUS_UNKNOWN_ADDR_IN(1)              => '0',
+      --TDC
+      BUS_READ_ENABLE_OUT(2)              => bustdc_rx.read,
+      BUS_WRITE_ENABLE_OUT(2)             => bustdc_rx.write,
+      BUS_DATA_OUT(2*32+31 downto 2*32)   => bustdc_rx.data,
+      BUS_ADDR_OUT(2*16+15 downto 2*16)   => bustdc_rx.addr,
+      BUS_TIMEOUT_OUT(2)                  => bustdc_rx.timeout,
+      BUS_DATA_IN(2*32+31 downto 2*32)    => bustdc_tx.data,
+      BUS_DATAREADY_IN(2)                 => bustdc_tx.ack,
+      BUS_WRITE_ACK_IN(2)                 => bustdc_tx.ack,
+      BUS_NO_MORE_DATA_IN(2)              => bustdc_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(2)              => bustdc_tx.unknown,
+      --SCI first Media Interface
+      BUS_READ_ENABLE_OUT(3)              => sci1_read,
+      BUS_WRITE_ENABLE_OUT(3)             => sci1_write,
+      BUS_DATA_OUT(3*32+7 downto 3*32)    => sci1_data_in,
+      BUS_DATA_OUT(3*32+31 downto 3*32+8) => open,
+      BUS_ADDR_OUT(3*16+8 downto 3*16)    => sci1_addr,
+      BUS_ADDR_OUT(3*16+15 downto 3*16+9) => open,
+      BUS_TIMEOUT_OUT(3)                  => open,
+      BUS_DATA_IN(3*32+7 downto 3*32)     => sci1_data_out,
+      BUS_DATAREADY_IN(3)                 => sci1_ack,
+      BUS_WRITE_ACK_IN(3)                 => sci1_ack,
+      BUS_NO_MORE_DATA_IN(3)              => '0',
+      BUS_UNKNOWN_ADDR_IN(3)              => '0',
+      --Trigger logic registers
+      BUS_READ_ENABLE_OUT(4)              => trig_read,
+      BUS_WRITE_ENABLE_OUT(4)             => trig_write,
+      BUS_DATA_OUT(4*32+31 downto 4*32)   => trig_din,
+      BUS_ADDR_OUT(4*16+15 downto 4*16)   => trig_addr,
+      BUS_TIMEOUT_OUT(4)                  => open,
+      BUS_DATA_IN(4*32+31 downto 4*32)    => trig_dout,
+      BUS_DATAREADY_IN(4)                 => trig_ack,
+      BUS_WRITE_ACK_IN(4)                 => trig_ack,
+      BUS_NO_MORE_DATA_IN(4)              => '0',
+      BUS_UNKNOWN_ADDR_IN(4)              => trig_nack,
+      --Input statistics
+      BUS_READ_ENABLE_OUT(5)              => stat_read,
+      BUS_WRITE_ENABLE_OUT(5)             => stat_write,
+      BUS_DATA_OUT(5*32+31 downto 5*32)   => stat_din,
+      BUS_ADDR_OUT(5*16+15 downto 5*16)   => stat_addr,
+      BUS_TIMEOUT_OUT(5)                  => open,
+      BUS_DATA_IN(5*32+31 downto 5*32)    => stat_dout,
+      BUS_DATAREADY_IN(5)                 => stat_ack,
+      BUS_WRITE_ACK_IN(5)                 => stat_ack,
+      BUS_NO_MORE_DATA_IN(5)              => '0',
+      BUS_UNKNOWN_ADDR_IN(5)              => stat_nack,
+      --SEU Detection
+      BUS_READ_ENABLE_OUT(6)              => bussed_rx.read,
+      BUS_WRITE_ENABLE_OUT(6)             => bussed_rx.write,
+      BUS_DATA_OUT(6*32+31 downto 6*32)   => bussed_rx.data,
+      BUS_ADDR_OUT(6*16+15 downto 6*16)   => bussed_rx.addr,
+      BUS_TIMEOUT_OUT(6)                  => bussed_rx.timeout,
+      BUS_DATA_IN(6*32+31 downto 6*32)    => bussed_tx.data,
+      BUS_DATAREADY_IN(6)                 => bussed_tx.ack,
+      BUS_WRITE_ACK_IN(6)                 => bussed_tx.ack,
+      BUS_NO_MORE_DATA_IN(6)              => bussed_tx.nack,
+      BUS_UNKNOWN_ADDR_IN(6)              => bussed_tx.unknown,
+
+      STAT_DEBUG => open
+      );
+
+---------------------------------------------------------------------------
+-- SPI / Flash
+---------------------------------------------------------------------------
+    THE_SPI_RELOAD : entity spi_flash_and_fpga_reload
+    port map(
+      CLK_IN   => clk_100_i,
+      RESET_IN => reset_i,
+
+      BUS_ADDR_IN          => spimem_addr,
+      BUS_READ_IN          => spimem_read_en,
+      BUS_WRITE_IN         => spimem_write_en,
+      BUS_DATAREADY_OUT    => spimem_dataready_out,
+      BUS_WRITE_ACK_OUT    => spimem_write_ack_out,
+      BUS_UNKNOWN_ADDR_OUT => spimem_unknown_addr_out,
+      BUS_NO_MORE_DATA_OUT => spimem_no_more_data_out,
+      BUS_DATA_IN          => spimem_data_in,
+      BUS_DATA_OUT         => spimem_data_out,
+
+      DO_REBOOT_IN => common_ctrl_reg(15),
+      PROGRAMN     => PROGRAMN,
+
+      SPI_CS_OUT  => FLASH_CS,
+      SPI_SCK_OUT => FLASH_CLK,
+      SPI_SDO_OUT => FLASH_DIN,
+      SPI_SDI_IN  => FLASH_DOUT
+      );
+
+---------------------------------------------------------------------------
+-- DAC
+---------------------------------------------------------------------------      
+  gen_SPI : if INCLUDE_SPI = 1 generate
+    THE_DAC_SPI : spi_ltc2600
+      port map(
+        CLK_IN                 => clk_100_i,
+        RESET_IN               => reset_i,
+        -- Slave bus
+        BUS_ADDR_IN            => dac_addr,
+        BUS_READ_IN            => dac_read_en,
+        BUS_WRITE_IN           => dac_write_en,
+        BUS_ACK_OUT            => dac_ack,
+        BUS_BUSY_OUT           => dac_busy,
+        BUS_DATA_IN            => dac_data_in,
+        BUS_DATA_OUT           => dac_data_out,
+        -- SPI connections
+        SPI_CS_OUT(3 downto 0) => padiwa_cs,
+        SPI_SDI_IN             => padiwa_sdi,
+        SPI_SDO_OUT            => padiwa_sdo,
+        SPI_SCK_OUT            => padiwa_sck
+        );
+    OUT_CS     <= padiwa_cs(3 downto 0);
+    OUT_SCK    <= padiwa_sck & padiwa_sck & padiwa_sck & padiwa_sck;
+    OUT_SDO    <= padiwa_sdo & padiwa_sdo & padiwa_sdo & padiwa_sdo;
+    padiwa_sdi <= or_all(IN_SDI and not padiwa_cs(3 downto 0));
+  end generate;
+
+---------------------------------------------------------------------------
+-- Trigger logic
+---------------------------------------------------------------------------
+  gen_TRIGGER_LOGIC : if INCLUDE_TRIGGER_LOGIC = 1 generate
+    THE_TRIG_LOGIC : input_to_trigger_logic
+      generic map(
+        INPUTS  => PHYSICAL_INPUTS,
+        OUTPUTS => 4
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT  => input_i(PHYSICAL_INPUTS downto 1),
+        OUTPUT => trig_out,
+
+        DATA_IN  => trig_din,
+        DATA_OUT => trig_dout,
+        WRITE_IN => trig_write,
+        READ_IN  => trig_read,
+        ACK_OUT  => trig_ack,
+        NACK_OUT => trig_nack,
+        ADDR_IN  => trig_addr
+        );
+    FPGA5_COMM(10 downto 7) <= trig_out;
+  end generate;
+
+---------------------------------------------------------------------------
+-- Input Statistics
+---------------------------------------------------------------------------
+  gen_STATISTICS : if INCLUDE_STATISTICS = 1 generate
+
+    THE_STAT_LOGIC : entity input_statistics
+      generic map(
+        INPUTS => PHYSICAL_INPUTS
+        )
+      port map(
+        CLK => clk_100_i,
+
+        INPUT => input_i(PHYSICAL_INPUTS downto 1),
+
+        DATA_IN  => stat_din,
+        DATA_OUT => stat_dout,
+        WRITE_IN => stat_write,
+        READ_IN  => stat_read,
+        ACK_OUT  => stat_ack,
+        NACK_OUT => stat_nack,
+        ADDR_IN  => stat_addr
+        );
+  end generate;
+
+---------------------------------------------------------------------------
+-- SED Detection
+---------------------------------------------------------------------------
+  THE_SED : entity sedcheck
+    port map(
+      CLK       => clk_100_i,
+      ERROR_OUT => sed_error,
+      BUS_RX    => bussed_rx,
+      BUS_TX    => bussed_tx
+      );  
+
+---------------------------------------------------------------------------
+-- LED
+---------------------------------------------------------------------------
+  LED_ORANGE <= not reset_i when rising_edge(clk_100_i);
+  LED_YELLOW <= '1';
+  LED_GREEN  <= not med_stat_op(9);
+  LED_RED    <= not (med_stat_op(10) or med_stat_op(11));
+
+---------------------------------------------------------------------------
+-- Test Connector
+---------------------------------------------------------------------------    
+--  TEST_LINE(15 downto 0) <= (others => '0');
+---------------------------------------------------------------------------
+-- Test Circuits
+---------------------------------------------------------------------------
+  process
+  begin
+    wait until rising_edge(clk_100_i);
+    time_counter <= time_counter + 1;
+  end process;
+
+-------------------------------------------------------------------------------
+-- TDC
+-------------------------------------------------------------------------------
+  THE_TDC : TDC_record
+    generic map (
+      CHANNEL_NUMBER => NUM_TDC_CHANNELS,  -- Number of TDC channels per module
+      STATUS_REG_NR  => 21,             -- Number of status regs
+      DEBUG          => c_YES,
+      SIMULATION     => c_NO)
+    port map (
+      RESET              => reset_i,
+      CLK_TDC            => clk_tdc,
+      CLK_READOUT        => clk_100_i,  -- Clock for the readout
+      REFERENCE_TIME     => timing_trg_received_i,  -- Reference time input
+      HIT_IN             => hit_in_i(NUM_TDC_CHANNELS-1 downto 1),  -- Channel start signals
+      HIT_CAL_IN         => osc_int,    -- Hits for calibrating the TDC
+      -- Trigger signals from handler
+      BUSRDO_RX          => readout_rx,
+      BUSRDO_TX          => readout_tx(0),
+      -- Slow control bus
+      BUS_RX             => bustdc_rx,
+      BUS_TX             => bustdc_tx,
+      -- Dubug signals
+      INFO_IN            => timer,
+      LOGIC_ANALYSER_OUT => TEST_LINE
+      );
+
+  -- For single edge measurements
+  gen_single : if DOUBLE_EDGE_TYPE = 0 or DOUBLE_EDGE_TYPE = 1 or DOUBLE_EDGE_TYPE = 3 generate
+    hit_in_i <= INP;
+    input_i  <= INP;
+  end generate;
+
+  -- For ToT Measurements
+  gen_double : if DOUBLE_EDGE_TYPE = 2 and USE_PADIWA_FAST_ONLY = 0 generate
+    Gen_Hit_In_Signals : for i in 1 to 32 generate
+      hit_in_i(i*2-1) <= INP(i-1);
+      hit_in_i(i*2)   <= not INP(i-1);
+      input_i(i)      <= INP(i-1);
+    end generate Gen_Hit_In_Signals;
+  end generate;
+
+  gen_double_padiwa_fast : if USE_PADIWA_FAST_ONLY = 1 generate
+    Gen_Hit_Fast_Signals : for i in 1 to 32 generate
+      hit_in_i(i*2-1) <= INP(i*2-2);
+      hit_in_i(i*2)   <= not INP(i*2-2);
+      input_i(i)      <= INP(i*2-2);
+    end generate;
+  end generate;
+
+
+end architecture;
diff --git a/releases/tdc_v2.3.1/trbnet_constraints.lpf b/releases/tdc_v2.3.1/trbnet_constraints.lpf
new file mode 100644 (file)
index 0000000..c86091a
--- /dev/null
@@ -0,0 +1,53 @@
+#################################################################
+# Reset Nets
+#################################################################  
+GSR_NET NET "reset_i";  
+
+#################################################################
+# Locate Serdes and media interfaces
+#################################################################
+
+MULTICYCLE TO CELL "THE_MEDIA_DOWNLINK/SCI_DATA_OUT*" 50 ns;
+MULTICYCLE TO CELL "THE_MEDIA_UPLINK/SCI_DATA_OUT*" 50 ns;
+MULTICYCLE TO CELL "THE_RESET_HANDLER/final_reset*" 30 ns;
+MULTICYCLE TO CELL "THE_RESET_HANDLER/trb_reset_*" 20 ns;
+MULTICYCLE TO CELL "gen_SPI.THE_DAC_SPI_*io*" 20 ns;
+MULTICYCLE TO CELL "THE_SPI_RELOAD_THE_SPI_MASTER_THE_SPI_SLIM_tx_sreg_oregio*" 20 ns;
+
+BLOCK PATH TO CELL "gen_TRIGGER_LOGIC_THE_TRIG_LOGIC/out_*";
+
+#Jan: Placement of TrbNet components (at least, most of them)
+
+
+MULTICYCLE FROM CELL "THE_RESET_HANDLER/final_reset*" 30 ns;
+
+
+
+REGION "REGION_SPI" "R2C110D"  16 18 DEVSIZE;
+LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MASTER/SPI_group" REGION "REGION_SPI";
+LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MEMORY/SPI_group" REGION "REGION_SPI";
+
+
+
+REGION "REGION_TRBNET" "R35C110D"  70 18 DEVSIZE;
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/MPLEX/MUX_group" REGION "REGION_TRBNET";
+
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.gen_api.DAT_PASSIVE_API/API_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_api.DAT_PASSIVE_API/API_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.2.gentermbuf.termbuf/TRMBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_regio.regIO/the_addresses/HUBLOGIC_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_regio.regIO/RegIO_group" REGION "REGION_TRBNET";
+
+LOCATE UGROUP "THE_BUS_HANDLER/Bus_handler_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_INTERNAL_BUS_HANDLER/Bus_handler_group" REGION "REGION_TRBNET";
+
diff --git a/releases/tdc_v2.3.1/trbnet_constraints_dirich.lpf b/releases/tdc_v2.3.1/trbnet_constraints_dirich.lpf
new file mode 100644 (file)
index 0000000..8501ad4
--- /dev/null
@@ -0,0 +1,53 @@
+#################################################################
+# Reset Nets
+#################################################################  
+GSR_NET NET "reset_i";  
+
+#################################################################
+# Locate Serdes and media interfaces
+#################################################################
+
+MULTICYCLE TO CELL "THE_MEDIA_DOWNLINK/SCI_DATA_OUT*" 50 ns;
+MULTICYCLE TO CELL "THE_MEDIA_UPLINK/SCI_DATA_OUT*" 50 ns;
+MULTICYCLE TO CELL "THE_RESET_HANDLER/final_reset*" 30 ns;
+MULTICYCLE TO CELL "THE_RESET_HANDLER/trb_reset_*" 20 ns;
+MULTICYCLE TO CELL "gen_SPI_DAC_SPI_*io*" 20 ns;
+MULTICYCLE TO CELL "THE_SPI_MASTER_THE_SPI_SLIM_tx_sreg_oregio*" 20 ns;
+
+BLOCK PATH TO CELL "gen_TRIGGER_LOGIC_THE_TRIG_LOGIC/out_*";
+
+#Jan: Placement of TrbNet components (at least, most of them)
+
+
+MULTICYCLE FROM CELL "THE_RESET_HANDLER/final_reset*" 30 ns;
+
+
+
+REGION "REGION_SPI" "R18C60D"  8 18 DEVSIZE;
+LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MASTER/SPI_group" REGION "REGION_SPI";
+LOCATE UGROUP "THE_SPI_RELOAD/THE_SPI_MEMORY/SPI_group" REGION "REGION_SPI";
+
+
+
+REGION "REGION_TRBNET" "R2C47D"  85 33 DEVSIZE;
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/MPLEX/MUX_group" REGION "REGION_TRBNET";
+
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/GEN_IBUF.THE_IBUF/IBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/genREPLYOBUF1.REPLYOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.0.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.IOBUF/genINITOBUF2.gen_INITOBUF3.INITOBUF/OBUF_group" REGION "REGION_TRBNET";
+
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.1.geniobuf.gen_api.DAT_PASSIVE_API/API_group" REGION "REGION_TRBNET";
+#LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_api.DAT_PASSIVE_API/API_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.2.gentermbuf.termbuf/TRMBUF_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_regio.regIO/the_addresses/HUBLOGIC_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_ENDPOINT/genbuffers.3.geniobuf.gen_regio.regIO/RegIO_group" REGION "REGION_TRBNET";
+
+LOCATE UGROUP "THE_BUS_HANDLER/Bus_handler_group" REGION "REGION_TRBNET";
+LOCATE UGROUP "THE_ENDPOINT/THE_INTERNAL_BUS_HANDLER/Bus_handler_group" REGION "REGION_TRBNET";
+
diff --git a/releases/tdc_v2.3.1/unimportant_lines_constraints.lpf b/releases/tdc_v2.3.1/unimportant_lines_constraints.lpf
new file mode 100644 (file)
index 0000000..55461da
--- /dev/null
@@ -0,0 +1,110 @@
+#############################################################################
+##                         Unimportant Data Lines                          ##
+#############################################################################
+BLOCK PATH FROM CLKNET "THE_TDC/edge_rising[*]";
+BLOCK NET "THE_TDC/hit_in_s*";
+
+USE SECONDARY NET "THE_TDC/coarse_cntr_reset";
+USE SECONDARY NET "THE_TDC/trg_win_end_tdc";
+
+
+MULTICYCLE FROM CELL "THE_TDC/reset_counters*" 4x;
+MULTICYCLE FROM CELL "THE_TDC/reset_tdc" 4x;
+
+MULTICYCLE FROM CELL "THE_TDC/ReferenceChannel/Channel200/RingBuffer*FIFO/FF*" TO CELL "THE_TDC/ReferenceChannel/Channel200/ringBuffer_almost_full_sync*" 2x;
+MULTICYCLE FROM CELL "THE_TDC/GEN_Channels*Channels/Channel200/RingBuffer*FIFO/FF*" TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/ringBuffer_almost_full_sync*" 2x;
+
+MULTICYCLE FROM CELL "THE_TDC/TheEpochCounter/counter*" TO CELL "THE_TDC/ReferenceChannel/Channel200/epoch_cntr[*]" 4 X;
+MULTICYCLE FROM CELL "THE_TDC/TheEpochCounter/counter*" TO CELL "THE_TDC/GEN_Channels*Channels/Channel200/epoch_cntr[*]" 4 X;
+
+MULTICYCLE TO CELL "THE_TDC/TheReadout/TW_pre*" 4 x;
+MULTICYCLE TO CELL "THE_TDC/TheReadout/TW_post*" 4 x;
+
+MULTICYCLE FROM CELL "THE_TDC/hit_edge[*]" TO CELL "THE_TDC/GEN_Channels.*.Channels/Channel200/memory_ram" 2.000000 X ;
+
+MULTICYCLE TO CELL "THE_TDC/edge_rising_100_r[*]" 4 x;
+MULTICYCLE FROM CELL "THE_TDC/GEN_Channels.*.Channels/Channel200/ringBuffer_almost_full_flag*" TO CELL "THE_TDC/TheReadout/data_out_r[*]" 2 x;
+
+#MULTICYCLE TO CELL "THE_TDC/ReferenceChannel/Channel200/SimAdderNo.FC/FF*" 4x;
+#MULTICYCLE TO CELL "THE_TDC/GEN_Channels.*.Channels/Channel200/SimAdderNo.FC/FF*" 4x;
+
+MULTICYCLE TO CELL "THE_TDC/ReferenceChannel/Channel200/CHANNEL_200_DEBUG_OUT_1[*]" 4x;
+MULTICYCLE TO CELL "THE_TDC/GEN_Channels.*.Channels/Channel200/CHANNEL_200_DEBUG_OUT_1[*]" 4x;
+
+MULTICYCLE FROM CELL "THE_TDC/TheSlowcontrolBus/DATA_OUT*" 20 ns;
+MULTICYCLE TO CELL "THE_TDC/TheHitCounterBus/BUS_TX[data][*]" 20 ns;
+MULTICYCLE TO CELL "THE_TDC/TheStatusRegisterBus/BUS_TX[data][*]" 20 ns;
+MULTICYCLE TO CELL "THE_TDC/TheChannelDebugBus/BUS_TX[data][*]" 20 ns;
+MULTICYCLE FROM CELL "THE_ENDPOINT/THE_ENDPOINT/*" TO CELL "THE_TDC/TheTriggerHandler/STATE_TW_CURRENT*" 10 ns;
+
+MAXDELAY NET "THE_TDC/hit_in_i*" 0.600000 nS; #DATAPATH_ONLY ;
+
+
+
+
+
+PROHIBIT SECONDARY NET "THE_TDC/ReferenceChannel/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.1.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.2.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.3.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.4.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.5.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.6.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.7.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.8.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.9.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.10.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.11.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.12.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.13.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.14.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.15.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.16.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.17.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.18.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.19.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.20.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.21.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.22.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.23.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.24.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.25.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.26.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.27.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.28.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.29.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.30.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.31.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.32.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.33.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.34.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.35.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.36.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.37.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.38.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.39.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.40.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.41.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.42.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.43.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.44.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.45.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.46.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.47.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.48.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.49.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.50.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.51.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.52.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.53.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.54.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.55.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.56.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.57.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.58.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.59.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.60.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.61.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.62.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.63.Channels/Channel200/ff_array_en";
+PROHIBIT SECONDARY NET "THE_TDC/GEN_Channels.64.Channels/Channel200/ff_array_en";
diff --git a/releases/tdc_v2.3.1/up_counter.vhd b/releases/tdc_v2.3.1/up_counter.vhd
new file mode 100644 (file)
index 0000000..1d8a887
--- /dev/null
@@ -0,0 +1,41 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use IEEE.STD_LOGIC_UNSIGNED.all;
+
+entity up_counter is
+
+  generic (
+    NUMBER_OF_BITS : positive);
+  port (
+    CLK       : in  std_logic;
+    RESET     : in  std_logic;
+    COUNT_OUT : out std_logic_vector(NUMBER_OF_BITS-1 downto 0);
+    UP_IN     : in  std_logic);
+
+end up_counter;
+
+architecture up_counter of up_counter is
+
+  signal counter                    : std_logic_vector (NUMBER_OF_BITS-1 downto 0);
+  attribute syn_preserve            : boolean;
+  attribute syn_preserve of counter : signal is true;
+
+begin
+
+  COUNTER_PROC : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        counter <= (others => '0');
+      elsif UP_IN = '1' then
+        counter <= counter + 1;
+      else
+        counter <= counter;
+      end if;
+    end if;
+  end process COUNTER_PROC;
+
+  COUNT_OUT <= counter;
+
+end up_counter;