AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Files Variables
evt_bldrNew.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 11:26:30 01/23/2013
6 -- Design Name:
7 -- Module Name: evt_bldr - Behavioral
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 library IEEE;
21 use IEEE.STD_LOGIC_1164.ALL;
22 use IEEE.STD_LOGIC_1164.ALL;
23 use IEEE.STD_LOGIC_ARITH.ALL;
24 use IEEE.STD_LOGIC_UNSIGNED.ALL;
25 use IEEE.std_logic_misc.all;
26 use work.amc13_pack.all;
27 
28 -- Uncomment the following library declaration if using
29 -- arithmetic functions with Signed or Unsigned values
30 --use IEEE.NUMERIC_STD.ALL;
31 
32 -- Uncomment the following library declaration if instantiating
33 -- any Xilinx primitives in this code.
34 library UNISIM;
35 use UNISIM.VComponents.all;
36 Library UNIMACRO;
37 use UNIMACRO.vcomponents.all;
38 
39 entity evt_bldr is
40  Port ( clk : in STD_LOGIC;
41  reset : in STD_LOGIC;
42  fifo_rst : in STD_LOGIC;
43  fifo_en : in STD_LOGIC;
44  en_inject_err : in STD_LOGIC;
45  OneSFP : in STD_LOGIC;
46  Source_ID : in STD_LOGIC_VECTOR (7 downto 0);
47  block_wc : in STD_LOGIC_VECTOR (15 downto 0);
48  block_wc_we : in STD_LOGIC;
49  AMC_wc : in STD_LOGIC_VECTOR (17 downto 0); -- bit 12-0 64bit word count, bit 16-13 is AMC channel number bit 17 marks this is the last block of an event
50  AMC_wc_we : in STD_LOGIC;
51  AMC_wc_end : in STD_LOGIC;
52  bldr_fifo_full : out STD_LOGIC;
53  AMC_header : in STD_LOGIC_VECTOR (65 downto 0);
54  AMC_header_we : in STD_LOGIC;
55  AMC_DATA : in array12X64;
56  AMC_DATA_re : out STD_LOGIC_VECTOR (11 downto 0);
57  AMCCRC_bad : out STD_LOGIC_VECTOR (11 downto 0);
58  evt_data : out STD_LOGIC_VECTOR (66 downto 0);
59  evt_data_we : out STD_LOGIC;
60  evt_buf_full : in STD_LOGIC;
61  evt_data_re : in STD_LOGIC;
62  evt_data_rdy : out STD_LOGIC;
63  debug : out STD_LOGIC_VECTOR (255 downto 0);
64  EventBuilt : out STD_LOGIC);
65 end evt_bldr;
66 
67 architecture Behavioral of evt_bldr is
68 COMPONENT EthernetCRCD64
69  PORT(
70  clk : IN std_logic;
71  init : IN std_logic;
72  init_crc : IN std_logic_vector(31 downto 0);
73  ce : IN std_logic;
74  trailer : IN std_logic;
75  d : IN std_logic_vector(63 downto 0);
76  crc : OUT std_logic_vector(31 downto 0);
77  bad_crc : OUT std_logic
78  );
79 END COMPONENT;
80 COMPONENT cmsCRC64
81  PORT(
82  clk : IN std_logic;
83  reset : IN std_logic;
84  crc_init : IN std_logic;
85  inject_err : IN std_logic;
86  trailer : IN std_logic;
87  crc_d : IN std_logic_vector(63 downto 0);
88  crc_ce : IN std_logic;
89  crc : OUT std_logic_vector(15 downto 0);
90  crc_err : OUT std_logic;
91  dout : OUT std_logic_vector(63 downto 0);
92  dout_vld : OUT std_logic
93  );
94 END COMPONENT;
95 COMPONENT RAM32x6Db
96  PORT(
97  wclk : IN std_logic;
98  di : IN std_logic_vector(5 downto 0);
99  we : IN std_logic;
100  wa : IN std_logic_vector(4 downto 0);
101  ra : IN std_logic_vector(4 downto 0);
102  do : OUT std_logic_vector(5 downto 0)
103  );
104 END COMPONENT;
105 signal fifo_we : std_logic := '0';
106 signal fifo_re : std_logic := '0';
107 --signal fifo_empty : std_logic_vector(7 downto 0) := (others => '1');
108 signal fifo_empty : std_logic := '1';
109 signal fifo_full : std_logic := '0';
110 signal FIFO_di : std_logic_vector(66 downto 0) := (others => '0');
111 signal FIFO_do : std_logic_vector(66 downto 0) := (others => '0');
112 signal channel : std_logic_vector(3 downto 0) := (others => '0');
113 signal evt_data_we_i : std_logic := '0';
114 signal en_output : std_logic := '0';
115 signal evt_data_vld : std_logic := '0';
116 signal evt_buf_do_vld : std_logic := '0';
117 signal evt_buf_re : std_logic := '0';
118 signal evt_cnt : std_logic_vector(3 downto 0) := (others => '0');
119 signal evt_buf_regce : std_logic := '0';
120 signal evt_buf_we : std_logic_vector(0 downto 0) := (others => '0');
121 signal buf_full : std_logic := '0';
122 signal AMC_DATA_re_i : std_logic := '0';
123 signal AMC_header_avl : std_logic := '0';
124 signal AMC_header_re : std_logic := '0';
125 signal header_ra_selected : std_logic := '0';
126 signal AMC_header_vld : std_logic := '0';
127 --signal ec_header_wa : std_logic := '0';
128 signal evt_buf_avl : std_logic := '0';
129 signal FIFO_Di_vld : std_logic := '0';
130 signal evt_buf_wc : std_logic_vector(11 downto 0) := (others => '0');
131 signal evt_buf_wa : std_logic_vector(11 downto 0) := (others => '0');
132 signal FIFO_data_wa : std_logic_vector(11 downto 0) := (others => '0');
133 signal FIFO_data_wa_q : std_logic_vector(11 downto 0) := (others => '0');
134 signal header_fifo_wc : std_logic_vector(6 downto 0) := (others => '0');
135 signal header_wa : std_logic_vector(6 downto 0) := (others => '0');
136 signal header_ra : std_logic_vector(6 downto 0) := (others => '0');
137 signal evt_buf_din : std_logic_vector(66 downto 0) := (others => '0');
138 signal evt_buf_doa : std_logic_vector(66 downto 0) := (others => '0');
139 signal evt_buf_ra : std_logic_vector(11 downto 0) := (others => '0');
140 signal evt_buf_dout : std_logic_vector(66 downto 0) := (others => '0');
141 signal wc_fifo_wa : std_logic_vector(5 downto 0) := (others => '0');
142 signal wc_fifo_ra : std_logic_vector(5 downto 0) := (others => '0');
143 signal wc_fifo_di : std_logic_vector(18 downto 0) := (others => '0');
144 signal wc_fifo_do : std_logic_vector(18 downto 0) := (others => '0');
145 signal wc_fifo_we : std_logic := '0';
146 signal wc_fifo_full : std_logic := '0';
147 signal header_full : std_logic := '0';
148 signal HeaderWC_full : std_logic := '0';
149 signal wc_fifo_empty : std_logic := '0';
150 signal wc_fifo_di_vld : std_logic := '0';
151 signal NoAMCenabled : std_logic := '1';
152 signal idle : std_logic := '1';
153 --signal first_hw : std_logic := '1';
154 signal read_AMC : std_logic := '0';
155 signal read_AMC_q : std_logic := '0';
156 signal last_channel : std_logic := '0';
157 signal wc : std_logic_vector(12 downto 0) := (others => '0');
158 signal HeaderWC : std_logic_vector(3 downto 0) := (others => '0');
159 signal HeaderWC_i : std_logic_vector(3 downto 0) := (others => '0');
160 signal HeaderWC_o : std_logic_vector(3 downto 0) := (others => '0');
161 signal HeaderWC_a : std_logic_vector(3 downto 0) := (others => '0');
162 signal HeaderWC_we : std_logic := '0';
163 signal HeaderWC_re : std_logic := '0';
164 signal crc_init : std_logic := '0';
165 signal crc_ce : std_logic := '0';
166 signal rd_last_header : std_logic := '0';
167 signal rd_last_header_q : std_logic := '0';
168 signal crc_data : std_logic_vector(63 downto 0) := (others => '0');
169 signal BlockCRC_init : std_logic := '0';
170 signal BlockCRC_ce : std_logic := '0';
171 signal BlockCRC_ce_q : std_logic := '0';
172 signal BlockCRC : std_logic_vector(31 downto 0) := (others => '0');
173 signal BlockCRC_data : std_logic_vector(63 downto 0) := (others => '0');
174 signal BlockCRC_data_r : std_logic_vector(63 downto 0) := (others => '0');
175 signal block_num : std_logic_vector(11 downto 0) := (others => '0');
176 signal Lv1bx : std_logic_vector(19 downto 0) := (others => '0');
177 signal trailer_we : std_logic := '0';
178 signal inject_err : std_logic := '0';
179 signal first_block : std_logic := '0';
180 signal last_block : std_logic := '0';
181 signal block_wc_a : std_logic_vector(3 downto 0) := (others => '1');
182 signal block_wc_o : std_logic_vector(15 downto 0) := (others => '0');
183 signal block_trailer : std_logic := '0';
184 signal block_trailer_dl : std_logic_vector(4 downto 0) := (others => '0');
185 signal trailer : std_logic_vector(63 downto 0) := (others => '0');
186 signal trailer_dl : std_logic_vector(2 downto 0) := (others => '0');
187 type array8X12 is array (0 to 7) of std_logic_vector(11 downto 0);
188 signal rdcount : array8X12 := (others => (others => '0'));
189 signal wrcount : array8X12 := (others => (others => '0'));
190 signal evt_data_rdy_i : std_logic := '0';
191 signal AMCCRC_init : std_logic := '0';
192 signal init_AMCCRC : std_logic := '0';
193 signal AMCCRC_ce : std_logic := '0';
194 signal AMC_trailer : std_logic := '0';
195 signal AMClastWord : std_logic := '0';
196 signal bad_AMCCRC : std_logic := '0';
197 signal chk_AMCCRC : std_logic := '0';
198 signal bad_AMCCRC_l : std_logic_vector(11 downto 0) := (others => '0');
199 signal AMCCRC : std_logic_vector(31 downto 0) := (others => '0');
200 signal saved_AMCCRC : std_logic_vector(31 downto 0) := (others => '0');
201 signal saved_AMCCRC_di : std_logic_vector(31 downto 0) := (others => '0');
202 signal saved_AMCCRC_do : std_logic_vector(31 downto 0) := (others => '0');
203 signal saved_AMCCRC_a : std_logic_vector(4 downto 0) := (others => '0');
204 begin
205 debug(255 downto 236) <= (others => '0');
206 debug(235 downto 224) <= evt_buf_wc;
207 debug(223 downto 212) <= evt_buf_ra;
208 debug(211 downto 200) <= evt_buf_wa;
209 debug(199) <= AMC_DATA_re_i;
210 debug(198) <= evt_data_vld;
211 debug(197) <= evt_buf_regce;
212 debug(196) <= evt_buf_re;
213 debug(195) <= evt_buf_we(0);
214 debug(194 downto 131) <= crc_data;
215 debug(130 downto 66) <= evt_buf_din(64 downto 0);
216 debug(65) <= AMC_DATA_re_i;
217 debug(63 downto 0) <= BlockCRC_data;
218 --debug(82 downto 64) <= wc_fifo_do;
219 --debug(60) <= evt_data_rdy_i;
220 --debug(59) <= evt_data_re;
221 --debug(58) <= FIFO_empty;
222 --debug(57) <= evt_buf_full;
223 --debug(56) <= en_output;
224 --debug(55) <= evt_data_we_i;
225 --debug(54) <= evt_buf_avl;
226 --debug(53) <= AMC_DATA_re_i;
227 --debug(52) <= idle;
228 --debug(51) <= wc_fifo_empty;
229 --debug(50) <= fifo_full;
230 --debug(49 downto 44) <= wc_fifo_a;
231 --debug(43 downto 32) <= evt_buf_wc;
232 --debug(31 downto 28) <= channel;
233 --debug(27 downto 16) <= evt_buf_wa;
234 --debug(15 downto 12) <= evt_cnt;
235 --debug(11 downto 0) <= evt_buf_ra;
236 evt_data <= evt_buf_dout(66 downto 0);
237 evt_data_we <= evt_data_we_i;
238 evt_data_rdy <= evt_data_rdy_i;
239 EventBuilt <= trailer_we;
240 g_wc_fifo: for i in 0 to 18 generate
241  i_wc_fifo : RAM64X1D
242  port map (
243  DPO => wc_fifo_do(i), -- Read-only 1-bit data output
244  SPO => open, -- R/W 1-bit data output
245  A0 => wc_fifo_wa(0), -- R/W address[0] input bit
246  A1 => wc_fifo_wa(1), -- R/W address[1] input bit
247  A2 => wc_fifo_wa(2), -- R/W address[2] input bit
248  A3 => wc_fifo_wa(3), -- R/W address[3] input bit
249  A4 => wc_fifo_wa(4), -- R/W address[4] input bit
250  A5 => wc_fifo_wa(5), -- R/W address[5] input bit
251  D => wc_fifo_di(i), -- Write 1-bit data input
252  DPRA0 => wc_fifo_ra(0), -- Read-only address[0] input bit
253  DPRA1 => wc_fifo_ra(1), -- Read-only address[1] input bit
254  DPRA2 => wc_fifo_ra(2), -- Read-only address[2] input bit
255  DPRA3 => wc_fifo_ra(3), -- Read-only address[3] input bit
256  DPRA4 => wc_fifo_ra(4), -- Read-only address[4] input bit
257  DPRA5 => wc_fifo_ra(5), -- Read-only address[5] input bit
258  WCLK => clk, -- Write clock input
259  WE => wc_fifo_we -- Write enable input
260  );
261 end generate;
262 wc_fifo_di(18) <= AMC_wc_end;
263 wc_fifo_we <= wc_fifo_di_vld and (AMC_wc_we or AMC_wc_end);
264 g_HeaderWC: for i in 0 to 3 generate
265  i_HeaderWC : SRL16E
266  port map (
267  Q => HeaderWC_o(i), -- SRL data output
268  A0 => HeaderWC_a(0), -- Select[0] input
269  A1 => HeaderWC_a(1), -- Select[1] input
270  A2 => HeaderWC_a(2), -- Select[2] input
271  A3 => HeaderWC_a(3), -- Select[3] input
272  CE => HeaderWC_we, -- Clock enable input
273  CLK => clk, -- Clock input
274  D => HeaderWC_i(i) -- SRL data input
275  );
276 end generate;
277 HeaderWC_re <= block_trailer;
278 g_block_wc: for i in 0 to 15 generate
279  i_block_wc : SRL16E
280  port map (
281  Q => block_wc_o(i), -- SRL data output
282  A0 => block_wc_a(0), -- Select[0] input
283  A1 => block_wc_a(1), -- Select[1] input
284  A2 => block_wc_a(2), -- Select[2] input
285  A3 => block_wc_a(3), -- Select[3] input
286  CE => block_wc_we, -- Clock enable input
287  CLK => clk, -- Clock input
288  D => block_wc(i) -- SRL data input
289  );
290 end generate;
291 process(clk)
292 begin
293  if(clk'event and clk = '1')then
294  if(reset = '1')then
295  HeaderWC_a <= (others => '1');
296  elsif(HeaderWC_we = '1' and HeaderWC_re = '0')then
297  HeaderWC_a <= HeaderWC_a + 1;
298  elsif(HeaderWC_we = '0' and HeaderWC_re = '1')then
299  HeaderWC_a <= HeaderWC_a - 1;
300  end if;
301  if(reset = '1' or HeaderWC_we = '1')then
302  HeaderWC_i <= (others => '0');
303  elsif(AMC_header_we = '1')then
304  HeaderWC_i <= HeaderWC_i + 1;
305  end if;
306  HeaderWC_we <= AMC_wc_end and or_reduce(HeaderWC_i);
307  if(reset = '1')then
308  block_wc_a <= (others => '1');
309  elsif(block_wc_we = '1' and block_trailer = '0')then
310  block_wc_a <= block_wc_a + 1;
311  elsif(block_wc_we = '0' and block_trailer = '1')then
312  block_wc_a <= block_wc_a - 1;
313  end if;
314  end if;
315 end process;
316 process(clk)
317 begin
318  if(clk'event and clk = '1')then
319  if(AMC_wc_we = '1')then
320  wc_fifo_di(17 downto 0) <= AMC_wc;
321  end if;
322  if(reset = '1')then
323  NoAMCenabled <= '0';
324  elsif(AMC_wc_end = '1')then
325  NoAMCenabled <= not wc_fifo_di_vld;
326  end if;
327  if(reset = '1' or AMC_wc_end = '1')then
328  wc_fifo_di_vld <= '0';
329  elsif(AMC_wc_we = '1')then
330  wc_fifo_di_vld <= '1';
331  end if;
332  if(AMC_header_we = '1')then
333  evt_buf_din(66) <= '0';
334  evt_buf_din(65 downto 0) <= AMC_header;
335  else
336  evt_buf_din <= FIFO_do;
337  end if;
338  if(reset = '1')then
339  evt_buf_wa <= (others => '0');
340  elsif(AMC_header_we = '1')then
341  evt_buf_wa <= "11111" & header_wa;
342  elsif(AMC_header_re = '1')then
343  evt_buf_wa <= "11111" & header_ra;
344  else
345  evt_buf_wa <= FIFO_data_wa;
346  end if;
347  if(reset = '1')then
348  FIFO_data_wa <= (others => '0');
349  elsif(FIFO_re = '1')then
350  if(FIFO_data_wa = x"f7f")then
351  FIFO_data_wa <= (others => '0');
352  else
353  FIFO_data_wa <= FIFO_data_wa + 1;
354  end if;
355  end if;
356  if(reset = '1')then
357  FIFO_data_wa_q <= (others => '0');
358  else
359  FIFO_data_wa_q <= FIFO_data_wa;
360  end if;
361  evt_buf_we(0) <= not reset and (FIFO_re or AMC_header_we);
362  if(reset = '1' or (evt_buf_wc(11 downto 8) = x"f" and evt_buf_wc(6 downto 3) = x"f"))then
363  evt_buf_avl <= '0';
364  else
365  evt_buf_avl <= '1';
366  end if;
367  if(reset = '1')then
368  header_wa <= (others => '0');
369  elsif(AMC_header_we = '1')then
370  header_wa <= header_wa + 1;
371  end if;
372  if(reset = '1' or and_reduce(HeaderWC_a) = '1')then
373  AMC_header_avl <= '0';
374  else
375  AMC_header_avl <= '1';
376  end if;
377  header_ra_selected <= not reset and AMC_header_re and not AMC_header_we;
378  AMC_header_vld <= not reset and header_ra_selected;
379  if(AMC_header_vld = '1')then
380  FIFO_di(66) <= not evt_buf_doa(64);
381  end if;
382  BlockCRC_ce <= not reset and (AMC_header_vld or AMC_DATA_re_i or block_trailer);
383  if(AMC_DATA_re_i = '1')then
384  BlockCRC_data <= AMC_DATA(CONV_INTEGER(channel));
385  elsif(block_trailer = '1')then
386  BlockCRC_data <= x"00000000" & block_num & Lv1Bx;
387  elsif(evt_buf_doa(65) = '1')then
388  BlockCRC_data <= evt_buf_doa(63 downto 52) & block_wc_o & evt_buf_doa(35 downto 0);
389  else
390  BlockCRC_data <= evt_buf_doa(63 downto 0);
391  end if;
392  if(reset = '1')then
393  block_trailer_dl(2 downto 0) <= (others => '0');
394  else
395  block_trailer_dl(2 downto 0) <= block_trailer_dl(1 downto 0) & block_trailer;
396  end if;
397  if(block_trailer = '1')then
398  inject_err <= en_inject_err and last_block and and_reduce(Lv1Bx(19 downto 12)); -- one in 256 events
399  end if;
400  if(block_trailer_dl(1) = '0')then
401  BlockCRC_data_r <= BlockCRC_data;
402  elsif(inject_err = '0')then
403  BlockCRC_data_r <= BlockCRC & BlockCRC_data_r(31 downto 0);
404  end if;
405  BlockCRC_init <= reset or block_trailer_dl(0);
406  if(trailer_we = '1')then
407  crc_data <= trailer;
408  else
409  crc_data <= BlockCRC_data_r;
410  end if;
411  BlockCRC_ce_q <= not reset and ((BlockCRC_ce and not block_trailer_dl(0)) or block_trailer_dl(1));
412  crc_ce <= not reset and (trailer_we or BlockCRC_ce_q);
413  crc_init <= reset or trailer_dl(0);
414  header_fifo_wc <= header_wa - header_ra;
415  if(header_fifo_wc(6 downto 4) = "111")then
416  header_full <= '1';
417  else
418  header_full <= '0';
419  end if;
420  if(HeaderWC_a = x"e")then
421  HeaderWC_full <= '1';
422  else
423  HeaderWC_full <= '0';
424  end if;
425  bldr_fifo_full <= reset or wc_fifo_full or header_full or HeaderWC_full;
426  end if;
427 end process;
428 process(clk)
429 variable wc_fifo_wc : std_logic_vector(5 downto 0);
430 begin
431  wc_fifo_wc := wc_fifo_wa - wc_fifo_ra;
432  if(clk'event and clk = '1')then
433  if(reset = '1')then
434  wc_fifo_wa <= (others => '0');
435  elsif(wc_fifo_we = '1')then
436  wc_fifo_wa <= wc_fifo_wa + 1;
437  end if;
438  if(reset = '1')then
439  wc_fifo_ra <= (others => '0');
440  elsif(read_AMC = '1')then
441  wc_fifo_ra <= wc_fifo_ra + 1;
442  end if;
443  if(wc_fifo_wc(5 downto 4) = "11")then
444  wc_fifo_full <= '1';
445  elsif(OneSFP = '0' and wc_fifo_wc(5 downto 3) = "111")then
446  wc_fifo_full <= '1';
447  else
448  wc_fifo_full <= '0';
449  end if;
450  if(reset = '1' or wc_fifo_wa = wc_fifo_ra)then
451  wc_fifo_empty <= '1';
452  else
453  wc_fifo_empty <= '0';
454  end if;
455  end if;
456 end process;
457 i_BlockCRC: EthernetCRCD64 PORT MAP(
458  clk => clk,
459  init => BlockCRC_init ,
460  init_crc => (others => '1'),
461  ce => BlockCRC_ce ,
462  trailer => block_trailer_dl (0),
463  d => BlockCRC_data,
464  crc => BlockCRC ,
465  bad_crc => open
466  );
467 i_EventCRC: cmsCRC64 PORT MAP(
468  clk => clk,
469  reset => reset,
470  crc_init => crc_init,
471  inject_err => inject_err,
472  trailer => trailer_dl(0),
473  crc_d => crc_data,
474  crc_ce => crc_ce,
475  crc => open,
476  crc_err => open,
477  dout => FIFO_di (63 downto 0),
478  dout_vld => FIFO_di_vld
479  );
480 g_evt_FIFO: for i in 0 to 6 generate
481  i_evt_FIFO : FIFO_DUALCLOCK_MACRO
482  generic map (
483  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES"
484  ALMOST_FULL_OFFSET => X"0010", -- Sets almost full threshold
485  ALMOST_EMPTY_OFFSET => X"0080", -- Sets the almost empty threshold
486  DATA_WIDTH => 9, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb")
487  FIFO_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
488  FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE
489  port map (
490  ALMOSTEMPTY => open, -- 1-bit output almost empty
491  ALMOSTFULL => open, -- 1-bit output almost full
492  DO => FIFO_do(i*9+8 downto i*9), -- Output data, width defined by DATA_WIDTH parameter
493  EMPTY => open, -- 1-bit output empty
494  FULL => open, -- 1-bit output full
495  RDCOUNT => rdcount(i), -- Output read count, width determined by FIFO depth
496  RDERR => open, -- 1-bit output read error
497  WRCOUNT => wrcount(i), -- Output write count, width determined by FIFO depth
498  WRERR => open, -- 1-bit output write error
499  DI => FIFO_di(i*9+8 downto i*9), -- Input data, width defined by DATA_WIDTH parameter
500  RDCLK => clk, -- 1-bit input read clock
501  RDEN => FIFO_re, -- 1-bit input read enable
502  RST => fifo_rst, -- 1-bit input reset
503  WRCLK => clk, -- 1-bit input write clock
504  WREN => FIFO_we -- 1-bit input write enable
505  );
506 end generate;
507 i_evt_FIFO_MSB : FIFO_DUALCLOCK_MACRO
508  generic map (
509  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES"
510  ALMOST_FULL_OFFSET => X"0020", -- Sets almost full threshold
511  ALMOST_EMPTY_OFFSET => X"0080", -- Sets the almost empty threshold
512  DATA_WIDTH => 4, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb")
513  FIFO_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb"
514  FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE
515  port map (
516  ALMOSTEMPTY => open, -- 1-bit output almost empty
517  ALMOSTFULL => fifo_full, -- 1-bit output almost full
518  DO => FIFO_do(66 downto 63), -- Output data, width defined by DATA_WIDTH parameter
519  EMPTY => FIFO_empty, -- 1-bit output empty
520  FULL => open, -- 1-bit output full
521  RDCOUNT => rdcount(7), -- Output read count, width determined by FIFO depth
522  RDERR => open, -- 1-bit output read error
523  WRCOUNT => wrcount(7), -- Output write count, width determined by FIFO depth
524  WRERR => open, -- 1-bit output write error
525  DI => FIFO_di(66 downto 63), -- Input data, width defined by DATA_WIDTH parameter
526  RDCLK => clk, -- 1-bit input read clock
527  RDEN => FIFO_re, -- 1-bit input read enable
528  RST => fifo_rst, -- 1-bit input reset
529  WRCLK => clk, -- 1-bit input write clock
530  WREN => FIFO_we -- 1-bit input write enable
531  );
532 FIFO_di(65) <= trailer_dl(2);
533 --FIFO_re <= fifo_en and evt_buf_avl and not or_reduce(FIFO_empty) and not AMC_header_we and not AMC_header_re;
534 FIFO_re <= fifo_en and evt_buf_avl and not FIFO_empty and not AMC_header_we and not AMC_header_re;
535 FIFO_we <= fifo_en and FIFO_Di_vld;
536 process(clk)
537 begin
538  if(clk'event and clk = '1')then
539  if(reset = '1')then
540  en_output <= '0';
541  elsif(evt_data_re = '1' and evt_data_rdy_i = '1')then
542  en_output <= '1';
543  elsif(evt_data_we_i = '1' and evt_buf_dout(64) = '1')then
544  en_output <= '0';
545  end if;
546  if(reset = '1' or (evt_data_we_i = '1' and evt_buf_dout(64) = '1') or evt_data_vld = '0' or (evt_data_we_i = '1' and evt_buf_do_vld = '0'))then
547  evt_data_we_i <= '0';
548  else
549  evt_data_we_i <= en_output and not evt_buf_full;
550  end if;
551  if(reset = '1')then
552  evt_data_vld <= '0';
553  elsif(evt_buf_do_vld = '1')then
554  evt_data_vld <= '1';
555  elsif(evt_data_we_i = '1')then
556  evt_data_vld <= '0';
557  end if;
558  if(reset = '1')then
559  evt_buf_do_vld <= '0';
560  elsif(FIFO_data_wa_q /= evt_buf_ra)then
561  evt_buf_do_vld <= '1';
562  elsif(evt_data_vld = '0' or evt_data_we_i = '1')then
563  evt_buf_do_vld <= '0';
564  end if;
565  if(reset = '1')then
566  evt_buf_ra <= (others => '0');
567  elsif(FIFO_data_wa_q /= evt_buf_ra and evt_buf_re = '1')then
568  if(evt_buf_ra = x"f7f")then
569  evt_buf_ra <= (others => '0');
570  else
571  evt_buf_ra <= evt_buf_ra + 1;
572  end if;
573  end if;
574  if(reset = '1')then
575  trailer_dl <= (others => '0');
576  else
577  trailer_dl <= trailer_dl(1 downto 0) & trailer_we;
578  end if;
579  if(reset = '1')then
580  evt_cnt <= (others => '0');
581  elsif(trailer_we = '1' and (evt_buf_dout(65) = '0' or evt_data_we_i = '0'))then
582  evt_cnt <= evt_cnt + 1;
583  elsif(trailer_we = '0' and evt_buf_dout(65) = '1' and evt_data_we_i = '1')then
584  evt_cnt <= evt_cnt - 1;
585  end if;
586  if(reset = '1' or evt_data_we_i = '1' or evt_data_vld = '0')then
587  evt_data_rdy_i <= '0';
588  else
589  evt_data_rdy_i <= or_reduce(evt_cnt) or or_reduce(evt_buf_wc(11 downto 8));
590  end if;
591  if(reset = '1')then
592  evt_buf_wc <= (others => '0');
593 -- elsif(evt_data_we_i = '0' and FIFO_re = '1')then
594  elsif((or_reduce(evt_buf_wc) = '0' or evt_buf_re = '0') and FIFO_re = '1')then
595  evt_buf_wc <= evt_buf_wc + 1;
596 -- elsif(evt_data_we_i = '1' and FIFO_re = '0')then
597  elsif(or_reduce(evt_buf_wc) = '1' and evt_buf_re = '1' and FIFO_re = '0')then
598  evt_buf_wc <= evt_buf_wc - 1;
599  end if;
600  end if;
601 end process;
602 g_evt_buf: for i in 0 to 6 generate
603  i_evt_buf : BRAM_TDP_MACRO
604  generic map (
605  BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
606  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
607  DOA_REG => 0, -- Optional port A output register (0 or 1)
608  DOB_REG => 1, -- Optional port B output register (0 or 1)
609  INIT_A => X"000000000", -- Initial values on A output port
610  INIT_B => X"000000000", -- Initial values on B output port
611  INIT_FILE => "NONE",
612  READ_WIDTH_A => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
613  READ_WIDTH_B => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
614  SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY",
615  -- "GENERATE_X_ONLY" or "NONE"
616  SRVAL_A => X"000000000", -- Set/Reset value for A port output
617  SRVAL_B => X"000000000", -- Set/Reset value for B port output
618  WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
619  WRITE_MODE_B => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
620  WRITE_WIDTH_A => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
621  WRITE_WIDTH_B => 9) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
622  port map (
623  DOA => evt_buf_doA(i*9+8 downto i*9), -- Output port-A data, width defined by READ_WIDTH_A parameter
624  DOB => evt_buf_dout(i*9+8 downto i*9), -- Output port-B data, width defined by READ_WIDTH_B parameter
625  ADDRA => evt_buf_wa, -- Input port-A address, width defined by Port A depth
626  ADDRB => evt_buf_ra, -- Input port-B address, width defined by Port B depth
627  CLKA => clk, -- 1-bit input port-A clock
628  CLKB => clk, -- 1-bit input port-B clock
629  DIA => evt_buf_din(i*9+8 downto i*9), -- Input port-A data, width defined by WRITE_WIDTH_A parameter
630  DIB => (others => '0'), -- Input port-B data, width defined by WRITE_WIDTH_B parameter
631  ENA => '1', -- 1-bit input port-A enable
632  ENB => evt_buf_re, -- 1-bit input port-B enable
633  REGCEA => '1', -- 1-bit input port-A output register enable
634  REGCEB => evt_buf_regce, -- 1-bit input port-B output register enable
635  RSTA => '0', -- 1-bit input port-A reset
636  RSTB => '0', -- 1-bit input port-B reset
637  WEA => evt_buf_we, -- Input port-A write enable, width defined by Port A depth
638  WEB => "0" -- Input port-B write enable, width defined by Port B depth
639  );
640 end generate;
641 i_evt_buf_MSB : BRAM_TDP_MACRO
642  generic map (
643  BRAM_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb"
644  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
645  DOA_REG => 0, -- Optional port A output register (0 or 1)
646  DOB_REG => 1, -- Optional port B output register (0 or 1)
647  INIT_A => X"000000000", -- Initial values on A output port
648  INIT_B => X"000000000", -- Initial values on B output port
649  INIT_FILE => "NONE",
650  READ_WIDTH_A => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
651  READ_WIDTH_B => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
652  SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY",
653  -- "GENERATE_X_ONLY" or "NONE"
654  SRVAL_A => X"000000000", -- Set/Reset value for A port output
655  SRVAL_B => X"000000000", -- Set/Reset value for B port output
656  WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
657  WRITE_MODE_B => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
658  WRITE_WIDTH_A => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
659  WRITE_WIDTH_B => 4) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
660  port map (
661  DOA => evt_buf_doA(66 downto 63), -- Output port-A data, width defined by READ_WIDTH_A parameter
662  DOB => evt_buf_dout(66 downto 63), -- Output port-B data, width defined by READ_WIDTH_B parameter
663  ADDRA => evt_buf_wa, -- Input port-A address, width defined by Port A depth
664  ADDRB => evt_buf_ra, -- Input port-B address, width defined by Port B depth
665  CLKA => clk, -- 1-bit input port-A clock
666  CLKB => clk, -- 1-bit input port-B clock
667  DIA => evt_buf_din(66 downto 63), -- Input port-A data, width defined by WRITE_WIDTH_A parameter
668  DIB => (others => '0'), -- Input port-B data, width defined by WRITE_WIDTH_B parameter
669  ENA => '1', -- 1-bit input port-A enable
670  ENB => evt_buf_re, -- 1-bit input port-B enable
671  REGCEA => '1', -- 1-bit input port-A output register enable
672  REGCEB => evt_buf_regce, -- 1-bit input port-B output register enable
673  RSTA => '0', -- 1-bit input port-A reset
674  RSTB => '0', -- 1-bit input port-B reset
675  WEA => evt_buf_we, -- Input port-A write enable, width defined by Port A depth
676  WEB => "0" -- Input port-B write enable, width defined by Port B depth
677  );
678 evt_buf_regce <= not evt_data_vld or evt_data_we_i;
679 evt_buf_re <= not evt_buf_do_vld or not evt_data_vld or evt_data_we_i;
680 -- event word count and trailer
681 process(clk)
682 begin
683  if(clk'event and clk = '1')then
684  rd_last_header_q <= not reset and rd_last_header;
685  if(reset = '0' and block_trailer = '0' and ((last_channel = '1' and or_reduce(wc(12 downto 1)) = '0' and AMC_DATA_re_i = '1') or (rd_last_header_q = '1' and NoAMCenabled = '1')))then
686  block_trailer <= '1';
687  else
688  block_trailer <= '0';
689  end if;
690  if(reset = '0' and block_trailer_dl(2) = '1' and last_block = '1')then
691  trailer_we <= '1';
692  else
693  trailer_we <= '0';
694  end if;
695  block_trailer_dl(3) <= block_trailer_dl(2) and not last_block;
696  block_trailer_dl(4) <= block_trailer_dl(3);
697  if(trailer_dl(1) = '1' or block_trailer_dl(4) = '1')then
698  FIFO_di(64) <= '1';
699  else
700  FIFO_di(64) <= '0';
701  end if;
702  if(reset = '1' or trailer_we = '1')then
703  block_num <= (others => '0');
704  elsif(block_trailer = '1')then
705  block_num <= block_num + 1;
706  end if;
707  if(reset = '1' or trailer_we = '1')then
708  trailer(55 downto 32) <= x"000001";
709  elsif(BlockCRC_ce = '1')then
710  trailer(55 downto 32) <= trailer(55 downto 32) + 1;
711  end if;
712  end if;
713 end process;
714 trailer(63 downto 56) <= x"a0";
715 trailer(31 downto 16) <= x"0000";
716 trailer(15 downto 8) <= Source_ID;
717 trailer(7 downto 0) <= x"00";
718 process(clk)
719 begin
720  if(clk'event and clk = '1')then
721  if(reset = '1' or block_trailer_dl(2) = '1')then
722  idle <= '1';
723  elsif(AMC_header_re = '1')then
724  idle <= '0';
725  end if;
726  if(reset = '1')then
727  HeaderWC <= (others => '0');
728  elsif(idle = '1' and AMC_header_re = '0')then
729  HeaderWC <= HeaderWC_o;
730  elsif(AMC_header_we = '0' and AMC_header_re = '1')then
731  HeaderWC <= HeaderWC - 1;
732  end if;
733  if(reset = '1' or (HeaderWC = x"1" and AMC_header_we = '0' and AMC_header_re = '1'))then
734  AMC_header_re <= '0';
735  elsif(idle = '1' and AMC_header_avl = '1' and (wc_fifo_empty = '0' or NoAMCenabled = '1') and fifo_full = '0' and and_reduce(evt_cnt) = '0')then
736  AMC_header_re <= '1';
737  end if;
738  if(reset = '1')then
739  header_ra <= (others => '0');
740  elsif(AMC_header_we = '0' and AMC_header_re = '1')then
741  header_ra <= header_ra + 1;
742  end if;
743  if(reset = '0' and HeaderWC = x"1" and AMC_header_re = '1' and AMC_header_we = '0')then
744  rd_last_header <= '1';
745  else
746  rd_last_header <= '0';
747  end if;
748  if(reset = '1' or read_AMC = '1')then
749  read_AMC <= '0';
750  elsif((last_channel = '0' and or_reduce(wc(12 downto 1)) = '0' and AMC_DATA_re_i = '1') or (rd_last_header = '1' and NoAMCenabled = '0'))then
751  read_AMC <= '1';
752  end if;
753  if(reset = '1' or fifo_full = '1' or (or_reduce(wc(12 downto 1)) = '0' and (AMC_DATA_re_i = '1' or wc(0) = '0')))then
754  AMC_DATA_re_i <= '0';
755  AMC_DATA_re <= (others => '0');
756  else
757  AMC_DATA_re_i <= '1';
758  for i in 0 to 11 loop
759  if(i = channel)then
760  AMC_DATA_re(i) <= '1';
761  else
762  AMC_DATA_re(i) <= '0';
763  end if;
764  end loop;
765  end if;
766  if(AMC_header_vld = '1' and first_block = '1')then
767  Lv1bx <= evt_buf_doa(39 downto 20);
768  end if;
769  if(reset = '1' or trailer_we = '1')then
770  first_block <= '1';
771  elsif(AMC_header_vld = '1')then
772  first_block <= '0';
773  end if;
774  if(reset = '1')then
775  last_channel <= '0';
776  last_block <= '0';
777  elsif(AMC_header_re = '1')then
778  last_channel <= '0';
779  last_block <= first_block and NoAMCenabled;
780  elsif(read_AMC = '1')then
781  last_channel <= wc_fifo_do(18);
782  last_block <= wc_fifo_do(17);
783  end if;
784  if(reset = '1')then
785  channel <= (others => '0');
786  wc <= (others => '0');
787  elsif(read_AMC = '1')then
788  channel <= wc_fifo_do(16 downto 13);
789  wc <= wc_fifo_do(12 downto 0);
790  elsif(AMC_DATA_re_i = '1')then
791  wc <= wc - 1;
792  end if;
793  end if;
794 end process;
795 -- check AMC event CRC
796 g_saved_AMCCRC: for i in 0 to 3 generate
797  i_saved_AMCCRC : RAM32M
798  port map (
799  DOA => saved_AMCCRC_do(i*8+1 downto i*8), -- Read port A 2-bit output
800  DOB => saved_AMCCRC_do(i*8+3 downto i*8+2), -- Read port B 2-bit output
801  DOC => saved_AMCCRC_do(i*8+5 downto i*8+4), -- Read port C 2-bit output
802  DOD => saved_AMCCRC_do(i*8+7 downto i*8+6), -- Read/Write port D 2-bit output
803  ADDRA => saved_AMCCRC_a, -- Read port A 5-bit address input
804  ADDRB => saved_AMCCRC_a, -- Read port B 5-bit address input
805  ADDRC => saved_AMCCRC_a, -- Read port C 5-bit address input
806  ADDRD => saved_AMCCRC_a, -- Read/Write port D 5-bit address input
807  DIA => saved_AMCCRC_di(i*8+1 downto i*8), -- RAM 2-bit data write input addressed by ADDRD,
808  -- read addressed by ADDRA
809  DIB => saved_AMCCRC_di(i*8+3 downto i*8+2), -- RAM 2-bit data write input addressed by ADDRD,
810  -- read addressed by ADDRB
811  DIC => saved_AMCCRC_di(i*8+5 downto i*8+4), -- RAM 2-bit data write input addressed by ADDRD,
812  -- read addressed by ADDRC
813  DID => saved_AMCCRC_di(i*8+7 downto i*8+6), -- RAM 2-bit data write input addressed by ADDRD,
814  -- read addressed by ADDRD
815  WCLK => clk, -- Write clock input
816  WE => chk_AMCCRC -- Write enable input
817  );
818 end generate;
819 g_saved_AMCCRC_di: for i in 0 to 31 generate
820  saved_AMCCRC_di(i) <= not AMCCRC(31-i);
821 end generate;
822 process(clk)
823 begin
824  if(clk'event and clk = '1')then
825  if(reset = '1')then
826  AMCCRC_bad <= (others => '0');
827  elsif(trailer_we = '1')then
828  AMCCRC_bad <= bad_AMCCRC_l;
829  else
830  AMCCRC_bad <= (others => '0');
831  end if;
832  if(reset = '1' or trailer_we = '1')then
833  init_AMCCRC <= '1';
834  elsif(last_channel = '1' and AMCCRC_init = '1')then
835  init_AMCCRC <= '0';
836  end if;
837  AMCCRC_ce <= AMC_DATA_re_i;
838  if(or_reduce(wc(12 downto 1)) = '0' and AMC_DATA_re_i = '1')then
839  AMClastWord <= '1';
840  else
841  AMClastWord <= '0';
842  end if;
843  chk_AMCCRC <= AMClastWord;
844  saved_AMCCRC_a(3 downto 0) <= channel;
845  read_AMC_q <= read_AMC;
846  AMCCRC_init <= read_AMC_q;
847  if(first_block = '1')then
848  bad_AMCCRC_l <= (others => '0');
849  elsif(chk_AMCCRC = '1')then
850  bad_AMCCRC_l(conv_integer(saved_AMCCRC_a(3 downto 0))) <= bad_AMCCRC;
851  end if;
852  end if;
853 end process;
854 i_AMCCRC: EthernetCRCD64 PORT MAP(
855  clk => clk,
856  init => AMCCRC_init ,
857  init_crc => saved_AMCCRC,
858  ce => AMCCRC_ce ,
859  trailer => AMC_trailer,
860  d => BlockCRC_data,
861  crc => AMCCRC ,
862  bad_crc => bad_AMCCRC
863  );
864 saved_AMCCRC <= (others => '1') when init_AMCCRC = '1' else saved_AMCCRC_do(31 downto 0);
865 end Behavioral;
866