]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
nxyter update, timing corrections etc.
authorLudwig Maier <lmaier@crius.e12.ph.tum.de>
Mon, 28 Apr 2014 07:22:41 +0000 (09:22 +0200)
committerLudwig Maier <lmaier@crius.e12.ph.tum.de>
Mon, 28 Apr 2014 07:22:56 +0000 (09:22 +0200)
nxyter/source/adc_ad9228.vhd
nxyter/source/nx_data_receiver.vhd
nxyter/source/nx_trigger_generator.vhd
nxyter/source/nx_trigger_handler.vhd
nxyter/source/nx_trigger_validate.vhd
nxyter/source/nxyter_components.vhd
nxyter/source/nxyter_fee_board.vhd
nxyter/trb3_periph_constraints.lpf

index 2ca5424485f0cf089abed8dc1845d8c4647ebe4a..4e9789dda01c2d5e8ee64eaf5619f6d3f86c2f2a 100644 (file)
@@ -55,7 +55,11 @@ architecture Behavioral of  adc_ad9228 is
 
   -- DDR Generic Handler
   signal DDR_DATA_CLK           : std_logic;
+  signal q_0_ff                 : std_logic_vector(19 downto 0);
+  signal q_0_f                  : std_logic_vector(19 downto 0);
   signal q_0                    : std_logic_vector(19 downto 0);
+  signal q_1_ff                 : std_logic_vector(19 downto 0);
+  signal q_1_f                  : std_logic_vector(19 downto 0);
   signal q_1                    : std_logic_vector(19 downto 0);
 
   -- NotLock Counters
@@ -219,10 +223,17 @@ begin
       datain_1(3)    => ADC1_DATA_D_IN,
       datain_1(4)    => ADC1_FCLK_IN,
                      
-      q_0            => q_0,
-      q_1            => q_1
+      q_0            => q_0_ff,
+      q_1            => q_1_ff
       );
 
+  -- Two Input FIFOs to relaxe timing
+  q_0_f   <= q_0_ff when rising_edge(DDR_DATA_CLK);
+  q_0     <= q_0_f  when rising_edge(DDR_DATA_CLK);
+
+  q_1_f   <= q_1_ff when rising_edge(DDR_DATA_CLK);
+  q_1     <= q_1_f  when rising_edge(DDR_DATA_CLK);
+  
   -----------------------------------------------------------------------------
   
   PROC_MERGE_DATA0: process(DDR_DATA_CLK)
index 34d1c81de3f8f0a50d7cf8766ac3245d73310fb7..7561a813aa6e5dfe12401884b09d21ea8b5853c9 100644 (file)
@@ -236,6 +236,8 @@ architecture Behavioral of nx_data_receiver is
   signal new_adc_dt_error_ctr_r       : unsigned(11 downto 0);
   signal new_timestamp_dt_error_ctr_r : unsigned(11 downto 0);
   signal adc_notlock_ctr_r           : unsigned(7 downto 0);
+  signal merge_error_ctr_r           : unsigned(11 downto 0);
+  signal nx_frame_synced_r           : std_logic;
   
   -----------------------------------------------------------------------------
   -- Reset Handler
@@ -251,6 +253,8 @@ architecture Behavioral of nx_data_receiver is
   signal fifo_reset_handler          : std_logic;
  
   type R_STATES is (R_IDLE,
+                    R_RESET_TIMESTAMP,
+                    R_WAIT_0,
                     R_SET_ALL_RESETS,
                     R_WAIT_1,
                     R_WAIT_NX_FRAME_RATE_OK,
@@ -280,7 +284,7 @@ architecture Behavioral of nx_data_receiver is
   signal parity_error_c100           : std_logic;
   signal parity_error_counter        : unsigned(11 downto 0);
                                      
-  signal reg_nx_frame_synced         : std_logic;
+
 
   -- Reset Domain Transfers
   signal RESET_NX_TIMESTAMP_CLK_IN   : std_logic;
@@ -321,7 +325,7 @@ begin
           -- Reset Handler
           DEBUG_OUT(0)            <= CLK_IN;
           DEBUG_OUT(1)            <= nx_frame_clk;
-          DEBUG_OUT(2)            <= adc_clk_skip;
+          DEBUG_OUT(2)            <= adc_data_clk_c100; --clk_skip;
           DEBUG_OUT(3)            <= adc_clk_ok;
           DEBUG_OUT(4)            <= adc_reset_sync;
           DEBUG_OUT(5)            <= adc_reset_handler;
@@ -1074,14 +1078,6 @@ begin
       PULSE_B_OUT => resync_ctr_inc
       );
 
-  -- nx_frame_synced --> CLK_IN Domain
-  signal_async_trans_1: signal_async_trans
-    port map (
-      CLK_IN      => CLK_IN,
-      SIGNAL_A_IN => nx_frame_synced,
-      SIGNAL_OUT  => reg_nx_frame_synced
-      );
-  
   -- Counters
   PROC_RESYNC_COUNTER: process(CLK_IN)
   begin
@@ -1362,12 +1358,12 @@ begin
         if (reset_handler_start_r = '1') then
           -- Reset by register always wins, start it
           rs_timeout_timer_reset    <= '1';
-          R_STATE                   <= R_SET_ALL_RESETS;
+          R_STATE                   <= R_RESET_TIMESTAMP;
         elsif (rs_timeout_timer_done = '1') then
           -- Reset Timeout, retry RESET
           rs_timeout_timer_reset    <= '1';
           reset_timeout_flag        <= '1';
