]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
- Trigger: All inputs are now selected via multiplexers, i.e. inputs from TRB3's...
authorManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Fri, 13 Dec 2013 16:27:37 +0000 (17:27 +0100)
committerManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Fri, 13 Dec 2013 16:27:37 +0000 (17:27 +0100)
- Output-Multiplexer: The CTS now can drive the LVDS outputs of the input. The 8 bit pin-headers currently and the two LVDS-RJ45 jacks are currently connected, outputting the same 8-bit vector.

cts/source/cts.vhd
cts/source/cts_fifo.vhd
cts/source/cts_pkg.vhd
cts/source/cts_trigger.vhd
cts/trb3_central.vhd

index 76e6370b87aed0bfae5bdcb910722500f4ec3fe4..a84c2d6ca2a723af6d06b8bc7078a2270a11b2b5 100755 (executable)
@@ -98,7 +98,7 @@ library work;
 
 entity CTS is
    generic (
-      TRIGGER_INPUT_COUNT : integer range 1 to 8 := 4;
+      TRIGGER_INPUT_COUNT : integer range 0 to  8 := 4;
       TRIGGER_COIN_COUNT  : integer range 0 to 15 := 4;
       TRIGGER_PULSER_COUNT: integer range 0 to 15 := 4;
       TRIGGER_RAND_PULSER : integer range 0 to  1 := 1;
@@ -111,6 +111,9 @@ entity CTS is
       
       PERIPH_TRIGGER_COUNT: integer range 0 to 1 := 1;
       
+      OUTPUT_MULTIPLEXERS : integer range 0 to 255 := 0;
+      OUTPUT_EXTRA_INPUTS : integer range 0 to 255 := 0;
+      
       EXTERNAL_TRIGGER_ID  : std_logic_vector(7 downto 0) := X"00";
 
       TIME_REFERENCE_COUNT : positive := 10;
@@ -122,7 +125,7 @@ entity CTS is
       RESET     : in  std_logic;      
       
   -- Trigger Logic
-      TRIGGERS_IN        : in std_logic_vector(TRIGGER_INPUT_COUNT-1 downto 0);
+      TRIGGERS_IN        : in std_logic_vector(max(0,TRIGGER_INPUT_COUNT-1) downto 0):= (others => '0');
       TRIGGER_BUSY_OUT   : out std_logic;
       TIME_REFERENCE_OUT : out std_logic;
       
@@ -132,6 +135,9 @@ entity CTS is
 
       PERIPH_TRIGGER_IN : in std_logic_vector(3 downto 0) := (others => '0');
       
+      OUTPUT_MULTIPLEXERS_OUT : out std_logic_vector(OUTPUT_MULTIPLEXERS-1 downto 0);
+      OUTPUT_EXTRA_INPUTS_IN  : in std_logic_vector(max(0, OUTPUT_EXTRA_INPUTS-1) downto 0) := (others => '0');
+      
    -- External trigger logic
       EXT_TRIGGER_IN  : in std_logic;
       EXT_STATUS_IN   : in std_logic_vector(31 downto 0) := X"00000000";
@@ -185,6 +191,8 @@ entity CTS is
 end entity;
 
 architecture RTL of CTS is
+   constant EFFECTIVE_INPUT_COUNT : integer := TRIGGER_INPUT_COUNT + TRIGGER_ADDON_COUNT;
+
    -- the time reference signal is generated by the time_reference_proc process
    -- and started by asserting time_reference_start_i for 1 cycle.
    signal time_reference_start_i : std_logic := '0';
@@ -226,7 +234,7 @@ architecture RTL of CTS is
    signal throttle_active_i, throttle_enabled_i : std_logic := '0';
    signal throttle_threshold_i,
           throttle_counter_i  : unsigned(9 downto 0) := (others => '0');
-   
+
    signal stop_triggers_i : std_logic := '0';
    
 -- Trigger Distribution
@@ -332,10 +340,14 @@ architecture RTL of CTS is
    
    signal eb_regio_updated_i : std_logic := '0';
 begin
+   assert(EFFECTIVE_INPUT_COUNT > 0) report "The CTS requires atleast 1 input or input multiplexer";
+   assert(TRIGGER_ADDON_COUNT = 0 or ADDON_LINE_COUNT > 0) report "If you use an input multiplexer you have to provide atleast 1 addon input line";
+
+
 -- Trigger Distribution
 -----------------------------------------
    td_proc: process(CLK) is
-      variable fee_input_counter_v : integer range 0 to 2*(TRIGGER_INPUT_COUNT+TRIGGER_ADDON_COUNT) - 1 := 0;
+      variable fee_input_counter_v : integer range 0 to 2*(EFFECTIVE_INPUT_COUNT) - 1 := 0;
       variable fee_channel_counter_v : integer range 0 to 2* channel_counters_i'LENGTH / 32 - 1 := 0;
       
    begin
@@ -427,7 +439,7 @@ begin
                   -- write packet header
                      FEE_DATA_OUT(15 downto  0) <= trigger_bitmask_buf_i;
                      if ro_configuration_buf_i(0) = '1' then
-                        FEE_DATA_OUT(19 downto 16) <= STD_LOGIC_VECTOR(TO_UNSIGNED(TRIGGER_INPUT_COUNT+TRIGGER_ADDON_COUNT, 4));
+                        FEE_DATA_OUT(19 downto 16) <= STD_LOGIC_VECTOR(TO_UNSIGNED(EFFECTIVE_INPUT_COUNT, 4));
                      end if;
                      
                      if ro_configuration_buf_i(1) = '1' then
@@ -457,7 +469,7 @@ begin
                      end if;
                   end if;
 
-                  if fee_input_counter_v = 2*(TRIGGER_INPUT_COUNT+TRIGGER_ADDON_COUNT) - 1 or ro_configuration_buf_i(0) = '0' then
+                  if fee_input_counter_v = 2*EFFECTIVE_INPUT_COUNT - 1 or ro_configuration_buf_i(0) = '0' then
                      td_fsm_i <= TD_FSM_FEE_ENQUEUE_CHANNEL_COUNTER;
                   end if;
 
@@ -722,13 +734,16 @@ begin
       TRIGGER_COIN_COUNT   => TRIGGER_COIN_COUNT,
       TRIGGER_PULSER_COUNT => TRIGGER_PULSER_COUNT,
       TRIGGER_RAND_PULSER  => TRIGGER_RAND_PULSER,
-      
+     
       ADDON_LINE_COUNT     => ADDON_LINE_COUNT,
       ADDON_GROUPS         => ADDON_GROUPS,
       ADDON_GROUP_UPPER    => ADDON_GROUP_UPPER,
       
       PERIPH_TRIGGER_COUNT => PERIPH_TRIGGER_COUNT,
       
+      OUTPUT_MULTIPLEXERS  => OUTPUT_MULTIPLEXERS,
+      OUTPUT_EXTRA_INPUTS  => OUTPUT_EXTRA_INPUTS,
+      
       TRIGGER_ADDON_COUNT  => TRIGGER_ADDON_COUNT,
       EXTERNAL_TRIGGER_ID  => EXTERNAL_TRIGGER_ID
    )
