eFEX firmware  1.7.3
ATLAS l1-calo - electron and tau feature extraction firmware for eFEX boards

Back to eFEX documentation
efex_tob_processor.vhd
Go to the documentation of this file.
1 
12 
14 library ieee;
15 use ieee.std_logic_1164.all;
16 use ieee.numeric_std.all;
17 
18 LIBRARY infrastructure_lib;
19 use infrastructure_lib.packet_mux_type.all;
20 
23  GENERIC(
24  DEBUG_FORMAT_VERSION : std_logic_vector (2 DOWNTO 0) := "001"
25  );
26  port (
27  clk : in std_logic;
28  rst_clk : in std_logic;
29 -- TTC input signals
30  ttc_info : IN std_logic_vector(49 DOWNTO 0);
31  ttc_valid : IN std_logic;
32 -- Input pFPGA TOB packet
33  input_fifo_empty : IN std_logic;
34  input_tob_data : IN std_logic_vector(63 downto 0);
35  input_tob_valid : IN std_logic;
36  input_tob_last : IN std_logic;
37  input_tob_ready : OUT std_logic;
38 -- Output FIFO signals (0 - TOB merging, 1 - debug)
39  output_fifo_data : OUT packet_data_array(1 downto 0);
40  output_fifo_valid : OUT std_logic_vector(1 downto 0);
41  output_fifo_last : OUT std_logic_vector(1 downto 0);
42  output_fifo_ready : IN std_logic_vector(1 downto 0);
43 -- Status signals
44  TOB_packet_ready : OUT std_logic;
45  TOB_packet_to_merge : OUT std_logic;
46  TOB_packet_missing : OUT std_logic;
47  debug_packet_created : OUT std_logic
48  );
49 end entity efex_tob_processer;
50 
52 Architecture rtl of efex_tob_processer is
53 
54 component efex_packet_merger is
55  generic(NSRC: positive := 4);
56  port (
57  clk : in std_logic;
58  rst_clk : in std_logic;
59  packet_merger_start : in std_logic := '0';
60  packet_merger_enabled : IN std_logic_vector(NSRC-1 downto 0);
61  packet_merger_source : OUT std_logic_vector(2 downto 0);
63  packet_merger_data : IN packet_data_array(NSRC-1 downto 0);
64  packet_merger_valid : IN std_logic_vector(NSRC-1 downto 0);
65  packet_merger_last : IN std_logic_vector(NSRC-1 downto 0);
66  packet_merger_ready : OUT std_logic_vector(NSRC-1 downto 0);
68  packet_data : OUT std_logic_vector (63 DOWNTO 0) ;
69  packet_valid : OUT std_logic;
70  packet_last : OUT std_logic;
71  packet_sub_last : OUT std_logic;
72  packet_ready : IN std_logic
73  );
74 end component efex_packet_merger;
75 
76 COMPONENT SRLC32E is
77  generic(
78  INIT : std_logic_vector(31 downto 0) := (Others => '0')
79  );
80  port(
81  CLK : in std_logic;
82  D : in std_logic;
83  CE : in std_logic;
84  A : in std_logic_vector(4 downto 0);
85  Q : out std_logic;
86  Q31 : out std_logic
87  );
88 end COMPONENT SRLC32E;
89 
90 TYPE STATE_TYPE IS (
91  idle,
92  prepare_l1id,
93  parse_l1id,
94  check_l1id,
95  start_debug_merger,
96  send_debug_header,
97  send_debug,
98  wait_fifo,
99  send_status,
100  skip_payload_header,
101  send_payload,
102  end_event
103 );
104 
105 signal header_sig: std_logic_vector(63 downto 0);
106 signal start_debug_merger_sig, header_valid_sig, header_ready_sig, debug_ready_sig, l1id_correct_sig, event_missing_sig, fifo_delay_start, fifo_delay_end: std_logic;
107 signal state_sig: STATE_TYPE;
108 
109 Begin
110 
111 -- map input onto TOB output when state_sig = send_payload
112 output_fifo_data(0) <= input_tob_data;
113 output_fifo_valid(0) <= input_tob_valid when (state_sig = send_payload) else '0';
114 output_fifo_last(0) <= input_tob_last;
115 
116 ready_mux: with state_sig select
117  input_tob_ready <= debug_ready_sig when send_debug,
118  '1' when skip_payload_header,
119  output_fifo_ready(0) when send_payload,
120  '0' when Others;
121 
122 -- debug packet with extra header
123 Debug_packet_merger : efex_packet_merger
124  GENERIC MAP (
125  NSRC => 2
126  )
127  PORT MAP (
128  clk => clk,
129  rst_clk => rst_clk,
130  packet_merger_start => start_debug_merger_sig,
131  packet_merger_enabled => "11",
132  packet_merger_source => OPEN,
133  packet_merger_data(0) => header_sig,
134  packet_merger_data(1) => input_tob_data,
135  packet_merger_valid(0) => header_valid_sig,
136  packet_merger_valid(1) => input_tob_valid,
137  packet_merger_last(0) => header_valid_sig,
138  packet_merger_last(1) => input_tob_last,
139  packet_merger_ready(0) => header_ready_sig,
140  packet_merger_ready(1) => debug_ready_sig,
141  packet_data => output_fifo_data(1),
142  packet_valid => output_fifo_valid(1),
143  packet_last => output_fifo_last(1),
144  packet_sub_last => OPEN,
145  packet_ready => output_fifo_ready(1)
146  );
147 
148 send_debug_block: process(clk)
149 variable header_valid: std_logic;
150 begin
151  if rising_edge(clk) then
152  if (state_sig = send_debug_header) then
153  header_valid := '1';
154  else
155  header_valid := '0';
156  end if;
157  header_valid_sig <= header_valid
158  -- pragma translate_off
159  after 2 ns
160  -- pragma translate_on
161  ;
162  end if;
163 end process send_debug_block;
164 
165 header_block: process(clk)
166 variable header: std_logic_vector(63 downto 0) := (Others => '1');
167 begin
168  if rising_edge(clk) then
169  if (state_sig = idle) then
170  if (ttc_valid = '1') then
171  header := ttc_info(43 downto 12) & DEBUG_FORMAT_VERSION & "0" & x"00" & ttc_info(11 downto 0) & x"C0"; -- Phase-I
172  else
173  header := (Others => '1');
174  end if;
175  end if;
176  header_sig <= header
177  -- pragma translate_off
178  after 2 ns
179  -- pragma translate_on
180  ;
181  end if;
182 end process header_block;
183 
184 l1id_correct_block: process(clk)
185 variable bcn_match, l1id_match, ecrid_match, l1id_correct: std_logic;
186 begin
187  if rising_edge(clk) then
188  case state_sig is
189  when idle =>
190  l1id_correct := '0';
191  when prepare_l1id =>
192  if (input_tob_valid = '1') then
193  if (header_sig(19 downto 8) = input_tob_data(19 downto 8)) then
194  bcn_match := '1';
195  else
196  bcn_match := '0';
197  end if;
198  if (header_sig(55 downto 32) = input_tob_data(55 downto 32)) then
199  l1id_match := '1';
200  else
201  l1id_match := '0';
202  end if;
203  if (header_sig(63 downto 56) = input_tob_data(63 downto 56)) then
204  ecrid_match := '1';
205  else
206  ecrid_match := '0';
207  end if;
208  else -- no incoming packet...
209  bcn_match := '0';
210  l1id_match := '0';
211  ecrid_match := '0';
212  end if;
213  when parse_l1id =>
214  if (bcn_match = '1') and (l1id_match = '1') and (ecrid_match = '1') then
215  l1id_correct := '1';
216  else
217  l1id_correct := '0';
218  end if;
219  when Others =>
220  end case;
221  l1id_correct_sig <= l1id_correct
222  -- pragma translate_off
223  after 2 ns
224  -- pragma translate_on
225  ;
226  end if;
227 end process l1id_correct_block;
228 
229 event_missing_block: process(clk)
230 variable l1id_future, ecrid_future, ecrid_wraparound, event_missing: std_logic;
231 variable first_strike: std_logic := '1';
232 variable processed_packet: std_logic := '0';
233 begin
234  if rising_edge(clk) then
235  if rst_clk = '1' then
236  event_missing := '0';
237  processed_packet := '0';
238  first_strike := '1';
239  Else
240  case state_sig is
241  when idle =>
242  event_missing := '0';
243  when prepare_l1id =>
244  if (input_tob_valid = '1') then
245  if (unsigned(header_sig(55 downto 32)) < unsigned(input_tob_data(55 downto 32))) then
246  l1id_future := '1';
247  else
248  l1id_future := '0';
249  end if;
250  if (unsigned(header_sig(63 downto 56)) < unsigned(input_tob_data(63 downto 56))) then
251  ecrid_future := '1';
252  else
253  ecrid_future := '0';
254  end if;
255  if (header_sig(63 downto 60) = "1111") and (input_tob_data(63 downto 60) = "0000") then
256  ecrid_wraparound := '1';
257  else
258  ecrid_wraparound := '0';
259  end if;
260  else -- no incoming packet, signify it's really not there...
261  l1id_future := '1';
262  ecrid_future := '1';
263  ecrid_wraparound := '1';
264  first_strike := '1';
265  processed_packet := '1'; -- set up first strike for next packet when it arrives...
266  end if;
267  when parse_l1id =>
268  if ((l1id_future = '1') or (ecrid_future = '1') or (ecrid_wraparound = '1')) and (first_strike = '1') then
269  event_missing := '1'; -- keep it if first strike on this Processor packet/signify it's really not there
270  else
271  event_missing := '0';
272  end if;
273  when start_debug_merger | skip_payload_header => -- moving the current packet on...
274  first_strike := '1';
275  processed_packet := '1';
276  when end_event =>
277  if (processed_packet = '1') then
278  first_strike := '1';
279  else
280  first_strike := '0';
281  end if;
282  processed_packet := '0';
283  when Others =>
284  end case;
285  end if;
286  event_missing_sig <= event_missing
287  -- pragma translate_off
288  after 2 ns
289  -- pragma translate_on
290  ;
291  end if;
292 end process event_missing_block;
293 
294 merger_start_block: process(clk)
295 begin
296  if rising_edge(clk) then
297  if (state_sig = start_debug_merger) then
298  start_debug_merger_sig <= '1'
299  -- pragma translate_off
300  after 2 ns
301  -- pragma translate_on
302  ;
303  else
304  start_debug_merger_sig <= '0'
305  -- pragma translate_off
306  after 2 ns
307  -- pragma translate_on
308  ;
309  end if;
310  end if;
311 end process merger_start_block;
312 
313 report_status_block: process(clk)
314 begin
315  if rising_edge(clk) then
316  if (state_sig = send_status) then
317  TOB_packet_ready <= '1'
318  -- pragma translate_off
319  after 2 ns
320  -- pragma translate_on
321  ;
322  TOB_packet_to_merge <= l1id_correct_sig
323  -- pragma translate_off
324  after 2 ns
325  -- pragma translate_on
326  ;
327  TOB_packet_missing <= event_missing_sig
328  -- pragma translate_off
329  after 2 ns
330  -- pragma translate_on
331  ;
332  else
333  TOB_packet_ready <= '0'
334  -- pragma translate_off
335  after 2 ns
336  -- pragma translate_on
337  ;
338  TOB_packet_to_merge <= '0'
339  -- pragma translate_off
340  after 2 ns
341  -- pragma translate_on
342  ;
343  TOB_packet_missing <= '0'
344  -- pragma translate_off
345  after 2 ns
346  -- pragma translate_on
347  ;
348  end if;
349  if (state_sig = start_debug_merger) then
350  debug_packet_created <= '1'
351  -- pragma translate_off
352  after 2 ns
353  -- pragma translate_on
354  ;
355  else
356  debug_packet_created <= '0'
357  -- pragma translate_off
358  after 2 ns
359  -- pragma translate_on
360  ;
361  end if;
362  end if;
363 end process report_status_block;
364 
365 SRLC32E_fifo_delay : SRLC32E
366  generic map (INIT => X"00000000")
367  port map (
368  Q => Open,
369  Q31 => fifo_delay_end, -- SRL cascaded data output
370  A => (Others => '1'), -- Delay input
371  CE => '1', -- Clock enable input
372  CLK => clk, -- Clock input
373  D => fifo_delay_start -- SRL data input
374  );
375 
376 state_machine: process(clk)
377 variable next_state: STATE_TYPE := idle;
378 variable fifo_start: std_logic;
379 begin
380  if rising_edge(clk) then
381  fifo_start := '0';
382  if rst_clk = '1' then
383  next_state := idle;
384  else
385  case state_sig is
386  when prepare_l1id =>
387  next_state := parse_l1id;
388  when parse_l1id =>
389  next_state := check_l1id;
390  when check_l1id =>
391  if (l1id_correct_sig = '1') or (event_missing_sig = '1') then
392  next_state := send_status;
393  else
394  next_state := start_debug_merger;
395  end if;
396  when start_debug_merger =>
397  next_state := send_debug_header;
398  when send_debug_header =>
399  if (header_ready_sig = '1') then
400  next_state := send_debug;
401  else
402  next_state := send_debug_header;
403  end if;
404  when send_debug =>
405  if (input_tob_last = '1') and (input_tob_valid = '1') and (debug_ready_sig = '1') then
406  next_state := wait_fifo;
407  fifo_start := '1';
408  else
409  next_state := send_debug;
410  end if;
411  when wait_fifo =>
412  if (input_fifo_empty = '1') and (fifo_delay_end = '1') then
413  next_state := send_status;
414  elsif (input_tob_valid = '1') then
415  next_state := prepare_l1id;
416  else
417  next_state := wait_fifo;
418  end if;
419  when send_status =>
420  if (l1id_correct_sig = '1') then
421  next_state := skip_payload_header;
422  else
423  next_state := end_event;
424  end if;
425  when skip_payload_header =>
426  next_state := send_payload;
427  when send_payload =>
428  if (input_tob_last = '1') and (input_tob_valid = '1') and (output_fifo_ready(0) = '1') then
429  next_state := end_event;
430  else
431  next_state := send_payload;
432  end if;
433  when end_event =>
434  next_state := idle;
435  when others => -- idle
436  if (ttc_valid = '1') then
437  next_state := prepare_l1id;
438  else
439  next_state := idle;
440  end if;
441  end case;
442  end if;
443  state_sig <= next_state
444  -- pragma translate_off
445  after 2 ns
446  -- pragma translate_on
447  ;
448  fifo_delay_start <= fifo_start
449  -- pragma translate_off
450  after 2 ns
451  -- pragma translate_on
452  ;
453  end if;
454 end process state_machine;
455 
456 END Architecture rtl;
MUX to concatenate AXI-stream fragments into single packet...
in packet_merger_data packet_data_array( NSRC- 1 downto 0)
Input signals.
out packet_data std_logic_vector( 63 DOWNTO 0)
FIFO signals.
efex_packet_merger
Input signals.