-          R_STATE                   <= R_SET_ALL_RESETS;
+          R_STATE                   <= R_RESET_TIMESTAMP;
         else
           
           case R_STATE is
@@ -1377,93 +1373,115 @@ begin
                   adc_reset_sync        = '1' or
                   startup_reset         = '1'
                   ) then
-                R_STATE                 <= R_SET_ALL_RESETS;
+                R_STATE                 <= R_RESET_TIMESTAMP;
               else 
                 reset_timeout_flag      <= '0';
                 rs_timeout_timer_reset  <= '1';
                 reset_handler_busy      <= '0';
                 R_STATE                 <= R_IDLE;
               end if;
-          
+
+            when R_RESET_TIMESTAMP =>
+              -- must reset/resync Timestamp clock and data trnasmission clock
+              -- of nxyter first, afterwards wait a bit to let settle down
+              reset_handler_counter     <= reset_handler_counter + 1;
+              nx_timestamp_reset_o      <= '1';
+              rs_wait_timer_start       <= '1';  -- wait 1mue to settle
+              R_STATE                   <= R_WAIT_0;  
+              debug_state               <= x"1";
+              
+            when R_WAIT_0 =>
+              if (rs_wait_timer_done = '0') then
+                R_STATE                 <= R_WAIT_0;
+              else
+                R_STATE                 <= R_SET_ALL_RESETS;
+              end if;  
+              debug_state               <= x"2";
+              
             when R_SET_ALL_RESETS =>
+              -- timer reset should be finished, can we check status,To be done?
+              -- now set reset of all handlers
               frame_rates_reset         <= '1';
-              fifo_reset_handler        <= '1';
               sampling_clk_reset        <= '1';
               adc_reset_p               <= '1';
               adc_reset_handler         <= '1';
               output_handler_reset      <= '1';
-
-              rs_wait_timer_start       <= '1';  -- wait 1mue to settle
+              fifo_reset_handler        <= '1';
+              
+              -- give resets 1mue to take effect  
+              rs_wait_timer_start       <= '1';  
               R_STATE                   <= R_WAIT_1;
-              debug_state               <= x"1";
-              reset_handler_counter     <= reset_handler_counter + 1;
-
+              debug_state               <= x"3";
+                            
             when R_WAIT_1 =>
+              sampling_clk_reset      <= '1';
+              adc_reset_handler       <= '1';
+              output_handler_reset    <= '1';
+              fifo_reset_handler      <= '1';
               if (rs_wait_timer_done = '0') then
-                fifo_reset_handler      <= '1';
-                sampling_clk_reset      <= '1';
-                adc_reset_handler       <= '1';
-                output_handler_reset    <= '1';
                 R_STATE                 <= R_WAIT_1;
               else
-                -- Release NX Fifo Reset + Start Timeout Handler
-                sampling_clk_reset      <= '1';
-                adc_reset_handler       <= '1';
-                output_handler_reset    <= '1';
+                -- now start timeout timer and begin to release resets
+                -- step by step
                 rs_timeout_timer_start  <= '1';
                 R_STATE                 <= R_WAIT_NX_FRAME_RATE_OK;
               end if;
-              debug_state               <= x"2";
+              debug_state               <= x"4";
 
             when R_WAIT_NX_FRAME_RATE_OK =>
               if (nx_frame_rate_offline = '0' and
                   nx_frame_rate_error   = '0') then
-                -- Release PLL Reset
+                -- Next: Release PLL Reset, i.e. sampling_clk_reset
                 adc_reset_handler       <= '1';
                 output_handler_reset    <= '1';
+                fifo_reset_handler      <= '1';
                 R_STATE                 <= R_PLL_WAIT_LOCK;
               else
                 sampling_clk_reset      <= '1';
                 adc_reset_handler       <= '1';
                 output_handler_reset    <= '1';
+                fifo_reset_handler      <= '1';
                 R_STATE                 <= R_WAIT_NX_FRAME_RATE_OK;
               end if;
-              debug_state               <= x"3";
+              debug_state               <= x"5";
               
             when R_PLL_WAIT_LOCK =>
-              if (pll_adc_not_lock = '1') then
-                adc_reset_handler       <= '1';
+              if (pll_adc_not_lock = '0') then
+                -- Next: Release ADC Reset
                 output_handler_reset    <= '1';
-                R_STATE                 <= R_PLL_WAIT_LOCK;
+                fifo_reset_handler      <= '1';
+                R_STATE                 <= R_WAIT_ADC_OK;
               else
-                -- Release ADC Reset
+                adc_reset_handler       <= '1';
                 output_handler_reset    <= '1';
-                R_STATE                 <= R_WAIT_ADC_OK;
+                fifo_reset_handler      <= '1';
+                R_STATE                 <= R_PLL_WAIT_LOCK;
               end if;
-              debug_state               <= x"4";
+              debug_state               <= x"6";
               
             when R_WAIT_ADC_OK =>
               if (error_adc0 = '0' and
                   adc_frame_rate_error = '0') then
-                -- Release Output Handler Reset
+                -- Next: Release Output Handler and Clock Domain transfer Fifo
+                -- Resets
                 R_STATE                 <= R_WAIT_DATA_HANDLER_OK;
               else
                 output_handler_reset    <= '1';
+                fifo_reset_handler      <= '1';
                 R_STATE                 <= R_WAIT_ADC_OK;
               end if;
-              debug_state               <= x"5";
+              debug_state               <= x"7";
 
             when R_WAIT_DATA_HANDLER_OK =>
               if (frame_rate_error = '0') then
                 startup_reset           <= '0';
                 reset_timeout_flag      <= '0';
                 rs_timeout_timer_reset  <= '1';