@@ -744,6 +759,9 @@ begin
       
       PERIPH_TRIGGER_IN => PERIPH_TRIGGER_IN,
       
+      OUTPUT_MULTIPLEXERS_OUT => OUTPUT_MULTIPLEXERS_OUT,
+      OUTPUT_EXTRA_INPUTS_IN  => OUTPUT_EXTRA_INPUTS_IN,
+      
       EXT_TRIGGER_IN  => EXT_TRIGGER_IN,
       EXT_STATUS_IN   => EXT_STATUS_IN,
       EXT_CONTROL_OUT => EXT_CONTROL_OUT,
index d0282b9351e3d4577d5fe12b5442d85f291abbde..94ff0aa450f670b73b31da60b120cb9aeb3e7578 100644 (file)
@@ -28,8 +28,12 @@ end entity;
 architecture RTL of CTS_FIFO is
    constant DEPTH : integer := 2**ADDR_WIDTH;
    
+   attribute syn_ramstyle : string;
+   
    type memory_t is array(0 to DEPTH-1) of std_logic_vector(WIDTH-1 downto 0);
    signal memory_i : memory_t;   
+   attribute syn_ramstyle of memory_i : signal is "block_ram";
+   
    signal index_read_i, index_write_i : integer range 0 to DEPTH - 1 := 0;
    signal full_i, empty_i : std_logic;
    
index 64b9e8def287bdf737a32bf76aafe3ccd21a3690..b69569c64bf4346b3c33ebf898c16cefd92be2cc 100755 (executable)
@@ -4,11 +4,14 @@ library ieee;
 
 package cts_pkg is
    type CTS_GROUP_CONFIG_T is array(0 to 7) of integer;
