From 374d4bd2d0a7a722e91fb3ff4b19ddf7364750b2 Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Mon, 4 Nov 2013 19:15:46 +0100 Subject: [PATCH] Improvements to the CTS AddOn Added RoundRobin for EventBuilders --- cts/.kateconfig | 1 + cts/decode_evt.pl | 63 ++++++++++++++++++++++++++++++++++++++ cts/source/cts.vhd | 24 +++++++++++++-- cts/source/cts_pkg.vhd | 12 ++++++++ cts/source/cts_trigger.vhd | 46 ++++++++++++++++++++++++++-- cts/trb3_central.vhd | 55 ++++++++++++++++++++++++++------- 6 files changed, 185 insertions(+), 16 deletions(-) create mode 100644 cts/.kateconfig create mode 100755 cts/decode_evt.pl diff --git a/cts/.kateconfig b/cts/.kateconfig new file mode 100644 index 0000000..8224436 --- /dev/null +++ b/cts/.kateconfig @@ -0,0 +1 @@ +kate: space-indent on; indent-width 3; tab-width 3; replace-tabs on; diff --git a/cts/decode_evt.pl b/cts/decode_evt.pl new file mode 100755 index 0000000..936efc4 --- /dev/null +++ b/cts/decode_evt.pl @@ -0,0 +1,63 @@ +#!/usr/bin/env perl +# little tool to decode a CTS subevent provided via stdin in the daq_anal +# format. just copy and paste the frame starting with the subevent header + +use strict; +use warnings; +use Data::Dumper; + +my $input = ''; +while (my $line = ) { + chomp($line); + last unless $line; + $input .= $line . ' '; +}; + +my @dec = grep(/^0x/, (split /\s+/, $input)); +shift @dec; + + +my $word = hex(shift @dec); +my $evt = { + 'itc_state' => $word & 0xffff, + 'input_counters' => ($word >> 16) & 0xf, + 'itc_counters' => ($word >> 20) & 0xf, + 'idledead' => ($word >> 25) & 0x1, + 'trigger_stats' => ($word >> 26) & 0x1, + 'timestamp' => ($word >> 27) & 0x1, + 'etm_mode' => ($word >> 28) & 0x2 +}; + +print Dumper $evt; + +for(my $i=0; $i < $evt->{'input_counters'}; $i++) { + printf "Input %d Level Counter: % 14d\n", $i, hex(shift(@dec)); + printf "Input %d Edge Counter: % 14d\n", $i, hex(shift(@dec)); +} + +for(my $i=0; $i < $evt->{'itc_counters'}; $i++) { + printf "ITC %02d Level Counter: % 14d\n", $i, hex(shift(@dec)); + printf "ITC %02d Edge Counter: % 14d\n", $i, hex(shift(@dec)); +} + +if ($evt->{'idledead'}) { + printf "Idle Time: %e s\n", hex(shift(@dec)) * 1e-8; + printf "Dead Time: %e s\n", hex(shift(@dec)) * 1e-8; +} + +if ($evt->{'trigger_stats'}) { + printf "Trigger asserted : % 14d cycles\n", hex(shift(@dec)); + printf "Trigger rising edge: % 14d edges\n", hex(shift(@dec)); + printf "Trigger accepted : % 14d evts\n", hex(shift(@dec)); +} + +if ($evt->{'timestamp'}) { + printf "Timestamp: %d cycles\n", hex(shift(@dec)); +} + +my $etmno = (!$evt->{'timestamp'} < 2) ? (!$evt->{'timestamp'}) : ((!$evt->{'timestamp'} == 2) ? 4 : -1); +if ($etmno >= 0) { + for(my $i=0; $i < $etmno; $i++) { + printf "ETM data: %s\n", $i, shift(@dec); + } +} diff --git a/cts/source/cts.vhd b/cts/source/cts.vhd index ac7cb2d..3e4a66b 100644 --- a/cts/source/cts.vhd +++ b/cts/source/cts.vhd @@ -4,6 +4,7 @@ library IEEE; library work; use work.trb_net_components.all; + use work.trb_net_std.all; use work.CTS_PKG.ALL; -- Debug and status registers @@ -20,7 +21,7 @@ library work; -- -- 0x04 Buffered trigger status -- 15 : 00 Trigger bitmask (before filtering) --- 19 : 16 Trigger type +-- 19 :16 Trigger type -- -- 0x05 TD FSM State (Trigger Distribution). One-Hot-Encoding: -- 0 TD_FSM_IDLE @@ -75,7 +76,7 @@ library work; -- -- 0x0d Event Builder selection -- 15 : 00 Event Builder mask (default: 0x1) --- 23 : 16 Number of events before selecting next builder (useful to aggregate events to support large data packets +-- 23 : 16 Number of events before selecting next builder (useful to aggregate events to support large data packets) -- 27 : 24 Event Builder number of calibration trigger -- 28 If asserted: Use special event builder for calibration trigger, otherwise, use ordinary round robin selection. -- @@ -103,7 +104,10 @@ entity CTS is TRIGGER_RAND_PULSER : integer range 0 to 1 := 1; ADDON_LINE_COUNT : integer := 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'); EXTERNAL_TRIGGER_ID : std_logic_vector(7 downto 0) := X"00"; @@ -121,6 +125,8 @@ entity CTS is TIME_REFERENCE_OUT : out std_logic; 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'); -- External trigger logic EXT_TRIGGER_IN : in std_logic; @@ -683,7 +689,12 @@ begin -- we can switch to a sequential process instead of a parallel priority encoder eb_sel_loop: for i in 0 to 15 loop if eb_mask_buf_i(i) = '1' then - eb_mask_buf_i(i) <= '0'; + if OR_ALL(eb_mask_buf_i(15 downto i+1)) = '0' then + eb_mask_buf_i <= eb_mask_i; + else + eb_mask_buf_i(i downto 0) <= (others => '0'); + end if; + eb_selection_i <= STD_LOGIC_VECTOR(TO_UNSIGNED(i, 4)); exit eb_sel_loop; @@ -707,16 +718,23 @@ 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, + TRIGGER_ADDON_COUNT => TRIGGER_ADDON_COUNT, EXTERNAL_TRIGGER_ID => EXTERNAL_TRIGGER_ID ) port map ( CLK_IN => CLK, + CLK_1KHZ_IN => clk_1khz_i, RESET_IN => RESET, TRIGGERS_IN => TRIGGERS_IN, ADDON_TRIGGERS_IN => ADDON_TRIGGERS_IN, + ADDON_GROUP_ACTIVITY_OUT => ADDON_GROUP_ACTIVITY_OUT, + ADDON_GROUP_SELECTED_OUT => ADDON_GROUP_SELECTED_OUT, EXT_TRIGGER_IN => EXT_TRIGGER_IN, EXT_STATUS_IN => EXT_STATUS_IN, diff --git a/cts/source/cts_pkg.vhd b/cts/source/cts_pkg.vhd index 37cadbc..0aa1826 100644 --- a/cts/source/cts_pkg.vhd +++ b/cts/source/cts_pkg.vhd @@ -3,6 +3,8 @@ library ieee; use ieee.numeric_std.all; package cts_pkg is + type CTS_GROUP_CONFIG_T is array(0 to 7) of integer; + component CTS is generic ( -- The total number of trigger units below has to be below 16 @@ -13,6 +15,8 @@ package cts_pkg is 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'); EXTERNAL_TRIGGER_ID : std_logic_vector(7 downto 0) := X"00"; @@ -30,6 +34,8 @@ package cts_pkg is TIME_REFERENCE_OUT : out std_logic; 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'); -- External trigger logic EXT_TRIGGER_IN : in std_logic; @@ -164,17 +170,23 @@ package cts_pkg is 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'); + EXTERNAL_TRIGGER_ID : std_logic_vector(7 downto 0) := X"00" ); port ( CLK_IN : in std_logic; + CLK_1KHZ_IN : in std_logic; RESET_IN : in std_logic; -- Input pins TRIGGERS_IN : in std_logic_vector(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'); -- External EXT_TRIGGER_IN : in std_logic; diff --git a/cts/source/cts_trigger.vhd b/cts/source/cts_trigger.vhd index 1bbd2b1..eab26c1 100644 --- a/cts/source/cts_trigger.vhd +++ b/cts/source/cts_trigger.vhd @@ -12,21 +12,27 @@ entity CTS_TRIGGER is 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; - TRIGGER_ADDON_COUNT : integer range 0 to 15 := 2; + TRIGGER_ADDON_COUNT : integer range 0 to 15 := 2; ADDON_LINE_COUNT : integer range 0 to 255 := 22; + ADDON_GROUPS : integer range 1 to 8 := 5; + ADDON_GROUP_UPPER : CTS_GROUP_CONFIG_T := (3,7,11,12,13, others=>'0'); EXTERNAL_TRIGGER_ID : std_logic_vector(7 downto 0) := X"00" ); port ( CLK_IN : in std_logic; + CLK_1KHZ_IN : in std_logic; RESET_IN : in std_logic; -- Trigger Inputs TRIGGERS_IN : in std_logic_vector(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'); + -- External EXT_TRIGGER_IN : in std_logic; EXT_STATUS_IN : in std_logic_vector(31 downto 0) := X"00000000"; @@ -122,6 +128,8 @@ architecture RTL of CTS_TRIGGER is -- Add On type trigger_addon_configs_t is array(TRIGGER_ADDON_COUNT - 1 downto 0) of std_logic_vector(7 downto 0); signal trigger_addon_configs_i : trigger_addon_configs_t; + 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'); -- Trigger Type Assoc type trigger_type_assoc_t is array(0 to 15) of std_logic_vector(3 downto 0); @@ -295,7 +303,41 @@ begin CHANNEL_COUNTERS_OUT(i*32 + 31 downto i*32) <= channel_counters_i(i); CHANNEL_EDGE_COUNTERS_OUT(i*32 + 31 downto i*32) <= channel_edge_counters_i(i); end generate; + +-- AddOn Leds +----------------------------------------- + process(CLK_IN) is + variable from : integer; + begin + if rising_edge(CLK_IN) then + from := 0; + if CLK_1KHZ_IN ='1' then + addon_group_activity_i <= (others => '0'); + + else + for i in 0 to ADDON_GROUPS-1 loop + addon_group_activity_i(i) <= addon_group_activity_i(i) or + OR_ALL(ADDON_TRIGGERS_IN(ADDON_GROUP_UPPER(i) downto from)); + + addon_group_selected_i(i) <= '0'; + for j in 0 to TRIGGER_ADDON_COUNT-1 loop + if from <= to_integer( UNSIGNED(trigger_addon_configs_i(j)) ) and + to_integer( UNSIGNED(trigger_addon_configs_i(j)) ) <= ADDON_GROUP_UPPER(i) then + addon_group_selected_i(i) <= '1'; + end if; + end loop; + + from := ADDON_GROUP_UPPER(i)+1; + end loop; + end if; + end if; + end process; + + ADDON_GROUP_ACTIVITY_OUT <= addon_group_activity_i; + ADDON_GROUP_SELECTED_OUT <= addon_group_selected_i; +-- RegIO +----------------------------------------- proc_regio: process(CLK_IN) is variable addr : integer range 0 to 255; variable ref_addr : integer range 0 to 255; diff --git a/cts/trb3_central.vhd b/cts/trb3_central.vhd index 3a6c625..f53c1ae 100644 --- a/cts/trb3_central.vhd +++ b/cts/trb3_central.vhd @@ -332,6 +332,8 @@ architecture trb3_central_arch of trb3_central is constant CTS_ADDON_LINE_COUNT : integer := 14; 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); signal cts_trg_send : std_logic; signal cts_trg_type : std_logic_vector(3 downto 0); @@ -422,7 +424,7 @@ architecture trb3_central_arch of trb3_central is signal tdc_ctrl_reg : std_logic_vector(5*32-1 downto 0); signal tdc_debug : std_logic_vector(15 downto 0); - + signal led_time_ref_i : std_logic; begin -- MBS Module gen_mbs_vulom_as_etm : if ETM_CHOICE = ETM_CHOICE_MBS_VULOM generate @@ -488,17 +490,23 @@ begin TRIGGER_PULSER_COUNT => 2, TRIGGER_RAND_PULSER => 1, TRIGGER_ADDON_COUNT => 2, - ADDON_LINE_COUNT => CTS_ADDON_LINE_COUNT + + ADDON_LINE_COUNT => CTS_ADDON_LINE_COUNT, + ADDON_GROUPS => 5, + ADDON_GROUP_UPPER => (3,7,11,12,13, others=>0) ) port map ( CLK => clk_100_i, RESET => reset_i, TRIGGERS_IN => trigger_in_buf_i, - ADDON_TRIGGERS_IN => cts_addon_triggers_in, TRIGGER_BUSY_OUT => trigger_busy_i, TIME_REFERENCE_OUT => cts_trigger_out, + ADDON_TRIGGERS_IN => cts_addon_triggers_in, + ADDON_GROUP_ACTIVITY_OUT => cts_addon_activity_i, + ADDON_GROUP_SELECTED_OUT => cts_addon_selected_i, + EXT_TRIGGER_IN => cts_ext_trigger, EXT_STATUS_IN => cts_ext_status, EXT_CONTROL_OUT => cts_ext_control, @@ -540,7 +548,8 @@ begin FEE_DATA_FINISHED_OUT => cts_rdo_finished ); - process is begin + 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; @@ -548,6 +557,21 @@ begin cts_addon_triggers_in(13 downto 12) <= 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), + others => '0' + ); + + LED_RJ_RED <= ( + 0 => cts_addon_selected_i(1), + 1 => cts_addon_selected_i(2), + 5 => cts_addon_selected_i(0), + others => '0' + ); + -- cts_rdo_trg_status_bits <= cts_rdo_trg_status_bits_cts OR cts_rdo_trg_status_bits_additional; @@ -1365,6 +1389,17 @@ process begin TRIGGER_OUT <= cts_trigger_out; TRIGGER_OUT2 <= cts_trigger_out; TRG_FANOUT_ADDON <= cts_trigger_out; + +end process; + +process(clk_100_i) is begin + if rising_edge(clk_100_i) then + if timer_ticks(0) = '1' then + led_time_ref_i <= '0'; + else + led_time_ref_i <= led_time_ref_i or cts_trigger_out; + end if; + end if; end process; @@ -1397,13 +1432,11 @@ end process; JOUTLVDS <= x"00"; JTTL <= x"0000"; - LED_BANK <= x"FF"; - LED_RJ_GREEN <= "111111"; - LED_RJ_RED <= "111111"; - LED_FAN_GREEN <= '1'; - LED_FAN_ORANGE <= '1'; - LED_FAN_RED <= '1'; - LED_FAN_YELLOW <= '1'; + LED_BANK(5 downto 0) <= (others => '0'); + LED_FAN_GREEN <= led_time_ref_i; + LED_FAN_ORANGE <= '0'; + LED_FAN_RED <= trigger_busy_i; + LED_FAN_YELLOW <= '0'; --------------------------------------------------------------------------- -- 2.43.0