-                nx_timestamp_reset_o    <= '1';
                 R_STATE                 <= R_IDLE;
               else
                 R_STATE                 <= R_WAIT_DATA_HANDLER_OK;
               end if;  
-              debug_state               <= x"6";
+              debug_state               <= x"8";
           end case;
         end if;
       end if;
@@ -1485,7 +1503,7 @@ begin
         error_status_bits(2)   <= nx_frame_rate_error;
         error_status_bits(3)   <= adc_frame_rate_error;
         error_status_bits(4)   <= parity_rate_error;
-        error_status_bits(5)   <= not reg_nx_frame_synced;
+        error_status_bits(5)   <= not nx_frame_synced_r;
         error_status_bits(6)   <= error_adc0;
         error_status_bits(7)   <= pll_adc_not_lock;
         error_status_bits(8)   <= not adc_clk_ok_c100;
@@ -1510,6 +1528,14 @@ begin
   PROC_SLAVE_BUS: process(CLK_IN)
   begin
     if (rising_edge(CLK_IN) ) then
+      fifo_full_r                     <= fifo_full;
+      fifo_empty_r                    <= fifo_empty;
+      new_adc_dt_error_ctr_r          <= new_adc_dt_error_ctr;
+      new_timestamp_dt_error_ctr_r    <= new_timestamp_dt_error_ctr;
+      adc_notlock_ctr_r               <= adc_notlock_ctr;
+      merge_error_ctr_r               <= merge_error_ctr;
+      nx_frame_synced_r               <= nx_frame_synced;
+
       if( RESET_IN = '1' ) then
         slv_data_out_o                <= (others => '0');
         slv_ack_o                     <= '0';
@@ -1528,8 +1554,6 @@ begin
         adc_debug_type                <= (others => '0');
         fifo_full_r                   <= '0';
         fifo_empty_r                  <= '0';
-        new_adc_dt_error_ctr_r        <= (others => '0');
-        new_timestamp_dt_error_ctr_r  <= (others => '0');
       else                      
         slv_data_out_o                <= (others => '0');
         slv_ack_o                     <= '0';
@@ -1539,11 +1563,6 @@ begin
         reset_parity_error_ctr        <= '0';
         pll_adc_not_lock_ctr_clear    <= '0';
         reset_handler_start_r         <= '0';
-        fifo_full_r                   <= fifo_full;
-        fifo_empty_r                  <= fifo_empty;
-        new_adc_dt_error_ctr_r        <= new_adc_dt_error_ctr;
-        new_timestamp_dt_error_ctr_r  <= new_timestamp_dt_error_ctr;
-        adc_notlock_ctr_r             <= adc_notlock_ctr;
         
         if (SLV_READ_IN  = '1') then
           case SLV_ADDR_IN is
@@ -1595,7 +1614,7 @@ begin
               slv_ack_o                     <= '1';  
 
             when x"0009" =>
-              slv_data_out_o(11 downto 0)   <= merge_error_ctr;
+              slv_data_out_o(11 downto 0)   <= merge_error_ctr_r;
               slv_data_out_o(31 downto 12)  <= (others => '0');
               slv_ack_o                     <= '1';
               
@@ -1651,7 +1670,7 @@ begin
               slv_data_out_o(5)             <= '0';
               slv_data_out_o(29 downto 6)   <= (others => '0');
               slv_data_out_o(30)            <= '0';
-              slv_data_out_o(31)            <= reg_nx_frame_synced;
+              slv_data_out_o(31)            <= nx_frame_synced_r;
               slv_ack_o                     <= '1'; 
 
             when x"0012" =>
index a2547ea5a1531a134f23ae8a5666aca501672b38..2461a6ec8fd24dd3720ab8d83da8ac9dddb848aa 100644 (file)
@@ -7,70 +7,106 @@ use work.nxyter_components.all;
 
 entity nx_trigger_generator is
   port (
-    CLK_IN               : in  std_logic;
-    RESET_IN             : in  std_logic;
-    NX_MAIN_CLK_IN       : in  std_logic;
-
-    TRIGGER_BUSY_IN      : in  std_logic;
-    
-    TRIGGER_OUT          : out std_logic;
-    
-    DATA_IN              : in  std_logic_vector(43 downto 0);
-    DATA_CLK_IN          : in  std_logic;
-    SELF_TRIGGER_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;
+    CLK_IN                 : in  std_logic;
+    RESET_IN               : in  std_logic;
+    NX_MAIN_CLK_IN         : in  std_logic;
+                           
+    TRIGGER_BUSY_IN        : in  std_logic;
+    EXTERNAL_TRIGGER_OUT   : out std_logic;
+    INTERNAL_TRIGGER_OUT   : out std_logic;
+                           
+    DATA_IN                : in  std_logic_vector(43 downto 0);
+    DATA_CLK_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 Line
-    DEBUG_OUT            : out std_logic_vector(15 downto 0)
+    DEBUG_OUT              : out std_logic_vector(15 downto 0)
     );
 end entity;
 
 architecture Behavioral of nx_trigger_generator is
 
-  -- Self Trigger
+  -- Internal Trigger Generator 
+  signal pulser_trigger_on         : std_logic;
+  signal pulser_trigger_period     : unsigned(27 downto 0);
+  signal pulser_trigger            : std_logic;
+
+  -- Self Trigger Generator
+  signal data_i_f                  : std_logic_vector(43 downto 0);
+  signal data_i                    : std_logic_vector(43 downto 0);
+  signal data_clk_i_f              : std_logic;
+  signal data_clk_i                : std_logic;
   