-
+   
+   function MIN(x : integer; y : integer) return integer;
+   function MAX(x : integer; y : integer) return integer;
+   
    component CTS is
       generic (
          -- The total number of trigger units below has to be below 16
-         TRIGGER_INPUT_COUNT : integer range 1 to 8 := 4;
+         TRIGGER_INPUT_COUNT : integer range 0 to 8 := 4;
          TRIGGER_COIN_COUNT  : integer range 0 to 15 := 3;
          TRIGGER_PULSER_COUNT: integer range 0 to 15 := 4;
          TRIGGER_RAND_PULSER : integer range 0 to 15 := 1;
@@ -20,6 +23,10 @@ package cts_pkg is
 
          PERIPH_TRIGGER_COUNT: integer range 0 to 1 := 1;
          
+         OUTPUT_MULTIPLEXERS : integer range 0 to 255 := 0;
+         OUTPUT_EXTRA_INPUTS : integer range 0 to 255 := 0;
+
+         
          EXTERNAL_TRIGGER_ID : std_logic_vector(7 downto 0) := X"00";
          
          TIME_REFERENCE_COUNT: positive := 10;          -- Number of clock cycles the time reference needs to stay asserted (100ns)
@@ -31,7 +38,7 @@ package cts_pkg is
          RESET     : in  std_logic;      
          
    -- Trigger Logic
-         TRIGGERS_IN        : in std_logic_vector(TRIGGER_INPUT_COUNT-1 downto 0);
+         TRIGGERS_IN        : in std_logic_vector(MAX(0,TRIGGER_INPUT_COUNT-1) downto 0);
          TRIGGER_BUSY_OUT   : out std_logic;
          TIME_REFERENCE_OUT : out std_logic;
 
@@ -41,6 +48,9 @@ package cts_pkg is
          
          PERIPH_TRIGGER_IN : in std_logic_vector(3 downto 0) := (others => '0');
          
+         OUTPUT_MULTIPLEXERS_OUT : out std_logic_vector(OUTPUT_MULTIPLEXERS-1 downto 0);
+         OUTPUT_EXTRA_INPUTS_IN  : in std_logic_vector(max(0, OUTPUT_EXTRA_INPUTS-1) downto 0) := (others => '0');
+         
    -- External trigger logic
          EXT_TRIGGER_IN  : in std_logic;
          EXT_STATUS_IN   : in std_logic_vector(31 downto 0) := X"00000000";
@@ -167,18 +177,21 @@ package cts_pkg is
 
    component CTS_TRIGGER is
       generic (
-         TRIGGER_INPUT_COUNT  : integer range 1 to  8 := 4;
+         TRIGGER_INPUT_COUNT  : integer range 0 to  8 := 4;
          TRIGGER_COIN_COUNT   : integer range 0 to 15 := 4;
          TRIGGER_PULSER_COUNT : integer range 0 to 15 := 2;
          TRIGGER_RAND_PULSER  : integer range 0 to 15 := 1;
-         
+        
          ADDON_LINE_COUNT     : integer range 0 to 255 := 22;  -- number of lines available from add-on board
          TRIGGER_ADDON_COUNT  : integer range 0 to 15 := 2;  -- number of module instances used to patch through those lines
-         ADDON_GROUPS        : integer range 1 to 8 := 5;
-         ADDON_GROUP_UPPER   : CTS_GROUP_CONFIG_T  := (3,7,11,12,13, others=>'0');
+         ADDON_GROUPS         : integer range 1 to 8 := 5;
+         ADDON_GROUP_UPPER    : CTS_GROUP_CONFIG_T  := (3,7,11,12,13, others=>'0');
       
          PERIPH_TRIGGER_COUNT: integer range 0 to 1 := 1;
          
+         OUTPUT_MULTIPLEXERS : integer range 0 to 255 := 0;
+         OUTPUT_EXTRA_INPUTS : integer range 0 to 255 := 0;
+         
          EXTERNAL_TRIGGER_ID  : std_logic_vector(7 downto 0) := X"00"
       );
 
@@ -188,13 +201,16 @@ package cts_pkg is
          RESET_IN     : in  std_logic;      
          
       -- Input pins
-         TRIGGERS_IN : in std_logic_vector(TRIGGER_INPUT_COUNT - 1 downto 0);
+         TRIGGERS_IN : in std_logic_vector(MAX(0,TRIGGER_INPUT_COUNT-1) downto 0);
          ADDON_TRIGGERS_IN  : in std_logic_vector(ADDON_LINE_COUNT-1 downto 0) := (others => '0');
          ADDON_GROUP_ACTIVITY_OUT : out std_logic_vector(ADDON_GROUPS-1 downto 0) := (others => '0');
          ADDON_GROUP_SELECTED_OUT : out std_logic_vector(ADDON_GROUPS-1 downto 0) := (others => '0');
 
          PERIPH_TRIGGER_IN : in std_logic_vector(3 downto 0) := (others => '0');
          
+         OUTPUT_MULTIPLEXERS_OUT : out std_logic_vector(OUTPUT_MULTIPLEXERS-1 downto 0);
+         OUTPUT_EXTRA_INPUTS_IN  : in std_logic_vector(max(0, OUTPUT_EXTRA_INPUTS-1) downto 0) := (others => '0');
+         
       -- External 
          EXT_TRIGGER_IN  : in std_logic;
          EXT_STATUS_IN   : in std_logic_vector(31 downto 0) := X"00000000";
@@ -206,8 +222,9 @@ package cts_pkg is
          TRIGGER_BITMASK_OUT : out std_logic_vector(15 downto 0);
          
       -- Counters
-         INPUT_COUNTERS_OUT         : out std_logic_vector(32 * TRIGGER_INPUT_COUNT - 1 downto 0) := (others => '0');
-         INPUT_EDGE_COUNTERS_OUT    : out std_logic_vector(32 * TRIGGER_INPUT_COUNT - 1 downto 0) := (others => '0');
+         INPUT_COUNTERS_OUT         : out std_logic_vector(32 * (TRIGGER_INPUT_COUNT + TRIGGER_ADDON_COUNT) - 1 downto 0) := (others => '0');
+         INPUT_EDGE_COUNTERS_OUT    : out std_logic_vector(32 * (TRIGGER_INPUT_COUNT + TRIGGER_ADDON_COUNT) - 1 downto 0) := (others => '0');
+         
          CHANNEL_COUNTERS_OUT       : out std_logic_vector(32 * 16 - 1 downto 0) := (others => '0');
          CHANNEL_EDGE_COUNTERS_OUT  : out std_logic_vector(32 * 16 - 1 downto 0) := (others => '0');
          NUM_OF_ITC_USED_OUT        : out std_logic_vector(4 downto 0);
@@ -281,9 +298,6 @@ package cts_pkg is
       constant ITC_NUM : integer  range 0 to 15 := 0;
       constant LAST : boolean := false
    ) return std_logic_vector;
