ROD firmware  1.0.5
ATLAS l1-calo - ROD_eFEX and ROD_jFEX firmware for the L1Calo ROD board

Back to ROD documentation
backplane_crc.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 22.09.2021 10:58:44
6 -- Design Name:
7 -- Module Name: testbench_crc - rtl
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 
21 
22 library IEEE;
23 use IEEE.STD_LOGIC_1164.ALL;
24 use IEEE.numeric_std.all;
25 use IEEE.STD_LOGIC_UNSIGNED.ALL;
26 
27 -- Uncomment the following library declaration if using
28 -- arithmetic functions with Signed or Unsigned values
29 --use IEEE.NUMERIC_STD.ALL;
30 
31 -- Uncomment the following library declaration if instantiating
32 -- any Xilinx leaf cells in this code.
33 --library UNISIM;
34 --use UNISIM.VComponents.all;
35 
36 entity backplane_crc is
37  generic (
38  fex_check : integer := 0;
39  crc20_G_Poly : std_logic_vector(19 downto 0) := x"8349f" --old poly
40  );
41  Port (
42  clock : in std_logic;
43  reset : in std_logic;
44  s_tvalid : in std_logic;
45  s_tlast : in std_logic;
46  s_tdata : in std_logic_vector(63 downto 0);
47  header_error : out std_logic;
48  payload_error : out std_logic;
49  length_error : out std_logic
50  );
51 end backplane_crc;
52 
53 architecture rtl of backplane_crc is
54 
55 --incoming packet types
56 constant tob : std_logic_vector( 1 downto 0) := "01";
57 constant raw : std_logic_vector( 1 downto 0) := "10";
58 constant debug : std_logic_vector( 1 downto 0) := "11";
59 
60 component CRC
61  generic(
62  Nbits : positive := 64;
63  CRC_Width : positive := 20;
64  -- G_Poly: Std_Logic_Vector :=x"c1acf";
65  G_Poly: Std_Logic_Vector :=x"8349f";
66  G_InitVal: std_logic_vector:=x"fffff"
67  );
68  port(
69  CRC : out std_logic_vector(CRC_Width-1 downto 0);
70  Calc : in std_logic;
71  Clk : in std_logic;
72  DIn : in std_logic_vector(Nbits-1 downto 0);
73  Reset : in std_logic
74 
75  );
76 end component;
77 
78 component osum_crc9d32
79  port(
80  clock : in std_logic;
81 
82  crc_start : in std_logic;
83  d_in : in std_logic_vector(31 downto 0);
84 
85  crc_out : out std_logic_vector(8 downto 0)
86  );
87 
88 end component;
89 
90 
91 
92 signal CRC20_out : std_logic_vector(19 downto 0);
93 signal crc20_calc : std_logic;
94 signal crc20_din : std_logic_vector(63 downto 0);
95 
96 signal CRC9_out : std_logic_vector(8 downto 0);
97 signal crc9_calc : std_logic;
98 signal crc9_din : std_logic_vector(63 downto 0);
99 signal crc_din_32 : std_logic_vector(31 downto 0);
100 signal crc_din_sel : std_logic_vector (2 downto 0);
101 signal s_tvalid_del : std_logic;
102 signal s_tvalid_del2 : std_logic;
103 
104 signal s_tlast_del : std_logic;
105 signal s_tlast_del2 : std_logic;
106 
107 signal s_first_cyc : std_logic;
108 signal s_second_cyc : std_logic;
109 signal s_third_cyc : std_logic;
110 signal s_fourth_cyc : std_logic;
111 signal in_progress : std_logic;
112 signal in_progress_del1 : std_logic;
113 signal in_progress_del2 : std_logic;
114 signal proposed_crc9 : std_logic_vector(8 downto 0);
115 signal proposed_crc20 : std_logic_vector(19 downto 0);
116 signal proposed_length : std_logic_vector(15 downto 0);
117 signal header_error_i : std_logic;
118 signal payload_error_i : std_logic;
119 
120 signal swap_data : std_logic_vector(63 downto 0);
121 signal word2_reg : std_logic_vector(31 downto 0);
122 signal word3_reg : std_logic_vector(31 downto 0);
123 
124 signal stream_id : std_logic_vector(7 downto 0);
125 signal pkt_type : std_logic_vector(1 downto 0);
126 signal early_pkt_type : std_logic_vector(1 downto 0);
127 signal crc9_samp : std_logic;
128 
129 signal start_crc20_calc : std_logic;
130 signal length_counter : std_logic_vector(15 downto 0);
131 signal measured_length : std_logic_vector(15 downto 0);
132 signal length_error_i : std_logic;
133 
134 
135 signal crc9_out_64 : std_logic_vector(8 downto 0);
136 signal crc20_reset : std_logic;
137 
138 begin
139 
140 --pkt_type <= stream_id(7 downto 6);
141 
142 early_pkt_type <= (s_first_cyc and s_tdata(7)) & (s_first_cyc and s_tdata(7));
143 
144 with s_first_cyc select
145  pkt_type <= early_pkt_type when '1',
146  stream_id(7 downto 6) when others;
147 
148 with s_first_cyc select
149  crc9_din <= (s_tdata(31 downto 29) & "000000000" & s_tdata(19 downto 0) & s_tdata(63 downto 32)) when '1',
150  (s_tdata (31 downto 0) & s_tdata(63 downto 32)) when others;
151 
152 with s_tlast select
153  crc20_din <= (s_tdata(31 downto 0) & x"00000" & s_tdata(43 downto 32)) when '1',
154  (s_tdata (31 downto 0) & s_tdata(63 downto 32)) when others;
155 
156 
157 
158 
159 
160 payload_crc : CRC
161  generic map (
162  Nbits => 64,
163  CRC_Width => 20,
164  -- G_Poly => x"c1acf",
165  G_Poly => crc20_G_Poly,
166  G_InitVal => x"fffff"
167  )
168  port map(
169  Clk => Clock,
170  CRC => CRC20_out,
171  Calc => crc20_Calc,
172  Din => crc20_din,
173  -- Reset => s_first_cyc
174  Reset => crc20_reset
175  );
176 crc20_reset <= s_first_cyc or reset;
177 
178 header_crc : CRC
179  generic map (
180  Nbits => 64,
181  CRC_Width => 9,
182  G_Poly => "011111011", --this one is correct
183  G_InitVal => "111111111"
184  )
185  port map(
186  Clk => Clock,
187  CRC => crc9_out_64, --CRC9_out,
188  Calc => crc9_Calc,
189  Din => crc9_din,
190 -- Reset => reset
191  Reset => crc20_reset
192  );
193 
194 
195 three_word_header_crc : osum_crc9d32
196  port map(
197  clock => clock,
198 
199  CRC_out => crc9_out,
200  crc_start => s_first_cyc,
201  d_in => CRC_din_32
202  );
203 
204 crc_din_sel <= s_third_cyc & s_second_cyc & s_first_cyc;
205 
206 with crc_din_sel select
207  CRC_din_32 <= (s_tdata(31 downto 29) & "000000000" & s_tdata(19 downto 0)) when "001",
208  word2_reg when "010",
209  word3_reg when others;
210 
211 
212  process (clock) begin
213  if rising_edge(clock) then
214  if (s_first_cyc = '1') then
215  stream_id <= s_tdata(7 downto 0);
216  else
217  stream_id <= stream_id;
218  end if;
219  end if;
220  end process;
221 
222 
223 process (clock) begin
224  if rising_edge(clock) then
225  if (s_first_cyc = '1') then
226  word2_reg <= s_tdata(63 downto 32);
227  word3_reg <= word3_reg;
228  elsif (s_second_cyc = '1') then
229  word3_reg <= s_tdata(31 downto 0);
230  word2_reg <= word2_reg;
231  else
232  word2_reg <= word2_reg;
233  word3_reg <= word3_reg;
234  end if;
235  end if;
236  end process;
237 
238 
239 
240 process (clock) begin
241  if rising_edge(clock) then
242  if (reset = '1') then
243  s_tvalid_del <= '0';
244  s_tvalid_del2 <= '0';
245  else
246  s_tvalid_del <= s_tvalid;
247  s_tvalid_del2 <= s_tvalid_del;
248  end if;
249  end if;
250  end process;
251 
252 process (clock) begin
253  if rising_edge(clock) then
254  if (reset = '1') then
255  s_tlast_del <= '0';
256  s_tlast_del2 <= '0';
257  else
258  s_tlast_del <= s_tlast;
259  s_tlast_del2 <= s_tlast_del;
260  end if;
261  end if;
262  end process;
263 
264 
265 rod_test_1 : if fex_check = 0 generate
266 
267 with pkt_type select
268  start_crc20_calc <= s_first_cyc when debug,
269  s_second_cyc when others;
270 
271 end generate rod_test_1;
272 
273 fex_test_1 : if fex_check = 1 generate
274  start_crc20_calc <= s_first_cyc;
275 end generate fex_test_1;
276 
277 
278 
279 --process (clock) begin
280 -- if rising_edge(clock) then
281 -- if (reset = '1') or (s_tlast = '1')then
282 -- crc20_calc <= '0';
283 -- elsif (start_crc20_calc = '1') then
284 -- crc20_calc <= '1';
285 -- end if;
286 -- end if;
287 --end process;
288 crc20_calc <= s_tvalid and in_progress;
289 
290 
291 process(clock) begin
292  if rising_edge (clock) then
293  if (reset = '1') or (s_tlast = '1') then
294  in_progress <= '0';
295  elsif (s_first_cyc = '1') and (s_tlast = '0') then
296  in_progress <= '1';
297  else
298  in_progress <= in_progress;
299  end if;
300  end if;
301  end process;
302 
303  process(clock) begin
304  if rising_edge (clock) then
305  if (reset = '1') then
306  in_progress_del1 <= '0';
307  in_progress_del2 <= '0';
308  else
309  in_progress_del1 <= in_progress;
310  in_progress_del2 <= in_progress_del1;
311  end if;
312  end if;
313  end process;
314 
315 
316 ------------------prev cycle empty-------------or previous cycle was tlast ----
317 s_first_cyc <= ((s_tvalid and not s_tvalid_del) or (s_tvalid and s_tvalid_del and s_tlast_del)) and not in_progress;
318 --s_first_cyc <= ((s_tvalid and not s_tvalid_del) or (s_tvalid and s_tvalid_del and s_tlast_del));
319 --s_first_cyc <= ((s_tvalid and not s_tvalid_del) or (s_tvalid and s_tvalid_del and not s_tlast_del)) and not in_progress;
320 
321 process(clock) begin
322  if rising_edge (clock) then
323  if (reset = '1') or (s_tlast = '1') then
324  s_second_cyc <= '0';
325  s_third_cyc <= '0';
326  s_fourth_cyc <= '0';
327  else
328  s_second_cyc <= s_first_cyc;
329  s_third_cyc <= s_second_cyc;
330  s_fourth_cyc <= s_third_cyc;
331  end if;
332  end if;
333 end process;
334 
335 rod_test2: if fex_check = 0 generate
336  crc9_calc <= s_first_cyc or s_second_cyc;
337 end generate rod_test2;
338 
339 fex_test2: if fex_check = 1 generate
340  crc9_calc <= s_first_cyc;
341 end generate fex_test2;
342 
343 process(clock) begin
344  if rising_edge (clock) then
345  if (reset = '1') or (s_tlast = '1') then
346  proposed_crc9 <= "000000000";
347  elsif (s_first_cyc = '1') then
348  proposed_crc9 <= s_tdata(28 downto 20);
349  end if;
350  end if;
351 end process;
352 
353 
354 
355 process(clock) begin
356  if rising_edge (clock) then
357  if (reset = '1') then --or (s_first_cyc = '1') then
358  proposed_crc20 <= x"00000";
359  proposed_length <= x"0000";
360  elsif (s_tlast = '1') and (s_tvalid = '1') then
361  proposed_crc20 <= s_tdata(63 downto 44);
362  proposed_length <= s_tdata(15 downto 0);
363  end if;
364  end if;
365 end process;
366 
367 
368 --header error flag
369 
370 rod_test3: if fex_check = 0 generate
371 with pkt_type select
372  crc9_samp <= (s_third_cyc and in_progress) when debug,
373  (s_fourth_cyc and in_progress) when others;
374 
375 
376 
377 process(clock) begin
378  if rising_edge (clock) then
379  if (reset = '1') or (s_first_cyc = '1') then ---make this sticky for the whole sim
380  header_error_i <= '0';
381  elsif (crc9_samp = '1') and (proposed_crc9 /= crc9_out) then
382  header_error_i <= '1';
383  else
384  header_error_i <= header_error_i;
385  end if;
386  end if;
387 end process;
388 
389 end generate rod_test3;
390 
391 fex_test3: if fex_check = 1 generate
392  crc9_samp <= (s_third_cyc and in_progress);
393 
394 
395  process(clock) begin
396  if rising_edge (clock) then
397  if (reset = '1') or (s_first_cyc = '1') then ---make this sticky for the whole sim
398  header_error_i <= '0';
399  elsif (crc9_samp = '1') and (proposed_crc9 /= crc9_out_64) then
400  header_error_i <= '1';
401  else
402  header_error_i <= header_error_i;
403  end if;
404  end if;
405 end process;
406 
407  end generate fex_test3;
408 
409 
410 
411 
412 header_error <= header_error_i;
413 
414 process(clock) begin
415  if rising_edge (clock) then
416  if (reset = '1') or (s_first_cyc = '1') then ---make this sticky for the whole sim
417  payload_error_i <= '0';
418  elsif (s_tlast_del2 = '1') and (in_progress_del2 = '1') and (proposed_crc20 /= crc20_out) then
419  payload_error_i <= '1';
420  else
421  payload_error_i <= payload_error_i;
422  end if;
423  end if;
424 end process;
425 
426 payload_error <= payload_error_i;
427 
428 ---length counter -----
429 process(clock) begin
430  if rising_edge (clock) then
431  if (reset = '1') or (s_first_cyc = '1') then
432  length_counter <= x"0000";
433  elsif (crc20_Calc = '1') then
434  length_counter <= (length_counter + 2);
435  else
436  length_counter <= length_counter;
437  end if;
438  end if;
439 end process;
440 
441 process(clock) begin
442  if rising_edge (clock) then
443  if (reset = '1') then
444  measured_length <= x"0000";
445  elsif (s_tlast = '1') and (s_tvalid = '1') and (in_progress = '1') then
446  measured_length <= length_counter;
447  else
448  measured_length <= measured_length;
449  end if;
450  end if;
451 end process;
452 
453 
454 process(clock) begin
455  if rising_edge (clock) then
456  if (reset = '1') or (s_first_cyc = '1') then
457  length_error_i <= '0';
458  elsif (s_tlast_del = '1') and (measured_length /= proposed_length) then
459  length_error_i <= '1';
460  else
461  length_error_i <= length_error_i;
462  end if;
463  end if;
464 end process;
465 
466  length_error <= length_error_i;
467 end rtl;
Definition: crc.vhd:25