-  type ST_STATES is (ST_IDLE,
-                     ST_BUSY
+  signal self_trigger_on           : std_logic;
+  signal self_trigger              : std_logic;
+  
+  -- Trigger Outputs
+  signal trigger_output_select     : std_logic;  -- 0: Ext 1: Intern
+  signal external_trigger_i        : std_logic;
+  signal external_trigger_o        : std_logic;
+  signal internal_trigger_o        : std_logic;
+  signal trigger                   : std_logic;
+
+  type S_STATES is (S_IDLE,
+                     S_BUSY
                      );
-  signal ST_STATE : ST_STATES;
+  signal S_STATE : S_STATES;
 
-  signal self_trigger_ctr        : unsigned(4 downto 0);
-  signal self_trigger_busy       : std_logic;
-  signal self_trigger            : std_logic;
-  signal self_trigger_o          : std_logic;
-  
-  -- 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 external_trigger_on       : std_logic; 
+  signal external_trigger_ctr      : unsigned(4 downto 0);
+  signal external_trigger_busy     : std_logic;
+  signal external_trigger          : std_logic;
+
+  -- Rate Calculation
+  signal self_trigger_rate_t       : unsigned(27 downto 0);
+  signal self_trigger_rate         : unsigned(27 downto 0);
+  signal pulser_trigger_rate_t     : unsigned(27 downto 0);
+  signal pulser_trigger_rate       : unsigned(27 downto 0);
+  signal trigger_rate              : unsigned(27 downto 0);
+  signal 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 pulser_trigger_period_r   : unsigned(27 downto 0);
 
   -- Reset
-  signal RESET_NX_MAIN_CLK_IN    : std_logic;
+  signal RESET_NX_MAIN_CLK_IN      : std_logic;
 
-  signal new_data_frame_debug    : std_logic;
-  
 begin
   -- Debug Line
-  DEBUG_OUT(0)            <= CLK_IN;
-  DEBUG_OUT(1)            <= NX_MAIN_CLK_IN;
-  DEBUG_OUT(2)            <= self_trigger;
-  DEBUG_OUT(3)            <= self_trigger_o;
-  DEBUG_OUT(4)            <= self_trigger_busy;
-  DEBUG_OUT(5)            <= TRIGGER_BUSY_IN;
-  DEBUG_OUT(6)            <= DATA_CLK_IN;
-  DEBUG_OUT(7)            <= new_data_frame_debug;
-  DEBUG_OUT(15 downto 8 ) <= (others => '0');
+  DEBUG_OUT(0)             <= CLK_IN;
+  DEBUG_OUT(1)             <= NX_MAIN_CLK_IN;
+  DEBUG_OUT(2)             <= DATA_CLK_IN;
+  DEBUG_OUT(3)             <= TRIGGER_BUSY_IN;
+  
+  DEBUG_OUT(4)             <= self_trigger_on;
+  DEBUG_OUT(5)             <= self_trigger;
+
+  DEBUG_OUT(6)             <= pulser_trigger_on;
+  DEBUG_OUT(7)             <= pulser_trigger;
 
+  DEBUG_OUT(8)             <= external_trigger_busy;
+  DEBUG_OUT(9)             <= external_trigger;
+                           
+  DEBUG_OUT(10)            <= internal_trigger_o;
+  DEBUG_OUT(11)            <= external_trigger_o;
+  DEBUG_OUT(12)            <= trigger_output_select;
+  DEBUG_OUT(13)            <= trigger;
+  DEBUG_OUT(15 downto 14)  <= (others => '0');
+                             
   -----------------------------------------------------------------------------
   -- Reset Domain Transfer
   -----------------------------------------------------------------------------
@@ -82,74 +118,183 @@ begin
     );
   
   -----------------------------------------------------------------------------
-  -- Generate Trigger
+  -- Generate Pulser Trigger
   -----------------------------------------------------------------------------
 
+  timer_PULSER_TRIGGER: timer
+    generic map (
+      CTR_WIDTH => 28
+      )
+    port map (
+      CLK_IN         => CLK_IN,
+      RESET_IN       => RESET_IN,
+      TIMER_START_IN => pulser_trigger_on,
+      TIMER_END_IN   => pulser_trigger_period,
+
+      TIMER_DONE_OUT => pulser_trigger
+      );
+
+  pulser_trigger_period <= (pulser_trigger_period_r - 1)
+                           when pulser_trigger_period_r > 10
+                           else x"0000009";
+
   -----------------------------------------------------------------------------
   -- Self Trigger
   -----------------------------------------------------------------------------
-
+  
   PROC_SELF_TRIGGER: process(CLK_IN)
     variable frame_bits : std_logic_vector(3 downto 0);
   begin
     if( rising_edge(CLK_IN) ) then
+      data_i_f      <= DATA_IN;
+      data_i        <= data_i_f;
+      data_clk_i_f  <= DATA_CLK_IN;
+      data_clk_i    <= data_clk_i_f;
+                       
       if( RESET_IN = '1' ) then
-        self_trigger_ctr   <= (others => '0');
-        self_trigger_busy  <= '0';
         self_trigger       <= '0';
       else
