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

Back to ROD documentation
l1id_capture.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 19.07.2022 13:53:05
6 -- Design Name:
7 -- Module Name: l1id_capture - RTL
8 -- Project Name:
9 -- Target Devices:
10 -- Tool Versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 
21 
22 library IEEE;
23 use IEEE.STD_LOGIC_1164.ALL;
24 use IEEE.STD_LOGIC_unsigned.ALL;
25 use IEEE.NUMERIC_STD.ALL;
26 
27 use work.ipbus.all;
28 use work.ipbus_decode_L1CaloHubRodL1idCaptureRegisters.all;
29 -- Uncomment the following library declaration if instantiating
30 -- any Xilinx leaf cells in this code.
31 --library UNISIM;
32 --use UNISIM.VComponents.all;
33 
34 
35 
36 --could this function be implemented within the "input_capture" block if TTC_l1ID was added to the registers?
37 
38 entity l1id_capture is
39  generic (
40  sim : integer := 0
41  );
42  Port (
43  ipb_clk : in std_logic;
44  ipb_rst : in std_logic;
45  ipb_in : in ipb_wbus;
46  ipb_out : out ipb_rbus;
47  pp_clock : in STD_LOGIC;
48  reset : in STD_LOGIC;
49  s_tvalid : in STD_LOGIC;
50  s_tlast : in STD_LOGIC;
51  idle_state : in STD_LOGIC;
52  l1id_ttc : in STD_LOGIC_VECTOR(31 downto 0);
53  l1id_pkt : in STD_LOGIC_VECTOR(31 downto 0);
54  current_chan : in STD_LOGIC_VECTOR(7 downto 0); --allow any channel to mismatch, and then record that channel
55  first_chan : in STD_LOGIC_VECTOR(4 downto 0); --only capture the ttc_l1id on the first channel
56  poll_chan : in STD_LOGIC
57  );
58 end l1id_capture;
59 
60 architecture RTL of l1id_capture is
61 
62 signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
63 signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
64 signal l1id_ttc_prior_0 : STD_LOGIC_VECTOR(31 downto 0);
65 signal l1id_ttc_prior_1 : STD_LOGIC_VECTOR(31 downto 0);
66 signal l1id_ttc_prior_2 : STD_LOGIC_VECTOR(31 downto 0);
67 signal l1id_ttc_prior_n : STD_LOGIC_VECTOR(31 downto 0);
68 signal l1id_ttc_prior_m : STD_LOGIC_VECTOR(31 downto 0);
69 signal l1id_ttc_after_0 : STD_LOGIC_VECTOR(31 downto 0);
70 signal l1id_ttc_after_1 : STD_LOGIC_VECTOR(31 downto 0);
71 signal l1id_ttc_after_2 : STD_LOGIC_VECTOR(31 downto 0);
72 signal l1id_ttc_mismatch : STD_LOGIC_VECTOR(31 downto 0);
73 
74 signal l1id_pkt_prior_0 : STD_LOGIC_VECTOR(31 downto 0);
75 signal l1id_pkt_prior_1 : STD_LOGIC_VECTOR(31 downto 0);
76 signal l1id_pkt_prior_2 : STD_LOGIC_VECTOR(31 downto 0);
77 signal l1id_pkt_after_0 : STD_LOGIC_VECTOR(31 downto 0);
78 signal l1id_pkt_after_1 : STD_LOGIC_VECTOR(31 downto 0);
79 signal l1id_pkt_after_2 : STD_LOGIC_VECTOR(31 downto 0);
80 signal l1id_pkt_mismatch : STD_LOGIC_VECTOR(31 downto 0);
81 signal channel : STD_LOGIC_VECTOR(7 downto 0);
82 signal post_capture : STD_LOGIC;
83 signal postcapture_count : STD_LOGIC_VECTOR(1 downto 0);
84 
85 signal clear : std_logic;
86 signal clear_s : std_logic;
87 signal clear_s_del : std_logic;
88 signal armed : std_logic;
89 signal armed_s : std_logic;
90 signal armed_s_del : std_logic;
91 signal armed_pulse : std_logic;
92 signal armed_stat : std_logic;
93 signal l_header_marker : std_logic;
94 signal l1id_capture_control : std_logic_vector(31 downto 0);
95 signal tvalid_prev : std_logic;
96 signal sample : std_logic;
97 signal l1id_capture_status : std_logic_vector(31 downto 0);
98 signal l1id_capture_control_reg_stb : std_logic;
99 signal l1id_capture_control_reg_rst : std_logic;
100 signal l1id_eq : std_logic;
101 signal triggered : std_logic;
102 
103 --COMPONENT ila_l1icap
104 
105 --PORT (
106 -- clk : IN STD_LOGIC;
107 -- probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
108 -- probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
109 -- probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
110 -- probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
111 -- probe4 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
112 -- probe5 : IN STD_LOGIC_VECTOR(31 DOWNTO 0)
113 --);
114 --END COMPONENT ;
115 
116 begin
117 
118 no_sim_regs: if SIM=0 generate
119 fabric: entity work.ipbus_fabric_sel
120  generic map(
121  NSLV => N_SLAVES,
122  SEL_WIDTH => IPBUS_SEL_WIDTH)
123  port map(
124  ipb_in => ipb_in,
125  ipb_out => ipb_out,
126 
127  sel => ipbus_sel_L1CaloHubRodL1IDCaptureRegisters(ipb_in.ipb_addr),
128  ipb_to_slaves => ipbw,
129  ipb_from_slaves => ipbr
130  );
131 
132 
133 
134 --pulse reg for arming the capture mech -----
135 L1ID_Capture_Control_reg: entity work.ipbus_reg_v
136  port map(
137  clk => ipb_clk,
138  reset => l1id_capture_control_reg_rst,
139  ipbus_in => ipbw(N_SLV_L1ID_CAPTURE_CONTROL),
140  ipbus_out => ipbr(N_SLV_L1ID_CAPTURE_CONTROL),
141  stb(0) => l1id_capture_control_reg_stb,
142  q(0) => l1id_capture_control
143  );
144 l1id_capture_control_reg_rst <= l1id_capture_control_reg_stb or ipb_rst;
145 
146 L1ID_Capture_status_reg: entity work.ipbus_syncreg_v
147  generic map (
148  N_CTRL => 0,
149  N_STAT => 1
150  )
151  port map(
152  clk => ipb_clk,
153  rst => ipb_rst,
154  ipb_in => ipbw(N_SLV_L1ID_CAPTURE_STATUS),
155  ipb_out => ipbr(N_SLV_L1ID_CAPTURE_STATUS),
156  slv_clk => pp_clock,
157  d(0) => l1id_capture_status,
158  qmask => (others => (others => '1')),
159  stb => open,
160  rstb => open
161  );
162 
163 
164 pkt_miss_reg: entity work.ipbus_syncreg_v
165  generic map (
166  N_CTRL => 0,
167  N_STAT => 1
168  )
169  port map(
170  clk => ipb_clk,
171  rst => ipb_rst,
172  ipb_in => ipbw(N_SLV_PKT_MISS),
173  ipb_out => ipbr(N_SLV_PKT_MISS),
174  slv_clk => pp_clock,
175  d(0) => l1id_pkt_mismatch,
176  qmask => (others => (others => '1')),
177  stb => open,
178  rstb => open
179  );
180 
181 ttc_miss_reg: entity work.ipbus_syncreg_v
182  generic map (
183  N_CTRL => 0,
184  N_STAT => 1
185  )
186  port map(
187  clk => ipb_clk,
188  rst => ipb_rst,
189  ipb_in => ipbw(N_SLV_TTC_MISS),
190  ipb_out => ipbr(N_SLV_TTC_MISS),
191  slv_clk => pp_clock,
192  d(0) => l1id_ttc_mismatch,
193  qmask => (others => (others => '1')),
194  stb => open,
195  rstb => open
196  );
197 
198 
199 ttc_last_reg: entity work.ipbus_syncreg_v
200  generic map (
201  N_CTRL => 0,
202  N_STAT => 1
203  )
204  port map(
205  clk => ipb_clk,
206  rst => ipb_rst,
207  ipb_in => ipbw(N_SLV_TTC_LAST),
208  ipb_out => ipbr(N_SLV_TTC_LAST),
209  slv_clk => pp_clock,
210  d(0) => l1id_ttc_prior_n, --l1id_ttc_prior_0,
211  qmask => (others => (others => '1')),
212  stb => open,
213  rstb => open
214  );
215 
216 ttc_penultimate_reg: entity work.ipbus_syncreg_v
217  generic map (
218  N_CTRL => 0,
219  N_STAT => 1
220  )
221  port map(
222  clk => ipb_clk,
223  rst => ipb_rst,
224  ipb_in => ipbw(N_SLV_TTC_PENULTIMATE),
225  ipb_out => ipbr(N_SLV_TTC_PENULTIMATE),
226  slv_clk => pp_clock,
227  d(0) => l1id_ttc_prior_m, --l1id_ttc_prior_1,
228  qmask => (others => (others => '1')),
229  stb => open,
230  rstb => open
231  );
232 
233 
234 end generate no_sim_regs;
235 
236 
237 
238 l1id_eq <= '1' when l1ID_ttc = l1ID_pkt else '0';
239 
240 l1id_capture_status <= x"00000" & channel & "00" & triggered & armed_stat;
241 --sample <= idle_state and s_tvalid and l_header_marker; --sampling point to capture l1id, pkt, and equality --note that poll_chan could be used for this
242 sample <= poll_chan;
243 
244 --both L1ID's are available at the time poll_chan is activated.
245 
246 -------sample the pulse reg in the pp_clock domain ------
247 --armed_s samples the pulse bit running on ipb_clk
248 --armed_s_del sample armed_s synchronously on pp_clock
249 --armed_stat is the user's status flag indicating the mech is armed, but not triggered
250 
251 --clear <= l1id_capture_control(1);
252 
253 --clear pulse happens on trailing edge of ipbus pulse
254 process(pp_clock) begin
255  if rising_edge (pp_clock) then
256  clear_s <= l1id_capture_control(1);
257  clear_s_del <= clear_s;
258  end if;
259 end process;
260 
261 clear <= clear_s_del and not clear_s;
262 
263 process(pp_clock) begin
264  if rising_edge (pp_clock) then
265  armed_s <= l1id_capture_control(0);
266  armed_s_del <= armed_s;
267  end if;
268 end process;
269 
270 armed_pulse <= armed_s_del and not armed_s;
271 
272 process(pp_clock) begin
273  if rising_edge (pp_clock) then
274  if (armed_pulse = '1') then
275  armed_stat <= '1';
276  elsif (ipb_rst = '1') or (triggered = '1') or (clear = '1') or (reset = '1') then
277  armed_stat <= '0';
278  else
279  armed_stat <= armed_stat;
280  end if;
281  end if;
282 end process;
283 
284 
285 ----The header marker coming from the TOB processor is not currently reliable, so a stand alone version is created here
286 --process (pp_clock) begin
287 -- if rising_edge (pp_clock) then
288 -- if (ipb_rst = '1') or (clear = '1') then
289 -- tvalid_prev <= '0';
290 -- else
291 -- tvalid_prev <= (not s_tvalid) or (s_tlast and s_tvalid);
292 -- end if;
293 -- end if;
294 -- end process;
295 
296 --l_header_marker <= s_tvalid and tvalid_prev and not s_tlast; --packets should be at least two 64-bit words (header and trailer)
297 
298 
299 
300 
301 
302 
303 
304 process (pp_clock) begin
305  if rising_edge (pp_clock) then
306  if (ipb_rst = '1') or (clear = '1') or (reset = '1') or (armed_pulse = '1') then
307  triggered <= '0';
308  l1id_pkt_mismatch <= (others=> '0');
309  l1id_ttc_mismatch <= (others=> '0');
310  channel <= (others=> '0');
311  elsif (sample = '1') and (l1id_eq = '0') and (armed_stat = '1') then
312  channel <= current_chan;
313  triggered <= '1';
314  l1id_pkt_mismatch <= l1id_pkt;
315  l1id_ttc_mismatch <= l1id_ttc;
316  l1id_ttc_prior_n <= l1id_ttc_prior_0;
317  l1id_ttc_prior_m <= l1id_ttc_prior_1;
318 
319  else
320  channel <= channel;
321  triggered <= triggered;
322  l1id_pkt_mismatch <= l1id_pkt_mismatch;
323  l1id_ttc_mismatch <= l1id_ttc_mismatch;
324  end if;
325  end if;
326  end process;
327 
328 process (pp_clock) begin
329  if rising_edge (pp_clock) then
330  if (ipb_rst = '1') or (clear = '1') or (reset = '1') then
331  l1id_ttc_prior_0 <= (others=> '0');
332  l1id_ttc_prior_1 <= (others=> '0');
333 -- elsif (sample = '1') and (armed_stat = '1') and (l1id_ttc /= l1id_ttc_prior_0) then --and (l1id_eq = '1')
334 -- elsif (sample = '1') and (armed_stat = '1') and (current_chan = first_chan) then --only update past l1ids when capturing the first channel l1id
335  elsif (sample = '1') and (current_chan = first_chan) then --update these hidden registers every time a new event is being processed on first_chan
336  l1id_ttc_prior_0 <= l1id_ttc;
337  l1id_ttc_prior_1 <= l1id_ttc_prior_0;
338  else
339  l1id_ttc_prior_0 <= l1id_ttc_prior_0;
340  l1id_ttc_prior_1 <= l1id_ttc_prior_1;
341  end if;
342  end if;
343 end process;
344 
345 
346 --l1id_capture_ila : ila_l1icap
347 --PORT MAP (
348 -- clk => pp_clock,
349 
350 -- probe0(0) => armed_stat,
351 -- probe1(0) => triggered,
352 -- probe2(0) => sample,
353 -- probe3(0) => l1id_eq,
354 -- probe4 => l1id_ttc_prior_0,
355 -- probe5 => l1id_ttc_prior_1
356 --);
357 
358 
359 
360 end RTL;