ROD firmware  1.0.5
ATLAS l1-calo - ROD_eFEX and ROD_jFEX firmware for the L1Calo ROD board

Back to ROD documentation
pkt_capture_regs.vhd
1 library IEEE;
2 use IEEE.STD_LOGIC_1164.ALL;
3 use ieee.std_logic_unsigned.all;
4 use IEEE.NUMERIC_STD.ALL;
5 --library unisim;
6 --use unisim.vcomponents.all;
7 use work.ipbus.all;
8 use work.ipbus_decode_L1CaloHubRodPktCaptureRegisters.all;
9 
16 
17 
18 entity pkt_capture_regs is
19  generic (
20  packet_version : std_logic_vector(2 downto 0) := "001";
21  sim : integer := 0;
22  debug : integer := 1
23  );
24  Port (
25 
26  ipb_clk : in std_logic;
27  ipb_rst : in std_logic;
28  ipb_in : in ipb_wbus;
29  ipb_out : out ipb_rbus;
30  pp_clock : in std_logic;
31  full_mode_stat : in STD_LOGIC_VECTOR (31 downto 0);
32  m_tdata : in STD_LOGIC_VECTOR (63 downto 0);
33  m_tvalid : in std_logic;
34  m_tlast : in std_logic;
35  m_header_marker : in std_logic
36 
37  );
39 architecture RTL of pkt_capture_regs is
40 
41 COMPONENT pkt_capture_ila
42 
43 PORT (
44  clk : IN STD_LOGIC;
45  probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
46  probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
47  probe2 : IN STD_LOGIC_VECTOR(63 DOWNTO 0);
48  probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
49  probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
50  probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
51  probe6 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
52  probe7 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
53  probe8 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
54  probe9 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
55  probe10 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
56  probe11 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
57 );
58 END COMPONENT ;
59 
60 
61 
62 signal version : std_logic_vector(3 downto 0);
63 
64 signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
65 signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
66 signal capture_control_reg_rst : std_logic;
67 signal capture_control_reg_stb : std_logic;
68 signal pkt_capture_control : std_logic_vector(31 downto 0);
69 
70 signal clear : std_logic;
71 signal clear_s : std_logic;
72 signal clear_s_del : std_logic;
73 signal armed : std_logic;
74 signal armed_s : std_logic;
75 signal armed_s_del : std_logic;
76 signal armed_pulse : std_logic;
77 signal armed_stat : std_logic;
78 signal triggered : std_logic;
79 signal capture : std_logic;
80 signal tvalid_prev : std_logic;
81 signal l_header_marker : std_logic; --replaces m_header_marker input
82 
83 signal m_header_marker_2 : std_logic;
84 signal header_0 : std_logic_vector(63 downto 0);
85 signal header_0_i : std_logic_vector(31 downto 0);
86 signal header_2 : std_logic_vector(31 downto 0);
87 signal trailer : std_logic_vector(63 downto 0);
88 signal header_1 : std_logic_vector(31 downto 0);
89 signal trailer_1 : std_logic_vector(31 downto 0);
90 
91 signal incomp_pkt : std_logic;
92 signal capture_status : std_logic_vector(31 downto 0);
93 
94 signal pkt_count : std_logic_vector(31 downto 0);
95 
96 
97 
98 begin
99 
100 fabric: entity work.ipbus_fabric_sel
101  generic map(
102  NSLV => N_SLAVES,
103  SEL_WIDTH => IPBUS_SEL_WIDTH)
104  port map(
105  ipb_in => ipb_in,
106  ipb_out => ipb_out,
107 
108  sel => ipbus_sel_L1CaloHubRodPktCaptureRegisters(ipb_in.ipb_addr),
109  ipb_to_slaves => ipbw,
110  ipb_from_slaves => ipbr
111  );
112 
113 no_sim_regs: if SIM=0 generate
114 
115 --pulse reg for arming the capture mech -----
116 Capture_Control_reg: entity work.ipbus_reg_v
117  port map(
118  clk => ipb_clk,
119  reset => capture_control_reg_rst,
120  ipbus_in => ipbw(N_SLV_PKT_CAPTURE_CONTROL),
121  ipbus_out => ipbr(N_SLV_PKT_CAPTURE_CONTROL),
122  stb(0) => capture_control_reg_stb,
123  q(0) => pkt_capture_control
124  );
125 capture_control_reg_rst <= capture_control_reg_stb or ipb_rst;
126 
127 Capture_status_reg: entity work.ipbus_syncreg_v
128  generic map (
129  N_CTRL => 0,
130  N_STAT => 1
131  )
132  port map(
133  clk => ipb_clk,
134  rst => ipb_rst,
135  ipb_in => ipbw(N_SLV_PKT_CAPTURE_STATUS),
136  ipb_out => ipbr(N_SLV_PKT_CAPTURE_STATUS),
137  slv_clk => pp_clock,
138  d(0) => capture_status,
139  qmask => (others => (others => '1')),
140  stb => open,
141  rstb => open
142  );
143 
144 
145 Header_0_reg: entity work.ipbus_syncreg_v
146  generic map (
147  N_CTRL => 0,
148  N_STAT => 1
149  )
150  port map(
151  clk => ipb_clk,
152  rst => ipb_rst,
153  ipb_in => ipbw(N_SLV_HEADER_0),
154  ipb_out => ipbr(N_SLV_HEADER_0),
155  slv_clk => pp_clock,
156  d(0) => header_0(31 downto 0),
157  qmask => (others => (others => '1')),
158  stb => open,
159  rstb => open
160  );
161 
162 --header_0_i <= "000" & header_0(28 downto 0); --blank out "version" field
163 
164 
165 Header_1_reg: entity work.ipbus_syncreg_v
166  generic map (
167  N_CTRL => 0,
168  N_STAT => 1
169  )
170  port map(
171  clk => ipb_clk,
172  rst => ipb_rst,
173  ipb_in => ipbw(N_SLV_HEADER_1),
174  ipb_out => ipbr(N_SLV_HEADER_1),
175  slv_clk => pp_clock,
176  d(0) => header_0(63 downto 32),
177  qmask => (others => (others => '1')),
178  stb => open,
179  rstb => open
180  );
181 
182 
183 Header_2_reg: entity work.ipbus_syncreg_v
184  generic map (
185  N_CTRL => 0,
186  N_STAT => 1
187  )
188  port map(
189  clk => ipb_clk,
190  rst => ipb_rst,
191  ipb_in => ipbw(N_SLV_HEADER_2),
192  ipb_out => ipbr(N_SLV_HEADER_2),
193  slv_clk => pp_clock,
194  d(0) => header_2(31 downto 0),
195  qmask => (others => (others => '1')),
196  stb => open,
197  rstb => open
198  );
199 
200 trailer_0_reg: entity work.ipbus_syncreg_v
201  generic map (
202  N_CTRL => 0,
203  N_STAT => 1
204  )
205  port map(
206  clk => ipb_clk,
207  rst => ipb_rst,
208  ipb_in => ipbw(N_SLV_TRAILER_0),
209  ipb_out => ipbr(N_SLV_TRAILER_0),
210  slv_clk => pp_clock,
211  d(0) => trailer(31 downto 0),
212  qmask => (others => (others => '1')),
213  stb => open,
214  rstb => open
215  );
216 
217 trailer_1_reg: entity work.ipbus_syncreg_v
218  generic map (
219  N_CTRL => 0,
220  N_STAT => 1
221  )
222  port map(
223  clk => ipb_clk,
224  rst => ipb_rst,
225  ipb_in => ipbw(N_SLV_TRAILER_1),
226  ipb_out => ipbr(N_SLV_TRAILER_1),
227  slv_clk => pp_clock,
228  d(0) => trailer(63 downto 32),
229  qmask => (others => (others => '1')),
230  stb => open,
231  rstb => open
232  );
233 
234 pkt_count_reg: entity work.ipbus_syncreg_v
235  generic map (
236  N_CTRL => 0,
237  N_STAT => 1
238  )
239  port map(
240  clk => ipb_clk,
241  rst => ipb_rst,
242  ipb_in => ipbw(N_SLV_PKT_COUNT),
243  ipb_out => ipbr(N_SLV_PKT_COUNT),
244  slv_clk => pp_clock,
245  d(0) => pkt_count,
246  qmask => (others => (others => '1')),
247  stb => open,
248  rstb => open
249  );
250 
251 end generate no_sim_regs;
252 
253 header_0_i <= header_0(31 downto 0);
254 
255 -----capture mech -------------------
256 
257 -------sample the pulse reg in the pp_clock domain ------
258 --armed_s samples the pulse bit running on ipb_clk
259 --armed_s_del sample armed_s synchronously on pp_clock
260 --armed_stat is the user's status flag indicating the mech is armed, but not triggered
261 
262 --clear <= pkt_capture_control(1);
263 
264 --clear pulse happens on trailing edge of ipbus pulse
265 process(pp_clock) begin
266  if rising_edge (pp_clock) then
267  clear_s <= pkt_capture_control(1);
268  clear_s_del <= clear_s;
269  end if;
270 end process;
271 
272 clear <= clear_s_del and not clear_s;
273 
274 
275 process(pp_clock) begin
276  if rising_edge (pp_clock) then
277  armed_s <= pkt_capture_control(0);
278  armed_s_del <= armed_s;
279  end if;
280 end process;
281 
282 armed_pulse <= armed_s_del and not armed_s;
283 
284 process(pp_clock) begin
285  if rising_edge (pp_clock) then
286  if (ipb_rst = '1') or (capture = '1') or (clear = '1') then
287  armed_stat <= '0';
288  elsif (armed_pulse = '1') then
289  armed_stat <= '1';
290  else
291  armed_stat <= armed_stat;
292  end if;
293  end if;
294 end process;
295 
296 
297 --The header marker coming from the TOB processor is not currently reliable, so a stand alone version is created here
298 process (pp_clock) begin
299  if rising_edge (pp_clock) then
300  if (ipb_rst = '1') or (clear = '1') then
301  tvalid_prev <= '0';
302  else
303  tvalid_prev <= (not m_tvalid) or (m_tlast and m_tvalid);
304  end if;
305  end if;
306  end process;
307 
308 l_header_marker <= m_tvalid and tvalid_prev and not m_tlast; --packets should be at least two 64-bit words (header and trailer)
309 
310 
311 
312 
313 -- Capture - active during the event being captured and then cleared --
314 process(pp_clock) begin
315  if rising_edge (pp_clock) then
316  if (ipb_rst = '1') or (clear = '1') then
317  capture <= '0';
318  elsif (armed_stat = '1') and (l_header_marker = '1') then
319  capture <= '1';
320  elsif (capture = '1') and (m_tlast = '1') then
321  capture <= '0';
322  else
323  capture <= capture;
324  end if;
325  end if;
326 end process;
327 
328 -- triggered - status bit to indicate an event has been captured
329 process(pp_clock) begin
330  if rising_edge (pp_clock) then
331  if (ipb_rst = '1') or (clear = '1') then
332  triggered <= '0';
333  elsif (capture = '1') then
334  triggered <= '1';
335  elsif (armed_pulse = '1') then
336  triggered <= '0';
337  else
338  triggered <= triggered;
339  end if;
340  end if;
341 end process;
342 
343 -- capture the header
344 process(pp_clock) begin
345  if rising_edge (pp_clock) then
346  if (clear = '1') then
347  header_0 <= (others => '0');
348  elsif (armed_stat = '1' ) and (l_header_marker = '1') then
349  header_0 <= m_tdata;
350  else
351  header_0 <= header_0;
352  end if;
353  end if;
354 end process;
355 
356 --make an enable for capturing the second header word
357 process(pp_clock) begin
358  if rising_edge (pp_clock) then
359  m_header_marker_2 <= l_header_marker;
360  end if;
361 end process;
362 
363 process(pp_clock) begin
364  if rising_edge (pp_clock) then
365  if (clear = '1') then
366  header_2 <= (others => '0');
367  elsif (capture = '1' ) and (m_header_marker_2 = '1') then
368  header_2 <= m_tdata(31 downto 0);
369  else
370  header_2 <= header_2;
371  end if;
372  end if;
373 end process;
374 
375 --capture trailer
376 process(pp_clock) begin
377  if rising_edge (pp_clock) then
378  if (clear = '1') then
379  trailer <= (others => '0');
380  elsif (capture = '1' ) and (m_tlast = '1') then
381  trailer <= m_tdata;
382  else
383  trailer <= trailer;
384  end if;
385  end if;
386 end process;
387 
388 
389 --incomp_pkt is active while capture is active:
390 incomp_pkt <= capture;
391 
392 
393 capture_status <= '0' & packet_version & x"000000" & '0' & incomp_pkt & triggered & armed_stat;
394 
395 --packet counter
396 process(pp_clock) begin
397  if rising_edge (pp_clock) then
398  if (ipb_rst = '1') or (clear = '1') then
399  pkt_count <= (others => '0');
400  elsif (m_tlast = '1') and (m_tvalid = '1') then
401  pkt_count <= (pkt_count + 1);
402  else
403  pkt_count <= pkt_count;
404  end if;
405  end if;
406 end process;
407 
408 --pkt_capture_probe : pkt_capture_ila
409 -- Port map (
410 -- clk => pp_clock,
411 -- probe0(0) => m_tvalid, -- 1-bit
412 -- probe1(0) => m_tlast, -- 1-bit
413 -- probe2 => m_tdata, -- 64-bits
414 -- probe3(0) => l_header_marker, -- 1-bit
415 -- probe4(0) => m_header_marker_2, -- 1-bit
416 -- probe5(0) => capture, -- 1-bit
417 -- probe6 => header_0(31 downto 0), -- 32-bit
418 -- probe7 => header_1,
419 -- probe8 => header_2(31 downto 0),
420 -- probe9 => trailer(31 downto 0),
421 -- probe10 => trailer_1,
422 -- probe11(0) => m_header_marker
423 -- );
424 
425 -- header_1 <= header_0(63 downto 32);
426 -- trailer_1 <= trailer(63 downto 32);
427 
428 end RTL;