-        frame_bits      := DATA_IN(31) &
-                           DATA_IN(23) &
-                           DATA_IN(15) &
-                           DATA_IN(7);
-        self_trigger            <= '0';
-        self_trigger_busy       <= '0';
-
-        if (DATA_CLK_IN     = '1' and
+        frame_bits      := data_i(31) &
+                           data_i(23) &
+                           data_i(15) &
+                           data_i(7);
+        self_trigger       <= '0';
+
+        if (self_trigger_on = '1' and
+            data_clk_i      = '1' and
             frame_bits      = "1000") then
-          new_data_frame_debug  <= '1';
+          self_trigger     <= '1';
         else
-          new_data_frame_debug  <= '0';
+          self_trigger     <= '0';
         end if;
-        
-        case ST_STATE is
-          when ST_IDLE =>
+      end if;
+    end if;
+  end process PROC_SELF_TRIGGER;
+
+  -----------------------------------------------------------------------------
+  -- Trigger Output Handler
+  -----------------------------------------------------------------------------
+
+  PROC_TRIGGER_OUTPUTS: process (CLK_IN)
+    variable trigger_signals : std_logic;
+  begin 
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        external_trigger_i     <= '0';
+        internal_trigger_o     <= '0';
+      else
+        trigger_signals        := self_trigger or pulser_trigger;
+
+        if (trigger_output_select = '0') then
+          external_trigger_i   <= trigger_signals;
+        else
+          internal_trigger_o   <= trigger_signals;
+        end if;
+
+        -- For Rate Counter
+        trigger                <= external_trigger or internal_trigger_o;
+      end if;
+    end if;
+  end process PROC_TRIGGER_OUTPUTS;
+
+  PROC_EXTERN_TRIGGER_OUT: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        external_trigger_ctr    <= (others => '0');
+        external_trigger_busy   <= '0';
+        external_trigger        <= '0';
+      else
+        external_trigger             <= '0';
+        external_trigger_busy        <= '0';
+
+        case S_STATE is
+          when S_IDLE =>
             if (TRIGGER_BUSY_IN = '0' and
-                DATA_CLK_IN     = '1' and
-                frame_bits      = "1000") then
-              self_trigger_ctr  <= "10100";  -- 20
-              self_trigger      <= '1';
-              ST_STATE          <= ST_BUSY;
+                external_trigger_i = '1') then
+              external_trigger_ctr   <= "10100";  -- 20
+              external_trigger       <= '1';
+              S_STATE                <= S_BUSY;
             else
-              self_trigger_ctr  <= (others => '0');
-              ST_STATE          <= ST_IDLE;
+              external_trigger_ctr   <= (others => '0');
+              S_STATE                <= S_IDLE;
             end if;
             
-          when ST_BUSY =>
-            if (self_trigger_ctr > 0) then
-              self_trigger_ctr  <= self_trigger_ctr  - 1;
-              self_trigger_busy <= '1';
-              ST_STATE          <= ST_BUSY;
+          when S_BUSY =>
+            if (external_trigger_ctr > 0) then
+              external_trigger_ctr   <= external_trigger_ctr  - 1;
+              external_trigger_busy  <= '1';
+              S_STATE                <= S_BUSY;
             else
-              ST_STATE          <= ST_IDLE;
+              S_STATE                <= S_IDLE;
             end if;
         end case;
         
       end if;
     end if;
-  end process PROC_SELF_TRIGGER;
-
-  pulse_to_level_SELF_TRIGGER: pulse_to_level
+  end process PROC_EXTERN_TRIGGER_OUT;
+  
+  -- Goes to CTS
+  pulse_to_level_EXTERNAL_TRIGGER: pulse_to_level
     generic map (
       NUM_CYCLES => 8
       )
     port map (
       CLK_IN    => CLK_IN,
       RESET_IN  => RESET_IN,
-      PULSE_IN  => self_trigger,
-      LEVEL_OUT => self_trigger_o
+      PULSE_IN  => external_trigger,
+      LEVEL_OUT => external_trigger_o
       );
-    
+  
+  -----------------------------------------------------------------------------
+  --  Rate Counter
+  -----------------------------------------------------------------------------
+  PROC_CAL_RATES: process (CLK_IN)
+  begin 
+    if( rising_edge(CLK_IN) ) then
+      if (RESET_IN = '1') then
+        self_trigger_rate_t        <= (others => '0');
+        self_trigger_rate          <= (others => '0');
+        pulser_trigger_rate_t      <= (others => '0');
+        pulser_trigger_rate        <= (others => '0');
+        trigger_rate_t             <= (others => '0');
+        trigger_rate               <= (others => '0');
+        rate_timer                 <= (others => '0');
+      else
+        if (rate_timer < x"5f5e100") then
+          if (self_trigger = '1') then
+            self_trigger_rate_t     <= self_trigger_rate_t + 1;
+          end if;
+
+          if (pulser_trigger = '1') then
+            pulser_trigger_rate_t   <= pulser_trigger_rate_t + 1;
+          end if;
+
+          if (trigger = '1') then
+            trigger_rate_t          <= trigger_rate_t + 1;
+          end if;
+
+          rate_timer                <= rate_timer + 1;
+        else
+          self_trigger_rate_t(27 downto 1)    <= (others => '0');
+          self_trigger_rate_t(0)              <= '0';
+            
+          pulser_trigger_rate_t(27 downto 1)  <= (others => '0');
+          pulser_trigger_rate_t(0)            <= pulser_trigger;
+
+          trigger_rate_t(27 downto 1)         <= (others => '0');
+          trigger_rate_t(0)                   <= trigger;
+        
+          self_trigger_rate                   <= self_trigger_rate_t;
+          pulser_trigger_rate                 <= pulser_trigger_rate_t;
+          trigger_rate                        <= trigger_rate_t;
+
+          rate_timer                          <= (others => '0');
+        end if;
+      end if;
+    end if;
+  end process PROC_CAL_RATES;
+  
   -----------------------------------------------------------------------------
   -- TRBNet Slave Bus
   -----------------------------------------------------------------------------
