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

Back to eFEX documentation
backplane_registers.vhd
Go to the documentation of this file.
1 
7 
8 Library IEEE;
9 use IEEE.STD_LOGIC_1164.ALL;
10 use ieee.numeric_std.all;
11 library ipbus_lib;
12 use ipbus_lib.ipbus.all;
13 use ipbus_lib.ipbus_reg_types.all;
14 library infrastructure_lib;
15 use infrastructure_lib.packet_mux_type.all;
16 use infrastructure_lib.ipbus_decode_efex_cntrl_backplane.all;
17 
20  port(
22  ipb_clk : in std_logic;
24  ipb_rst : in std_logic;
26  clk : in std_logic;
28  rst : in std_logic;
30  ipb_in : in ipb_wbus;
32  ipb_out : out ipb_rbus;
34  ttc_info : in std_logic_vector(35 downto 0);
36  aurora_status_1 : in std_logic_vector(31 downto 0);
37  aurora_1_gt0_txctl : out std_logic_vector(23 downto 0);
38  aurora_1_gt1_txctl : out std_logic_vector(23 downto 0);
39  aurora_1_gt2_txctl : out std_logic_vector(23 downto 0);
40  aurora_1_gt3_txctl : out std_logic_vector(23 downto 0);
42  aurora_status_2 : in std_logic_vector(31 downto 0);
43  aurora_2_gt0_txctl : out std_logic_vector(23 downto 0);
44  aurora_2_gt1_txctl : out std_logic_vector(23 downto 0);
45  aurora_2_gt2_txctl : out std_logic_vector(23 downto 0);
46  aurora_2_gt3_txctl : out std_logic_vector(23 downto 0);
48  control_xoff_bus : in std_logic_vector(7 downto 0); -- Processor Number order, (7 downto 4) Input Data (3 downto 0) TOBs
49  control_busy_bus : in std_logic_vector(7 downto 0); -- Processor Number order, (7 downto 4) Input Data (3 downto 0) TOBs
50  processor_busy_bus : in std_logic_vector(7 downto 0); -- Processor Number order, (7 downto 4) Input Data (3 downto 0) TOBs
52  input_data_readout_control : out std_logic_vector(31 downto 0)
53  );
54 
56 
58 architecture Behavioral of backplane_registers is
59 
60  type integer_array is array(natural range <>) of integer range 0 to N_SLAVES;
61 -- mgt_data_array is array(natural range <>) of std_logic_vector(31 downto 0)
62 
63  signal ipbw: ipb_wbus_array(N_SLAVES-1 downto 0);
64  signal ipbr: ipb_rbus_array(N_SLAVES-1 downto 0);
65  signal aurora_status_bus: mgt_data_array(1 downto 0);
66  signal aurora_gt_txctl_bus: mgt_data_array(7 downto 0);
67  signal counter_control, bc_count, bc_count_ipb: std_logic_vector(31 downto 0);
68  signal update_counter_reg_1, update_counter_reg_2, update_counter_reg_3, update_counter_bcr, update_counter_reg: std_logic;
69  signal err_cntr_rst, status_cntr_rst, xoff_cntr_rst: std_logic;
70 -- TTC status
71  signal ttc_bits: std_logic_vector(3 downto 0);
72  signal ttc_counters, ttc_counters_ipb: mgt_data_array(3 downto 0);
73  signal last_l1id, input_data_l1id, last_l1id_ipb, input_data_l1id_ipb: std_logic_vector(31 downto 0);
74 -- ROD link status
75  signal rod_status, last_rod_status, rod_pulse: std_logic_vector(7 downto 0);
76  signal rod1_tx_reset, rod2_tx_reset: std_logic_vector(1 downto 0);
77  signal rod_counters, rod_counters_ipb: mgt_data_array(7 downto 0);
78 -- BUSY/XOff status
79  signal control_xoff_reg, control_busy_reg, processor_busy_reg: std_logic_vector(15 downto 0);
80  signal busy_xoff_bus_a, busy_xoff_bus_b, busy_xoff_bus_c, busy_xoff_reset_bus, busy_xoff_count_bus, busy_xoff_assert_bus: std_logic_vector(27 downto 0);
81  signal busy_xoff_total_counter_bus, busy_xoff_active_counter_bus, busy_xoff_total_counter_bus_ipb, busy_xoff_active_counter_bus_ipb: mgt_data_array(27 downto 0);
82  signal busy_xoff_assert_counter_bus, busy_xoff_assert_counter_bus_ipb: mgt_data_array(27 downto 0);
83 -- Mapping onto IPBus slave buses
84  constant aurora_status_slv_bus: integer_array(1 downto 0) := (N_SLV_AURORA_STATUS_2, N_SLV_AURORA_STATUS_1);
85  constant aurora_gt_txctl_slv_bus: integer_array(7 downto 0) := (
86  N_SLV_AURORA2_GT3_TXCTRL, N_SLV_AURORA2_GT2_TXCTRL, N_SLV_AURORA2_GT1_TXCTRL, N_SLV_AURORA2_GT0_TXCTRL,
87  N_SLV_AURORA1_GT3_TXCTRL, N_SLV_AURORA1_GT2_TXCTRL, N_SLV_AURORA1_GT1_TXCTRL, N_SLV_AURORA1_GT0_TXCTRL);
88  constant rod_link_status_slv_bus: integer_array(1 downto 0) := (N_SLV_ROD_LINK_STATUS_ROD1, N_SLV_ROD_LINK_STATUS_ROD0);
89  constant busy_xoff_slv_bus: integer_array(13 downto 0) := (
90  N_SLV_PROCESSOR_BUSY_STATUS_P3, N_SLV_PROCESSOR_BUSY_STATUS_P2, N_SLV_PROCESSOR_BUSY_STATUS_P1, N_SLV_PROCESSOR_BUSY_STATUS_P0,
91  N_SLV_CONTROL_BUSY_STATUS_P3, N_SLV_CONTROL_BUSY_STATUS_P2, N_SLV_CONTROL_BUSY_STATUS_P1, N_SLV_CONTROL_BUSY_STATUS_P0,
92  N_SLV_CONTROL_XOFF_STATUS_P3, N_SLV_CONTROL_XOFF_STATUS_P2, N_SLV_CONTROL_XOFF_STATUS_P1, N_SLV_CONTROL_XOFF_STATUS_P0,
93  N_SLV_BACKPLANE_XOFF_STATUS_ROD1, N_SLV_BACKPLANE_XOFF_STATUS_ROD0);
94 
95  attribute ASYNC_REG: string;
96  attribute ASYNC_REG of rod1_tx_reset: signal is "TRUE";
97  attribute ASYNC_REG of rod2_tx_reset: signal is "TRUE";
98  attribute ASYNC_REG of control_xoff_reg: signal is "TRUE";
99  attribute ASYNC_REG of control_busy_reg: signal is "TRUE";
100  attribute ASYNC_REG of processor_busy_reg: signal is "TRUE";
101 
102 begin
103 
104 aurora_status_bus <= aurora_status_2 & aurora_status_1;
105 
106 aurora_1_gt0_txctl<= aurora_gt_txctl_bus(0)(23 downto 0);
107 aurora_1_gt1_txctl<= aurora_gt_txctl_bus(1)(23 downto 0);
108 aurora_1_gt2_txctl<= aurora_gt_txctl_bus(2)(23 downto 0);
109 aurora_1_gt3_txctl<= aurora_gt_txctl_bus(3)(23 downto 0);
110 
111 aurora_2_gt0_txctl<= aurora_gt_txctl_bus(4)(23 downto 0);
112 aurora_2_gt1_txctl<= aurora_gt_txctl_bus(5)(23 downto 0);
113 aurora_2_gt2_txctl<= aurora_gt_txctl_bus(6)(23 downto 0);
114 aurora_2_gt3_txctl<= aurora_gt_txctl_bus(7)(23 downto 0);
115 
116 fabric_cntrl_backplane: entity ipbus_lib.ipbus_fabric_sel
117  generic map(NSLV => N_SLAVES, SEL_WIDTH => IPBUS_SEL_WIDTH)
118  port map(
119  ipb_in => ipb_in,
120  ipb_out => ipb_out,
121  sel => ipbus_sel_efex_cntrl_backplane(ipb_in.ipb_addr),
122  ipb_to_slaves => ipbw,
123  ipb_from_slaves => ipbr
124  );
125 
126 control: entity ipbus_lib.ipbus_ctrlreg_v
127  generic map (N_CTRL => 2, N_STAT => 1)
128  port map(
129  clk => ipb_clk,
130  reset => ipb_rst,
131  ipbus_in => ipbw(N_SLV_CONTROL),
132  ipbus_out => ipbr(N_SLV_CONTROL),
134  q(1) => counter_control,
135  d(0) => bc_count_ipb,
136  ctrl_default(0) => x"0000c802", -- Input Data every 200 events
137  ctrl_default(1) => x"002bd702", -- update at about 1 Hz
138  stb => open
139  );
140 
141 ttc_status: entity ipbus_lib.ipbus_ctrlreg_v
142  generic map (N_CTRL => 0, N_STAT => 6)
143  port map(
144  clk => ipb_clk,
145  reset => ipb_rst,
146  ipbus_in => ipbw(N_SLV_TTC_STATUS),
147  ipbus_out => ipbr(N_SLV_TTC_STATUS),
148  q => open,
149  d(0) => ttc_counters_ipb(0), -- L1A
150  d(1) => ttc_counters_ipb(3), -- privileged readout
151  d(2) => ttc_counters_ipb(1), -- BCR
152  d(3) => ttc_counters_ipb(2), -- ECR
153  d(4) => last_l1id_ipb,
154  d(5) => input_data_l1id_ipb,
155  stb => open
156  );
157 
158 aurora_status_generate_block: for i in 0 to 1 generate
159  aurora_status: entity ipbus_lib.ipbus_ctrlreg_v
160  generic map(N_CTRL => 0, N_STAT => 1)
161  port map(
162  clk => ipb_clk,
163  reset => ipb_rst,
164  ipbus_in => ipbw(aurora_status_slv_bus(i)),
165  ipbus_out => ipbr(aurora_status_slv_bus(i)),
166  d(0) => aurora_status_bus(i),
167  q => open,
168  stb => open
169  );
170 end generate aurora_status_generate_block;
171 
172 aurora_gt_txctl_generate_block: for i in 0 to 7 generate
173  aurora_gt_txctl: entity ipbus_lib.ipbus_ctrlreg_v
174  generic map(N_CTRL => 1, N_STAT => 0)
175  port map(
176  clk => ipb_clk,
177  reset => ipb_rst,
178  ipbus_in => ipbw(aurora_gt_txctl_slv_bus(i)),
179  ipbus_out => ipbr(aurora_gt_txctl_slv_bus(i)),
180  d => (others => (others => '0')),
181  ctrl_default(0) => x"00000c07",
182  q(0) => aurora_gt_txctl_bus(i),
183  stb => open
184  );
185 end generate aurora_gt_txctl_generate_block;
186 
187 rod_link_status_generate_block: for i in 0 to 1 generate
188  rod_link_status: entity ipbus_lib.ipbus_ctrlreg_v
189  generic map (N_CTRL => 0, N_STAT => 4)
190  port map(
191  clk => ipb_clk,
192  reset => ipb_rst,
193  ipbus_in => ipbw(rod_link_status_slv_bus(i)),
194  ipbus_out => ipbr(rod_link_status_slv_bus(i)),
195  q => open,
196  d(0) => rod_counters_ipb(i*4 + 2), -- rod_enable_count
197  d(1) => rod_counters_ipb(i*4 + 1), -- rod_up_count
198  d(2) => rod_counters_ipb(i*4), -- rod_reset_count
199  d(3) => rod_counters_ipb(i*4 + 3), -- rod_tx_reset_count
200  stb => open
201  );
202 end generate rod_link_status_generate_block;
203 
204 busy_xoff_status_generate_block: for i in 0 to 13 generate
205  busy_xoff_status: entity ipbus_lib.ipbus_ctrlreg_v
206  generic map (N_CTRL => 0, N_STAT => 6)
207  port map(
208  clk => ipb_clk,
209  reset => ipb_rst,
210  ipbus_in => ipbw(busy_xoff_slv_bus(i)),
211  ipbus_out => ipbr(busy_xoff_slv_bus(i)),
212  q => open,
213  d(0) => busy_xoff_total_counter_bus_ipb(2*i), -- TOB
214  d(1) => busy_xoff_active_counter_bus_ipb(2*i),
215  d(2) => busy_xoff_assert_counter_bus_ipb(2*i),
216  d(3) => busy_xoff_total_counter_bus_ipb(2*i + 1), -- Raw
217  d(4) => busy_xoff_active_counter_bus_ipb(2*i + 1),
218  d(5) => busy_xoff_assert_counter_bus_ipb(2*i + 1),
219  stb => open
220  );
221 end generate busy_xoff_status_generate_block;
222 
223 update_counter_bcr_block: process(clk)
224 variable bcr_counter, bcr_match: unsigned(23 downto 0) := (Others => '0');
225 begin
226  if rising_edge(clk) then
227  bcr_match := unsigned(counter_control(31 downto 8));
228  if (ttc_info(2) = '1') then -- ECR
229  update_counter_bcr <= '0';
230  bcr_counter := (Others => '0');
231  elsif (ttc_info(1) = '1') then -- BCR
232  if (bcr_counter >= bcr_match) then
233  update_counter_bcr <= counter_control(1);
234  bcr_counter := (Others => '0');
235  else
236  update_counter_bcr <= '0';
237  bcr_counter := bcr_counter + 1;
238  end if;
239  else
240  update_counter_bcr <= '0';
241  end if;
242  end if;
243 end process update_counter_bcr_block;
244 
245 register_update_control: process(clk)
246 begin
247  if rising_edge(clk) then
248  update_counter_reg_1 <= counter_control(0);
249  update_counter_reg_2 <= update_counter_reg_1;
250  update_counter_reg_3 <= counter_control(2);
251  if (update_counter_reg_1 = '1' and update_counter_reg_2 = '0') or (update_counter_reg_3 = '1') or (update_counter_bcr = '1') then
252  update_counter_reg <= '1';
253  else
254  update_counter_reg <= '0';
255  end if;
256  end if;
257 end process register_update_control;
258 
259 register_update: process(clk)
260 begin
261  if rising_edge(clk) then
262  if update_counter_reg = '1' then
263  ttc_counters_ipb <= ttc_counters;
264  last_l1id_ipb <= last_l1id;
265  input_data_l1id_ipb <= input_data_l1id;
266  rod_counters_ipb <= rod_counters;
267  bc_count_ipb <= bc_count;
268  busy_xoff_total_counter_bus_ipb <= busy_xoff_total_counter_bus;
269  busy_xoff_active_counter_bus_ipb <= busy_xoff_active_counter_bus;
270  busy_xoff_assert_counter_bus_ipb <= busy_xoff_assert_counter_bus;
271  end if;
272  end if;
273 end process register_update;
274 
275 reset_control: process(clk)
276 begin
277  if rising_edge(clk) then
278  if (rst = '1') or (counter_control(4) = '1') then
279  err_cntr_rst <= '1';
280  else
281  err_cntr_rst <= '0';
282  end if;
283  if (rst = '1') or (counter_control(5) = '1') then
284  status_cntr_rst <= '1';
285  else
286  status_cntr_rst <= '0';
287  end if;
288  if (rst = '1') or (counter_control(6) = '1') then
289  xoff_cntr_rst <= '1';
290  else
291  xoff_cntr_rst <= '0';
292  end if;
293  end if;
294 end process reset_control;
295 
296 ttc_registers: process(clk)
297 begin
298  if rising_edge(clk) then
299  if (status_cntr_rst = '1') then
300  last_l1id <= (Others => '0');
301  input_data_l1id <= (Others => '0');
302  elsif (ttc_info(0) = '1') then -- L1A
303  last_l1id <= ttc_info(11 downto 4) & ttc_info(35 downto 12);
304  if (ttc_info(3) = '1') then -- privileged readout
305  input_data_l1id <= ttc_info(11 downto 4) & ttc_info(35 downto 12);
306  end if;
307  end if;
308  ttc_bits(2 downto 0) <= ttc_info(2 downto 0);
309  if (ttc_info(3) = '1') then -- only count privileged readout on L1A
310  ttc_bits(3) <= ttc_info(0);
311  else
312  ttc_bits(3) <= '0';
313  end if;
314  end if;
315 end process ttc_registers;
316 
317 ttc_counter_generate_block: for i in 0 to 3 generate
318  ttc_counter_block : entity infrastructure_lib.cntr_generic
319  generic map (width => 32, WRAPAROUND => False)
320  port map (
321  CE => ttc_bits(i),
322  CLK => clk,
323  RST => status_cntr_rst,
324  Q => ttc_counters(i));
325 end generate ttc_counter_generate_block;
326 
327 rod1_tx_reset_block: process(clk)
328 begin
329  if rising_edge(clk) then
330  rod1_tx_reset <= rod1_tx_reset(0) & aurora_status_1(8);
331  end if;
332 end process rod1_tx_reset_block;
333 
334 rod2_tx_reset_block: process(clk)
335 begin
336  if rising_edge(clk) then
337  rod2_tx_reset <= rod2_tx_reset(0) & aurora_status_2(8);
338  end if;
339 end process rod2_tx_reset_block;
340 
341 rod_registers: process(clk)
342 begin
343  if rising_edge(clk) then
344  if (status_cntr_rst = '1') then
345  rod_status <= (Others => '0');
346  last_rod_status <= (Others => '0');
347  rod_pulse <= (Others => '0');
348  else
349  if (aurora_status_1(14) = '1') then -- cttc_valid
350  rod_status(2 downto 0) <= aurora_status_1(13 downto 11); -- ROD enable & up & reset
351  else
352  rod_status(2 downto 0) <= rod_status(2 downto 0);
353  end if;
354  rod_status(3) <= rod1_tx_reset(1); -- tx_reset
355  if (aurora_status_2(14) = '1') then -- cttc_valid
356  rod_status(6 downto 4) <= aurora_status_2(13 downto 11); -- ROD enable & up & reset
357  else
358  rod_status(6 downto 4) <= rod_status(6 downto 4);
359  end if;
360  rod_status(7) <= rod2_tx_reset(1); -- tx_reset
361  end if;
362  last_rod_status <= rod_status;
363  rod_pulse <= rod_status and not last_rod_status;
364  end if;
365 end process rod_registers;
366 
367 rod_counter_generate_block : for i in 0 to 7 generate
368  rod_counter_block : entity infrastructure_lib.cntr_generic
369  generic map (width => 32, WRAPAROUND => False)
370  port map (
371  CE => rod_pulse(i),
372  CLK => clk,
373  RST => status_cntr_rst,
374  Q => rod_counters(i));
375 end generate rod_counter_generate_block;
376 
377 bc_counter : entity infrastructure_lib.cntr_generic
378  generic map (width => 32, WRAPAROUND => False)
379  port map (
380  CE => '1',
381  CLK => clk,
382  RST => xoff_cntr_rst,
383  Q => bc_count
384  );
385 
386 control_xoff_block: process(clk)
387 begin
388  if rising_edge(clk) then
389  control_xoff_reg <= control_xoff_reg(7 downto 0) & control_xoff_bus;
390  end if;
391 end process control_xoff_block;
392 
393 control_busy_block: process(clk)
394 begin
395  if rising_edge(clk) then
396  control_busy_reg <= control_busy_reg(7 downto 0) & control_busy_bus;
397  end if;
398 end process control_busy_block;
399 
400 processor_busy_block: process(clk)
401 begin
402  if rising_edge(clk) then
403  processor_busy_reg <= processor_busy_reg(7 downto 0) & processor_busy_bus;
404  end if;
405 end process processor_busy_block;
406 
407 busy_xoff_registers: process(clk)
408 begin
409  if rising_edge(clk) then
410 -- remap to pairs of Raw and TOB for each of Processor 3:0 BUSY, Control 3:0 BUSY, Control 3:0 XOff and ROD 1:0 XOff
411  busy_xoff_bus_a(3 downto 0) <= aurora_status_2(10 downto 9) & aurora_status_1(10 downto 9); -- ROD 1 and 0, Raw and TOB
412  busy_xoff_bus_a(11 downto 4) <= control_xoff_reg(15) & control_xoff_reg(11) & control_xoff_reg(14) & control_xoff_reg(10) & control_xoff_reg(13) & control_xoff_reg(9) & control_xoff_reg(12) & control_xoff_reg(8);
413  busy_xoff_bus_a(19 downto 12) <= control_busy_reg(15) & control_busy_reg(11) & control_busy_reg(14) & control_busy_reg(10) & control_busy_reg(13) & control_busy_reg(9) & control_busy_reg(12) & control_busy_reg(8);
414  busy_xoff_bus_a(27 downto 20) <= processor_busy_reg(15) & processor_busy_reg(11) & processor_busy_reg(14) & processor_busy_reg(10) & processor_busy_reg(13) & processor_busy_reg(9) & processor_busy_reg(12) & processor_busy_reg(8);
415  busy_xoff_bus_b <= busy_xoff_bus_a;
416  busy_xoff_bus_c <= busy_xoff_bus_b;
417  busy_xoff_count_bus <= busy_xoff_bus_c; -- and delay the counters to be in sync after the reset for the active counters
418  if (xoff_cntr_rst = '1') then
419  busy_xoff_reset_bus <= (Others => '1');
420  busy_xoff_assert_bus <= (Others => '0');
421  else -- generate a reset for the active counters from transition from 0 to 1
422  busy_xoff_reset_bus <= busy_xoff_bus_a and not busy_xoff_bus_b;
423  busy_xoff_assert_bus <= busy_xoff_bus_a and not busy_xoff_bus_b;
424  end if;
425  end if;
426 end process busy_xoff_registers;
427 
428 busy_xoff_counter_generate_block : for i in 0 to 27 generate
429  total_counter_block : entity infrastructure_lib.cntr_generic
430  generic map (width => 32, WRAPAROUND => False)
431  port map (
432  CE => busy_xoff_count_bus(i),
433  CLK => clk,
434  RST => xoff_cntr_rst,
435  Q => busy_xoff_total_counter_bus(i));
436 
437  active_counter_block : entity infrastructure_lib.cntr_generic
438  generic map (width => 32, WRAPAROUND => False)
439  port map (
440  CE => busy_xoff_count_bus(i),
441  CLK => clk,
442  RST => busy_xoff_reset_bus(i),
443  Q => busy_xoff_active_counter_bus(i));
444 
445  assert_counter_block : entity infrastructure_lib.cntr_generic
446  generic map (width => 32, WRAPAROUND => False)
447  port map (
448  CE => busy_xoff_assert_bus(i),
449  CLK => clk,
450  RST => xoff_cntr_rst,
451  Q => busy_xoff_assert_counter_bus(i));
452 end generate busy_xoff_counter_generate_block;
453 
454 end Behavioral;
out input_data_readout_control std_logic_vector( 31 downto 0)
Privileged readout control.
in ipb_rst std_logic
ipbus reset
in aurora_status_1 std_logic_vector( 31 downto 0)
aurora status hub1
in clk std_logic
TTC fabric clock.
in control_xoff_bus std_logic_vector( 7 downto 0)
XOff and BUSY.
in aurora_status_2 std_logic_vector( 31 downto 0)
aurora status hub2
in ipb_clk std_logic
ipbus clock
out ipb_out ipb_rbus
IPBus output bus going from slaves to master.
in ipb_in ipb_wbus
IPBus input bus going from master to slaves.
in rst std_logic
fabric reset
in ttc_info std_logic_vector( 35 downto 0)
ttc_L1ID & ttc_ECRID & ttc_pr_rdout & ttc_ECR & ttc_BCR & ttc_L1A
Generic Counter for process FPGA.
in CLK STD_LOGIC
Clock signal input.
in CE STD_LOGIC
Enable signal input.
out Q STD_LOGIC_VECTOR( width- 1 downto 0)
Counter Output signal.
in RST STD_LOGIC
Reset signal input.