-   
-   
-   function MIN(x : integer; y : integer) return integer;
 end package cts_pkg;
 
 package body cts_pkg is
@@ -318,4 +332,14 @@ package body cts_pkg is
        return y;
      end if;
    end MIN;
+   
+   function MAX(x : integer; y : integer)
+    return integer is
+   begin
+     if x > y then
+       return x;
+     else
+       return y;
+     end if;
+   end MAX;
 end package body cts_pkg;
index 99cf30bb509f8513aa2466acfd3e3cabaeb4eea6..4f5ac6e755ddaccd634fa3f6ec42f5a1e2b074d3 100755 (executable)
@@ -8,7 +8,7 @@ library work;
    
 entity CTS_TRIGGER is
    generic (
-      TRIGGER_INPUT_COUNT  : integer range 1 to  8 := 4;
+      TRIGGER_INPUT_COUNT  : integer range 0 to  8 := 4;
       TRIGGER_COIN_COUNT   : integer range 0 to 15 := 4;
       TRIGGER_PULSER_COUNT : integer range 0 to 15 := 2;
       TRIGGER_RAND_PULSER  : integer range 0 to 15 := 1;
@@ -20,6 +20,9 @@ entity CTS_TRIGGER is
 
       PERIPH_TRIGGER_COUNT: integer range 0 to 1 := 1;
       
+      OUTPUT_MULTIPLEXERS : integer range 0 to 255 := 0;
+      OUTPUT_EXTRA_INPUTS : integer range 0 to 255 := 0;
+      
       EXTERNAL_TRIGGER_ID  : std_logic_vector(7 downto 0) := X"00"
    );
 
@@ -29,7 +32,7 @@ entity CTS_TRIGGER is
       RESET_IN     : in  std_logic;      
       
     -- Trigger Inputs
-      TRIGGERS_IN        : in std_logic_vector(TRIGGER_INPUT_COUNT-1 downto 0);
+      TRIGGERS_IN        : in std_logic_vector(MAX(0, TRIGGER_INPUT_COUNT-1) downto 0);
 
       ADDON_TRIGGERS_IN  : in std_logic_vector(ADDON_LINE_COUNT-1 downto 0) := (others => '0');
       ADDON_GROUP_ACTIVITY_OUT : out std_logic_vector(ADDON_GROUPS-1 downto 0) := (others => '0');
@@ -37,6 +40,9 @@ entity CTS_TRIGGER is
       
       PERIPH_TRIGGER_IN : in std_logic_vector(3 downto 0) := (others => '0');
 
+      OUTPUT_MULTIPLEXERS_OUT : out std_logic_vector(OUTPUT_MULTIPLEXERS-1 downto 0);
+      OUTPUT_EXTRA_INPUTS_IN  : in std_logic_vector(max(0, OUTPUT_EXTRA_INPUTS-1) downto 0) := (others => '0');
+      
     -- External 
       EXT_TRIGGER_IN  : in std_logic;
       EXT_STATUS_IN   : in std_logic_vector(31 downto 0) := X"00000000";
@@ -48,8 +54,8 @@ entity CTS_TRIGGER is
       TRIGGER_BITMASK_OUT : out std_logic_vector(15 downto 0);
       
     -- Counters
-      INPUT_COUNTERS_OUT         : out std_logic_vector(32 * (TRIGGER_INPUT_COUNT + TRIGGER_ADDON_COUNT) - 1 downto 0) := (others => '0');
-      INPUT_EDGE_COUNTERS_OUT    : out std_logic_vector(32 * (TRIGGER_INPUT_COUNT + TRIGGER_ADDON_COUNT) - 1 downto 0) := (others => '0');
+      INPUT_COUNTERS_OUT         : out std_logic_vector(32 * (TRIGGER_INPUT_COUNT+TRIGGER_ADDON_COUNT) - 1 downto 0) := (others => '0');
+      INPUT_EDGE_COUNTERS_OUT    : out std_logic_vector(32 * (TRIGGER_INPUT_COUNT+TRIGGER_ADDON_COUNT) - 1 downto 0) := (others => '0');
       CHANNEL_COUNTERS_OUT       : out std_logic_vector(32 * 16 - 1 downto 0) := (others => '0');
       CHANNEL_EDGE_COUNTERS_OUT  : out std_logic_vector(32 * 16 - 1 downto 0) := (others => '0');
       NUM_OF_ITC_USED_OUT        : out std_logic_vector(4 downto 0);
@@ -76,7 +82,7 @@ architecture RTL of CTS_TRIGGER is
    signal channel_edge_select_i : std_logic_vector(15 downto 0);
    
    -- internal trigger lines (i.e. all signals that are piped through the trigger input modules)
-   constant ITL_NUM : integer := TRIGGER_INPUT_COUNT + TRIGGER_ADDON_COUNT;
+   constant EFFECTIVE_INPUT_COUNT : integer := TRIGGER_INPUT_COUNT + TRIGGER_ADDON_COUNT;
 
    constant ITC_NUM_EXT_BUF : unsigned(0 downto 0) := (others => or_all(EXTERNAL_TRIGGER_ID));  -- oh, that's dirty, but dont know a better solution (but define a func)
    constant ITC_NUM_EXT     : integer := to_integer( ITC_NUM_EXT_BUF )  ;