@@ -158,33 +303,80 @@ begin
   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';
+        slv_data_out_o             <= (others => '0');
+        slv_no_more_data_o         <= '0';
+        slv_unknown_addr_o         <= '0';
+        slv_ack_o                  <= '0';
+        trigger_output_select      <= '0';
+        self_trigger_on            <= '1';
+        pulser_trigger_on          <= '0';
+        pulser_trigger_period_r    <= x"00186a0";
       else
         slv_unknown_addr_o       <= '0';
         slv_no_more_data_o       <= '0';
         slv_data_out_o           <= (others => '0');
-
+        
         if (SLV_WRITE_IN  = '1') then
           case SLV_ADDR_IN is
+            
+            when x"0000" =>
+              self_trigger_on               <= SLV_DATA_IN(0);
+              pulser_trigger_on             <= SLV_DATA_IN(1);
+              trigger_output_select         <= SLV_DATA_IN(2);
+              slv_ack_o                     <= '1';
 
+            when x"0001" =>
+              pulser_trigger_period_r       <=
+                unsigned(SLV_DATA_IN(27 downto 0));
+              slv_ack_o                     <= '1';
+                
             when others =>
-              slv_unknown_addr_o           <= '1';
-              slv_ack_o                    <= '0';
+              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(0)             <= self_trigger_on;
+              slv_data_out_o(1)             <= pulser_trigger_on;
+              slv_data_out_o(2)             <= trigger_output_select;
+              slv_data_out_o(31 downto 3)   <= (others => '0');
+              slv_ack_o                     <= '1';
+           
+            when x"0001" =>
+              slv_data_out_o(27 downto 0)   <=
+                std_logic_vector(pulser_trigger_period_r);
+              slv_data_out_o(31 downto 28)  <= (others => '0');
+              slv_ack_o                     <= '1';
+            
+            when x"0002" =>
+              slv_data_out_o(27 downto 0)   <=
+                std_logic_vector(self_trigger_rate);
+              slv_data_out_o(31 downto 28)  <= (others => '0');
+              slv_ack_o                     <= '1';
+
+            when x"0003" =>
+              slv_data_out_o(27 downto 0)   <=
+                std_logic_vector(pulser_trigger_rate);
+              slv_data_out_o(31 downto 28)  <= (others => '0');
+              slv_ack_o                     <= '1';
+
+            when x"0004" =>
+              slv_data_out_o(27 downto 0)   <=
+                std_logic_vector(trigger_rate);
+              slv_data_out_o(31 downto 28)  <= (others => '0');
+              slv_ack_o                     <= '1';
+
             when others =>
-              slv_unknown_addr_o           <= '1';
-              slv_ack_o                    <= '0';
+              slv_unknown_addr_o            <= '1';
+              slv_ack_o                     <= '0';
           end case;
 
         else
-          slv_ack_o                        <= '0';
+          slv_ack_o                         <= '0';
         end if;
       end if;
     end if;           
@@ -195,8 +387,8 @@ begin
   -----------------------------------------------------------------------------
 
   -- Trigger Output
-  TRIGGER_OUT              <= '0';
-  SELF_TRIGGER_OUT         <= self_trigger_o;
+  EXTERNAL_TRIGGER_OUT     <= external_trigger_o;
+  INTERNAL_TRIGGER_OUT     <= internal_trigger_o;
                            
   -- Slave Bus             
   SLV_DATA_OUT             <= slv_data_out_o;    
index e99744ba816c5a44af7c3bf95cadc0501b331805..9d6ed5c5dbaf7552c32352c0433f711a485d5608 100644 (file)
@@ -85,6 +85,9 @@ architecture Behavioral of nx_trigger_handler is
   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);
 
@@ -114,6 +117,7 @@ architecture Behavioral of nx_trigger_handler is
   signal fee_trg_release_o          : std_logic;
   signal fee_trg_statusbits_o       : std_logic_vector(31 downto 0);
   signal send_testpulse             : std_logic;
+  
   signal testpulse_enable           : std_logic;
   
   type STATES is (S_IDLE,
@@ -155,6 +159,9 @@ architecture Behavioral of nx_trigger_handler is
   signal wait_timer_end              : unsigned(11 downto 0);
   
   -- Rate Calculation
+  signal send_testpulse_ff           : std_logic;
+  signal send_testpulse_f            : std_logic;
+  
   signal accepted_trigger_rate_t     : unsigned(27 downto 0);
   signal testpulse_o_clk100          : std_logic;
   signal testpulse_rate_t            : unsigned(27 downto 0);
@@ -364,7 +371,12 @@ begin
       PULSE_A_IN => fast_clear_o,
       PULSE_OUT  => fast_clear
       );
