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

Back to eFEX documentation
tob_merger_spy.vhd
1 -- MUX TOB packets into spy RAM when error in input data or debug packet created...
2 --
3 -- Dave Sankey, November 2022
4 
5 library ieee;
6 use ieee.std_logic_1164.all;
7 use ieee.numeric_std.all;
8 
9 LIBRARY infrastructure_lib;
10 use infrastructure_lib.packet_mux_type.all;
11 
12 LIBRARY ipbus_lib;
13 USE ipbus_lib.ipbus.all;
14 
15 entity tob_merger_spy is
16  GENERIC(
17  RAM_ADDR_WIDTH : positive := 10
18  );
19  port (
20  clk_320 : in std_logic;
21  rst_320 : in std_logic;
22 -- TOB MGT status signals
23  tob_mgt_packet_err_bus : in std_logic_vector(3 downto 0);
24  tob_mgt_length_err_bus : in std_logic_vector(3 downto 0);
25  tob_mgt_last_l1id_bus : in mgt_data_array(3 downto 0);
26 -- Merger status signals
27  L1A_seen : in std_logic;
28  Last_L1ID_merged : in std_logic_vector(31 downto 0); -- ECRID and L1ID
29 -- Merger output FIFO signals
30  merged_fifo_data : in packet_data_array(1 downto 0);
31  merged_fifo_valid : in std_logic_vector(1 downto 0);
32  merged_fifo_last : in std_logic_vector(1 downto 0);
33 -- interface to IPBus
34  clk_ipb : in std_logic;
35  rst_ipb : in std_logic;
36  rst_ipbus_addr : in std_logic;
37  ipbus_wraparound : in std_logic;
38  ipb_in : in ipb_wbus;
39  ipb_out : out ipb_rbus
40  );
41 end entity tob_merger_spy;
42 
43 Architecture rtl of tob_merger_spy is
44 
45 Component fifo_spy IS
46  GENERIC(
47  IPBUS_ADDR_WIDTH : positive := 10
48  );
49  port (
50 --- data to FIFO
51  clk_320 : in std_logic;
52  rst_320 : in std_logic;
53  fifo_data : in std_logic_vector (63 DOWNTO 0);
54  fifo_valid : in std_logic;
55  fifo_last : in std_logic;
56  fifo_tready : in std_logic;
57 -- interface to IPBus
58  clk_ipb : in std_logic;
59  rst_ipb : in std_logic;
60  rst_ipbus_addr : in std_logic;
61  ipbus_wraparound : in std_logic;
62  ipb_in : in ipb_wbus;
63  ipb_out : out ipb_rbus
64  );
65 END Component fifo_spy;
66 
67 signal bad_l1id_sig, send_tob_sig, spy_last_sig, spy_valid_sig: std_logic;
68 signal spy_data_sig: std_logic_vector (63 DOWNTO 0);
69 
70 Begin
71 
72 -- This logic only really works if the MGT errors are few and far between
73 -- so that there is only one error out there at any particular moment in time
74 -- between when it is latched in the MGT and subsequently caught in the merger.
75 -- Or more generally only the last error is guaranteed to be caught...
76 Bad_mgt_L1ID_latch: process(clk_320)
77 variable error_pending_bus: std_logic_vector(3 downto 0) := (Others => '0');
78 variable last_error_l1id_bus: mgt_data_array(3 downto 0) := (Others => (Others => '0'));
79 variable found_bad_l1id: std_logic := '0';
80 begin
81  if (rising_edge(clk_320)) then
82  if (rst_320 = '1') then
83  error_pending_bus := (Others => '0');
84  for i in 3 downto 0 loop
85  last_error_l1id_bus(i) := (Others => '0');
86  end loop;
87  else
88  found_bad_l1id := '0';
89  for i in 3 downto 0 loop
90  if (L1A_seen = '1') and (error_pending_bus(i) = '1') and (Last_L1ID_merged = last_error_l1id_bus(i)) then
91  error_pending_bus(i) := '0';
92  found_bad_l1id := '1';
93  end if;
94  if (tob_mgt_packet_err_bus(i) = '1') or (tob_mgt_length_err_bus(i) = '1') then
95  last_error_l1id_bus(i) := tob_mgt_last_l1id_bus(i);
96  error_pending_bus(i) := '1';
97  end if;
98  end loop;
99  end if;
100  bad_l1id_sig <= found_bad_l1id;
101  end if;
102 end process Bad_mgt_L1ID_latch;
103 
104 -- Send TOB packet to debug spy if we latched an error in the MGT processing or we send a packet to debug for this event
105 send_tob_latch: process(clk_320)
106 variable send_tob: std_logic := '0';
107 begin
108  if (rising_edge(clk_320)) then
109  if (rst_320 = '1') or (L1A_seen = '1') then
110  send_tob := '0';
111  elsif (bad_l1id_sig = '1') or (merged_fifo_valid(1) = '1') then
112  send_tob := '1';
113  end if;
114  send_tob_sig <= send_tob;
115  end if;
116 end process send_tob_latch;
117 
118 send_to_spy_block: process(clk_320)
119 variable spy_data: std_logic_vector(63 downto 0);
120 variable spy_valid, spy_last: std_logic;
121 begin
122  if (rising_edge(clk_320)) then
123  if (merged_fifo_valid(1) = '1') then
124  spy_data := merged_fifo_data(1);
125  spy_last := merged_fifo_last(1);
126  spy_valid := '1';
127  elsif (merged_fifo_valid(0) = '1') and (send_tob_sig = '1') then
128  spy_data := merged_fifo_data(0);
129  spy_last := merged_fifo_last(0);
130  spy_valid := '1';
131  else
132  spy_data := (Others => '0');
133  spy_last := '0';
134  spy_valid := '0';
135  end if;
136  spy_data_sig <= spy_data;
137  spy_last_sig <= spy_last;
138  spy_valid_sig <= spy_valid;
139  end if;
140 end process send_to_spy_block;
141 
142 debug_spy : fifo_spy
143  GENERIC map (
144  IPBUS_ADDR_WIDTH => RAM_ADDR_WIDTH
145  )
146  port map (
147 --- data to FIFO
148  clk_320 => clk_320,
149  rst_320 => rst_320,
150  fifo_data => spy_data_sig,
151  fifo_valid => spy_valid_sig,
152  fifo_last => spy_last_sig,
153  fifo_tready => '1',
154 -- interface to IPBus for spy RAM
155  clk_ipb => clk_ipb,
156  rst_ipb => rst_ipb,
157  rst_ipbus_addr => rst_ipbus_addr,
158  ipbus_wraparound => ipbus_wraparound,
159  ipb_in => ipb_in,
160  ipb_out => ipb_out
161  );
162 
163 END Architecture rtl;
Capture FIFO traffic into IPBus DPRAM64...
Definition: fifo_spy.vhd:21