@@ -85,13 +91,13 @@ architecture RTL of CTS_TRIGGER is
    constant ITC_BASE_PULSER : integer      := ITC_BASE_EXT         + ITC_NUM_EXT;
    constant ITC_BASE_RAND_PULSER : integer := ITC_BASE_PULSER      + TRIGGER_PULSER_COUNT;
    constant ITC_BASE_INPUTS : integer      := ITC_BASE_RAND_PULSER + TRIGGER_RAND_PULSER;
-   constant ITC_BASE_PERIPH : integer      := ITC_BASE_INPUTS      + ITL_NUM;
+   constant ITC_BASE_PERIPH : integer      := ITC_BASE_INPUTS      + EFFECTIVE_INPUT_COUNT;
    constant ITC_BASE_COINS  : integer      := ITC_BASE_PERIPH      + PERIPH_TRIGGER_COUNT;
 
    constant ITC_NUM_USED    : integer := ITC_BASE_COINS       + TRIGGER_COIN_COUNT;
 
-   alias trigger_inputs_i : std_logic_vector(ITL_NUM - 1 downto 0) 
-      is channels_i(ITC_BASE_INPUTS + ITL_NUM - 1 downto ITC_BASE_INPUTS);
+   alias trigger_inputs_i : std_logic_vector(EFFECTIVE_INPUT_COUNT - 1 downto 0) 
+      is channels_i(ITC_BASE_INPUTS + EFFECTIVE_INPUT_COUNT - 1 downto ITC_BASE_INPUTS);
       
    alias coins_i          : std_logic_vector(TRIGGER_COIN_COUNT - 1 downto 0) 
       is channels_i(ITC_BASE_COINS + TRIGGER_COIN_COUNT - 1 downto ITC_BASE_COINS);
@@ -107,12 +113,12 @@ architecture RTL of CTS_TRIGGER is
    signal channel_edge_counters_i : channel_counters_t;
    
 -- Trigger Inputs (Spike Rejection, Negation, Override ...)
-   signal triggers_i : std_logic_vector(ITL_NUM - 1 downto 0);
+   signal triggers_i : std_logic_vector(EFFECTIVE_INPUT_COUNT - 1 downto 0);
 
-   type trigger_input_configs_t is array(ITL_NUM - 1 downto 0) of std_logic_vector(10 downto 0);
+   type trigger_input_configs_t is array(EFFECTIVE_INPUT_COUNT - 1 downto 0) of std_logic_vector(10 downto 0);
    signal trigger_input_configs_i : trigger_input_configs_t;
 
-   type   trigger_input_counters_t is array(ITL_NUM - 1 downto 0) of unsigned(31 downto 0);
+   type   trigger_input_counters_t is array(EFFECTIVE_INPUT_COUNT - 1 downto 0) of unsigned(31 downto 0);
    signal trigger_input_counters_i : trigger_input_counters_t;
    signal trigger_input_edge_counters_i : trigger_input_counters_t;
    
@@ -140,6 +146,10 @@ architecture RTL of CTS_TRIGGER is
    signal addon_group_activity_i : std_logic_vector(ADDON_GROUPS-1 downto 0) := (others => '0');
    signal addon_group_selected_i : std_logic_vector(ADDON_GROUPS-1 downto 0) := (others => '0');
    
+   type output_multiplexer_configs_t is array(OUTPUT_MULTIPLEXERS - 1 downto 0) of std_logic_vector(7 downto 0);
+   signal output_multiplexer_configs_i : output_multiplexer_configs_t;
+   signal output_multiplexer_ins_i : std_logic_vector(16 + 2*TRIGGER_INPUT_COUNT + ADDON_LINE_COUNT + TRIGGER_ADDON_COUNT + OUTPUT_EXTRA_INPUTS - 1 downto 0);
+   
 -- Trigger Type Assoc 
    type trigger_type_assoc_t is array(0 to 15) of std_logic_vector(3 downto 0);
    signal trigger_type_assoc_i : trigger_type_assoc_t := (others => X"1");
@@ -157,7 +167,7 @@ begin
 -- Modules   
    proc_input_ffs: process(CLK_IN) is
    begin
-      if rising_edge(CLK_IN) then
+      if rising_edge(CLK_IN) and TRIGGER_INPUT_COUNT > 0  then
          triggers_i(TRIGGER_INPUT_COUNT-1 downto 0) <= TRIGGERS_IN;
       end if;
    end process;
@@ -175,8 +185,46 @@ begin
    gen_ext_trigger: if EXTERNAL_TRIGGER_ID /= X"00" generate
       channels_i(ITC_BASE_EXT) <= EXT_TRIGGER_IN;
    end generate;