-  
+
+  -- Relax Timing 
+  invalid_timing_trigger_ff  <=
+    invalid_timing_trigger_n when rising_edge(NX_MAIN_CLK_IN);
+  invalid_timing_trigger_f   <=
+    invalid_timing_trigger_ff when rising_edge(NX_MAIN_CLK_IN);
   pulse_dtrans_INVALID_TIMING_TRIGGER: pulse_dtrans
     generic map (
       CLK_RATIO => 4
@@ -372,7 +384,7 @@ begin
     port map (
       CLK_A_IN    => NX_MAIN_CLK_IN,
       RESET_A_IN  => RESET_NX_MAIN_CLK_IN,
-      PULSE_A_IN  => invalid_timing_trigger_n,
+      PULSE_A_IN  => invalid_timing_trigger_f,
       CLK_B_IN    => CLK_IN,
       RESET_B_IN  => RESET_IN,
       PULSE_B_OUT => invalid_timing_trigger
@@ -594,6 +606,9 @@ begin
     end if;
   end process PROC_TESTPULSE_HANDLER; 
 
+  -- Relax Timing 
+  send_testpulse_ff <= send_testpulse    when rising_edge(NX_MAIN_CLK_IN);
+  send_testpulse_f  <= send_testpulse_ff when rising_edge(NX_MAIN_CLK_IN);
   pulse_dtrans_TESTPULSE_RATE: pulse_dtrans
     generic map (
       CLK_RATIO => 2
@@ -601,7 +616,7 @@ begin
     port map (
       CLK_A_IN    => NX_MAIN_CLK_IN,
       RESET_A_IN  => RESET_NX_MAIN_CLK_IN,
-      PULSE_A_IN  => testpulse_o,
+      PULSE_A_IN  => send_testpulse_f,
       CLK_B_IN    => CLK_IN,
       RESET_B_IN  => RESET_IN,
       PULSE_B_OUT => testpulse_o_clk100
index b18778e839584407995aa7157202bc28111d7508..7f6a5e05ba7572b31134951ea39e7aa4db8d338e 100644 (file)
@@ -165,7 +165,8 @@ architecture Behavioral of nx_trigger_validate is
   signal wait_timer_done       : std_logic;
   signal wait_timer_done_ns    : std_logic;
                                
-  -- Histogram                 
+  -- Histogram
+  signal histogram_trigger_all : std_logic;
   signal histogram_fill_o      : std_logic;
   signal histogram_bin_o       : std_logic_vector(6 downto 0);
   signal histogram_adc_o       : std_logic_vector(11 downto 0);
@@ -185,7 +186,8 @@ architecture Behavioral of nx_trigger_validate is
   signal slv_unknown_addr_o    : std_logic;
   signal slv_ack_o             : std_logic;
                                
-  signal readout_mode_r        : std_logic_vector(3 downto 0);
+  signal readout_mode_r           : std_logic_vector(3 downto 0);
+  signal histogram_trigger_all_r  : std_logic;
   signal out_of_window_error_ctr_clear : std_logic;
   
   -- Timestamp Trigger Window Settings
@@ -277,12 +279,13 @@ begin
         out_of_window_error     <= '0';
         fifo_delay_time         <= (others => '0');
         ch_status_cmd_pr        <= CS_NONE;
-
+        
         histogram_fill_o        <= '0';
         histogram_bin_o         <= (others => '0');
         histogram_adc_o         <= (others => '0');
         histogram_pileup_o      <= '0';
         histogram_ovfl_o        <= '0';
+        histogram_trigger_all   <= histogram_trigger_all_r;
         
         -----------------------------------------------------------------------
         -- Calculate Thresholds and values for FIFO Delay
@@ -408,6 +411,16 @@ begin
                   end if;
 
               end case;
+
+              -- Fill Histogram
+              if (histogram_trigger_all = '0') then
+                histogram_fill_o               <= '1';
+                histogram_bin_o                <= CHANNEL_IN;
+                histogram_adc_o                <= ADC_DATA_IN;
+                histogram_pileup_o             <= TIMESTAMP_STATUS_IN(S_PILEUP);
+                histogram_ovfl_o               <= TIMESTAMP_STATUS_IN(S_OVFL);
+              end if;
+          
             end if;
 
             if (out_of_window_error_ctr_clear = '1') then
@@ -416,12 +429,14 @@ begin
           end if;
 
           -- Fill Histogram
-          histogram_fill_o                   <= '1';
-          histogram_bin_o                    <= CHANNEL_IN;
-          histogram_adc_o                    <= ADC_DATA_IN;
-          histogram_pileup_o                 <= TIMESTAMP_STATUS_IN(S_PILEUP);
-          histogram_ovfl_o                   <= TIMESTAMP_STATUS_IN(S_OVFL);
-
+          if (histogram_trigger_all = '1') then
+            histogram_fill_o                   <= '1';
+            histogram_bin_o                    <= CHANNEL_IN;
+            histogram_adc_o                    <= ADC_DATA_IN;
+            histogram_pileup_o                 <= TIMESTAMP_STATUS_IN(S_PILEUP);
+            histogram_ovfl_o                   <= TIMESTAMP_STATUS_IN(S_OVFL);
+          end if;
+          
         end if;
       end if;
     end if;
@@ -844,7 +859,6 @@ begin
 
   -- Give status info to the TRB Slow Control Channel
   PROC_SLAVE_BUS: process(CLK_IN)
-
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
@@ -858,6 +872,7 @@ begin
         cts_trigger_delay             <= x"0c8";
         readout_mode_r                <= "0000";
         readout_time_max              <= x"3e8";
+        histogram_trigger_all_r       <= '1';
         fpga_timestamp_offset         <= (others => '0');
         out_of_window_error_ctr_clear <= '0';
         skip_wait_for_data            <= '0';
@@ -875,7 +890,8 @@ begin
           case SLV_ADDR_IN is
             when x"0000" =>
               slv_data_out_o( 3 downto  0)    <= readout_mode_r;
-              slv_data_out_o(31 downto  5)    <= (others => '0');
+              slv_data_out_o(30 downto  5)    <= (others => '0');
+              slv_data_out_o(31)              <= histogram_trigger_all_r;
               slv_ack_o                       <= '1';
 
             when x"0001" =>
@@ -1066,6 +1082,7 @@ begin
           case SLV_ADDR_IN is
             when x"0000" =>
               readout_mode_r                  <= SLV_DATA_IN(3 downto 0);
+              histogram_trigger_all_r         <= SLV_DATA_IN(31); 
               slv_ack_o                       <= '1';
                                               
             when x"0001" =>
index 93be57dfc3ca0851a621cac9e310cbb6c40d3918..5b022213ab9051aa8c8c0191c2746e9dccf5ca2e 100644 (file)
@@ -920,10 +920,10 @@ component nx_trigger_generator
     RESET_IN             : in  std_logic;
     NX_MAIN_CLK_IN       : in  std_logic;
     TRIGGER_BUSY_IN      : in  std_logic;
-    TRIGGER_OUT          : out std_logic;
+    EXTERNAL_TRIGGER_OUT : out std_logic;
+    INTERNAL_TRIGGER_OUT : out std_logic;
     DATA_IN              : in  std_logic_vector(43 downto 0);
     DATA_CLK_IN          : in  std_logic;
-    SELF_TRIGGER_OUT     : out std_logic;
     SLV_READ_IN          : in  std_logic;
     SLV_WRITE_IN         : in  std_logic;
     SLV_DATA_OUT         : out std_logic_vector(31 downto 0);
index 6500021db6c05c546abeae6b917dccf66c7a7388..2234176574f8077b2ec781a8d0661509fe37dd4e 100644 (file)
@@ -139,7 +139,6 @@ architecture Behavioral of nXyter_FEE_board is
   -- Data Receiver
   signal data_recv              : std_logic_vector(43 downto 0);
   signal data_clk_recv          : std_logic;
-  signal self_trigger           : std_logic;
   signal pll_sadc_clk_lock      : std_logic;
   
   -- Data Delay                 
@@ -205,8 +204,8 @@ architecture Behavioral of nXyter_FEE_board is
   signal timestamp_hold         : unsigned(11 downto 0);
   
   -- Trigger Generator
-  signal trigger_intern         : std_logic;
-
+  signal internal_trigger       : std_logic;
+  
   -- Error
   signal error_all              : std_logic_vector(7 downto 0);
   signal error_data_receiver    : std_logic;
@@ -438,7 +437,7 @@ begin
       CLK_IN                   => CLK_IN,
       RESET_IN                 => RESET_IN,
       NX_MAIN_CLK_IN           => CLK_NX_MAIN_IN,
-      TIMESTAMP_RESET_1_IN     => nx_timestamp_reset_status,
+      TIMESTAMP_RESET_1_IN     => '0', --nx_timestamp_reset_status,
       TIMESTAMP_RESET_2_IN     => nx_timestamp_reset_receiver,
       TIMESTAMP_RESET_OUT      => nx_timestamp_reset_o, 
       TRIGGER_IN               => timestamp_trigger,
@@ -488,7 +487,7 @@ begin
       FEE_DATA_WRITE_0_IN        => fee_data_write_o_0,
       FEE_DATA_1_IN              => fee_data_o_1,
       FEE_DATA_WRITE_1_IN        => fee_data_write_o_1,
-      INTERNAL_TRIGGER_IN        => trigger_intern,
+      INTERNAL_TRIGGER_IN        => '0', --internal_trigger,
 
       TRIGGER_VALIDATE_BUSY_IN   => trigger_validate_busy,
       TRIGGER_BUSY_0_IN          => trigger_evt_busy_0,
@@ -526,11 +525,11 @@ begin
       NX_MAIN_CLK_IN       => CLK_NX_MAIN_IN,
 
       TRIGGER_BUSY_IN      => trigger_busy,
-      TRIGGER_OUT          => trigger_intern,
-
+      EXTERNAL_TRIGGER_OUT => TRIGGER_OUT,
+      INTERNAL_TRIGGER_OUT => internal_trigger,
+      
       DATA_IN              => data_recv,
       DATA_CLK_IN          => data_clk_recv,
-      SELF_TRIGGER_OUT     => self_trigger,
       
       SLV_READ_IN          => slv_read(5),
       SLV_WRITE_IN         => slv_write(5),
@@ -800,7 +799,6 @@ begin
 -------------------------------------------------------------------------------
 -- Others
 -------------------------------------------------------------------------------
-  TRIGGER_OUT              <= self_trigger;
                               
 -------------------------------------------------------------------------------
 -- DEBUG Line Select
index 0ceebf749d1002df2e25a6a56b8e4fe76fc76f64..76de64814128f3c578aedb7387bc912ef70c900e 100644 (file)
@@ -100,9 +100,9 @@ MULTICYCLE TO   CELL "nXyter_FEE_board_*/nx_data_receiver_*/new_timestamp_dt_err
 MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_clk_ok"                                   100 ns;
 MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_debug_type*"                              100 ns;
 MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/nx_timestamp_reset_o*"                        100 ns;
-MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_notlock_ctr_r*                            100 ns;
-MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/merge_error_ctr_*"                            100 ns;
-MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/reg_nx_frame_synced*"                         100 ns;
+MULTICYCLE TO   CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_notlock_ctr_r*"                           100 ns;
+MULTICYCLE TO   CELL "nXyter_FEE_board_*/nx_data_receiver_*/merge_error_ctr_r*"                           100 ns;
+MULTICYCLE TO   CELL "nXyter_FEE_board_*/nx_data_receiver_*/nx_frame_synced_r*"                           100 ns;
 
 MULTICYCLE FROM CELL "nXyter_FEE_board_*/debug_multiplexer_*/port_select_*"                               100 ns;
 #SPI Interface