AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes 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  elsif(evt_data_re = '1')then
543  en_output <= '1';
544  elsif(evt_data_we_i = '1' and evt_buf_dout(64) = '1')then
545  en_output <= '0';
546  end if;
547  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
548  evt_data_we_i <= '0';
549  else
550  evt_data_we_i <= en_output and not evt_buf_full;
551  end if;
552  if(reset = '1')then
553  evt_data_vld <= '0';
554  elsif(evt_buf_do_vld = '1')then
555  evt_data_vld <= '1';
556  elsif(evt_data_we_i = '1')then
557  evt_data_vld <= '0';
558  end if;
559  if(reset = '1')then
560  evt_buf_do_vld <= '0';
561  elsif(FIFO_data_wa_q /= evt_buf_ra)then
562  evt_buf_do_vld <= '1';
563  elsif(evt_data_vld = '0' or evt_data_we_i = '1')then
564  evt_buf_do_vld <= '0';
565  end if;
566  if(reset = '1')then
567  evt_buf_ra <= (others => '0');
568  elsif(FIFO_data_wa_q /= evt_buf_ra and evt_buf_re = '1')then
569  if(evt_buf_ra = x"f7f")then
570  evt_buf_ra <= (others => '0');
571  else
572  evt_buf_ra <= evt_buf_ra + 1;
573  end if;
574  end if;
575  if(reset = '1')then
576  trailer_dl <= (others => '0');
577  else
578  trailer_dl <= trailer_dl(1 downto 0) & trailer_we;
579  end if;
580  if(reset = '1')then
581  evt_cnt <= (others => '0');
582  elsif(trailer_we = '1' and (evt_buf_dout(65) = '0' or evt_data_we_i = '0'))then
583  evt_cnt <= evt_cnt + 1;
584  elsif(trailer_we = '0' and evt_buf_dout(65) = '1' and evt_data_we_i = '1')then
585  evt_cnt <= evt_cnt - 1;
586  end if;
587  if(reset = '1' or evt_data_we_i = '1' or evt_data_vld = '0')then
588  evt_data_rdy_i <= '0';
589  else
590  evt_data_rdy_i <= or_reduce(evt_cnt) or or_reduce(evt_buf_wc(11 downto 8));
591  end if;
592  if(reset = '1')then
593  evt_buf_wc <= (others => '0');
594 -- elsif(evt_data_we_i = '0' and FIFO_re = '1')then
595  elsif((or_reduce(evt_buf_wc) = '0' or evt_buf_re = '0') and FIFO_re = '1')then
596  evt_buf_wc <= evt_buf_wc + 1;
597 -- elsif(evt_data_we_i = '1' and FIFO_re = '0')then
598  elsif(or_reduce(evt_buf_wc) = '1' and evt_buf_re = '1' and FIFO_re = '0')then
599  evt_buf_wc <= evt_buf_wc - 1;
600  end if;
601  end if;
602 end process;
603 g_evt_buf: for i in 0 to 6 generate
604  i_evt_buf : BRAM_TDP_MACRO
605  generic map (
606  BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
607  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
608  DOA_REG => 0, -- Optional port A output register (0 or 1)
609  DOB_REG => 1, -- Optional port B output register (0 or 1)
610  INIT_A => X"000000000", -- Initial values on A output port
611  INIT_B => X"000000000", -- Initial values on B output port
612  INIT_FILE => "NONE",
613  READ_WIDTH_A => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
614  READ_WIDTH_B => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
615  SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY",
616  -- "GENERATE_X_ONLY" or "NONE"
617  SRVAL_A => X"000000000", -- Set/Reset value for A port output
618  SRVAL_B => X"000000000", -- Set/Reset value for B port output
619  WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
620  WRITE_MODE_B => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
621  WRITE_WIDTH_A => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
622  WRITE_WIDTH_B => 9) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
623  port map (
624  DOA => evt_buf_doA(i*9+8 downto i*9), -- Output port-A data, width defined by READ_WIDTH_A parameter
625  DOB => evt_buf_dout(i*9+8 downto i*9), -- Output port-B data, width defined by READ_WIDTH_B parameter
626  ADDRA => evt_buf_wa, -- Input port-A address, width defined by Port A depth
627  ADDRB => evt_buf_ra, -- Input port-B address, width defined by Port B depth
628  CLKA => clk, -- 1-bit input port-A clock
629  CLKB => clk, -- 1-bit input port-B clock
630  DIA => evt_buf_din(i*9+8 downto i*9), -- Input port-A data, width defined by WRITE_WIDTH_A parameter
631  DIB => (others => '0'), -- Input port-B data, width defined by WRITE_WIDTH_B parameter
632  ENA => '1', -- 1-bit input port-A enable
633  ENB => evt_buf_re, -- 1-bit input port-B enable
634  REGCEA => '1', -- 1-bit input port-A output register enable
635  REGCEB => evt_buf_regce, -- 1-bit input port-B output register enable
636  RSTA => '0', -- 1-bit input port-A reset
637  RSTB => '0', -- 1-bit input port-B reset
638  WEA => evt_buf_we, -- Input port-A write enable, width defined by Port A depth
639  WEB => "0" -- Input port-B write enable, width defined by Port B depth
640  );
641 end generate;
642 i_evt_buf_MSB : BRAM_TDP_MACRO
643  generic map (
644  BRAM_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb"
645  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
646  DOA_REG => 0, -- Optional port A output register (0 or 1)
647  DOB_REG => 1, -- Optional port B output register (0 or 1)
648  INIT_A => X"000000000", -- Initial values on A output port
649  INIT_B => X"000000000", -- Initial values on B output port
650  INIT_FILE => "NONE",
651  READ_WIDTH_A => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
652  READ_WIDTH_B => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
653  SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY",
654  -- "GENERATE_X_ONLY" or "NONE"
655  SRVAL_A => X"000000000", -- Set/Reset value for A port output
656  SRVAL_B => X"000000000", -- Set/Reset value for B port output
657  WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
658  WRITE_MODE_B => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
659  WRITE_WIDTH_A => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
660  WRITE_WIDTH_B => 4) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
661  port map (
662  DOA => evt_buf_doA(66 downto 63), -- Output port-A data, width defined by READ_WIDTH_A parameter
663  DOB => evt_buf_dout(66 downto 63), -- Output port-B data, width defined by READ_WIDTH_B parameter
664  ADDRA => evt_buf_wa, -- Input port-A address, width defined by Port A depth
665  ADDRB => evt_buf_ra, -- Input port-B address, width defined by Port B depth
666  CLKA => clk, -- 1-bit input port-A clock
667  CLKB => clk, -- 1-bit input port-B clock
668  DIA => evt_buf_din(66 downto 63), -- Input port-A data, width defined by WRITE_WIDTH_A parameter
669  DIB => (others => '0'), -- Input port-B data, width defined by WRITE_WIDTH_B parameter
670  ENA => '1', -- 1-bit input port-A enable
671  ENB => evt_buf_re, -- 1-bit input port-B enable
672  REGCEA => '1', -- 1-bit input port-A output register enable
673  REGCEB => evt_buf_regce, -- 1-bit input port-B output register enable
674  RSTA => '0', -- 1-bit input port-A reset
675  RSTB => '0', -- 1-bit input port-B reset
676  WEA => evt_buf_we, -- Input port-A write enable, width defined by Port A depth
677  WEB => "0" -- Input port-B write enable, width defined by Port B depth
678  );
679 evt_buf_regce <= not evt_data_vld or evt_data_we_i;
680 evt_buf_re <= not evt_buf_do_vld or not evt_data_vld or evt_data_we_i;
681 -- event word count and trailer
682 process(clk)
683 begin
684  if(clk'event and clk = '1')then
685  rd_last_header_q <= not reset and rd_last_header;
686  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
687  block_trailer <= '1';
688  else
689  block_trailer <= '0';
690  end if;
691  if(reset = '0' and block_trailer_dl(2) = '1' and last_block = '1')then
692  trailer_we <= '1';
693  else
694  trailer_we <= '0';
695  end if;
696  block_trailer_dl(3) <= block_trailer_dl(2) and not last_block;
697  block_trailer_dl(4) <= block_trailer_dl(3);
698  if(trailer_dl(1) = '1' or block_trailer_dl(4) = '1')then
699  FIFO_di(64) <= '1';
700  else
701  FIFO_di(64) <= '0';
702  end if;
703  if(reset = '1' or trailer_we = '1')then
704  block_num <= (others => '0');
705  elsif(block_trailer = '1')then
706  block_num <= block_num + 1;
707  end if;
708  if(reset = '1' or trailer_we = '1')then
709  trailer(55 downto 32) <= x"000001";
710  elsif(BlockCRC_ce = '1')then
711  trailer(55 downto 32) <= trailer(55 downto 32) + 1;
712  end if;
713  end if;
714 end process;
715 trailer(63 downto 56) <= x"a0";
716 trailer(31 downto 16) <= x"0000";
717 trailer(15 downto 8) <= Source_ID;
718 trailer(7 downto 0) <= x"00";
719 process(clk)
720 begin
721  if(clk'event and clk = '1')then
722  if(reset = '1' or block_trailer_dl(2) = '1')then
723  idle <= '1';
724  elsif(AMC_header_re = '1')then
725  idle <= '0';
726  end if;
727  if(reset = '1')then
728  HeaderWC <= (others => '0');
729  elsif(idle = '1' and AMC_header_re = '0')then
730  HeaderWC <= HeaderWC_o;
731  elsif(AMC_header_we = '0' and AMC_header_re = '1')then
732  HeaderWC <= HeaderWC - 1;
733  end if;
734  if(reset = '1' or (HeaderWC = x"1" and AMC_header_we = '0' and AMC_header_re = '1'))then
735  AMC_header_re <= '0';
736  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
737  AMC_header_re <= '1';
738  end if;
739  if(reset = '1')then
740  header_ra <= (others => '0');
741  elsif(AMC_header_we = '0' and AMC_header_re = '1')then
742  header_ra <= header_ra + 1;
743  end if;
744  if(reset = '0' and HeaderWC = x"1" and AMC_header_re = '1' and AMC_header_we = '0')then
745  rd_last_header <= '1';
746  else
747  rd_last_header <= '0';
748  end if;
749  if(reset = '1' or read_AMC = '1')then
750  read_AMC <= '0';
751  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
752  read_AMC <= '1';
753  end if;
754  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
755  AMC_DATA_re_i <= '0';
756  AMC_DATA_re <= (others => '0');
757  else
758  AMC_DATA_re_i <= '1';
759  for i in 0 to 11 loop
760  if(i = channel)then
761  AMC_DATA_re(i) <= '1';
762  else
763  AMC_DATA_re(i) <= '0';
764  end if;
765  end loop;
766  end if;
767  if(AMC_header_vld = '1' and first_block = '1')then
768  Lv1bx <= evt_buf_doa(39 downto 20);
769  end if;
770  if(reset = '1' or trailer_we = '1')then
771  first_block <= '1';
772  elsif(AMC_header_vld = '1')then
773  first_block <= '0';
774  end if;
775  if(reset = '1')then
776  last_channel <= '0';
777  last_block <= '0';
778  elsif(AMC_header_re = '1')then
779  last_channel <= '0';
780  last_block <= first_block and NoAMCenabled;
781  elsif(read_AMC = '1')then
782  last_channel <= wc_fifo_do(18);
783  last_block <= wc_fifo_do(17);
784  end if;
785  if(reset = '1')then
786  channel <= (others => '0');
787  wc <= (others => '0');
788  elsif(read_AMC = '1')then
789  channel <= wc_fifo_do(16 downto 13);
790  wc <= wc_fifo_do(12 downto 0);
791  elsif(AMC_DATA_re_i = '1')then
792  wc <= wc - 1;
793  end if;
794  end if;
795 end process;
796 -- check AMC event CRC
797 g_saved_AMCCRC: for i in 0 to 3 generate
798  i_saved_AMCCRC : RAM32M
799  port map (
800  DOA => saved_AMCCRC_do(i*8+1 downto i*8), -- Read port A 2-bit output
801  DOB => saved_AMCCRC_do(i*8+3 downto i*8+2), -- Read port B 2-bit output
802  DOC => saved_AMCCRC_do(i*8+5 downto i*8+4), -- Read port C 2-bit output
803  DOD => saved_AMCCRC_do(i*8+7 downto i*8+6), -- Read/Write port D 2-bit output
804  ADDRA => saved_AMCCRC_a , -- Read port A 5-bit address input
805  ADDRB => saved_AMCCRC_a , -- Read port B 5-bit address input
806  ADDRC => saved_AMCCRC_a , -- Read port C 5-bit address input
807  ADDRD => saved_AMCCRC_a , -- Read/Write port D 5-bit address input
808  DIA => saved_AMCCRC_di(i*8+1 downto i*8), -- RAM 2-bit data write input addressed by ADDRD,
809  -- read addressed by ADDRA
810  DIB => saved_AMCCRC_di(i*8+3 downto i*8+2), -- RAM 2-bit data write input addressed by ADDRD,
811  -- read addressed by ADDRB
812  DIC => saved_AMCCRC_di(i*8+5 downto i*8+4), -- RAM 2-bit data write input addressed by ADDRD,
813  -- read addressed by ADDRC
814  DID => saved_AMCCRC_di(i*8+7 downto i*8+6), -- RAM 2-bit data write input addressed by ADDRD,
815  -- read addressed by ADDRD
816  WCLK => clk, -- Write clock input
817  WE => chk_AMCCRC -- Write enable input
818  );
819 end generate;
820 g_saved_AMCCRC_di: for i in 0 to 31 generate
821  saved_AMCCRC_di(i) <= not AMCCRC(31-i);
822 end generate;
823 process(clk)
824 begin
825  if(clk'event and clk = '1')then
826  if(reset = '1')then
827  AMCCRC_bad <= (others => '0');
828  elsif(trailer_we = '1')then
829  AMCCRC_bad <= bad_AMCCRC_l;
830  else
831  AMCCRC_bad <= (others => '0');
832  end if;
833  if(reset = '1' or trailer_we = '1')then
834  init_AMCCRC <= '1';
835  elsif(last_channel = '1' and AMCCRC_init = '1')then
836  init_AMCCRC <= '0';
837  end if;
838  AMCCRC_ce <= AMC_DATA_re_i;
839  if(or_reduce(wc(12 downto 1)) = '0' and AMC_DATA_re_i = '1')then
840  AMClastWord <= '1';
841  else
842  AMClastWord <= '0';
843  end if;
844  chk_AMCCRC <= AMClastWord;
845  saved_AMCCRC_a(3 downto 0) <= channel;
846  read_AMC_q <= read_AMC;
847  AMCCRC_init <= read_AMC_q;
848  if(first_block = '1')then
849  bad_AMCCRC_l <= (others => '0');
850  elsif(chk_AMCCRC = '1')then
851  bad_AMCCRC_l(conv_integer(saved_AMCCRC_a(3 downto 0))) <= bad_AMCCRC;
852  end if;
853  end if;
854 end process;
855 i_AMCCRC: EthernetCRCD64 PORT MAP(
856  clk => clk,
857  init => AMCCRC_init,
858  init_crc => saved_AMCCRC,
859  ce => AMCCRC_ce,
860  trailer => AMC_trailer,
861  d => BlockCRC_data,
862  crc => AMCCRC ,
863  bad_crc => bad_AMCCRC
864  );
865 saved_AMCCRC <= (others => '1') when init_AMCCRC = '1' else saved_AMCCRC_do(31 downto 0);
866 end Behavioral;
867