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

Back to ROD documentation
input_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_L1CaloHubRodInputCaptureRegisters.all;
9 
16 
17 
19  generic (
20  packet_version : std_logic_vector(2 downto 0) := "001";
21  addr_width_64 : integer := 4; --depth of each 32-bit memory
22  sim : integer := 0;
23  debug : integer := 1
24  );
25  Port (
26 
27  ipb_clk : in std_logic;
28  ipb_rst : in std_logic;
29  ipb_in : in ipb_wbus;
30  ipb_out : out ipb_rbus;
31  pp_clock : in std_logic;
32  current_chan : in STD_LOGIC_VECTOR (4 downto 0);
33  s_tdata : in STD_LOGIC_VECTOR (63 downto 0);
34  s_tvalid : in std_logic;
35  s_tlast : in std_logic;
36  s_header_mark : in std_logic;
37  poll_chan : in std_logic;
38  timeout_err : in std_logic
39 
40  );
42 architecture RTL of input_capture_regs is
43 
44 component input_capture
45  generic (
46  packet_version : std_logic_vector(2 downto 0) := "001";
47  addr_width : integer := (addr_width_64);
48  sim : integer := 0;
49  debug : integer := 1
50  );
51  Port (
52  pp_clock : in std_logic;
53  ipb_rst : in std_logic;
54  input_capture_control : in std_logic_vector(31 downto 0);
55  s_tvalid : in std_logic;
56  s_tlast : in std_logic;
57  s_tdata : in std_logic_vector(63 downto 0);
58  poll_chan : in std_logic;
59 
60  current_chan : in std_logic_vector(4 downto 0);
61  selected_chan : in std_logic_vector(4 downto 0);
62 
63  timeout_err : in std_logic;
64 
65  pkt_count : out std_logic_vector(31 downto 0);
66 
67  input_header : out std_logic_vector(63 downto 0);
68  input_trailer : out std_logic_vector(63 downto 0);
69  capture_status : out std_logic_vector(31 downto 0);
70  header_crc9_error : out std_logic;
71  payload_crc20_error : out std_logic;
72  length_error : out std_logic;
73 
74  spy_we : out std_logic;
75  spy_addr : out std_logic_vector(addr_width-1 downto 0)
76  );
77 end component;
78 
79 component ipbus_dpram is
80  generic(
81  ADDR_WIDTH: positive := addr_width_64;
82  DATA_WIDTH: positive := 32
83  );
84  port(
85 
86  clk: in std_logic;
87  rst: in std_logic;
88  ipb_in: in ipb_wbus;
89  ipb_out: out ipb_rbus;
90  rclk: in std_logic;
91  we: in std_logic := '0';
92  d: in std_logic_vector(DATA_WIDTH - 1 downto 0) := (others => '0');
93  q: out std_logic_vector(DATA_WIDTH - 1 downto 0);
94  addr: in std_logic_vector(ADDR_WIDTH - 1 downto 0)
95  );
96 
97 
98 
99 end component;
100 
101 
102 signal version : std_logic_vector(3 downto 0);
103 
104 signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
105 signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
106 signal capture_control_reg_rst : std_logic;
107 signal capture_control_reg_stb : std_logic;
108 signal input_capture_control : std_logic_vector(31 downto 0);
109 
110 signal clear : std_logic;
111 signal clear_s : std_logic;
112 signal clear_s_del : std_logic;
113 signal armed : std_logic;
114 signal armed_s : std_logic;
115 signal armed_s_del : std_logic;
116 signal armed_pulse : std_logic;
117 signal armed_stat : std_logic;
118 signal triggered : std_logic;
119 signal capture : std_logic;
120 signal tvalid_prev : std_logic;
121 signal l_header_marker : std_logic; --replaces m_header_marker input
122 
123 --signal m_header_marker_2 : std_logic;
124 --signal header_0 : std_logic_vector(63 downto 0);
125 --signal header_0_i : std_logic_vector(31 downto 0);
126 ----signal header_2 : std_logic_vector(31 downto 0);
127 --signal trailer : std_logic_vector(63 downto 0);
128 
129 --signal incomp_pkt : std_logic;
130 signal capture_status : std_logic_vector(31 downto 0);
131 
132 signal pkt_count : std_logic_vector(31 downto 0);
133 
134 signal selected_chan : std_logic_vector(31 downto 0);
135 --signal input_capture_control : std_logic_vector(31 downto 0);
136 signal input_header : std_logic_vector(63 downto 0);
137 signal input_trailer : std_logic_vector(63 downto 0);
138 signal header_crc9_error : std_logic;
139 signal payload_crc20_error : std_logic;
140 signal length_error : std_logic;
141 
142 signal spy_we : std_logic;
143 signal spy_addr : std_logic_vector(addr_width_64 - 1 downto 0); --addr width when 2x 32-bit memories are accessed
144 signal spy_reset : std_logic;
145 
146 
147 signal ipb_mux_data: std_logic_vector(31 downto 0);
148 signal capture_data_lsw : std_logic_vector(31 downto 0);
149 signal capture_data_msw : std_logic_vector(31 downto 0);
150 signal ipb_strobe_lsw : std_logic;
151 signal ipb_strobe_msw : std_logic;
152 signal ipb_rdata_lsw : std_logic_vector(31 downto 0);
153 signal ipb_rdata_msw : std_logic_vector(31 downto 0);
154 
155 signal ipb_in_lsw: ipb_wbus;
156 signal ipb_out_lsw: ipb_rbus;
157 signal ipb_in_msw: ipb_wbus;
158 signal ipb_out_msw: ipb_rbus;
159 
160 begin
161 
162 fabric: entity work.ipbus_fabric_sel
163  generic map(
164  NSLV => N_SLAVES,
165  SEL_WIDTH => IPBUS_SEL_WIDTH)
166  port map(
167  ipb_in => ipb_in,
168  ipb_out => ipb_out,
169 
170  sel => ipbus_sel_L1CaloHubRodInputCaptureRegisters(ipb_in.ipb_addr),
171  ipb_to_slaves => ipbw,
172  ipb_from_slaves => ipbr
173  );
174 
175 
176 Input_channel_select_reg: entity work.ipbus_reg_v
177  port map(
178  clk => ipb_clk,
179  reset => ipb_rst,
180  ipbus_in => ipbw(N_SLV_input_channel_select),
181  ipbus_out => ipbr(N_SLV_input_channel_select),
182  q(0) => selected_chan
183  );
184 
185 
186 
187 --pulse reg for arming the capture mech -----
188 Capture_Control_reg: entity work.ipbus_reg_v
189  port map(
190  clk => ipb_clk,
191  reset => capture_control_reg_rst,
192  ipbus_in => ipbw(N_SLV_INPUT_CAPTURE_CONTROL),
193  ipbus_out => ipbr(N_SLV_INPUT_CAPTURE_CONTROL),
194  stb(0) => capture_control_reg_stb,
195  q(0) => input_capture_control
196  );
197 capture_control_reg_rst <= capture_control_reg_stb or ipb_rst;
198 
199 Capture_status_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_INPUT_CAPTURE_STATUS),
208  ipb_out => ipbr(N_SLV_INPUT_CAPTURE_STATUS),
209  slv_clk => pp_clock,
210  d(0) => capture_status,
211  qmask => (others => (others => '1')),
212  stb => open,
213  rstb => open
214  );
215 
216 
217 Header_0_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_HEADER_0),
226  ipb_out => ipbr(N_SLV_HEADER_0),
227  slv_clk => pp_clock,
228  d(0) => input_header(31 downto 0),
229  qmask => (others => (others => '1')),
230  stb => open,
231  rstb => open
232  );
233 
234 --header_0_i <= "000" & header_0(28 downto 0); --blank out "version" field
235 
236 Header_1_reg: entity work.ipbus_syncreg_v
237  generic map (
238  N_CTRL => 0,
239  N_STAT => 1
240  )
241  port map(
242  clk => ipb_clk,
243  rst => ipb_rst,
244  ipb_in => ipbw(N_SLV_HEADER_1),
245  ipb_out => ipbr(N_SLV_HEADER_1),
246  slv_clk => pp_clock,
247  d(0) => input_header(63 downto 32),
248  qmask => (others => (others => '1')),
249  stb => open,
250  rstb => open
251  );
252 
253 
254 
255 trailer_0_reg: entity work.ipbus_syncreg_v
256  generic map (
257  N_CTRL => 0,
258  N_STAT => 1
259  )
260  port map(
261  clk => ipb_clk,
262  rst => ipb_rst,
263  ipb_in => ipbw(N_SLV_TRAILER_0),
264  ipb_out => ipbr(N_SLV_TRAILER_0),
265  slv_clk => pp_clock,
266  d(0) => input_trailer(31 downto 0),
267  qmask => (others => (others => '1')),
268  stb => open,
269  rstb => open
270  );
271 
272 trailer_1_reg: entity work.ipbus_syncreg_v
273  generic map (
274  N_CTRL => 0,
275  N_STAT => 1
276  )
277  port map(
278  clk => ipb_clk,
279  rst => ipb_rst,
280  ipb_in => ipbw(N_SLV_TRAILER_1),
281  ipb_out => ipbr(N_SLV_TRAILER_1),
282  slv_clk => pp_clock,
283  d(0) => input_trailer(63 downto 32),
284  qmask => (others => (others => '1')),
285  stb => open,
286  rstb => open
287  );
288 
289 pkt_count_reg: entity work.ipbus_syncreg_v
290  generic map (
291  N_CTRL => 0,
292  N_STAT => 1
293  )
294  port map(
295  clk => ipb_clk,
296  rst => ipb_rst,
297  ipb_in => ipbw(N_SLV_PKT_COUNT),
298  ipb_out => ipbr(N_SLV_PKT_COUNT),
299  slv_clk => pp_clock,
300  d(0) => pkt_count,
301  qmask => (others => (others => '1')),
302  stb => open,
303  rstb => open
304  );
305 
306 capture_lsw : ipbus_dpram
307  generic map (
308  ADDR_WIDTH => addr_width_64,
309  DATA_WIDTH => 32
310  )
311  PORT MAP (
312  clk => ipb_clk,
313  rst => spy_reset,
314  ipb_in => ipb_in_lsw,
315  ipb_out => ipb_out_lsw,
316  rclk => pp_clock,
317  we => spy_we,
318  d => s_tdata(31 downto 0),
319  q => capture_data_lsw,
320  addr => spy_addr
321 
322  );
323 
324 capture_msw : ipbus_dpram
325  generic map (
326  ADDR_WIDTH => addr_width_64,
327  DATA_WIDTH => 32
328  )
329  PORT MAP (
330  clk => ipb_clk,
331  rst => spy_reset,
332  ipb_in => ipb_in_msw,
333  ipb_out => ipb_out_msw,
334  rclk => pp_clock,
335  we => spy_we,
336  d => s_tdata(63 downto 32),
337  q => capture_data_msw,
338  addr => spy_addr
339 
340  );
341 
342 ---create ipb_in for the two RAMs ---
343 ipb_in_lsw.ipb_strobe <= ipbw(N_SLV_TRACE_Memory).ipb_strobe and not ipbw(N_SLV_TRACE_MEMORY).ipb_addr(0);
344 ipb_in_msw.ipb_strobe <= ipbw(N_SLV_TRACE_Memory).ipb_strobe and ipbw(N_SLV_TRACE_MEMORY).ipb_addr(0);
345 
346 ipb_in_lsw.ipb_addr(addr_width_64 -1 downto 0) <= ipbw(N_SLV_TRACE_MEMORY).ipb_addr((addr_width_64) downto 1);
347 ipb_in_msw.ipb_addr(addr_width_64 -1 downto 0) <= ipbw(N_SLV_TRACE_MEMORY).ipb_addr((addr_width_64) downto 1);
348 
349 ipb_in_lsw.ipb_wdata <= ipbw(N_SLV_TRACE_MEMORY).ipb_wdata;
350 ipb_in_msw.ipb_wdata <= ipbw(N_SLV_TRACE_MEMORY).ipb_wdata;
351 
352 ipb_in_lsw.ipb_write <= ipbw(N_SLV_TRACE_MEMORY).ipb_write and not ipbw(N_SLV_TRACE_MEMORY).ipb_addr(0);
353 ipb_in_msw.ipb_write <= ipbw(N_SLV_TRACE_MEMORY).ipb_write and ipbw(N_SLV_TRACE_MEMORY).ipb_addr(0);
354 
355 ---create ipb_out for the two RAMs ---
356 
357 with ipbw(N_SLV_TRACE_MEMORY).ipb_addr(0) select
358  ipbr(N_SLV_TRACE_MEMORY).ipb_rdata <= ipb_out_lsw.ipb_rdata when '0',
359  ipb_out_msw.ipb_rdata when others;
360 
361 
362 with ipbw(N_SLV_TRACE_MEMORY).ipb_addr(0) select
363  ipbr(N_SLV_TRACE_MEMORY).ipb_ack <= ipb_out_lsw.ipb_ack when '0',
364  ipb_out_msw.ipb_ack when others;
365 
366 
367 with ipbw(N_SLV_TRACE_MEMORY).ipb_addr(0) select
368  ipbr(N_SLV_TRACE_MEMORY).ipb_err <= ipb_out_lsw.ipb_err when '0',
369  ipb_out_msw.ipb_err when others;
370 
371 
372 
373 
374 spy_reset <= ipb_rst or input_capture_control(1); -- or clear or reset;
375 
376 
377 -----capture mech -------------------
378 
379 -------sample the pulse reg in the pp_clock domain ------
380 --armed_s samples the pulse bit running on ipb_clk
381 --armed_s_del sample armed_s synchronously on pp_clock
382 --armed_stat is the user's status flag indicating the mech is armed, but not triggered
383 
384 --clear <= pkt_capture_control(1);
385 
386 input_capture_mech: input_capture
387  generic map (
388  packet_version => "001",
389  addr_width => addr_width_64
390 
391  )
392  Port map(
393  pp_clock => pp_clock,
394  ipb_rst => ipb_rst,
395  input_capture_control => input_capture_control,
396  s_tvalid => s_tvalid,
397  s_tlast => s_tlast,
398  s_tdata => s_tdata,
399  poll_chan => poll_chan,
400 
401  current_chan => current_chan,
402  selected_chan => selected_chan(4 downto 0),
403  timeout_err => timeout_err,
404  pkt_count => pkt_count,
405 
406  input_header => input_header,
407  input_trailer => input_trailer,
408  capture_status => capture_status,
409  header_crc9_error => open,
410  payload_crc20_error => open,
411  length_error => open,
412  spy_we => spy_we,
413  spy_addr => spy_addr
414 
415  );
416 
417 
418 
419 end RTL;