+   
+   proc_output_multi_ins: process(channels_i, TRIGGERS_IN, ADDON_TRIGGERS_IN, trigger_inputs_i, 
+     OUTPUT_EXTRA_INPUTS_IN, output_multiplexer_configs_i) is
+      variable i : integer := 0;
+   begin
+      i := 0;
+   
+      output_multiplexer_ins_i(15 + i downto i) <= channels_i;
+      i := i + 16;
+      
+      if TRIGGER_INPUT_COUNT > 0 then
+         output_multiplexer_ins_i(TRIGGERS_IN'high + i downto i) <= TRIGGERS_IN;
+         i := i + TRIGGER_INPUT_COUNT;
+      end if;
+
+      if ADDON_LINE_COUNT > 0 then
+         output_multiplexer_ins_i(ADDON_TRIGGERS_IN'high + i downto i) <= ADDON_TRIGGERS_IN;
+         i := i + ADDON_LINE_COUNT;
+      end if;
+      
+      output_multiplexer_ins_i(trigger_inputs_i'high + i downto i) <= trigger_inputs_i;
+      i := i + EFFECTIVE_INPUT_COUNT;
+      
+      if OUTPUT_EXTRA_INPUTS > 0 then
+         output_multiplexer_ins_i(OUTPUT_EXTRA_INPUTS + i - 1 downto i) <= OUTPUT_EXTRA_INPUTS_IN;
+         i := i + OUTPUT_EXTRA_INPUTS;
+      end if;
+   end process;
+   
+   proc_out_multi: process(output_multiplexer_ins_i, output_multiplexer_configs_i) is
+      variable tmp : integer range 0 to 255 := 0;
+      variable idx : integer range 0 to output_multiplexer_ins_i'high := 0;
+      variable test : std_logic_vector(31 downto 0);
+   begin
+      for j in 0 to output_multiplexers - 1 loop
+          output_multiplexers_out(j) <= test(to_integer( unsigned( output_multiplexer_configs_i(j)))); --output_multiplexer_ins_i(idx);
+      end loop;   
+   end process;
          
-   gen_trigger_inputs: for i in 0 to ITL_NUM-1 generate
+   gen_trigger_inputs: for i in 0 to EFFECTIVE_INPUT_COUNT-1 generate
       my_trigger_input: CTS_TRG_INPUT port map (
          CLK_IN => CLK_IN,
          RST_IN => RESET_IN,
@@ -189,7 +237,7 @@ begin
    gen_coin: for i in 0 to TRIGGER_COIN_COUNT - 1 generate
       my_coin: CTS_TRG_COIN 
       generic map (
-         INPUT_COUNT => ITL_NUM
+         INPUT_COUNT => EFFECTIVE_INPUT_COUNT
       )
       port map (
          CLK_IN => CLK_IN,
@@ -283,7 +331,7 @@ begin
             channel_edge_counters_i       <= (others => (others => '0'));
          
          else
-            for i in 0 to ITL_NUM-1 loop
+            for i in 0 to EFFECTIVE_INPUT_COUNT-1 loop
                if triggers_i(i) = '1' then
                   trigger_input_counters_i(i) <= trigger_input_counters_i(i) + "1";
                   
@@ -310,7 +358,7 @@ begin
       end if;
    end process;
    
-   gen_input_counter: for i in 0 to ITL_NUM-1 generate
+   gen_input_counter: for i in 0 to EFFECTIVE_INPUT_COUNT-1 generate
       INPUT_COUNTERS_OUT(i*32 + 31 downto i*32) <= trigger_input_counters_i(i);
       INPUT_EDGE_COUNTERS_OUT(i*32 + 31 downto i*32) <= trigger_input_edge_counters_i(i);
    end generate;
@@ -380,6 +428,14 @@ begin
 
             ext_control_i <= (others => '0');
             
+            for i in 0 to TRIGGER_ADDON_COUNT - 1 loop
+               trigger_addon_configs_i(i) <= STD_LOGIC_VECTOR(TO_UNSIGNED(i mod ADDON_LINE_COUNT, 8));
+            end loop;
+            
+            for i in 0 to OUTPUT_MULTIPLEXERS - 1 loop
+               output_multiplexer_configs_i(i) <= STD_LOGIC_VECTOR(TO_UNSIGNED(i mod output_multiplexer_ins_i'length, 8));
+            end loop;
+            
          else
 
 -- Trigger Channel Masking         
@@ -436,15 +492,15 @@ begin
                REGIO_DATAREADY_OUT <= REGIO_READ_ENABLE_IN;
                REGIO_DATA_OUT <= CTS_BLOCK_HEADER(
                   id => 16#10#,
-                  len => ITL_NUM,
+                  len => EFFECTIVE_INPUT_COUNT,
                   itc_base => ITC_BASE_INPUTS,
-                  itc_num  => ITL_NUM
+                  itc_num  => EFFECTIVE_INPUT_COUNT
                );
             end if;
             ref_addr := ref_addr + 1;            
 
 -- INPUT CONFIGURATION
-            for i in 0 to ITL_NUM - 1 loop
+            for i in 0 to EFFECTIVE_INPUT_COUNT - 1 loop
                if addr = ref_addr then
                   REGIO_UNKNOWN_ADDR_OUT <= '0';
                   REGIO_DATAREADY_OUT <= REGIO_READ_ENABLE_IN;
@@ -463,11 +519,11 @@ begin
             if addr = ref_addr then
                REGIO_UNKNOWN_ADDR_OUT <= REGIO_WRITE_ENABLE_IN;
                REGIO_DATAREADY_OUT <= REGIO_READ_ENABLE_IN;
-               REGIO_DATA_OUT <= CTS_BLOCK_HEADER(id => 16#11#, len => 2*ITL_NUM);
+               REGIO_DATA_OUT <= CTS_BLOCK_HEADER(id => 16#11#, len => 2*EFFECTIVE_INPUT_COUNT);
             end if;
             ref_addr := ref_addr + 1;
             
-            for i in 0 to ITL_NUM - 1 loop
+            for i in 0 to EFFECTIVE_INPUT_COUNT - 1 loop
                if addr = ref_addr then
                   REGIO_UNKNOWN_ADDR_OUT <= REGIO_WRITE_ENABLE_IN;
                   REGIO_DATAREADY_OUT <= REGIO_READ_ENABLE_IN;
@@ -548,6 +604,38 @@ begin
                end loop;
             end if;            
 
+-- OUTPUT MULTIPLEXER MODULE
+            if OUTPUT_MULTIPLEXERS > 0 then
+               if addr = ref_addr then
+                  REGIO_UNKNOWN_ADDR_OUT <= REGIO_WRITE_ENABLE_IN;
+                  REGIO_DATAREADY_OUT <= REGIO_READ_ENABLE_IN;
+                  REGIO_DATA_OUT <= CTS_BLOCK_HEADER(
+                     id => 16#13#,
+                     len => OUTPUT_MULTIPLEXERS,
+                     itc_base => 0,
+                     itc_num  => 0
+                  );
+               end if;
+               ref_addr := ref_addr + 1;  
+               
+               for i in 0 to OUTPUT_MULTIPLEXERS - 1 loop
+                  if addr=ref_addr then
+                     REGIO_UNKNOWN_ADDR_OUT <= '0';
+                     REGIO_DATAREADY_OUT <= REGIO_READ_ENABLE_IN;
+                     REGIO_WRITE_ACK_OUT <= REGIO_WRITE_ENABLE_IN;
+                     
+                     REGIO_DATA_OUT <= (others => '0');
+                     REGIO_DATA_OUT(output_multiplexer_configs_i(i)'RANGE) <= output_multiplexer_configs_i(i);
+                     
+                     if REGIO_WRITE_ENABLE_IN = '1' then
+                        output_multiplexer_configs_i(i) <= REGIO_DATA_IN(output_multiplexer_configs_i(i)'RANGE);
+                     end if;
+                  end if;
+                  ref_addr := ref_addr + 1;                 
+   
+               end loop;
+            end if;            
+            
 -- PERIPH TRIGGER
             if PERIPH_TRIGGER_COUNT > 0 then
                if addr = ref_addr then
index 99eeb5e8c87ee5db1d32e3ebb7b3379ef36058e7..23a9e9980647167467e2d7d5e98facd3643cc7a6 100755 (executable)
@@ -16,7 +16,6 @@ library work;
 --Configuration is done in this file:   
    use work.config.all;
 -- The description of hub ports is also there!
-   
 
 --Slow Control
 --    0 -    7  Readout endpoint common status
@@ -29,9 +28,6 @@ library work;
 -- C000 - CFFF  TDC configuration & status
 -- D000 - D13F  Flash Programming
 
-
-
-
 entity trb3_central is
   port(
     --Clocks
@@ -330,12 +326,18 @@ architecture trb3_central_arch of trb3_central is
   signal cts_rdo_trg_information            : std_logic_vector(23 downto 0);
   signal cts_rdo_trg_number                 : std_logic_vector(15 downto 0);
       
-  constant CTS_ADDON_LINE_COUNT      : integer := 14;
+  constant CTS_ADDON_LINE_COUNT      : integer := 22;
+  constant CTS_OUTPUT_MULTIPLEXERS   : integer :=  8;
+  constant CTS_OUTPUT_INPUTS         : integer := 16;
+  
   signal cts_addon_triggers_in       : std_logic_vector(CTS_ADDON_LINE_COUNT-1 downto 0);
   signal cts_addon_activity_i,
-         cts_addon_selected_i        : std_logic_vector(4 downto 0);
+         cts_addon_selected_i        : std_logic_vector(6 downto 0);
          
   signal cts_periph_trigger_i        : std_logic_vector(3 downto 0);
+  signal cts_output_multiplexers_i   : std_logic_vector(CTS_OUTPUT_MULTIPLEXERS - 1 downto 0);
+  
+  signal cts_output_extra_inputs_i   : std_logic_vector(CTS_OUTPUT_INPUTS - 1 downto 0);
   
   signal cts_trg_send                : std_logic;
   signal cts_trg_type                : std_logic_vector(3 downto 0);
@@ -479,31 +481,32 @@ begin
                                );
        end generate;
 
-       
-       
-   trigger_in_buf_i(1 downto 0) <= CLK_EXT;
-   trigger_in_buf_i(3 downto 2) <= TRIGGER_EXT(3 downto 2);
 
  THE_CTS: CTS 
    generic map (
       EXTERNAL_TRIGGER_ID  => X"60"+ETM_CHOICE_type'pos(ETM_CHOICE), -- fill in trigger logic enumeration id of external trigger logic
-      TRIGGER_INPUT_COUNT  => 4,
+      
       TRIGGER_COIN_COUNT   => 4,
       TRIGGER_PULSER_COUNT => 2,
       TRIGGER_RAND_PULSER  => 1,
-      TRIGGER_ADDON_COUNT  => 2,
+
+      TRIGGER_INPUT_COUNT  => 0, -- now all inputs are routed via an input multiplexer!
+      TRIGGER_ADDON_COUNT  => 6,
       
       PERIPH_TRIGGER_COUNT => 1,
       
+      OUTPUT_MULTIPLEXERS  => CTS_OUTPUT_MULTIPLEXERS,
+      OUTPUT_EXTRA_INPUTS  => CTS_OUTPUT_INPUTS,
+      
       ADDON_LINE_COUNT     => CTS_ADDON_LINE_COUNT,
-      ADDON_GROUPS         => 5,
-      ADDON_GROUP_UPPER    => (3,7,11,12,13, others=>0)
+      ADDON_GROUPS         => 7,
+      ADDON_GROUP_UPPER    => (3,7,11,15,16,17, others=>0)
    )
    port map ( 
       CLK => clk_100_i,
       RESET => reset_i,
       
-      TRIGGERS_IN => trigger_in_buf_i,
+      --TRIGGERS_IN => trigger_in_buf_i,
       TRIGGER_BUSY_OUT => trigger_busy_i,
       TIME_REFERENCE_OUT => cts_trigger_out,
       
@@ -518,6 +521,9 @@ begin
       
       PERIPH_TRIGGER_IN => cts_periph_trigger_i,
       
+      OUTPUT_MULTIPLEXERS_OUT => cts_output_multiplexers_i,
+      OUTPUT_EXTRA_INPUTS_IN  => cts_output_extra_inputs_i,
+      
       CTS_TRG_SEND_OUT => cts_trg_send,
       CTS_TRG_TYPE_OUT => cts_trg_type,
       CTS_TRG_NUMBER_OUT => cts_trg_number,
@@ -554,33 +560,46 @@ begin
       FEE_DATA_FINISHED_OUT   => cts_rdo_finished
    );   
    
-   process is
-   begin
-      wait until rising_edge(clk_100_i);
-      cts_addon_triggers_in( 3 downto  0) <= ECL_IN;
-      cts_addon_triggers_in( 7 downto  4) <= JIN1;
-      cts_addon_triggers_in(11 downto  8) <= JIN2;
-      cts_addon_triggers_in(13 downto 12) <= NIM_IN;
-   end process;
+   --process is
+   --begin
+      --wait until rising_edge(clk_100_i);
+      
+   cts_addon_triggers_in( 1 downto  0) <= CLK_EXT;                 -- former trigger inputs
+   cts_addon_triggers_in( 3 downto  2) <= TRIGGER_EXT(3 downto 2); -- former trigger inputs
+   
+   cts_addon_triggers_in( 7 downto  4) <= ECL_IN;
+   cts_addon_triggers_in(11 downto  8) <= JIN1;
+   cts_addon_triggers_in(15 downto 12) <= JIN2;
+   cts_addon_triggers_in(17 downto 16) <= NIM_IN;
+   
+   cts_addon_triggers_in(18) <= or_all(ECL_IN);
+   cts_addon_triggers_in(19) <= or_all(JIN1);
+   cts_addon_triggers_in(20) <= or_all(JIN2);
+   cts_addon_triggers_in(21) <= or_all(NIM_IN);
+   --end process;
    
    LED_BANK(7 downto 6) <= cts_addon_activity_i(4 downto 3);
    LED_RJ_GREEN <= (
-      0 => cts_addon_activity_i(1),
-      1 => cts_addon_activity_i(2),
-      5 => cts_addon_activity_i(0),
+      0 => cts_addon_activity_i(2),
+      1 => cts_addon_activity_i(3),
+      5 => cts_addon_activity_i(1),
       others => '0'
    );
       
    LED_RJ_RED <= (
-      0 => cts_addon_selected_i(1),
-      1 => cts_addon_selected_i(2),
-      5 => cts_addon_selected_i(0),
+      0 => cts_addon_selected_i(2),
+      1 => cts_addon_selected_i(3),
+      5 => cts_addon_selected_i(1),
       others => '0'
    );
    
    cts_periph_trigger_i <= FPGA4_COMM(10) & FPGA3_COMM(10) & FPGA2_COMM(10) & FPGA1_COMM(10);
+
+   cts_output_extra_inputs_i <= FPGA4_COMM(7 downto 4) & FPGA3_COMM(7 downto 4) & FPGA2_COMM(7 downto 4) & FPGA1_COMM(7 downto 4);
    
---    cts_rdo_trg_status_bits <= cts_rdo_trg_status_bits_cts OR cts_rdo_trg_status_bits_additional;
+   JOUT1    <= cts_output_multiplexers_i(3 downto 0);
+   JOUT2    <= cts_output_multiplexers_i(7 downto 4);
+   JOUTLVDS <= cts_output_multiplexers_i(7 downto 0);
    
 ---------------------------------------------------------------------------
 -- Reset Generation