source: firmware/FTM/trigger/kernel/trigger_generator/trigger_generator.vhd

Last change on this file was 10418, checked in by weitzel, 14 years ago
New FTM firmare: dna, fad_broadcast, FTU error messages, rates readout
File size: 18.2 KB
Line 
1--=======================================================================================
2-- TITLE : Trigger generator
3-- DESCRIPTION : Generates triggers from events, calibration pulses or external inputs
4-- FILE : trigger_generator.vhd
5-- COMPANY : Micro-Cameras & Space Exploration SA
6--=======================================================================================
7-- CREATION
8-- DATE AUTHOR PROJECT REVISION
9-- 14/03/2011 JGi 110314a
10--=======================================================================================
11-- MODIFICATION HISTORY
12-- DATE AUTHOR PROJECT REVISION COMMENTS
13-- 14/03/2011 JGi 110314a Description
14-- 13/04/2011 JGi 110413a Update trigger enable management
15-- 15/04/2011 JGi 110415a Update LP1 "N-out-of-40" logic detection
16-- in order to allow user to reset it by
17-- disabling LP1 pulse as trigger source if the
18-- N is never reached and system is locked
19--=======================================================================================
20-- Library Definition
21library ieee;
22 use ieee.std_logic_1164.all;
23 use ieee.numeric_std.all;
24
25library ftm_definitions;
26 use ftm_definitions.ftm_array_types.all;
27 use ftm_definitions.ftm_constants.all;
28
29-- Entity Definition
30entity trigger_generator is
31 port( --clock
32 clk_250MHz : in std_logic;
33 --config inputs
34 start_run : in std_logic;
35 stop_run : in std_logic;
36 general_settings : in std_logic_vector(7 downto 0);
37 maj_coinc_n_phys : in std_logic_vector(5 downto 0);
38 maj_coinc_n_calib : in std_logic_vector(5 downto 0);
39 trigger_delay : in std_logic_vector(9 downto 0);
40 TIM_delay : in std_logic_vector(9 downto 0);
41 dead_time : in std_logic_vector(15 downto 0);
42 --trigger inputs
43 ext_trig_1 : in std_logic;
44 ext_trig_2 : in std_logic;
45 ext_veto : in std_logic;
46 FAD_busy_0 : in std_logic;
47 FAD_busy_1 : in std_logic;
48 FAD_busy_2 : in std_logic;
49 FAD_busy_3 : in std_logic;
50 phys_events : in std_logic_vector(5 downto 0);
51 calib_events : in std_logic_vector(5 downto 0);
52 LP1_pulse : in std_logic;
53 LP2_pulse : in std_logic;
54 PED_pulse : in std_logic;
55 --outputs
56 trigger_ID_done : out std_logic;
57 trigger_ID : out std_logic_vector(55 downto 0);
58 trigger_active : out std_logic;
59 trigger_signal : out std_logic;
60 TIM_signal : out std_logic);
61end trigger_generator;
62
63-- Architecture Definition
64architecture RTL of trigger_generator is
65
66 component deadtime_generator is
67 port( clk_250MHz : in std_logic;
68 deadtime : in std_logic_vector(15 downto 0);
69 start : in std_logic;
70 waiting : out std_logic);
71 end component;
72
73 signal i_deadtime : std_logic;
74
75 component delayed_pulse is
76 generic( pulse_width : integer range 0 to 15);
77 port( clk_250MHz : in std_logic;
78 delay : in std_logic_vector(9 downto 0);
79 input : in std_logic;
80 output : out std_logic);
81 end component;
82
83 signal i_trigger_signal : std_logic;
84 signal i_TIM_signal : std_logic;
85
86 component trigger_ID_count is
87 port( clk_250MHz : in std_logic;
88 start_run : in std_logic;
89 stop_run : in std_logic;
90 maj_coinc_n_phys : in std_logic_vector(5 downto 0);
91 maj_coinc_n_calib : in std_logic_vector(5 downto 0);
92 trigger : in std_logic_vector(8 downto 0);
93 phys_trigger : in std_logic;
94 calib_trigger : in std_logic;
95 internal_trigger : in std_logic_vector(1 downto 0);
96 external_trigger : in std_logic_vector(1 downto 0);
97 trigger_ID_done : out std_logic;
98 trigger_ID : out std_logic_vector(55 downto 0));
99 end component;
100
101 type t_reg is record
102 -- Internal register declaration
103 start_run : std_logic;
104 LP1_delay : std_logic_vector(2 downto 0);
105 LP2_delay : std_logic_vector(2 downto 0);
106 PED_delay : std_logic_vector(2 downto 0);
107 ext_trig_1 : std_logic_vector(2 downto 0);
108 ext_trig_2 : std_logic_vector(2 downto 0);
109 ext_veto : std_logic_vector(1 downto 0);
110 FAD_busy_0 : std_logic_vector(1 downto 0);
111 FAD_busy_1 : std_logic_vector(1 downto 0);
112 FAD_busy_2 : std_logic_vector(1 downto 0);
113 FAD_busy_3 : std_logic_vector(1 downto 0);
114 general_settings : std_logic_vector(7 downto 0);
115 maj_coinc_n_phys : std_logic_vector(5 downto 0);
116 maj_coinc_n_calib : std_logic_vector(5 downto 0);
117 enable_trigger : std_logic;
118 phys_compare : std_logic_vector(1 downto 0);
119 phys_trigger : std_logic;
120 ext_trigger : std_logic_vector(1 downto 0);
121 calib_compare : std_logic_vector(1 downto 0);
122 calib_trigger : std_logic;
123 wait_for_calib : std_logic;
124 internal_trigger : std_logic_vector(1 downto 0);
125 trigger : std_logic_vector(12 downto 0);
126 trigger_active : std_logic;
127 -- Ouput register declaration
128 end record;
129
130 signal i_next_reg : t_reg := (start_run => '0',
131 LP1_delay => (others => '0'),
132 LP2_delay => (others => '0'),
133 PED_delay => (others => '0'),
134 ext_trig_1 => (others => '0'),
135 ext_trig_2 => (others => '0'),
136 ext_veto => (others => '0'),
137 FAD_busy_0 => (others => '0'),
138 FAD_busy_1 => (others => '0'),
139 FAD_busy_2 => (others => '0'),
140 FAD_busy_3 => (others => '0'),
141 general_settings => (others => '0'),
142 maj_coinc_n_phys => (others => '1'),
143 maj_coinc_n_calib => (others => '1'),
144 enable_trigger => '0',
145 phys_compare => (others => '0'),
146 phys_trigger => '0',
147 ext_trigger => (others => '0'),
148 calib_compare => (others => '0'),
149 calib_trigger => '0',
150 wait_for_calib => '0',
151 internal_trigger => (others => '0'),
152 trigger => (others => '0'),
153 trigger_active => '1');
154 signal i_reg : t_reg := (start_run => '0',
155 LP1_delay => (others => '0'),
156 LP2_delay => (others => '0'),
157 PED_delay => (others => '0'),
158 ext_trig_1 => (others => '0'),
159 ext_trig_2 => (others => '0'),
160 ext_veto => (others => '0'),
161 FAD_busy_0 => (others => '0'),
162 FAD_busy_1 => (others => '0'),
163 FAD_busy_2 => (others => '0'),
164 FAD_busy_3 => (others => '0'),
165 general_settings => (others => '0'),
166 maj_coinc_n_phys => (others => '1'),
167 maj_coinc_n_calib => (others => '1'),
168 enable_trigger => '0',
169 phys_compare => (others => '0'),
170 phys_trigger => '0',
171 ext_trigger => (others => '0'),
172 calib_compare => (others => '0'),
173 calib_trigger => '0',
174 wait_for_calib => '0',
175 internal_trigger => (others => '0'),
176 trigger => (others => '0'),
177 trigger_active => '1');
178
179begin
180
181 -- Component instantiation
182 inst_deadtime: deadtime_generator
183 port map( clk_250MHz => clk_250MHz,
184 deadtime => dead_time,
185 start => i_reg.trigger(0),
186 waiting => i_deadtime);
187
188 inst_phys_trig: delayed_pulse
189 generic map( pulse_width => TRIG_SIGNAL_PULSE_WIDTH)
190 port map( clk_250MHz => clk_250MHz,
191 delay => trigger_delay,
192 input => i_reg.trigger(1),
193 output => i_trigger_signal);
194
195 trigger_signal <= i_trigger_signal and i_reg.start_run;
196
197 inst_phys_TIM: delayed_pulse
198 generic map( pulse_width => TIM_SIGNAL_PULSE_WIDTH)
199 port map( clk_250MHz => clk_250MHz,
200 delay => TIM_delay,
201 input => i_reg.trigger(2),
202 output => i_TIM_signal);
203
204 TIM_signal <= i_TIM_signal and i_reg.start_run;
205
206 inst_trig_ID: trigger_ID_count
207 port map( clk_250MHz => clk_250MHz,
208 start_run => start_run,
209 stop_run => stop_run,
210 maj_coinc_n_phys => maj_coinc_n_phys,
211 maj_coinc_n_calib => maj_coinc_n_calib,
212 trigger => i_reg.trigger(12 downto 4),
213 phys_trigger => i_reg.phys_trigger,
214 calib_trigger => i_reg.calib_trigger,
215 internal_trigger => i_reg.internal_trigger,
216 external_trigger => i_reg.ext_trigger,
217 trigger_ID_done => trigger_ID_done,
218 trigger_ID => trigger_ID);
219
220 -- Combinatorial logic
221 process(start_run, general_settings, maj_coinc_n_phys, maj_coinc_n_calib,
222 ext_trig_1, ext_trig_2, ext_veto, FAD_busy_0, FAD_busy_1, FAD_busy_2,
223 FAD_busy_3, phys_events, calib_events, LP1_pulse, LP2_pulse, PED_pulse,
224 i_deadtime, i_reg)
225 variable v_reg : t_reg := (start_run => '0',
226 LP1_delay => (others => '0'),
227 LP2_delay => (others => '0'),
228 PED_delay => (others => '0'),
229 ext_trig_1 => (others => '0'),
230 ext_trig_2 => (others => '0'),
231 ext_veto => (others => '0'),
232 FAD_busy_0 => (others => '0'),
233 FAD_busy_1 => (others => '0'),
234 FAD_busy_2 => (others => '0'),
235 FAD_busy_3 => (others => '0'),
236 general_settings => (others => '0'),
237 maj_coinc_n_phys => (others => '1'),
238 maj_coinc_n_calib => (others => '1'),
239 enable_trigger => '0',
240 phys_compare => (others => '0'),
241 phys_trigger => '0',
242 ext_trigger => (others => '0'),
243 calib_compare => (others => '0'),
244 calib_trigger => '0',
245 wait_for_calib => '0',
246 internal_trigger => (others => '0'),
247 trigger => (others => '0'),
248 trigger_active => '1');
249 begin
250 v_reg := i_reg;
251 --===================================================================================
252
253 --===================================================================================
254 -- External inputs double-sync
255 --===================================================================================
256 v_reg.ext_trig_1(0) := ext_trig_1;
257 v_reg.ext_trig_1(1) := i_reg.ext_trig_1(0);
258 v_reg.ext_trig_1(2) := i_reg.ext_trig_1(1);
259 v_reg.ext_trig_2(0) := ext_trig_2;
260 v_reg.ext_trig_2(1) := i_reg.ext_trig_2(0);
261 v_reg.ext_trig_2(2) := i_reg.ext_trig_2(1);
262 v_reg.ext_veto(0) := ext_veto;
263 v_reg.ext_veto(1) := i_reg.ext_veto(0);
264 v_reg.FAD_busy_0(0) := FAD_busy_0;
265 v_reg.FAD_busy_0(1) := i_reg.FAD_busy_0(0);
266 v_reg.FAD_busy_1(0) := FAD_busy_1;
267 v_reg.FAD_busy_1(1) := i_reg.FAD_busy_1(0);
268 v_reg.FAD_busy_2(0) := FAD_busy_2;
269 v_reg.FAD_busy_2(1) := i_reg.FAD_busy_2(0);
270 v_reg.FAD_busy_3(0) := FAD_busy_3;
271 v_reg.FAD_busy_3(1) := i_reg.FAD_busy_3(0);
272 --===================================================================================
273
274 --===================================================================================
275 -- Re-sync of calibration and pedestal triggers to the 250MHz clock
276 --===================================================================================
277 v_reg.LP1_delay(0) := LP1_pulse;
278 v_reg.LP1_delay(1) := i_reg.LP1_delay(0);
279 v_reg.LP1_delay(2) := i_reg.LP1_delay(1);
280 v_reg.LP2_delay(0) := LP2_pulse;
281 v_reg.LP2_delay(1) := i_reg.LP2_delay(0);
282 v_reg.LP2_delay(2) := i_reg.LP2_delay(1);
283 v_reg.PED_delay(0) := PED_pulse;
284 v_reg.PED_delay(1) := i_reg.PED_delay(0);
285 v_reg.PED_delay(2) := i_reg.PED_delay(1);
286 --===================================================================================
287
288 --===================================================================================
289 -- Settings registration
290 --===================================================================================
291 v_reg.general_settings := general_settings;
292 v_reg.maj_coinc_n_phys := maj_coinc_n_phys;
293 v_reg.maj_coinc_n_calib := maj_coinc_n_calib;
294 --===================================================================================
295
296 --===================================================================================
297 -- Master enable management
298 --===================================================================================
299 v_reg.start_run := start_run;
300 --===================================================================================
301
302 --===================================================================================
303 -- Trigger generation
304 --===================================================================================
305 -- Enable trigger generation only if veto is not active, FAD are not busy and
306 -- deadtime is not enabled
307 if i_reg.trigger(3) = '1' or i_deadtime = '1' or
308 (i_reg.ext_veto(1) = '1' and i_reg.general_settings(1) = '1') or
309 i_reg.FAD_busy_0(1) = '1' or i_reg.FAD_busy_1(1) = '1' or
310 i_reg.FAD_busy_2(1) = '1' or i_reg.FAD_busy_3(1) = '1' then
311 v_reg.enable_trigger := '0';
312 else
313 v_reg.enable_trigger := '1';
314 end if;
315
316 -- Compare number of detected physics event to the physics threshold
317 if phys_events >= i_reg.maj_coinc_n_phys then
318 v_reg.phys_compare(0) := '1';
319 else
320 v_reg.phys_compare(0) := '0';
321 end if;
322 v_reg.phys_compare(1) := i_reg.phys_compare(0);
323
324 -- Activate physics trigger when enabled by settings and physics threhsold is reached
325 if i_reg.general_settings(7) = '1' and i_reg.wait_for_calib = '0' and
326 i_reg.phys_compare(0) = '1' and i_reg.phys_compare(1) = '0' and
327 i_reg.enable_trigger = '1' then
328 v_reg.phys_trigger := '1';
329 else
330 v_reg.phys_trigger := '0';
331 end if;
332
333 -- Lock trigger generator when a pulse on LP1 is detected and wait for FTU events
334 -- counter reach the calibration threshold
335 if i_reg.LP1_delay(1) = '1' and i_reg.LP1_delay(2) = '0' and
336 general_settings(4) = '1' then
337 v_reg.wait_for_calib := '1';
338 -- If trigger is processed or disabled by user, reset detection logic to avoid
339 -- remaining in locked state
340 elsif i_reg.enable_trigger = '0' or general_settings(4) = '0' then
341 v_reg.wait_for_calib := '0';
342 end if;
343
344 -- Compare number of detected physics event to the calibration threshold
345 if calib_events >= i_reg.maj_coinc_n_calib then
346 v_reg.calib_compare(0) := '1';
347 else
348 v_reg.calib_compare(0) := '0';
349 end if;
350 v_reg.calib_compare(1) := i_reg.calib_compare(0);
351
352 -- Activate calibration trigger when enabled by settings and
353 -- calibration threhsold is reached
354 if i_reg.general_settings(4) = '1' and i_reg.wait_for_calib = '1' and
355 i_reg.calib_compare(0) = '1' and i_reg.calib_compare(1) = '0' and
356 i_reg.enable_trigger = '1' then
357 v_reg.calib_trigger := '1';
358 else
359 v_reg.calib_trigger := '0';
360 end if;
361
362 -- Activate trigger number 1 from external NIM inputs
363 if i_reg.ext_trig_1(1) = '1' and i_reg.ext_trig_1(2) = '0' and
364 i_reg.general_settings(2) = '1' and i_reg.wait_for_calib = '0' and
365 i_reg.enable_trigger = '1' then
366 v_reg.ext_trigger(0) := '1';
367 else
368 v_reg.ext_trigger(0) := '0';
369 end if;
370
371 -- Activate trigger number 2 from external NIM inputs
372 if i_reg.ext_trig_2(1) = '1' and i_reg.ext_trig_2(2) = '0' and
373 i_reg.general_settings(3) = '1' and i_reg.wait_for_calib = '0' and
374 i_reg.enable_trigger = '1' then
375 v_reg.ext_trigger(1) := '1';
376 else
377 v_reg.ext_trigger(1) := '0';
378 end if;
379
380 -- Activate calibration trigger from LP2 pulse
381 if i_reg.LP2_delay(1) = '1' and i_reg.LP2_delay(2) = '0' and
382 i_reg.general_settings(5) = '1' and i_reg.wait_for_calib = '0' and
383 i_reg.enable_trigger = '1' then
384 v_reg.internal_trigger(0) := '1';
385 else
386 v_reg.internal_trigger(0) := '0';
387 end if;
388
389 -- Activate calibration trigger from Pedestal signal
390 if i_reg.PED_delay(1) = '1' and i_reg.PED_delay(2) = '0' and
391 i_reg.general_settings(6) = '1' and i_reg.wait_for_calib = '0' and
392 i_reg.enable_trigger = '1' then
393 v_reg.internal_trigger(1) := '1';
394 else
395 v_reg.internal_trigger(1) := '0';
396 end if;
397
398 -- Generate master trigger for deadtime, trigger and TIM signals,
399 -- triggers counting and ID generation
400 -- It is replicated to limit fanout and improve speed
401 v_reg.trigger(0) := i_reg.phys_trigger or i_reg.calib_trigger or
402 i_reg.ext_trigger(0) or i_reg.ext_trigger(1) or
403 i_reg.internal_trigger(0) or i_reg.internal_trigger(1);
404 v_reg.trigger(1) := v_reg.trigger(0);
405 v_reg.trigger(2) := v_reg.trigger(0);
406 v_reg.trigger(3) := v_reg.trigger(0);
407 v_reg.trigger(4) := v_reg.trigger(0);
408 v_reg.trigger(5) := v_reg.trigger(0);
409 v_reg.trigger(6) := v_reg.trigger(0);
410 v_reg.trigger(7) := v_reg.trigger(0);
411 v_reg.trigger(8) := v_reg.trigger(0);
412 v_reg.trigger(9) := v_reg.trigger(0);
413 v_reg.trigger(10) := v_reg.trigger(0);
414 v_reg.trigger(11) := v_reg.trigger(0);
415 v_reg.trigger(12) := v_reg.trigger(0);
416
417 -- Manage trigger active signal
418 -- Set low when a trigger is processed or FAD are busy or veto is active
419 v_reg.trigger_active := i_reg.enable_trigger and not(i_reg.wait_for_calib);
420 --===================================================================================
421
422 --===================================================================================
423 -- Drive register input
424 i_next_reg <= v_reg;
425
426 --===================================================================================
427 -- Output assignation
428 trigger_active <= i_reg.trigger_active;
429 --===================================================================================
430 end process;
431
432 -- Sequential logic
433 process(clk_250MHz)
434 begin
435 if rising_edge(clk_250MHz) then
436 i_reg <= i_next_reg;
437 end if;
438 end process;
439
440end RTL;
Note: See TracBrowser for help on using the repository browser.