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

Back to eFEX documentation
IPBusTopMergingModule.vhd
Go to the documentation of this file.
1 
8 
9 library IEEE;
10 use IEEE.STD_LOGIC_1164.all;
11 use IEEE.NUMERIC_STD.all;
12 
13 library work;
14 use work.ipbus_decode_efex_merging.all;
15 
16 use work.DataTypes.all;
17 use work.AlgoDataTypes.all;
18 
19 library ipbus_lib;
20 use ipbus_lib.ipbus_reg_types.all;
21 
22 use ipbus_lib.ipbus.all;
23 
26  generic (TEST : boolean := false;
27  ENABLE : std_logic := '1'
28  );
29  port (
30  CLK : in std_logic;
31 
32  IN_Data : in AlgoTriggerObjects(3 downto 0);
33  IN_Sync : in std_logic;
34  IN_BCN_sync : in std_logic_vector(3 downto 0); -- BCN synch from other FPGAs
35 
36  --TOB BCN delay
37  IN_local_BCN : in std_logic_vector(11 downto 0);
38  OUT_merged_BCN : out std_logic_vector(11 downto 0);
39 
40  --IPBus connection
41  ipb_clk : in std_logic;
42  ipb_rst : in std_logic;
43  ipb_in : in ipb_wbus;
44  ipb_out : out ipb_rbus;
45 
46  OUT_Sync : out std_logic;
47  OUT_Valid : out std_logic;
48  OUT_TOB : out AlgoTriggerObject);
50 
53  constant N_CTRL : positive := 3; --number of control reg
54  constant N_STAT : positive := 2; --number of status reg
55 
56  -- Algorithm signal
57 
58 -- IPBus signals
59  signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0);
60  signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0) := (others => IPB_RBUS_NULL);
61 
62  signal write_reg : ipb_reg_v(N_STAT - 1 downto 0) := (others => (others => '0'));
63  signal read_reg : ipb_reg_v(N_CTRL - 1 downto 0);
64 
65 -- registers
66  signal regMergingControl, regInternalSortingControl, regMergingStatus, regOffset : AlgoRegister;
67 
68 -- i/o signals
69  signal MergingStart : std_logic;
70  signal MergedStart : std_logic;
71  signal MergedWrite : std_logic;
72  signal MergedData : AlgoTriggerObject;
73  signal MergedDataOut : AlgoTriggerObject;
74 
75  signal MergingDataIn : AlgoTriggerObjects(3 downto 0);
76  signal OffsetData : AlgoTriggerObjects(3 downto 0);
77  signal MergingData : AlgoTriggerObjects(3 downto 0);
78 
79 
80 -- spy RAMs
81  signal InputRAMOut : AlgoTriggerObjects(3 downto 0);
82  signal FakeInputEnable : std_logic := '0';
83  signal SpyInputEnable : std_logic := '0';
84 
85  signal OutputRAMOut : AlgoTriggerObject;
86  signal FakeOutputEnable : std_logic := '0';
87  signal SpyOutputEnable : std_logic := '0';
88 
89 -- syng signals
90  signal Offset0, Offset1, Offset2, Offset3 : std_logic_vector(5 downto 0);
91  signal Enable0, Enable1, Enable2, Enable3 : std_logic;
92 
93  signal bcn_sync : std_logic;
94  signal BCN_cnt3, BCN_cnt2, BCN_cnt1, BCN_cnt0 : std_logic_vector(9 downto 0) := (others => '0');
95  signal BCN_done : std_logic_vector(2 downto 0) := (others => '0');
96  signal BCN_counters : std_logic_vector(29 downto 0) := (others => '0');
97  signal reset_cnt : std_logic_vector(15 downto 0) := (others => '0');
98 
99 
100  -- to delay BCN and form the merged BCN
101  signal merged_bcn_d1, merged_bcn_d2 : std_logic_vector(11 downto 0);
102  type BCN_t is array(6 downto 0) of std_logic_vector(11 downto 0);
103  signal TOB_BCN_d : BCN_t := (others => (others => '0'));
104 
105 begin
106  ENABLED_MERGE : if ENABLE = '1' generate
107  IPBUS_FABRIC : entity ipbus_lib.ipbus_fabric_sel
108  generic map (
109  NSLV => N_SLAVES, --defined in ipbus_sel_address_table_MERGING
110  SEL_WIDTH => IPBUS_SEL_WIDTH)
111  port map (
112  sel => ipbus_sel_efex_merging(ipb_in.ipb_addr), --function defined in ipbus_sel_address_table_MERGING
113 
114  ipb_in => ipb_in,
115  ipb_out => ipb_out,
116  ipb_to_slaves => ipb_to_slaves,
117  ipb_from_slaves => ipb_from_slaves);
118  end generate ENABLED_MERGE;
119 
120  DISABLED_MERGE : if ENABLE = '0' generate
121  IPBUS_FABRIC : entity ipbus_lib.ipbus_fabric_sel
122  generic map (
123  NSLV => N_SLAVES, --defined in ipbus_sel_address_table_MERGING
124  SEL_WIDTH => IPBUS_SEL_WIDTH)
125  port map (
126  sel => (others => '0'),
127  ipb_in => IPB_WBUS_NULL,
128  ipb_out => open,
129  ipb_to_slaves => open,
130  ipb_from_slaves => (others => IPB_RBUS_NULL)
131  );
132  ipb_out <= (x"DEADBEEF", '1', '0');
133  end generate DISABLED_MERGE;
134 
135  IPBUS_MERGING_REGISTERS : entity ipbus_lib.ipbus_ctrlreg_v
136  generic map (
137  N_CTRL => N_CTRL,
138  N_STAT => N_STAT)
139  port map (
140  clk => ipb_clk,
141  reset => ipb_rst,
142  ctrl_default => (2 => x"00000003", others => x"00000000"),
143  ipbus_in => ipb_to_slaves(N_SLV_MERGING_REGISTERS),
144  ipbus_out => ipb_from_slaves(N_SLV_MERGING_REGISTERS),
145  d => write_reg,
146  q => read_reg,
147  stb => open);
148 
149  -----------------------------------------------------------------------------
150  -- TOB merging
151  -----------------------------------------------------------------------------
152  TOB_SYNCH_OFFSET : entity work.TOB_synch
153  port map (
154  CLK => CLK,
155 
156  IN_Offset0 => Offset0,
157  IN_Offset1 => Offset1,
158  IN_Offset2 => Offset2,
159  IN_Offset3 => Offset3,
160 
161  IN_BCN => IN_local_BCN,
162  OUT_BCN => TOB_BCN_d(0), --connected to additional local delay
163 
164  IN_Enable0 => Enable0,
165  IN_Enable1 => Enable1,
166  IN_Enable2 => Enable2,
167  IN_Enable3 => Enable3,
168 
169  IN_Start => IN_Sync,
170  OUT_Start => MergingStart,
171  IN_Data => MergingDataIn,
172  OUT_Data => OffsetData);
173 
174 --input MUX: real data/ data from input RAM
175  MergingData <= InputRAMOut when FakeInputEnable = '1' else OffsetData;
176 
177 
178  TOBMerging : entity work.TopSortingModule
179  generic map (
180  STAGE => 2,
181  N_TOBS => 7)
182  port map (
183  CLK => CLK,
184  IN_Control => regInternalSortingControl,
185  OUT_Status => regMergingStatus, --not used
186  IN_Start => MergingStart,
187  IN_Data => MergingData,
188  OUT_Start => MergedStart,
189  OUT_Write => MergedWrite,
190  OUT_Data => MergedData);
191 
192 -- Conversion to external TOBs
193  MergedDataOut <= to_AlgoTriggerObject(MergedData);
194 
195 --------------------------------------------------------------------------------
196 -- Input RAMs
197 --------------------------------------------------------------------------------
198 
199  inputRAM_1 : entity work.ipbus_sorting_outputRAM_wrapper
200  port map (
201  clk_ipb => ipb_clk,
202  rst => ipb_rst,
203  ipb_in => ipb_to_slaves(N_SLV_MERGING_INPUT_RAM_1),
204  ipb_out => ipb_from_slaves(N_SLV_MERGING_INPUT_RAM_1),
205 
206  BCNIn => (others => '0'),
207  SpyBCNIN => '0',
208  SortedIn => IN_Data(0),
209  rclk => CLK,
210  Sync => MergingStart,
211  we => SpyInputEnable,
212  SortedOut => InputRAMOut(0));
213 
214  inputRAM_2 : entity work.ipbus_sorting_outputRAM_wrapper
215  port map (
216  clk_ipb => ipb_clk,
217  rst => ipb_rst,
218  ipb_in => ipb_to_slaves(N_SLV_MERGING_INPUT_RAM_2),
219  ipb_out => ipb_from_slaves(N_SLV_MERGING_INPUT_RAM_2),
220 
221  BCNIn => (others => '0'),
222  SpyBCNIN => '0',
223  SortedIn => IN_Data(1),
224  rclk => CLK,
225  Sync => MergingStart,
226  we => SpyInputEnable,
227  SortedOut => InputRAMOut(1));
228 
229  inputRAM_3 : entity work.ipbus_sorting_outputRAM_wrapper
230  port map (
231  clk_ipb => ipb_clk,
232  rst => ipb_rst,
233  ipb_in => ipb_to_slaves(N_SLV_MERGING_INPUT_RAM_3),
234  ipb_out => ipb_from_slaves(N_SLV_MERGING_INPUT_RAM_3),
235 
236  BCNIn => (others => '0'),
237  SpyBCNIN => '0',
238  SortedIn => IN_Data(2),
239  rclk => CLK,
240  Sync => MergingStart,
241  we => SpyInputEnable,
242  SortedOut => InputRAMOut(2));
243 
244  inputRAM_4 : entity work.ipbus_sorting_outputRAM_wrapper
245  port map (
246  clk_ipb => ipb_clk,
247  rst => ipb_rst,
248  ipb_in => ipb_to_slaves(N_SLV_MERGING_INPUT_RAM_4),
249  ipb_out => ipb_from_slaves(N_SLV_MERGING_INPUT_RAM_4),
250 
251  BCNIn => (others => '0'),
252  SpyBCNIN => '0',
253  SortedIn => IN_Data(3),
254  rclk => CLK,
255  Sync => MergingStart,
256  we => SpyInputEnable,
257  SortedOut => InputRAMOut(3));
258 
259 
260 --------------------------------------------------------------------------------
261 -- Output RAMs
262 --------------------------------------------------------------------------------
263 
264  outputRAM : entity work.ipbus_sorting_outputRAM_wrapper
265  port map (
266  clk_ipb => ipb_clk,
267  rst => ipb_rst,
268  ipb_in => ipb_to_slaves(N_SLV_MERGING_OUTPUT_RAM),
269  ipb_out => ipb_from_slaves(N_SLV_MERGING_OUTPUT_RAM),
270 
271  BCNIn => (others => '0'),
272  SpyBCNIN => '0',
273  SortedIn => MergedDataOut,
274  rclk => CLK,
275  Sync => MergedStart,
276  we => SpyOutputEnable,
277  SortedOut => OutputRAMOut);
278 
279 --output MUX: real data/ data from output RAM
280  ENABLED_MERGING_OUTPUT : if ENABLE = '1' generate
281  -- input
282  MergingDataIn <= IN_Data;
283  -- output
284  OUT_TOB <= OutputRAMOut when FakeOutputEnable = '1' else MergedDataOut;
285  OUT_Valid <= '1' when FakeOutputEnable = '1' else MergedWrite;
286  OUT_Sync <= MergedStart;
287  end generate ENABLED_MERGING_OUTPUT;
288 
289  DISABLED_MERGING_OUTPUT : if ENABLE = '0' generate
290  -- input
291  MergingDataIn <= (ZERO_ALGO_TRIGGER_OBJECT, ZERO_ALGO_TRIGGER_OBJECT, ZERO_ALGO_TRIGGER_OBJECT, ZERO_ALGO_TRIGGER_OBJECT);
292  -- output
293  OUT_TOB <= (others => '0');
294  OUT_Valid <= '0';
295  OUT_Sync <= '0';
296  end generate DISABLED_MERGING_OUTPUT;
297 
298 
299  BCN_FPGA_sych : process (CLK)
300  begin
301  if rising_edge(CLK) then
302  -- handling BCN counters
303  if IN_BCN_sync(3) = '1' then
304  BCN_cnt0 <= (others => '0');
305  BCN_cnt1 <= (others => '0');
306  BCN_cnt2 <= (others => '0');
307  BCN_done <= IN_BCN_sync(2 downto 0); -- was "000", but this handle the case when start and stop are simulatneous
308  reset_cnt <= std_logic_vector(unsigned(reset_cnt) + 1);
309 
310  else
311  if IN_BCN_sync(0) = '1' or BCN_done(0) = '1' then
312  BCN_done(0) <= '1';
313  BCN_cnt0 <= BCN_cnt0;
314  else
315  BCN_done(0) <= BCN_done(0);
316  BCN_cnt0 <= std_logic_vector(unsigned(BCN_cnt0) + 1);
317  end if;
318 
319  if IN_BCN_sync(1) = '1' or BCN_done(1) = '1' then
320  BCN_done(1) <= '1';
321  BCN_cnt1 <= BCN_cnt1;
322  else
323  BCN_done(1) <= BCN_done(1);
324  BCN_cnt1 <= std_logic_vector(unsigned(BCN_cnt1) + 1);
325  end if;
326 
327  if IN_BCN_sync(2) = '1' or BCN_done(2) = '1' then
328  BCN_done(2) <= '1';
329  BCN_cnt2 <= BCN_cnt2;
330  else
331  BCN_done(2) <= BCN_done(2);
332  BCN_cnt2 <= std_logic_vector(unsigned(BCN_cnt2) + 1);
333  end if;
334 
335  reset_cnt <= reset_cnt;
336  end if;
337  end if;
338  end process;
339 
340  BCN_published_ipbus : process (CLK)
341  begin
342  if rising_edge(CLK) then
343  if BCN_done(0) = '1' then
344  BCN_counters(9 downto 0) <= BCN_cnt0;
345  else
346  BCN_counters(9 downto 0) <= BCN_counters(9 downto 0);
347  end if;
348 
349  if BCN_done(1) = '1' then
350  BCN_counters(19 downto 10) <= BCN_cnt1;
351  else
352  BCN_counters(19 downto 10) <= BCN_counters(19 downto 10);
353  end if;
354 
355  if BCN_done(2) = '1' then
356  BCN_counters(29 downto 20) <= BCN_cnt2;
357  else
358  BCN_counters(29 downto 20) <= BCN_counters(29 downto 20);
359  end if;
360 
361  end if;
362  end process;
363 
364 
365  OUT_merged_BCN <= TOB_BCN_d(6); -- this will be delayed as much as Offset0 + 4
366 
367  local_BCN_delay : process (CLK)
368  begin
369  if rising_edge(CLK) then
370  TOB_BCN_d(6 downto 1) <= TOB_BCN_d(5 downto 0); --add 4 more ticks of delay to compensate for merging
371  end if;
372  end process;
373 
374 
375 
376 -- Sorting registers connection
377  regMergingControl <= read_reg(0);
378  regInternalSortingControl <= read_reg(1);
379  regOffset <= read_reg(2);
380 
381  write_reg(0) <= "00" & BCN_counters;
382  write_reg(1) <= x"0" & reset_cnt & x"00" & "0" & BCN_done(2) & BCN_done(1) & BCN_done(0);
383 
384 
385 -- Sorting register funcionality
386  FakeInputEnable <= '0' when TEST else regMergingControl(0);
387  SpyInputEnable <= '0' when TEST else regMergingControl(1);
388  FakeOutputEnable <= '0' when TEST else regMergingControl(2);
389  SpyOutputEnable <= '0' when TEST else regMergingControl(3);
390 
391  Offset0 <= (0 => '1', others => '0') when TEST else regOffset(5 downto 0);
392  Offset1 <= (0 => '1', others => '0') when TEST else regOffset(13 downto 8);
393  Offset2 <= (0 => '0', others => '0') when TEST else regOffset(21 downto 16);
394  Offset3 <= (0 => '1', others => '0') when TEST else regOffset(29 downto 24);
395 
396  Enable0 <= '1' when TEST else not regOffset(7);
397  Enable1 <= '1' when TEST else not regOffset(15);
398  Enable2 <= '0' when TEST else not regOffset(23);
399  Enable3 <= '1' when TEST else not regOffset(31);
400 
401 end architecture;
External data-types and functions.
array(natural range <> ) of AlgoTriggerObject AlgoTriggerObjects
Algorithm OUTPUT port.
std_logic_vector( OUT_TOB_WIDTH- 1 downto 0) AlgoTriggerObject
Algorithm Trigger Object TOB.
Top of TOB merging module with IPBus interface.
AlgoTriggerObjects( 3 downto 0) MergingDataIn
Input data before offset.
AlgoTriggerObjects( 3 downto 0) MergingData
Input data after demux.
AlgoTriggerObjects( 3 downto 0) OffsetData
Input data after offset, before demux.
Top of TOB merging module with IPBus interface.
TOB synchronisation module.
Definition: TOB_synch.vhd:18
Top of TOB sorting module.