--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.nxyter_components.all;
+
+entity nx_fpga_timestamp is
+ port (
+ CLK_IN : in std_logic;
+ RESET_IN : in std_logic;
+
+ TIMESTAMP_SYNC_IN : in std_logic;
+ TRIGGER_IN : in std_logic;
+
+ TIMESTAMP_OUT : out unsigned(11 downto 0);
+ NX_TIMESTAMP_SYNC_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_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 nx_fpga_timestamp is
+
+ signal timestamp_ctr : unsigned(11 downto 0);
+ signal timestamp_o : unsigned(11 downto 0);
+ signal trigger_x : std_logic;
+ signal trigger_l : std_logic;
+ signal trigger : std_logic;
+ signal timestamp_sync_x : std_logic;
+ signal timestamp_sync_l : std_logic;
+ signal timestamp_sync : std_logic;
+
+ signal nx_timestamp_sync_o : std_logic;
+
+begin
+
+ DEBUG_OUT(0) <= CLK_IN;
+ DEBUG_OUT(1) <= trigger;
+ DEBUG_OUT(2) <= timestamp_sync;
+ DEBUG_OUT(3) <= '0';
+ DEBUG_OUT(15 downto 4) <= TIMESTAMP_OUT;
+
+ -- Cross the abyss for trigger and sync signal
+
+ PROC_SYNC: process (CLK_IN)
+ begin
+ if( rising_edge(CLK_IN) ) then
+ if (RESET_IN = '1') then
+ trigger_x <= '0';
+ trigger_l <= '0';
+ timestamp_sync_x <= '0';
+ timestamp_sync_l <= '0';
+ else
+ trigger_x <= TRIGGER_IN;
+ trigger_l <= trigger_x;
+ timestamp_sync_x <= TIMESTAMP_SYNC_IN;
+ timestamp_sync_l <= timestamp_sync_x;
+ end if;
+ end if;
+ end process PROC_SYNC;
+
+ -- Convert TRIGGER_IN to Pulse
+
+ level_to_pulse_1: level_to_pulse
+ port map (
+ CLK_IN => CLK_IN,
+ RESET_IN => RESET_IN,
+ LEVEL_IN => trigger_l,
+ PULSE_OUT => trigger
+ );
+
+ -- Convert TIMESTAMP_SYNC_IN to Pulse
+
+ level_to_pulse_2: level_to_pulse
+ port map (
+ CLK_IN => CLK_IN,
+ RESET_IN => RESET_IN,
+ LEVEL_IN => timestamp_sync_l,
+ PULSE_OUT => timestamp_sync
+ );
+
+ -- Timestamp Process + Trigger
+
+ PROC_TIMESTAMP_CTR: process (CLK_IN)
+ begin
+ if( rising_edge(CLK_IN) ) then
+ if( RESET_IN = '1' ) then
+ timestamp_ctr <= (others => '0');
+ timestamp_o <= (others => '0');
+ nx_timestamp_sync_o <= '0';
+ else
+ nx_timestamp_sync_o <= '0';
+
+ if (timestamp_sync = '1') then
+ timestamp_ctr <= (others => '0');
+ timestamp_o <= (others => '0');
+ nx_timestamp_sync_o <= '1';
+ else
+ if (trigger = '1') then
+ timestamp_o <= timestamp_ctr - 3;
+ end if;
+ timestamp_ctr <= timestamp_ctr + 1;
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Output Signals
+ -----------------------------------------------------------------------------
+
+ TIMESTAMP_OUT <= timestamp_o;
+ NX_TIMESTAMP_SYNC_OUT <= nx_timestamp_sync_o;
+
+end Behavioral;
--- /dev/null
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+library work;\r
+use work.trb_net_std.all;\r
+use work.nxyter_components.all;\r
+\r
+entity nx_timestamp_decode is\r
+ port (\r
+ CLK_IN : in std_logic; \r
+ RESET_IN : in std_logic;\r
+\r
+ -- Inputs\r
+ NX_NEW_TIMESTAMP_IN : in std_logic;\r
+ NX_TIMESTAMP_IN : in std_logic_vector(31 downto 0);\r
+ TIMESTAMP_REF_IN : in unsigned(11 downto 0);\r
+\r
+ -- Outputs\r
+ TIMESTAMP_DATA_OUT : out std_logic_vector(31 downto 0);\r
+ TIMESTAMP_VALID_OUT : out std_logic;\r
+ NX_TOKEN_RETURN : out std_logic;\r
+ NX_NOMORE_DATA : out std_logic;\r
+\r
+ -- Slave bus \r
+ SLV_READ_IN : in std_logic;\r
+ SLV_WRITE_IN : in std_logic;\r
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);\r
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);\r
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);\r
+ SLV_ACK_OUT : out std_logic;\r
+ SLV_NO_MORE_DATA_OUT : out std_logic;\r
+ SLV_UNKNOWN_ADDR_OUT : out std_logic;\r
+ \r
+ DEBUG_OUT : out std_logic_vector(15 downto 0)\r
+ );\r
+\r
+end entity;\r
+\r
+architecture Behavioral of nx_timestamp_decode is\r
+ \r
+ -- Sync Ref\r
+ signal timestamp_ref_x : unsigned(11 downto 0);\r
+ signal timestamp_ref : unsigned(11 downto 0);\r
+\r
+ -- Gray Decoder\r
+ signal nx_timestamp : std_logic_vector(13 downto 0);\r
+ signal nx_channel_id : std_logic_vector( 6 downto 0);\r
+\r
+ -- TIMESTAMP_BITS\r
+ signal new_timestamp : std_logic;\r
+ signal valid_frame_bits : std_logic_vector(3 downto 0);\r
+ signal status_bits : std_logic_vector(1 downto 0);\r
+ signal parity_bit : std_logic;\r
+ signal parity : std_logic;\r
+ signal timstamp_raw : std_logic_vector(31 downto 0);\r
+ \r
+ -- Validate Timestamp\r
+ signal timestamp_data_o : std_logic_vector(31 downto 0);\r
+ signal timestamp_valid_o : std_logic;\r
+ signal nx_token_return_o : std_logic;\r
+ signal nx_nomore_data_o : std_logic;\r
+ signal nx_data_notvalid_ctr : unsigned(1 downto 0);\r
+ signal invalid_frame_ctr : unsigned(15 downto 0);\r
+ signal overflow_ctr : unsigned(15 downto 0);\r
+ signal pileup_ctr : unsigned(15 downto 0);\r
+ signal parity_error_ctr : unsigned(15 downto 0);\r
+ \r
+ -- Config\r
+ signal readout_type : std_logic_vector(1 downto 0);\r
+\r
+ -- Slave Bus \r
+ signal slv_data_out_o : std_logic_vector(31 downto 0);\r
+ signal slv_no_more_data_o : std_logic;\r
+ signal slv_unknown_addr_o : std_logic;\r
+ signal slv_ack_o : std_logic;\r
+ signal clear_counters : std_logic;\r
+ signal trigger_window_width : unsigned(13 downto 0);\r
+ signal trigger_window_delay : unsigned(13 downto 0);\r
+ signal readout_mode : std_logic_vector(1 downto 0);\r
+\r
+begin\r
+\r
+ -- Debug Line\r
+ DEBUG_OUT(0) <= CLK_IN;\r
+ DEBUG_OUT(1) <= NX_NEW_TIMESTAMP_IN;\r
+ DEBUG_OUT(2) <= TIMESTAMP_VALID_OUT;\r
+ DEBUG_OUT(3) <= new_timestamp;\r
+ DEBUG_OUT(5 downto 4) <= status_bits;\r
+\r
+ DEBUG_OUT(6) <= parity;\r
+ DEBUG_OUT(7) <= '0';\r
+ \r
+ DEBUG_OUT(14 downto 8) <= nx_channel_id;\r
+ DEBUG_OUT(15) <= '0';\r
+ \r
+ -----------------------------------------------------------------------------\r
+ -- Gray Decoder for Timestamp and Chgannel Id\r
+ -----------------------------------------------------------------------------\r
+\r
+ Gray_Decoder_1: Gray_Decoder -- Decode nx_timestamp\r
+ generic map (\r
+ WIDTH => 14\r
+ )\r
+ port map (\r
+ CLK_IN => CLK_IN,\r
+ RESET_IN => RESET_IN,\r
+ GRAY_IN(13 downto 7) => not NX_TIMESTAMP_IN(30 downto 24),\r
+ GRAY_IN( 6 downto 0) => not NX_TIMESTAMP_IN(22 downto 16),\r
+ BINARY_OUT => nx_timestamp\r
+ );\r
+\r
+ Gray_Decoder_2: Gray_Decoder -- Decode Channel_ID\r
+ generic map (\r
+ WIDTH => 7\r
+ )\r
+ port map (\r
+ CLK_IN => CLK_IN,\r
+ RESET_IN => RESET_IN,\r
+ GRAY_IN => NX_TIMESTAMP_IN(14 downto 8),\r
+ BINARY_OUT => nx_channel_id\r
+ );\r
+\r
+ -- Sync Timestamp Ref\r
+ PROC_SYNC_TIMESTAMP_REF: process (CLK_IN)\r
+ begin\r
+ if( rising_edge(CLK_IN) ) then\r
+ if (RESET_IN = '1') then\r
+ timestamp_ref_x <= (others => '0');\r
+ timestamp_ref <= (others => '0');\r
+ else\r
+ timestamp_ref_x <= TIMESTAMP_REF_IN;\r
+ timestamp_ref <= timestamp_ref_x;\r
+ end if;\r
+ end if;\r
+ end process PROC_SYNC_TIMESTAMP_REF;\r
+ \r
+ -- Separate Status-, Parity- and Frame-bits, calculate parity\r
+ PROC_TIMESTAMP_BITS: process (CLK_IN)\r
+ variable parity_bits : std_logic_vector(22 downto 0);\r
+ begin\r
+ if( rising_edge(CLK_IN) ) then\r
+ if (RESET_IN = '1') then\r
+ valid_frame_bits <= (others => '0');\r
+ status_bits <= (others => '0');\r
+ parity_bit <= '0';\r
+ parity <= '0';\r
+ new_timestamp <= '0';\r
+ timstamp_raw <= (others => '0');\r
+ else\r
+ -- Timestamp Bit #6 is excluded (funny nxyter-bug)\r
+ parity_bits := NX_TIMESTAMP_IN(31 downto 24) &\r
+ NX_TIMESTAMP_IN(21 downto 16) &\r
+ NX_TIMESTAMP_IN(14 downto 8) &\r
+ NX_TIMESTAMP_IN( 2 downto 1);\r
+ valid_frame_bits <= (others => '0');\r
+ status_bits <= (others => '0');\r
+ parity_bit <= '0';\r
+ parity <= '0';\r
+ new_timestamp <= '0';\r
+ timstamp_raw <= (others => '0');\r
+ \r
+ if (NX_NEW_TIMESTAMP_IN = '1') then\r
+ valid_frame_bits(3) <= NX_TIMESTAMP_IN(31);\r
+ valid_frame_bits(2) <= NX_TIMESTAMP_IN(23);\r
+ valid_frame_bits(1) <= NX_TIMESTAMP_IN(15);\r
+ valid_frame_bits(0) <= NX_TIMESTAMP_IN(7);\r
+ status_bits <= NX_TIMESTAMP_IN(2 downto 1);\r
+ parity_bit <= NX_TIMESTAMP_IN(0);\r
+ parity <= xor_all(parity_bits);\r
+ timstamp_raw <= NX_TIMESTAMP_IN;\r
+ new_timestamp <= '1';\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process PROC_TIMESTAMP_BITS; \r
+\r
+ -----------------------------------------------------------------------------\r
+ -- Filter only valid events\r
+ -----------------------------------------------------------------------------\r
+\r
+ PROC_VALIDATE_TIMESTAMP: process (CLK_IN)\r
+ variable ref : unsigned(13 downto 0);\r
+ variable deltaT : unsigned(13 downto 0);\r
+ begin \r
+ if( rising_edge(CLK_IN) ) then\r
+ if (RESET_IN = '1') then\r
+ timestamp_data_o <= (others => '0');\r
+ timestamp_valid_o <= '0';\r
+ nx_token_return_o <= '0';\r
+ nx_nomore_data_o <= '1';\r
+ nx_data_notvalid_ctr <= (others => '0');\r
+ invalid_frame_ctr <= (others => '0');\r
+ overflow_ctr <= (others => '0');\r
+ pileup_ctr <= (others => '0');\r
+ parity_error_ctr <= (others => '0');\r
+ else\r
+ timestamp_data_o(31 downto 0) <= (others => '0');\r
+ timestamp_valid_o <= '0';\r
+ nx_token_return_o <= '0';\r
+ nx_nomore_data_o <= '0';\r
+ \r
+ if (new_timestamp = '1') then\r
+ case valid_frame_bits is\r
+ when "1000" =>\r
+ ---- Check Overflow\r
+ if (status_bits(0) = '1') then\r
+ if (clear_counters = '0') then\r
+ overflow_ctr <= overflow_ctr + 1;\r
+ end if;\r
+ end if;\r
+\r
+ ---- Check Parity\r
+ if ((parity_bit /= parity) and (clear_counters = '0')) then\r
+ parity_error_ctr <= parity_error_ctr + 1;\r
+ end if;\r
+\r
+ -- Check PileUp\r
+ if ((status_bits(1) = '1') and (clear_counters = '0')) then\r
+ pileup_ctr <= pileup_ctr + 1;\r
+ end if;\r
+ \r
+ -- Take Timestamp\r
+ ref := timestamp_ref & "00";\r
+ deltaT := ref - unsigned(nx_timestamp);\r
+ \r
+ case readout_mode is\r
+ \r
+ when "00" => \r
+ -- Raw\r
+ timestamp_data_o(13 downto 0) <= nx_timestamp; \r
+ timestamp_valid_o <= '1';\r
+ \r
+ when "01" =>\r
+ -- Ref\r
+ timestamp_data_o(13 downto 0) <= std_logic_vector(deltaT);\r
+ timestamp_valid_o <= '1';\r
+\r
+ when "10" =>\r
+ -- Trigger Window\r
+ if ((deltaT < trigger_window_delay) and\r
+ (deltaT > (trigger_window_delay - trigger_window_width)))\r
+ then\r
+ timestamp_data_o(13 downto 0) <= std_logic_vector(deltaT);\r
+ timestamp_valid_o <= '1';\r
+ end if;\r
+\r
+ when others => null;\r
+ end case;\r
+ \r
+ timestamp_data_o(15 downto 14) <= (others => '0');\r
+ timestamp_data_o(22 downto 16) <= nx_channel_id;\r
+ timestamp_data_o(23) <= '0';\r
+ timestamp_data_o(24) <= parity_bit;\r
+ timestamp_data_o(25) <= parity;\r
+ timestamp_data_o(29 downto 26) <= (others => '0');\r
+ timestamp_data_o(31 downto 30) <= status_bits;\r
+\r
+ nx_data_notvalid_ctr <= (others => '0');\r
+ \r
+ when "0000" =>\r
+ case nx_data_notvalid_ctr is\r
+ when "00" =>\r
+ nx_token_return_o <= '1';\r
+ nx_data_notvalid_ctr <= nx_data_notvalid_ctr + 1;\r
+ when "01" =>\r
+ nx_nomore_data_o <= '1';\r
+ nx_data_notvalid_ctr <= nx_data_notvalid_ctr + 1;\r
+ when others => null;\r
+ end case;\r
+ \r
+ when others =>\r
+ -- Invalid frame, not empty, discard timestamp\r
+ if (clear_counters = '0') then\r
+ invalid_frame_ctr <= invalid_frame_ctr + 1;\r
+ end if;\r
+ end case;\r
+ end if;\r
+\r
+ -- Reset Counters\r
+ if (clear_counters = '1') then\r
+ invalid_frame_ctr <= (others => '0');\r
+ overflow_ctr <= (others => '0');\r
+ pileup_ctr <= (others => '0');\r
+ parity_error_ctr <= (others => '0');\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process PROC_VALIDATE_TIMESTAMP;\r
+\r
+ -----------------------------------------------------------------------------\r
+ -- TRBNet Slave Bus\r
+ -----------------------------------------------------------------------------\r
+\r
+ -- Give status info to the TRB Slow Control Channel\r
+ PROC_FIFO_REGISTERS: process(CLK_IN)\r
+ begin\r
+ if( rising_edge(CLK_IN) ) then\r
+ if( RESET_IN = '1' ) then\r
+ slv_data_out_o <= (others => '0');\r
+ slv_ack_o <= '0';\r
+ slv_unknown_addr_o <= '0';\r
+ slv_no_more_data_o <= '0';\r
+ readout_mode <= "00";\r
+ clear_counters <= '0';\r
+ trigger_window_width <= (others => '0');\r
+ trigger_window_delay <= (others => '0');\r
+ else\r
+ slv_data_out_o <= (others => '0');\r
+ slv_unknown_addr_o <= '0';\r
+ slv_no_more_data_o <= '0';\r
+ clear_counters <= '0';\r
+ \r
+ if (SLV_READ_IN = '1') then\r
+ case SLV_ADDR_IN is\r
+ when x"0000" =>\r
+ slv_data_out_o(1 downto 0) <= readout_mode;\r
+ slv_data_out_o(31 downto 2) <= (others => '0');\r
+ slv_ack_o <= '1';\r
+\r
+ when x"0001" =>\r
+ slv_data_out_o(13 downto 0) <=\r
+ std_logic_vector(trigger_window_width);\r
+ slv_data_out_o(31 downto 14) <= (others => '0');\r
+ slv_ack_o <= '1';\r
+\r
+ when x"0002" =>\r
+ slv_data_out_o(13 downto 0) <=\r
+ std_logic_vector(trigger_window_delay);\r
+ slv_data_out_o(31 downto 14) <= (others => '0');\r
+ slv_ack_o <= '1'; \r
+ \r
+ when x"000a" =>\r
+ slv_data_out_o(15 downto 0) <=\r
+ std_logic_vector(invalid_frame_ctr);\r
+ slv_data_out_o(31 downto 16) <= (others => '0');\r
+ slv_ack_o <= '1';\r
+\r
+ when x"000b" =>\r
+ slv_data_out_o(15 downto 0) <=\r
+ std_logic_vector(overflow_ctr);\r
+ slv_data_out_o(31 downto 16) <= (others => '0');\r
+ slv_ack_o <= '1';\r
+\r
+ when x"000c" =>\r
+ slv_data_out_o(15 downto 0) <=\r
+ std_logic_vector(pileup_ctr);\r
+ slv_data_out_o(31 downto 16) <= (others => '0');\r
+ slv_ack_o <= '1';\r
+\r
+ when x"000d" =>\r
+ slv_data_out_o(15 downto 0) <=\r
+ std_logic_vector(parity_error_ctr);\r
+ slv_data_out_o(31 downto 16) <= (others => '0');\r
+ slv_ack_o <= '1';\r
+ \r
+ when others =>\r
+ slv_unknown_addr_o <= '1';\r
+ slv_ack_o <= '0';\r
+ end case;\r
+ \r
+ elsif (SLV_WRITE_IN = '1') then\r
+ case SLV_ADDR_IN is\r
+ when x"0000" =>\r
+ readout_mode <= SLV_DATA_IN(1 downto 0);\r
+ slv_ack_o <= '1';\r
+\r
+ when x"0001" =>\r
+ trigger_window_width <=\r
+ unsigned(SLV_DATA_IN(13 downto 0));\r
+ slv_ack_o <= '1';\r
+\r
+ when x"0002" =>\r
+ trigger_window_delay <=\r
+ unsigned(SLV_DATA_IN(13 downto 0));\r
+ slv_ack_o <= '1'; \r
+\r
+ when x"000f" =>\r
+ clear_counters <= '1';\r
+ slv_ack_o <= '1';\r
+ \r
+ when others =>\r
+ slv_unknown_addr_o <= '1';\r
+ slv_ack_o <= '0';\r
+ end case; \r
+ else\r
+ slv_ack_o <= '0';\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process PROC_FIFO_REGISTERS;\r
+ \r
+ -----------------------------------------------------------------------------\r
+ -- Output Signals\r
+ -----------------------------------------------------------------------------\r
+\r
+ TIMESTAMP_DATA_OUT <= timestamp_data_o;\r
+ TIMESTAMP_VALID_OUT <= timestamp_valid_o;\r
+ NX_TOKEN_RETURN <= nx_token_return_o;\r
+ NX_NOMORE_DATA <= nx_nomore_data_o;\r
+ \r
+ -- Slave \r
+ SLV_DATA_OUT <= slv_data_out_o; \r
+ SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; \r
+ SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o;\r
+ SLV_ACK_OUT <= slv_ack_o;\r
+end Behavioral;\r
--- /dev/null
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+library work;\r
+use work.nxyter_components.all;\r
+\r
+entity nx_trigger_generator is\r
+ port (\r
+ CLK_IN : in std_logic;\r
+ RESET_IN : in std_logic;\r
+\r
+ TRIGGER_OUT : out std_logic;\r
+ TS_RESET_OUT : out std_logic;\r
+ \r
+ -- Slave bus \r
+ SLV_READ_IN : in std_logic;\r
+ SLV_WRITE_IN : in std_logic;\r
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);\r
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);\r
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);\r
+ SLV_ACK_OUT : out std_logic;\r
+ SLV_NO_MORE_DATA_OUT : out std_logic;\r
+ SLV_UNKNOWN_ADDR_OUT : out std_logic;\r
+ \r
+ -- Debug Line\r
+ DEBUG_OUT : out std_logic_vector(15 downto 0)\r
+ );\r
+end entity;\r
+\r
+architecture Behavioral of nx_trigger_generator is\r
+\r
+ signal start_cycle : std_logic;\r
+ signal trigger_cycle_ctr : unsigned(7 downto 0);\r
+ signal trigger_cycle_ctr_x : unsigned(7 downto 0);\r
+ signal wait_timer_init : unsigned(15 downto 0);\r
+ signal wait_timer_init_x : unsigned(15 downto 0);\r
+ signal wait_timer_done : std_logic;\r
+ signal trigger_o : std_logic;\r
+ signal trigger_o_x : std_logic;\r
+ signal ts_reset_o : std_logic;\r
+ signal ts_reset_o_x : std_logic;\r
+ \r
+ type STATES is (S_IDLE,\r
+ S_WAIT_TS_RESET,\r
+ S_NEXT_CYCLE,\r
+ S_SET_TRIGGER,\r
+ S_WAIT_TRIGGER\r
+ );\r
+ signal STATE, NEXT_STATE : STATES;\r
+ \r
+ -- TRBNet Slave Bus \r
+ signal slv_data_out_o : std_logic_vector(31 downto 0);\r
+ signal slv_no_more_data_o : std_logic;\r
+ signal slv_unknown_addr_o : std_logic;\r
+ signal slv_ack_o : std_logic;\r
+\r
+ signal reg_trigger_period : unsigned(15 downto 0);\r
+ signal reg_trigger_length : unsigned(15 downto 0);\r
+ signal reg_trigger_num_cycles : unsigned(7 downto 0); \r
+ signal reg_reset_on : std_logic;\r
+ \r
+begin\r
+\r
+ -- Debug Line\r
+ DEBUG_OUT(0) <= CLK_IN;\r
+ DEBUG_OUT(1) <= TRIGGER_OUT;\r
+ DEBUG_OUT(2) <= start_cycle;\r
+ DEBUG_OUT(3) <= wait_timer_done;\r
+ DEBUG_OUT(4) <= ts_reset_o;\r
+ DEBUG_OUT(7 downto 5) <= (others => '0');\r
+ DEBUG_OUT(15 downto 8) <= trigger_cycle_ctr;\r
+\r
+ -- Timer\r
+ nx_timer_1: nx_timer\r
+ generic map (\r
+ CTR_WIDTH => 16\r
+ )\r
+ port map (\r
+ CLK_IN => CLK_IN,\r
+ RESET_IN => RESET_IN,\r
+ TIMER_START_IN => wait_timer_init,\r
+ TIMER_DONE_OUT => wait_timer_done\r
+ );\r
+\r
+ -----------------------------------------------------------------------------\r
+ -- Gernerate Trigger\r
+ -----------------------------------------------------------------------------\r
+\r
+ PROC_TRIGGER_OUT_TRANSFER: process (CLK_IN)\r
+ begin \r
+ if( rising_edge(CLK_IN) ) then\r
+ if (RESET_IN = '1') then\r
+ trigger_o <= '0';\r
+ ts_reset_o <= '0';\r
+ wait_timer_init <= (others => '0');\r
+ trigger_cycle_ctr <= (others => '0');\r
+ STATE <= S_IDLE;\r
+ else\r
+ trigger_o <= trigger_o_x;\r
+ ts_reset_o <= ts_reset_o_x;\r
+ wait_timer_init <= wait_timer_init_x;\r
+ trigger_cycle_ctr <= trigger_cycle_ctr_x;\r
+ STATE <= NEXT_STATE;\r
+ end if;\r
+ end if;\r
+ end process PROC_TRIGGER_OUT_TRANSFER;\r
+\r
+ PROC_TRIGGER_OUT: process(STATE,\r
+ start_cycle,\r
+ reg_trigger_num_cycles,\r
+ wait_timer_done\r
+ )\r
+ begin\r
+ trigger_o_x <= '0';\r
+ ts_reset_o_x <= '0';\r
+ wait_timer_init_x <= (others => '0');\r
+ trigger_cycle_ctr_x <= trigger_cycle_ctr;\r
+ \r
+ case STATE is\r
+ when S_IDLE =>\r
+ if (start_cycle = '1') then\r
+ trigger_cycle_ctr_x <= reg_trigger_num_cycles;\r
+ if reg_reset_on = '1' then\r
+ ts_reset_o_x <= '1';\r
+ wait_timer_init_x <= reg_trigger_period;\r
+ NEXT_STATE <= S_WAIT_TS_RESET;\r
+ else\r
+ NEXT_STATE <= S_NEXT_CYCLE;\r
+ end if;\r
+ else\r
+ NEXT_STATE <= S_IDLE;\r
+ end if;\r
+\r
+ when S_WAIT_TS_RESET =>\r
+ if (wait_timer_done = '0') then\r
+ NEXT_STATE <= S_WAIT_TS_RESET;\r
+ else\r
+ NEXT_STATE <= S_NEXT_CYCLE;\r
+ end if;\r
+ \r
+ when S_NEXT_CYCLE =>\r
+ if (trigger_cycle_ctr > 0) then\r
+ trigger_cycle_ctr_x <= trigger_cycle_ctr - 1;\r
+ wait_timer_init_x <= reg_trigger_length;\r
+ NEXT_STATE <= S_SET_TRIGGER;\r
+ else\r
+ NEXT_STATE <= S_IDLE;\r
+ end if;\r
+\r
+ when S_SET_TRIGGER =>\r
+ trigger_o_x <= '1';\r
+ if (wait_timer_done = '0') then\r
+ NEXT_STATE <= S_SET_TRIGGER;\r
+ else\r
+ wait_timer_init_x <= reg_trigger_period - reg_trigger_length;\r
+ NEXT_STATE <= S_WAIT_TRIGGER;\r
+ end if;\r
+ \r
+ when S_WAIT_TRIGGER =>\r
+ if (wait_timer_done = '0') then\r
+ NEXT_STATE <= S_WAIT_TRIGGER;\r
+ else\r
+ NEXT_STATE <= S_NEXT_CYCLE;\r
+ end if;\r
+\r
+ end case;\r
+ end process PROC_TRIGGER_OUT;\r
+\r
+ -----------------------------------------------------------------------------\r
+ -- TRBNet Slave Bus\r
+ -----------------------------------------------------------------------------\r
+ \r
+ PROC_SLAVE_BUS: process(CLK_IN)\r
+ begin\r
+ if( rising_edge(CLK_IN) ) then\r
+ if( RESET_IN = '1' ) then\r
+ reg_trigger_period <= x"00ff";\r
+ reg_trigger_num_cycles <= x"01";\r
+ reg_trigger_length <= x"000a";\r
+ reg_reset_on <= '0';\r
+ slv_data_out_o <= (others => '0');\r
+ slv_no_more_data_o <= '0';\r
+ slv_unknown_addr_o <= '0';\r
+ start_cycle <= '0';\r
+ slv_ack_o <= '0';\r
+ else\r
+ slv_unknown_addr_o <= '0';\r
+ slv_no_more_data_o <= '0';\r
+ slv_data_out_o <= (others => '0');\r
+ start_cycle <= '0';\r
+\r
+\r
+ if (SLV_WRITE_IN = '1') then\r
+ case SLV_ADDR_IN is\r
+ when x"0000" =>\r
+ start_cycle <= '1';\r
+ slv_ack_o <= '1';\r
+ when x"0001" =>\r
+ reg_trigger_period <= unsigned(SLV_DATA_IN(15 downto 0));\r
+ slv_ack_o <= '1';\r
+ when x"0002" =>\r
+ reg_trigger_num_cycles <= unsigned(SLV_DATA_IN(7 downto 0));\r
+ slv_ack_o <= '1';\r
+ when x"0003" =>\r
+ reg_trigger_length <= unsigned(SLV_DATA_IN(15 downto 0));\r
+ slv_ack_o <= '1';\r
+ when x"0004" =>\r
+ reg_reset_on <= SLV_DATA_IN(0);\r
+ slv_ack_o <= '1';\r
+ when others =>\r
+ slv_unknown_addr_o <= '1';\r
+ slv_ack_o <= '0';\r
+ end case;\r
+\r
+ elsif (SLV_READ_IN = '1') then\r
+ case SLV_ADDR_IN is\r
+ when x"0001" =>\r
+ slv_data_out_o(15 downto 0) <=\r
+ std_logic_vector(reg_trigger_period);\r
+ slv_ack_o <= '1';\r
+ when x"0002" =>\r
+ slv_data_out_o(7 downto 0) <=\r
+ std_logic_vector(reg_trigger_num_cycles);\r
+ slv_ack_o <= '1';\r
+ when x"0003" =>\r
+ slv_data_out_o(15 downto 0) <=\r
+ std_logic_vector(reg_trigger_length);\r
+ slv_ack_o <= '1';\r
+ when x"0004" =>\r
+ slv_data_out_o(0) <= reg_reset_on;\r
+ slv_ack_o <= '1';\r
+ when others =>\r
+ slv_unknown_addr_o <= '1';\r
+ slv_ack_o <= '0';\r
+ end case;\r
+\r
+ else\r
+ slv_ack_o <= '0';\r
+ end if;\r
+ end if;\r
+ end if; \r
+ end process PROC_SLAVE_BUS;\r
+ \r
+ -----------------------------------------------------------------------------\r
+ -- Output Signals\r
+ -----------------------------------------------------------------------------\r
+ \r
+ -- Trigger Output\r
+ TRIGGER_OUT <= trigger_o;\r
+ TS_RESET_OUT <= ts_reset_o;\r
+\r
+ -- Slave Bus\r
+ SLV_DATA_OUT <= slv_data_out_o; \r
+ SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; \r
+ SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o;\r
+ SLV_ACK_OUT <= slv_ack_o; \r
+\r
+end Behavioral;\r
--- /dev/null
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+library work;\r
+use work.nxyter_components.all;\r
+\r
+entity nx_trigger_handler is\r
+ port (\r
+ CLK_IN : in std_logic;\r
+ RESET_IN : in std_logic;\r
+\r
+ -- IN\r
+ TRIGGER_IN : in std_logic;\r
+ TRIGGER_RELEASE_IN : in std_logic;\r
+\r
+ -- OUT\r
+ TRIGGER_OUT : out std_logic;\r
+ TIMESTAMP_HOLD_OUT : out std_logic;\r
+ TRIGGER_BUSY_OUT : out std_logic;\r
+ \r
+ -- Slave bus \r
+ SLV_READ_IN : in std_logic;\r
+ SLV_WRITE_IN : in std_logic;\r
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);\r
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);\r
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);\r
+ SLV_ACK_OUT : out std_logic;\r
+ SLV_NO_MORE_DATA_OUT : out std_logic;\r
+ SLV_UNKNOWN_ADDR_OUT : out std_logic;\r
+ \r
+ -- Debug Line\r
+ DEBUG_OUT : out std_logic_vector(15 downto 0)\r
+ );\r
+end entity;\r
+\r
+architecture Behavioral of nx_trigger_handler is\r
+\r
+ signal start_cycle : std_logic;\r
+ signal trigger_cycle_ctr : unsigned(7 downto 0);\r
+ signal trigger_cycle_ctr_x : unsigned(7 downto 0);\r
+ signal wait_timer_init : unsigned(15 downto 0);\r
+ signal wait_timer_init_x : unsigned(15 downto 0);\r
+ signal wait_timer_done : std_logic;\r
+ signal trigger_o : std_logic;\r
+ signal trigger_o_x : std_logic;\r
+ signal timestamp_hold_o : std_logic;\r
+ signal timestamp_hold_o_x : std_logic;\r
+ signal trigger_busy_o : std_logic;\r
+ signal trigger_busy_o_x : std_logic;\r
+ \r
+ type STATES is (S_IDLE,\r
+ S_WAIT_HOLD,\r
+ S_WAIT_TRIGGER_RELEASE\r
+ );\r
+ signal STATE, NEXT_STATE : STATES;\r
+ \r
+ -- TRBNet Slave Bus \r
+ signal slv_data_out_o : std_logic_vector(31 downto 0);\r
+ signal slv_no_more_data_o : std_logic;\r
+ signal slv_unknown_addr_o : std_logic;\r
+ signal slv_ack_o : std_logic;\r
+\r
+ signal reg_timestamp_hold_delay : unsigned(15 downto 0);\r
+ \r
+begin\r
+\r
+ -- Debug Line\r
+ DEBUG_OUT(0) <= CLK_IN;\r
+ DEBUG_OUT(1) <= TRIGGER_IN;\r
+ DEBUG_OUT(2) <= trigger_o;\r
+ DEBUG_OUT(3) <= timestamp_hold_o;\r
+ DEBUG_OUT(4) <= wait_timer_done;\r
+ DEBUG_OUT(15 downto 5) <= (others => '0');\r
+\r
+ -- Timer\r
+ nx_timer_1: nx_timer\r
+ generic map (\r
+ CTR_WIDTH => 16\r
+ )\r
+ port map (\r
+ CLK_IN => CLK_IN,\r
+ RESET_IN => RESET_IN,\r
+ TIMER_START_IN => wait_timer_init,\r
+ TIMER_DONE_OUT => wait_timer_done\r
+ );\r
+\r
+ -----------------------------------------------------------------------------\r
+ -- Trigger Handler\r
+ -----------------------------------------------------------------------------\r
+\r
+ PROC_TRIGGER_HANDLER_TRANSFER: process (CLK_IN)\r
+ begin \r
+ if( rising_edge(CLK_IN) ) then\r
+ if (RESET_IN = '1') then\r
+ trigger_o <= '0';\r
+ timestamp_hold_o <= '0';\r
+ trigger_busy_o <= '1';\r
+ wait_timer_init <= (others => '0');\r
+ STATE <= S_IDLE;\r
+ else\r
+ trigger_o <= trigger_o_x;\r
+ timestamp_hold_o <= timestamp_hold_o_x;\r
+ trigger_busy_o <= trigger_busy_o_x;\r
+ wait_timer_init <= wait_timer_init_x;\r
+ STATE <= NEXT_STATE;\r
+ end if;\r
+ end if;\r
+ end process PROC_TRIGGER_HANDLER_TRANSFER;\r
+\r
+ PROC_TRIGGER_HANDLER: process(STATE,\r
+ TRIGGER_IN,\r
+ TRIGGER_RELEASE_IN,\r
+ wait_timer_done\r
+ )\r
+ begin\r
+ trigger_o_x <= '0';\r
+ timestamp_hold_o_x <= '0';\r
+ trigger_busy_o_x <= '1';\r
+ wait_timer_init_x <= (others => '0');\r
+ \r
+ case STATE is\r
+ when S_IDLE =>\r
+ if (TRIGGER_IN = '1') then\r
+ trigger_o_x <= '1';\r
+ wait_timer_init_x <= reg_timestamp_hold_delay;\r
+ NEXT_STATE <= S_WAIT_HOLD;\r
+ else\r
+ trigger_busy_o_x <= '0';\r
+ NEXT_STATE <= S_IDLE;\r
+ end if;\r
+\r
+ when S_WAIT_HOLD =>\r
+ if (wait_timer_done = '1') then\r
+ timestamp_hold_o_x <= '1';\r
+ NEXT_STATE <= S_IDLE;\r
+ else\r
+ NEXT_STATE <= S_WAIT_HOLD ;\r
+ end if;\r
+\r
+ when S_WAIT_TRIGGER_RELEASE =>\r
+ if (TRIGGER_RELEASE_IN = '0') then\r
+ NEXT_STATE <= S_WAIT_TRIGGER_RELEASE;\r
+ else\r
+ NEXT_STATE <= S_IDLE;\r
+ end if;\r
+ \r
+ end case;\r
+ end process PROC_TRIGGER_HANDLER;\r
+\r
+ -----------------------------------------------------------------------------\r
+ -- TRBNet Slave Bus\r
+ -----------------------------------------------------------------------------\r
+ \r
+ PROC_SLAVE_BUS: process(CLK_IN)\r
+ begin\r
+ if( rising_edge(CLK_IN) ) then\r
+ if( RESET_IN = '1' ) then\r
+ slv_data_out_o <= (others => '0');\r
+ slv_no_more_data_o <= '0';\r
+ slv_unknown_addr_o <= '0';\r
+ start_cycle <= '0';\r
+ slv_ack_o <= '0';\r
+ reg_timestamp_hold_delay <= x"00ff";\r
+ else\r
+ slv_unknown_addr_o <= '0';\r
+ slv_no_more_data_o <= '0';\r
+ slv_data_out_o <= (others => '0');\r
+ start_cycle <= '0';\r
+\r
+ if (SLV_WRITE_IN = '1') then\r
+ case SLV_ADDR_IN is\r
+ when x"0000" =>\r
+ reg_timestamp_hold_delay <= SLV_DATA_IN(15 downto 0);\r
+ slv_ack_o <= '1';\r
+ when others =>\r
+ slv_unknown_addr_o <= '1';\r
+ slv_ack_o <= '0';\r
+ end case;\r
+\r
+ elsif (SLV_READ_IN = '1') then\r
+ case SLV_ADDR_IN is\r
+ when x"0000" =>\r
+ slv_data_out_o(15 downto 0) <=\r
+ std_logic_vector(reg_timestamp_hold_delay);\r
+ slv_data_out_o(31 downto 16) <= (others => '0');\r
+ slv_ack_o <= '1';\r
+ when others =>\r
+ slv_unknown_addr_o <= '1';\r
+ slv_ack_o <= '0';\r
+ end case;\r
+\r
+ else\r
+ slv_ack_o <= '0';\r
+ end if;\r
+ end if;\r
+ end if; \r
+ end process PROC_SLAVE_BUS;\r
+ \r
+ -----------------------------------------------------------------------------\r
+ -- Output Signals\r
+ -----------------------------------------------------------------------------\r
+ \r
+ -- Trigger Output\r
+ TRIGGER_OUT <= trigger_o;\r
+ TIMESTAMP_HOLD_OUT <= timestamp_hold_o;\r
+ TRIGGER_BUSY_OUT <= trigger_busy_o;\r
+ \r
+ -- Slave Bus\r
+ SLV_DATA_OUT <= slv_data_out_o; \r
+ SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; \r
+ SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o;\r
+ SLV_ACK_OUT <= slv_ack_o; \r
+\r
+end Behavioral;\r