From: Ludwig Maier Date: Sun, 16 Aug 2015 20:51:53 +0000 (+0200) Subject: scaler update X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=fc761ce2301beb1e8f56bd06831c62a416317f78;p=trb3.git scaler update --- diff --git a/scaler/source/latch_handler.vhd b/scaler/source/latch_handler.vhd new file mode 100644 index 0000000..9c9cd13 --- /dev/null +++ b/scaler/source/latch_handler.vhd @@ -0,0 +1,298 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.scaler_components.all; + +entity latch_handler is + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + CLK_D1_IN : in std_logic; + RESET_D1_IN : in std_logic; -- Rest CLK_D1 Domain + + --Inputs + RESET_CTR_IN : in std_logic; + LATCH_TRIGGER_IN : in std_logic; -- The raw Timing Trigger Signal + LATCH_EXTERN_IN : in std_logic; -- The raw Latch Signal + + -- Outputs + RESET_CTR_OUT : out std_logic; + LATCH_OUT : out std_logic; + LATCH_VALID_OUT : out std_logic; + LATCH_INVALID_OUT : out std_logic; + + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic; + + -- Debug Line + DEBUG_OUT : out std_logic_vector(15 downto 0) + ); +end entity; + +architecture Behavioral of latch_handler is + + -- Reset Counters + signal reset_d1_ff : std_logic_vector(1 downto 0); + signal RESET_D1 : std_logic; + + signal reset_ctr_ff : std_logic_vector(2 downto 0); + signal reset_ctr_o : std_logic; + + -- Latch Handler + signal latch_select_ff : std_logic_vector(1 downto 0); + signal latch_ff : std_logic_vector(2 downto 0); + + signal latch_i : std_logic; + signal latch : std_logic; + signal latch_o : std_logic; + signal latch_valid_o : std_logic; + signal latch_invalid_o : std_logic; + +-- -- Latch Handler +-- type LH_STATES is (LH_IDLE, +-- LH_VALIDATE, +-- LH_WAIT +-- ); +-- signal LH_STATE : LH_STATES; +-- +-- signal lh_wait_timer_reset : std_logic; +-- signal lh_wait_timer_start : std_logic; +-- signal lh_wait_timer_done : std_logic; +-- +-- signal latch_validate_ctr : unsigned(4 downto 0); +-- +-- signal latch_o : std_logic; +-- signal latch_valid_o : std_logic; +-- signal latch_invalid_o : std_logic; +-- +-- -- Rate Calculation +-- signal accepted_trigger_rate_t : unsigned(27 downto 0); +-- signal rate_timer : unsigned(27 downto 0); + + -- TRBNet Slave Bus + signal slv_data_out_o : std_logic_vector(31 downto 0); + signal slv_no_more_data_o : std_logic; + signal slv_unknown_addr_o : std_logic; + signal slv_ack_o : std_logic; + + signal latch_select_r : std_logic; + + ----------------------------------------------------------------------------- + + attribute syn_keep : boolean; + attribute syn_keep of latch_select_ff : signal is true; + attribute syn_keep of latch_ff : signal is true; + attribute syn_keep of reset_ctr_ff : signal is true; + + attribute syn_preserve : boolean; + attribute syn_preserve of latch_select_ff : signal is true; + attribute syn_preserve of latch_ff : signal is true; + attribute syn_preserve of reset_ctr_ff : signal is true; + + ----------------------------------------------------------------------------- + +begin + + -- Debug Line + DEBUG_OUT(0) <= CLK_IN; + DEBUG_OUT(1) <= LATCH_TRIGGER_IN; + + DEBUG_OUT(2) <= latch_i; + DEBUG_OUT(3) <= latch_ff(2); + DEBUG_OUT(4) <= latch_ff(1); + DEBUG_OUT(5) <= latch_ff(0); + DEBUG_OUT(6) <= latch_o; + + DEBUG_OUT(7) <= RESET_CTR_IN; + DEBUG_OUT(8) <= reset_ctr_ff(2); + DEBUG_OUT(9) <= reset_ctr_ff(1); + DEBUG_OUT(10) <= reset_ctr_ff(0); + DEBUG_OUT(11) <= reset_ctr_o; + + + DEBUG_OUT(15 downto 12) <= (others => '0'); + + ----------------------------------------------------------------------------- + -- Reset Counter Sync + ----------------------------------------------------------------------------- + reset_d1_ff(1) <= RESET_D1_IN when rising_edge(CLK_D1_IN); + reset_d1_ff(0) <= reset_d1_ff(1) when rising_edge(CLK_D1_IN); + RESET_D1 <= reset_d1_ff(0) when rising_edge(CLK_D1_IN); + + reset_ctr_ff(2) <= RESET_CTR_IN when rising_edge(CLK_D1_IN); + reset_ctr_ff(1) <= reset_ctr_ff(2) when rising_edge(CLK_D1_IN); + reset_ctr_ff(0) <= reset_ctr_ff(1) when rising_edge(CLK_D1_IN); + reset_ctr_o <= reset_ctr_ff(0) when rising_edge(CLK_D1_IN); + + ----------------------------------------------------------------------------- + -- Latch Handler + ----------------------------------------------------------------------------- + + latch_select_ff(1) <= latch_select_r when rising_edge(CLK_D1_IN); + latch_select_ff(0) <= latch_select_ff(1) when rising_edge(CLK_D1_IN); + + PROC_LATCH_MULTIPLEXER: process(latch_select_ff(0), + LATCH_TRIGGER_IN, + LATCH_EXTERN_IN) + begin + if (latch_select_ff(0) = '0') then + latch_i <= LATCH_TRIGGER_IN; + else + latch_i <= LATCH_EXTERN_IN; + end if; + end process PROC_LATCH_MULTIPLEXER; + + latch_ff(2) <= latch_i when rising_edge(CLK_D1_IN); + latch_ff(1) <= latch_ff(2) when rising_edge(CLK_D1_IN); + latch_ff(0) <= latch_ff(1) when rising_edge(CLK_D1_IN); + + latch <= '1' when latch_ff(1 downto 0) = "10" else '0'; + + latch_o <= latch; + latch_valid_o <= latch; + latch_invalid_o <= '0'; + +-- -- Timer +-- lh_timer_static: timer_static +-- generic map ( +-- CTR_WIDTH => 8, +-- CTR_END => 32 -- 128ns +-- ) +-- port map ( +-- CLK_IN => CLK_D1_IN, +-- RESET_IN => lh_wait_timer_reset, +-- TIMER_START_IN => lh_wait_timer_start, +-- TIMER_DONE_OUT => lh_wait_timer_done +-- ); +-- +-- PROC_LATCH_HANDLER: process(CLK_D1_IN) +-- begin +-- if( rising_edge(CLK_D1_IN) ) then +-- if (RESET_D1 = '1') then +-- latch_validate_ctr <= (others => '0'); +-- latch_o <= '0'; +-- latch_valid_o <= '0'; +-- latch_invalid_o <= '0'; +-- +-- lh_wait_timer_start <= '0'; +-- lh_wait_timer_reset <= '1'; +-- +-- LH_STATE <= LH_IDLE; +-- else +-- lh_wait_timer_start <= '0'; +-- lh_wait_timer_reset <= '0'; +-- +-- latch_o <= '0'; +-- latch_valid_o <= '0'; +-- latch_invalid_o <= '0'; +-- +-- case LH_STATE is +-- when LH_IDLE => +-- if (latch = '1') then +-- latch_validate_ctr <= (others => '0'); +-- latch_o <= '1'; +-- LH_STATE <= LH_VALIDATE; +-- end if; +-- LH_STATE <= LH_IDLE; +-- +-- when LH_VALIDATE => +-- if (latch_validate_ctr < x"a") then +-- if (latch = '1') then +-- latch_validate_ctr <= latch_validate_ctr + 1; +-- LH_STATE <= LH_VALIDATE; +-- else +-- latch_invalid_o <= '1'; +-- lh_wait_timer_start <= '1'; +-- LH_STATE <= LH_WAIT; +-- end if; +-- else +-- latch_valid_o <= '1'; +-- lh_wait_timer_start <= '1'; +-- LH_STATE <= LH_WAIT; +-- end if; +-- +-- when LH_WAIT => +-- if (lh_wait_timer_done = '1') then +-- LH_STATE <= LH_IDLE; +-- else +-- LH_STATE <= LH_WAIT; +-- end if; +-- end case; +-- +-- end if; +-- end if; +-- end process PROC_LATCH_HANDLER; + + --------------------------------------------------------------------------- + -- TRBNet Slave Bus + --------------------------------------------------------------------------- + + PROC_SLAVE_BUS: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + latch_select_r <= '0'; + else + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + slv_data_out_o <= (others => '0'); + slv_ack_o <= '0'; + + if (SLV_WRITE_IN = '1') then + case SLV_ADDR_IN is + when x"0000" => + latch_select_r <= SLV_DATA_IN(0); + slv_ack_o <= '1'; + + when others => + slv_unknown_addr_o <= '1'; + + end case; + + elsif (SLV_READ_IN = '1') then + case SLV_ADDR_IN is + when x"0000" => + slv_data_out_o(0) <= latch_select_r; + slv_data_out_o(31 downto 1) <= (others => '0'); + + slv_ack_o <= '1'; + + when others => + slv_unknown_addr_o <= '1'; + + end case; + + end if; + end if; + end if; + end process PROC_SLAVE_BUS; + +----------------------------------------------------------------------------- +-- Output Signals +----------------------------------------------------------------------------- + + RESET_CTR_OUT <= reset_ctr_o; + LATCH_OUT <= latch_o; + LATCH_VALID_OUT <= latch_valid_o; + LATCH_INVALID_OUT <= latch_invalid_o; + + -- Slave Bus + SLV_DATA_OUT <= slv_data_out_o; + SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; + SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; + SLV_ACK_OUT <= slv_ack_o; + +end Behavioral; diff --git a/scaler/source/scaler_channel.vhd b/scaler/source/scaler_channel.vhd new file mode 100644 index 0000000..a758ac3 --- /dev/null +++ b/scaler/source/scaler_channel.vhd @@ -0,0 +1,329 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.scaler_components.all; + +entity scaler_channel is + port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + CLK_D1_IN : in std_logic; + RESET_D1_IN : in std_logic; + + -- Scaler Inputs + RESET_CTR_IN : in std_logic; + LATCH_IN : in std_logic; + PULSE_IN : in std_logic; + INHIBIT_IN : in std_logic; + + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(15 downto 0) + ); +end entity; + +architecture Behavioral of scaler_channel is + + -- Sync Inputs + signal reset_d1_ff : std_logic_vector(1 downto 0); + signal RESET_D1 : std_logic; + + signal reset_ctr_ff : std_logic_vector(1 downto 0); + signal RESET_CTR : std_logic; + + signal pulse_ff : std_logic_vector(2 downto 0); + signal pulse_l : std_logic; + signal pulse_i : std_logic; + signal latch_d1 : std_logic; + + -- Scaler CLK_SCALER Domain + signal inhibit : std_logic; + + signal johnson : std_logic_vector(3 downto 0); + + signal counter_low_d1 : std_logic_vector(2 downto 0); + signal counter_low_ovfl_d1 : std_logic; + + signal counter_latched : std_logic_vector(47 downto 0); + + -- Counter Clock Domain Transfer + signal fifo_reset_i : std_logic; + signal fifo_write_enable : std_logic; + signal fifo_read_enable : std_logic; + signal fifo_empty : std_logic; + signal fifo_full : std_logic; + signal fifo_data_clk_t : std_logic; + signal fifo_data_clk : std_logic; + signal fifo_data : std_logic_vector(5 downto 0); + + signal counter_low : std_logic_vector(2 downto 0); + signal counter_low_ovfl : std_logic; + signal latch : std_logic; + + signal counter_high : unsigned(44 downto 0); + + signal data_clk : std_logic; + signal data_reg : std_logic_vector(47 downto 0); + + -- Slave Bus + signal slv_data_out_o : std_logic_vector(31 downto 0); + signal slv_no_more_data_o : std_logic; + signal slv_unknown_addr_o : std_logic; + signal slv_ack_o : std_logic; + signal counter_latched_offset : std_logic_vector(15 downto 0); + + ----------------------------------------------------------------------------- + + attribute syn_keep : boolean; + attribute syn_keep of pulse_ff : signal is true; + + attribute syn_preserve : boolean; + attribute syn_preserve of pulse_ff : signal is true; + + ----------------------------------------------------------------------------- + +begin + + ---------------------------------------------------------------------- + -- DEBUG + ---------------------------------------------------------------------- + DEBUG_OUT(0) <= CLK_IN; + DEBUG_OUT(1) <= pulse_i; --LATCH_IN; --data_clk; + DEBUG_OUT(2) <= fifo_data_clk; + DEBUG_OUT(3) <= counter_low_ovfl; + DEBUG_OUT(4) <= latch; + DEBUG_OUT(5) <= data_clk; + DEBUG_OUT(15 downto 6) <= counter_latched(9 downto 0); + + -- Sync input signals to Scaler CLK_D1_IN Domain + reset_d1_ff(1) <= RESET_D1_IN when rising_edge(CLK_D1_IN); + reset_d1_ff(0) <= reset_d1_ff(1) when rising_edge(CLK_D1_IN); + RESET_D1 <= reset_d1_ff(0) when rising_edge(CLK_D1_IN); + + reset_ctr_ff(1) <= RESET_CTR_IN when rising_edge(CLK_D1_IN); + reset_ctr_ff(0) <= reset_ctr_ff(1) when rising_edge(CLK_D1_IN); + RESET_CTR <= reset_ctr_ff(0) when rising_edge(CLK_D1_IN); + + pulse_ff(2) <= PULSE_IN when rising_edge(CLK_D1_IN); + pulse_ff(1) <= pulse_ff(2) when rising_edge(CLK_D1_IN); + pulse_ff(0) <= pulse_ff(1) when rising_edge(CLK_D1_IN); + + pulse_i <= '1' when pulse_ff(1 downto 0) = "10" else '0'; + + ----------------------------------------------------------------------------- + -- The Primary Counter + ----------------------------------------------------------------------------- + + -- Johnson Counter for lower 3 Bits + PROC_LOWER_BIT_COUNTER: process(CLK_D1_IN) + begin + if (rising_edge(CLK_D1_IN)) then + if (RESET_D1 = '1' or RESET_CTR = '1') then + johnson <= (others => '0'); + counter_low_ovfl_d1 <= '0'; + else + counter_low_ovfl_d1 <= '0'; + if (pulse_i = '1') then + johnson(0) <= not johnson(3); + johnson(1) <= johnson(0); + johnson(2) <= johnson(1); + johnson(3) <= johnson(2); + counter_low_ovfl_d1 <= '0'; + + case johnson is + when "0000" => counter_low_d1 <= "001"; + when "0001" => counter_low_d1 <= "010"; + when "0011" => counter_low_d1 <= "011"; + when "0111" => counter_low_d1 <= "100"; + when "1111" => counter_low_d1 <= "101"; + when "1110" => counter_low_d1 <= "110"; + when "1100" => counter_low_d1 <= "111"; + when "1000" => counter_low_d1 <= "000"; + counter_low_ovfl_d1 <= '1'; + when others => counter_low_d1 <= "000"; + end case; + end if; + end if; + end if; + end process PROC_LOWER_BIT_COUNTER; + + ----------------------------------------------------------------------------- + -- Clock Domain Transfer in case of latch or overflow + ----------------------------------------------------------------------------- + + --latch_d1 <= LATCH_IN when rising_edge(CLK_D1_IN); + latch_d1 <= counter_low_ovfl_d1 when rising_edge(CLK_D1_IN); + + COUNTER_LOW_DOMAIN_TRANSFER_1: entity work.fifo_6to6_dc + port map ( + Data(2 downto 0) => counter_low_d1, + Data(3) => counter_low_ovfl_d1, + Data(4) => latch_d1, + Data(5) => RESET_CTR, + WrClock => CLK_D1_IN, + RdClock => CLK_IN, + WrEn => fifo_write_enable, + RdEn => fifo_read_enable, + Reset => fifo_reset_i, + RPReset => fifo_reset_i, + Q => fifo_data, + Empty => fifo_empty, + Full => fifo_full + ); + fifo_reset_i <= RESET_IN; + fifo_write_enable <= not fifo_full and (counter_low_ovfl_d1 or + latch_d1 or + RESET_CTR); + fifo_read_enable <= not fifo_empty; + + PROC_FIFO_READ_ENABLE: process(CLK_IN) + begin + if (rising_edge(CLK_IN)) then + fifo_data_clk_t <= fifo_read_enable; + if (RESET_IN = '1') then + fifo_data_clk_t <= '0'; + fifo_data_clk <= '0'; + else + -- Delay read signal by two Clock Cycles + fifo_data_clk <= fifo_data_clk_t; + end if; + end if; + end process PROC_FIFO_READ_ENABLE; + + PROC_FIFO_OUTPUT_HANDLER: process(CLK_IN) + begin + if (rising_edge(CLK_IN)) then + if (RESET_IN = '1') then + counter_high <= (others => '0'); + counter_low <= (others => '0'); + counter_low_ovfl <= '0'; + latch <= '0'; + else + counter_low <= (others => '0'); + counter_low_ovfl <= '0'; + latch <= '0'; + + if (fifo_data_clk = '1') then + counter_low <= (others => '0'); + counter_low_ovfl <= '0'; + latch <= '0'; + + -- High Bit Counter + if (fifo_data(5) = '1') then -- in case of Reset Counters + counter_high <= (others => '0'); + else + if (fifo_data(3) = '1') then -- in case of overflow + counter_low <= fifo_data(2 downto 0); + counter_low_ovfl <= fifo_data(3); + counter_high <= counter_high + 1; + end if; + + if (fifo_data(4) = '1') then + latch <= '1'; + end if; + end if; + end if; + end if; + end if; + end process PROC_FIFO_OUTPUT_HANDLER; + + PROC_LATCH: process(CLK_IN) + begin + if (rising_edge(CLK_IN)) then + if (RESET_IN = '1') then + counter_latched <= (others => '0'); + data_clk <= '0'; + else + data_clk <= '0'; + if (latch = '1') then + counter_latched(2 downto 0) <= counter_low; + counter_latched(47 downto 3) <= counter_high; + data_clk <= '1'; + end if; + end if; + end if; + end process PROC_LATCH; + + ----------------------------------------------------------------------------- + -- Slave Bus + ----------------------------------------------------------------------------- + + PROC_TRB3_REGISTERS: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + + counter_latched_offset <= (others => '0'); + data_reg <= (others => '0'); + else + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + slv_data_out_o <= (others => '0'); + + if (data_clk = '1') then + data_reg <= counter_latched; + end if; + + if (SLV_WRITE_IN = '1') then + case SLV_ADDR_IN is + when x"0000" => + counter_latched_offset <= SLV_DATA_IN(15 downto 0); + slv_ack_o <= '1'; + + when others => + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; + end case; + + elsif (SLV_READ_IN = '1') then + case SLV_ADDR_IN is + when x"0000" => + slv_data_out_o(15 downto 0) <= counter_latched_offset; + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0001" => + slv_data_out_o <= data_reg(31 downto 0); + slv_ack_o <= '1'; + + when x"0002" => + slv_data_out_o(15 downto 0) <= data_reg(47 downto 32); + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + + when others => + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; + end case; + + else + slv_ack_o <= '0'; + end if; + end if; + end if; + end process PROC_TRB3_REGISTERS; + + ---------------------------------------------------------------------- + -- Output Signals + ---------------------------------------------------------------------- + + SLV_DATA_OUT <= slv_data_out_o; + SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; + SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; + SLV_ACK_OUT <= slv_ack_o; + +end Behavioral; diff --git a/scaler/source/trigger_handler.vhd b/scaler/source/trigger_handler.vhd new file mode 100644 index 0000000..15674ad --- /dev/null +++ b/scaler/source/trigger_handler.vhd @@ -0,0 +1,776 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.scaler_components.all; + +entity trigger_handler is + port ( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + CLK_D1_IN : in std_logic; + RESET_D1_IN : in std_logic; -- Rest CLK_D1 Domain + OFFLINE_IN : in std_logic; + + --Input Triggers + TIMING_TRIGGER_IN : in std_logic; -- The raw timing Trigger Signal + LVL1_TRG_DATA_VALID_IN : in std_logic; -- Data Trigger is valid + LVL1_VALID_TIMING_TRG_IN : in std_logic; -- Timin Trigger is valid + LVL1_VALID_NOTIMING_TRG_IN : in std_logic; -- calib trigger w/o ref time + LVL1_INVALID_TRG_IN : in std_logic; + + LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0); + LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); + LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0); + LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0); + LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); + + --Response from FEE + FEE_DATA_OUT : out std_logic_vector(31 downto 0); + FEE_DATA_WRITE_OUT : out std_logic; + FEE_DATA_FINISHED_OUT : out std_logic; + FEE_TRG_RELEASE_OUT : out std_logic; + FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0); + + FEE_DATA_0_IN : in std_logic_vector(31 downto 0); + FEE_DATA_WRITE_0_IN : in std_logic; + FEE_DATA_1_IN : in std_logic_vector(31 downto 0); + FEE_DATA_WRITE_1_IN : in std_logic; + + -- Internal FPGA Trigger + INTERNAL_TRIGGER_IN : in std_logic; + + -- Trigger FeedBack + TRIGGER_VALIDATE_BUSY_IN : in std_logic; + TRIGGER_BUSY_0_IN : in std_logic; + TRIGGER_BUSY_1_IN : in std_logic; + + -- OUT + VALID_TRIGGER_OUT : out std_logic; + TIMESTAMP_TRIGGER_OUT : out std_logic; + TRIGGER_TIMING_OUT : out std_logic; + TRIGGER_STATUS_OUT : out std_logic; + TRIGGER_CALIBRATION_OUT : out std_logic; + FAST_CLEAR_OUT : out std_logic; + TRIGGER_BUSY_OUT : out std_logic; + + -- Pulser + TESTPULSE_OUT : out std_logic; + + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic; + + -- Debug Line + DEBUG_OUT : out std_logic_vector(15 downto 0) + ); +end entity; + +architecture Behavioral of trigger_handler is + + -- Timing Trigger Handler + constant NUM_FF : integer := 10; + signal timing_trigger_ff_p : std_logic_vector(1 downto 0); + signal timing_trigger_ff : std_logic_vector(NUM_FF - 1 downto 0); + signal timing_trigger_l : std_logic; + signal timing_trigger : std_logic; + signal timing_trigger_set : std_logic; + signal timestamp_trigger_o : std_logic; + + signal invalid_timing_trigger_n : std_logic; + + signal invalid_timing_trigger_ff : std_logic; + signal invalid_timing_trigger_f : std_logic; + signal invalid_timing_trigger : std_logic; + signal invalid_timing_trigger_ctr : unsigned(15 downto 0); + + signal trigger_busy_ff : std_logic; + signal trigger_busy_f : std_logic; + signal trigger_busy : std_logic; + + signal fast_clear_ff : std_logic; + signal fast_clear_f : std_logic; + signal fast_clear : std_logic; + + type TS_STATES is (TS_IDLE, + TS_WAIT_VALID_TIMING_TRIGGER, + TS_INVALID_TRIGGER, + TS_WAIT_TRIGGER_END + ); + signal TS_STATE : TS_STATES; + + signal ts_wait_timer_reset : std_logic; + signal ts_wait_timer_start : std_logic; + signal ts_wait_timer_done : std_logic; + + -- Trigger Handler + signal valid_trigger_o : std_logic; + signal timing_trigger_o : std_logic; + signal status_trigger_o : std_logic; + signal calibration_trigger_o : std_logic; + signal calib_downscale_ctr : unsigned(15 downto 0); + signal fast_clear_o : std_logic; + signal trigger_busy_o : std_logic; + signal fee_data_o : std_logic_vector(31 downto 0); + signal fee_data_write_o : std_logic; + signal fee_data_finished_o : std_logic; + signal fee_trg_release_o : std_logic; + signal fee_trg_statusbits_o : std_logic_vector(31 downto 0); + + signal timestamp_calib_trigger_c100 : std_logic; + signal timestamp_calib_trigger_f : std_logic; + signal timestamp_calib_trigger_o : std_logic; + + type STATES is (S_IDLE, + S_IGNORE_TRIGGER, + S_STATUS_TRIGGER, + S_TIMING_TRIGGER, + S_CALIBRATION_TRIGGER, + S_WAIT_TRG_DATA_VALID, + S_WAIT_TIMING_TRIGGER_DONE, + S_FEE_TRIGGER_RELEASE, + S_WAIT_FEE_TRIGGER_RELEASE_ACK, + S_INTERNAL_TRIGGER, + S_WAIT_TRIGGER_VALIDATE_ACK, + S_WAIT_TRIGGER_VALIDATE_DONE + ); + signal STATE : STATES; + + type TRIGGER_TYPES is (T_UNDEF, + T_IGNORE, + T_TIMING, + T_STATUS, + T_CALIBRATION + ); + signal TRIGGER_TYPE : TRIGGER_TYPES; + + + -- Testpulse Handler + type T_STATES is (T_IDLE, + T_WAIT_TESTPULE_DELAY, + T_SET_TESTPULSE, + T_WAIT_TESTPULE_END + ); + + signal T_STATE : T_STATES; + + signal internal_trigger_f : std_logic; + signal internal_trigger : std_logic; + + -- Rate Calculation + signal accepted_trigger_rate_t : unsigned(27 downto 0); + signal rate_timer : unsigned(27 downto 0); + + -- TRBNet Slave Bus + signal slv_data_out_o : std_logic_vector(31 downto 0); + signal slv_no_more_data_o : std_logic; + signal slv_unknown_addr_o : std_logic; + signal slv_ack_o : std_logic; + + signal accepted_trigger_rate : unsigned(27 downto 0); + signal invalid_t_trigger_ctr_clear : std_logic; + signal bypass_all_trigger : std_logic; + signal bypass_physics_trigger : std_logic; + signal bypass_status_trigger : std_logic; + signal bypass_calibration_trigger : std_logic; + signal calibration_downscale : unsigned(15 downto 0); + signal physics_trigger_type : std_logic_vector(3 downto 0); + signal status_trigger_type : std_logic_vector(3 downto 0); + signal calibration_trigger_type : std_logic_vector(3 downto 0); + + attribute syn_keep : boolean; + + attribute syn_keep of trigger_busy_ff : signal is true; + attribute syn_keep of trigger_busy_f : signal is true; + + attribute syn_keep of fast_clear_ff : signal is true; + attribute syn_keep of fast_clear_f : signal is true; + + attribute syn_keep of internal_trigger_f : signal is true; + attribute syn_keep of internal_trigger : signal is true; + + attribute syn_keep of timestamp_calib_trigger_f : signal is true; + attribute syn_keep of timestamp_calib_trigger_o : signal is true; + + attribute syn_preserve : boolean; + + attribute syn_preserve of trigger_busy_ff : signal is true; + attribute syn_preserve of trigger_busy_f : signal is true; + + attribute syn_preserve of fast_clear_ff : signal is true; + attribute syn_preserve of fast_clear_f : signal is true; + + attribute syn_preserve of internal_trigger_f : signal is true; + attribute syn_preserve of internal_trigger : signal is true; + + attribute syn_preserve of timestamp_calib_trigger_f : signal is true; + attribute syn_preserve of timestamp_calib_trigger_o : signal is true; + +begin + + -- Debug Line + DEBUG_OUT(0) <= CLK_IN; + DEBUG_OUT(1) <= TIMING_TRIGGER_IN; + DEBUG_OUT(2) <= invalid_timing_trigger; + DEBUG_OUT(3) <= LVL1_VALID_TIMING_TRG_IN; + DEBUG_OUT(4) <= LVL1_TRG_DATA_VALID_IN; + DEBUG_OUT(5) <= fee_data_write_o; + DEBUG_OUT(6) <= TRIGGER_VALIDATE_BUSY_IN; + DEBUG_OUT(7) <= TRIGGER_BUSY_0_IN; + DEBUG_OUT(8) <= valid_trigger_o; + DEBUG_OUT(9) <= timing_trigger_o; + DEBUG_OUT(10) <= fee_data_finished_o; + DEBUG_OUT(11) <= fee_trg_release_o; + DEBUG_OUT(12) <= trigger_busy_o; + DEBUG_OUT(13) <= timestamp_trigger_o; + DEBUG_OUT(14) <= '0'; + DEBUG_OUT(15) <= '0'; + + ----------------------------------------------------------------------------- + -- Trigger Handler + ----------------------------------------------------------------------------- + + PROC_TIMING_TRIGGER_HANDLER: process(CLK_D1_IN) + constant pattern : std_logic_vector(NUM_FF - 1 downto 0) + := (others => '1'); + begin + if( rising_edge(CLK_D1_IN) ) then + timing_trigger_ff_p(1) <= TIMING_TRIGGER_IN; + if (RESET_D1_IN = '1') then + timing_trigger_ff_p(0) <= '0'; + timing_trigger_ff(NUM_FF - 1 downto 0) <= (others => '0'); + timing_trigger_l <= '0'; + else + timing_trigger_ff_p(0) <= timing_trigger_ff_p(1); + timing_trigger_ff(NUM_FF - 1) <= timing_trigger_ff_p(0); + + for I in NUM_FF - 2 downto 0 loop + timing_trigger_ff(I) <= timing_trigger_ff(I + 1); + end loop; + + if (timing_trigger_ff = pattern) then + timing_trigger_l <= '1'; + else + timing_trigger_l <= '0'; + end if; + end if; + end if; + end process PROC_TIMING_TRIGGER_HANDLER; + + level_to_pulse_1: level_to_pulse + port map ( + CLK_IN => CLK_D1_IN, + RESET_IN => RESET_D1_IN, + LEVEL_IN => timing_trigger_l, + PULSE_OUT => timing_trigger + ); + + -- Signal Domain Transfers to NX Clock + trigger_busy_ff <= trigger_busy_o + when rising_edge(CLK_D1_IN); + trigger_busy_f <= trigger_busy_ff + when rising_edge(CLK_D1_IN); + trigger_busy <= trigger_busy_f + when rising_edge(CLK_D1_IN); + + fast_clear_ff <= fast_clear_o + when rising_edge(CLK_D1_IN); + fast_clear_f <= fast_clear_ff + when rising_edge(CLK_D1_IN); + fast_clear <= fast_clear_f + when rising_edge(CLK_D1_IN); + + PROC_TIMING_TRIGGER_HANDLER: process(CLK_D1_IN) + begin + if( rising_edge(CLK_D1_IN) ) then + if (RESET_D1_IN = '1') then + invalid_timing_trigger_n <= '1'; + ts_wait_timer_start <= '0'; + ts_wait_timer_reset <= '1'; + timestamp_trigger_o <= '0'; + TS_STATE <= TS_IDLE; + else + invalid_timing_trigger_n <= '0'; + ts_wait_timer_start <= '0'; + ts_wait_timer_reset <= '0'; + timestamp_trigger_o <= '0'; + + if (fast_clear = '1') then + ts_wait_timer_reset <= '1'; + TS_STATE <= TS_IDLE; + else + case TS_STATE is + when TS_IDLE => + -- Wait for Timing Trigger synced to NX_MAIN_CLK_DOMAIN + if (timing_trigger = '1') then + if (trigger_busy = '1') then + -- If busy is set --> Error + TS_STATE <= TS_INVALID_TRIGGER; + else + timestamp_trigger_o <= '1'; + ts_wait_timer_start <= '1'; + TS_STATE <= TS_WAIT_VALID_TIMING_TRIGGER; + end if; + else + TS_STATE <= TS_IDLE; + end if; + + when TS_WAIT_VALID_TIMING_TRIGGER => + -- Wait and test if CLK_IN Trigger Handler does accepted Trigger + if (trigger_busy = '1') then + -- Trigger has been accepted, stop timer and wait trigger end + ts_wait_timer_reset <= '1'; + TS_STATE <= TS_WAIT_TRIGGER_END; + else + if (ts_wait_timer_done = '1') then + -- Timeout after 128ns --> Invalid Trigger Error + TS_STATE <= TS_INVALID_TRIGGER; + else + TS_STATE <= TS_WAIT_VALID_TIMING_TRIGGER; + end if; + end if; + + when TS_INVALID_TRIGGER => + invalid_timing_trigger_n <= '1'; + TS_STATE <= TS_IDLE; + + when TS_WAIT_TRIGGER_END => + if (trigger_busy = '0') then + TS_STATE <= TS_IDLE; + else + TS_STATE <= TS_WAIT_TRIGGER_END; + end if; + + end case; + end if; + end if; + end if; + end process PROC_TIMING_TRIGGER_HANDLER; + + PROC_TIMING_TRIGGER_COUNTER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if (RESET_IN = '1') then + invalid_timing_trigger_ctr <= (others => '0'); + else + if (invalid_t_trigger_ctr_clear = '1') then + invalid_timing_trigger_ctr <= (others => '0'); + elsif (invalid_timing_trigger = '1') then + invalid_timing_trigger_ctr <= invalid_timing_trigger_ctr + 1; + end if; + end if; + end if; + end process PROC_TIMING_TRIGGER_COUNTER; + + -- Relax Timing + invalid_timing_trigger_ff <= invalid_timing_trigger_n + when rising_edge(CLK_D1_IN); + invalid_timing_trigger_f <= invalid_timing_trigger_ff + when rising_edge(CLK_D1_IN); + + pulse_dtrans_INVALID_TIMING_TRIGGER: pulse_dtrans + generic map ( + CLK_RATIO => 4 + ) + port map ( + CLK_A_IN => CLK_D1_IN, + RESET_A_IN => RESET_D1_IN, + PULSE_A_IN => invalid_timing_trigger_f, + CLK_B_IN => CLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => invalid_timing_trigger + ); + + ----------------------------------------------------------------------------- + + PROC_TRIGGER_HANDLER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if (RESET_IN = '1') then + valid_trigger_o <= '0'; + timing_trigger_o <= '0'; + status_trigger_o <= '0'; + calibration_trigger_o <= '0'; + fee_data_finished_o <= '0'; + fee_trg_release_o <= '0'; + fee_trg_statusbits_o <= (others => '0'); + fast_clear_o <= '0'; + trigger_busy_o <= '0'; + timestamp_calib_trigger_c100 <= '0'; + calib_downscale_ctr <= (others => '0'); + TRIGGER_TYPE <= T_UNDEF; + STATE <= S_IDLE; + else + valid_trigger_o <= '0'; + timing_trigger_o <= '0'; + status_trigger_o <= '0'; + calibration_trigger_o <= '0'; + fee_data_finished_o <= '0'; + fee_trg_release_o <= '0'; + fee_trg_statusbits_o <= (others => '0'); + fast_clear_o <= '0'; + trigger_busy_o <= '1'; + timestamp_calib_trigger_c100 <= '0'; + + if (LVL1_INVALID_TRG_IN = '1') then + -- There was no valid Timing Trigger at CTS, do a fast clear + fast_clear_o <= '1'; + fee_trg_release_o <= '1'; + STATE <= S_IDLE; + else + + case STATE is + + when S_IDLE => + + if (LVL1_VALID_TIMING_TRG_IN = '1') then + -- Timing Trigger IN + if (OFFLINE_IN = '1' or + bypass_all_trigger = '1') then + + -- Ignore Trigger for nxyter is or pretends to be offline + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + -- Check Trigger Type + if (LVL1_TRG_TYPE_IN = physics_trigger_type) then + -- Physiks Trigger + if (bypass_physics_trigger = '1') then + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + TRIGGER_TYPE <= T_TIMING; + STATE <= S_TIMING_TRIGGER; + end if; + else + -- Unknown Timing Trigger, ignore + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + end if; + end if; + + elsif (LVL1_VALID_NOTIMING_TRG_IN = '1') then + -- No Timing Trigger IN + if (OFFLINE_IN = '1' or + bypass_all_trigger = '1') then + + -- Ignore Trigger for nxyter or pretend to be offline + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + -- Check Trigger Type + if (LVL1_TRG_TYPE_IN = calibration_trigger_type) then + -- Calibration Trigger + if (bypass_calibration_trigger = '1') then + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + if (calib_downscale_ctr >= calibration_downscale) then + timestamp_calib_trigger_c100 <= '1'; + calib_downscale_ctr <= x"0001"; + TRIGGER_TYPE <= T_CALIBRATION; + STATE <= S_CALIBRATION_TRIGGER; + else + calib_downscale_ctr <= calib_downscale_ctr + 1; + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + end if; + end if; + + elsif (LVL1_TRG_TYPE_IN = status_trigger_type) then + -- Status Trigger + if (bypass_status_trigger = '1') then + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + -- Status Trigger + status_trigger_o <= '1'; + TRIGGER_TYPE <= T_STATUS; + STATE <= S_STATUS_TRIGGER; + end if; + + else + -- Some other Trigger, ignore it + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + end if; + + end if; + + else + -- No Trigger IN, Nothing to do, Sleep Well + trigger_busy_o <= '0'; + TRIGGER_TYPE <= T_UNDEF; + STATE <= S_IDLE; + end if; + + when S_TIMING_TRIGGER => + valid_trigger_o <= '1'; + timing_trigger_o <= '1'; + STATE <= S_WAIT_TRG_DATA_VALID; + + when S_CALIBRATION_TRIGGER => + calibration_trigger_o <= '1'; + valid_trigger_o <= '1'; + timing_trigger_o <= '1'; + STATE <= S_WAIT_TRG_DATA_VALID; + + when S_WAIT_TRG_DATA_VALID | S_STATUS_TRIGGER | S_IGNORE_TRIGGER => + if (LVL1_TRG_DATA_VALID_IN = '0') then + STATE <= S_WAIT_TRG_DATA_VALID; + else + STATE <= S_WAIT_TIMING_TRIGGER_DONE; + end if; + + when S_WAIT_TIMING_TRIGGER_DONE => + if (((TRIGGER_TYPE = T_TIMING or + TRIGGER_TYPE = T_CALIBRATION) + and TRIGGER_BUSY_0_IN = '1') + or + (TRIGGER_TYPE = T_STATUS and + TRIGGER_BUSY_1_IN = '1') + ) then + STATE <= S_WAIT_TIMING_TRIGGER_DONE; + else + fee_data_finished_o <= '1'; + STATE <= S_FEE_TRIGGER_RELEASE; + end if; + + when S_FEE_TRIGGER_RELEASE => + fee_trg_release_o <= '1'; + STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; + + when S_WAIT_FEE_TRIGGER_RELEASE_ACK => + if (LVL1_TRG_DATA_VALID_IN = '1') then + STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; + else + STATE <= S_IDLE; + end if; + + -- Internal Trigger Handler + when S_INTERNAL_TRIGGER => + valid_trigger_o <= '1'; + STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; + + when S_WAIT_TRIGGER_VALIDATE_ACK => + if (TRIGGER_VALIDATE_BUSY_IN = '0') then + STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; + else + STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; + end if; + + when S_WAIT_TRIGGER_VALIDATE_DONE => + if (TRIGGER_VALIDATE_BUSY_IN = '1') then + STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; + else + STATE <= S_IDLE; + end if; + + end case; + end if; + end if; + end if; + end process PROC_TRIGGER_HANDLER; + + PROC_EVENT_DATA_MULTIPLEXER: process(TRIGGER_TYPE) + begin + case TRIGGER_TYPE is + when T_UNDEF | T_IGNORE => + fee_data_o <= (others => '0'); + fee_data_write_o <= '0'; + + when T_TIMING | T_CALIBRATION => + fee_data_o <= FEE_DATA_0_IN; + fee_data_write_o <= FEE_DATA_WRITE_0_IN; + + when T_STATUS => + fee_data_o <= FEE_DATA_1_IN; + fee_data_write_o <= FEE_DATA_WRITE_1_IN; + + end case; + end process PROC_EVENT_DATA_MULTIPLEXER; + + internal_trigger_f <= INTERNAL_TRIGGER_IN or + calibration_trigger_o when rising_edge(CLK_D1_IN); + internal_trigger <= internal_trigger_f when rising_edge(CLK_D1_IN); + + PROC_CAL_RATES: process (CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if (RESET_IN = '1') then + accepted_trigger_rate_t <= (others => '0'); + accepted_trigger_rate <= (others => '0'); + rate_timer <= (others => '0'); + else + if (rate_timer < x"5f5e100") then + if (timing_trigger_o = '1') then + accepted_trigger_rate_t <= accepted_trigger_rate_t + 1; + end if; + + rate_timer <= rate_timer + 1; + else + rate_timer <= (others => '0'); + accepted_trigger_rate <= accepted_trigger_rate_t; + + accepted_trigger_rate_t <= (others => '0'); + end if; + end if; + end if; + end process PROC_CAL_RATES; + +----------------------------------------------------------------------------- +-- TRBNet Slave Bus +----------------------------------------------------------------------------- + + PROC_SLAVE_BUS: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + invalid_t_trigger_ctr_clear <= '1'; + bypass_all_trigger <= '0'; + bypass_physics_trigger <= '0'; + bypass_status_trigger <= '1'; + bypass_calibration_trigger <= '1'; + calibration_downscale <= x"0001"; + physics_trigger_type <= x"1"; + calibration_trigger_type <= x"9"; + status_trigger_type <= x"e"; + else + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + slv_data_out_o <= (others => '0'); + slv_ack_o <= '0'; + invalid_t_trigger_ctr_clear <= '0'; + + if (SLV_WRITE_IN = '1') then + case SLV_ADDR_IN is + when x"0003" => + invalid_t_trigger_ctr_clear <= '1'; + slv_ack_o <= '1'; + + when x"0006" => + bypass_physics_trigger <= SLV_DATA_IN(0); + bypass_status_trigger <= SLV_DATA_IN(1); + bypass_calibration_trigger <= SLV_DATA_IN(2); + bypass_all_trigger <= SLV_DATA_IN(3); + slv_ack_o <= '1'; + + when x"0007" => + if (unsigned(SLV_DATA_IN(15 downto 0)) > x"0000") then + calibration_downscale <= + unsigned(SLV_DATA_IN(15 downto 0)); + end if; + slv_ack_o <= '1'; + + when x"0008" => + physics_trigger_type <= SLV_DATA_IN(3 downto 0); + slv_ack_o <= '1'; + + when x"0009" => + status_trigger_type <= SLV_DATA_IN(3 downto 0); + slv_ack_o <= '1'; + + when x"000a" => + calibration_trigger_type <= SLV_DATA_IN(3 downto 0); + slv_ack_o <= '1'; + + when others => + slv_unknown_addr_o <= '1'; + + end case; + + elsif (SLV_READ_IN = '1') then + case SLV_ADDR_IN is + when x"0003" => + slv_data_out_o(15 downto 0) <= + std_logic_vector(invalid_timing_trigger_ctr); + slv_data_out_o(31 downto 26) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0004" => + slv_data_out_o(27 downto 0) <= + std_logic_vector(accepted_trigger_rate); + slv_data_out_o(31 downto 28) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0006" => + slv_data_out_o(0) <= bypass_physics_trigger; + slv_data_out_o(1) <= bypass_status_trigger; + slv_data_out_o(2) <= bypass_calibration_trigger; + slv_data_out_o(3) <= bypass_all_trigger; + slv_data_out_o(31 downto 4) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0007" => + slv_data_out_o(15 downto 0) <= calibration_downscale; + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0008" => + slv_data_out_o(3 downto 0) <= physics_trigger_type; + slv_data_out_o(31 downto 4) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0009" => + slv_data_out_o(3 downto 0) <= status_trigger_type; + slv_data_out_o(31 downto 4) <= (others => '0'); + slv_ack_o <= '1'; + + when x"000a" => + slv_data_out_o(3 downto 0) <= calibration_trigger_type; + slv_data_out_o(31 downto 4) <= (others => '0'); + slv_ack_o <= '1'; + + when others => + slv_unknown_addr_o <= '1'; + + end case; + + end if; + end if; + end if; + end process PROC_SLAVE_BUS; + +----------------------------------------------------------------------------- +-- Output Signals +----------------------------------------------------------------------------- + + timestamp_calib_trigger_f <= timestamp_calib_trigger_c100 + when rising_edge(CLK_D1_IN); + + timestamp_calib_trigger_o <= timestamp_calib_trigger_f + when rising_edge(CLK_D1_IN); + + -- Trigger Output + VALID_TRIGGER_OUT <= valid_trigger_o; + TIMESTAMP_TRIGGER_OUT <= timestamp_trigger_o or timestamp_calib_trigger_o; + TRIGGER_TIMING_OUT <= timing_trigger_o; + TRIGGER_STATUS_OUT <= status_trigger_o; + TRIGGER_CALIBRATION_OUT <= calibration_trigger_o; + FAST_CLEAR_OUT <= fast_clear_o; + TRIGGER_BUSY_OUT <= trigger_busy_o; + + FEE_DATA_OUT <= fee_data_o; + FEE_DATA_WRITE_OUT <= fee_data_write_o; + FEE_DATA_FINISHED_OUT <= fee_data_finished_o; + FEE_TRG_RELEASE_OUT <= fee_trg_release_o; + FEE_TRG_STATUSBITS_OUT <= fee_trg_statusbits_o; + + -- Slave Bus + SLV_DATA_OUT <= slv_data_out_o; + SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; + SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; + SLV_ACK_OUT <= slv_ack_o; + +end Behavioral;