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

Back to ROD documentation
packet_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 packet_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 packet_crc;
52 
53 architecture rtl of packet_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  );
192 
193 
194 three_word_header_crc : osum_crc9d32
195  port map(
196  clock => clock,
197 
198  CRC_out => crc9_out,
199  crc_start => s_first_cyc,
200  d_in => CRC_din_32
201  );
202 
203 crc_din_sel <= s_third_cyc & s_second_cyc & s_first_cyc;
204 
205 with crc_din_sel select
206  CRC_din_32 <= (s_tdata(31 downto 29) & "000000000" & s_tdata(19 downto 0)) when "001",
207  word2_reg when "010",
208  word3_reg when others;
209 
210 
211  process (clock) begin
212  if rising_edge(clock) then
213  if (s_first_cyc = '1') then
214  stream_id <= s_tdata(7 downto 0);
215  else
216  stream_id <= stream_id;
217  end if;
218  end if;
219  end process;
220 
221 
222 process (clock) begin
223  if rising_edge(clock) then
224  if (s_first_cyc = '1') then
225  word2_reg <= s_tdata(63 downto 32);
226  word3_reg <= word3_reg;
227  elsif (s_second_cyc = '1') then
228  word3_reg <= s_tdata(31 downto 0);
229  word2_reg <= word2_reg;
230  else
231  word2_reg <= word2_reg;
232  word3_reg <= word3_reg;
233  end if;
234  end if;
235  end process;
236 
237 
238 
239 process (clock) begin
240  if rising_edge(clock) then
241  if (reset = '1') then
242  s_tvalid_del <= '0';
243  s_tvalid_del2 <= '0';
244  else
245  s_tvalid_del <= s_tvalid;
246  s_tvalid_del2 <= s_tvalid_del;
247  end if;
248  end if;
249  end process;
250 
251 process (clock) begin
252  if rising_edge(clock) then
253  if (reset = '1') then
254  s_tlast_del <= '0';
255  s_tlast_del2 <= '0';
256  else
257  s_tlast_del <= s_tlast;
258  s_tlast_del2 <= s_tlast_del;
259  end if;
260  end if;
261  end process;
262 
263 
264 rod_test_1 : if fex_check = 0 generate
265 
266 with pkt_type select
267  start_crc20_calc <= s_first_cyc when debug,
268  s_second_cyc when others;
269 
270 end generate rod_test_1;
271 
272 fex_test_1 : if fex_check = 1 generate
273  start_crc20_calc <= s_first_cyc;
274 end generate fex_test_1;
275 
276 
277 
278 --process (clock) begin
279 -- if rising_edge(clock) then
280 -- if (reset = '1') or (s_tlast = '1')then
281 -- crc20_calc <= '0';
282 -- elsif (start_crc20_calc = '1') then
283 -- crc20_calc <= '1';
284 -- end if;
285 -- end if;
286 --end process;
287 crc20_calc <= s_tvalid and in_progress;
288 
289 
290 process(clock) begin
291  if rising_edge (clock) then
292  if (reset = '1') or (s_tlast = '1') then
293  in_progress <= '0';
294  elsif (s_first_cyc = '1') and (s_tlast = '0') then
295  in_progress <= '1';
296  else
297  in_progress <= in_progress;
298  end if;
299  end if;
300  end process;
301 
302  process(clock) begin
303  if rising_edge (clock) then
304  if (reset = '1') then
305  in_progress_del1 <= '0';
306  in_progress_del2 <= '0';
307  else
308  in_progress_del1 <= in_progress;
309  in_progress_del2 <= in_progress_del1;
310  end if;
311  end if;
312  end process;
313 
314 
315 ------------------prev cycle empty-------------or previous cycle was tlast ----
316 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;
317 --s_first_cyc <= ((s_tvalid and not s_tvalid_del) or (s_tvalid and s_tvalid_del and s_tlast_del));
318 --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;
319 
320 process(clock) begin
321  if rising_edge (clock) then
322  if (reset = '1') or (s_tlast = '1') then
323  s_second_cyc <= '0';
324  s_third_cyc <= '0';
325  s_fourth_cyc <= '0';
326  else
327  s_second_cyc <= s_first_cyc;
328  s_third_cyc <= s_second_cyc;
329  s_fourth_cyc <= s_third_cyc;
330  end if;
331  end if;
332 end process;
333 
334 rod_test2: if fex_check = 0 generate
335  crc9_calc <= s_first_cyc or s_second_cyc;
336 end generate rod_test2;
337 
338 fex_test2: if fex_check = 1 generate
339  crc9_calc <= s_first_cyc;
340 end generate fex_test2;
341 
342 process(clock) begin
343  if rising_edge (clock) then
344  if (reset = '1') or (s_tlast = '1') then
345  proposed_crc9 <= "000000000";
346  elsif (s_first_cyc = '1') then
347  proposed_crc9 <= s_tdata(28 downto 20);
348  end if;
349  end if;
350 end process;
351 
352 
353 
354 process(clock) begin
355  if rising_edge (clock) then
356  if (reset = '1') then --or (s_first_cyc = '1') then
357  proposed_crc20 <= x"00000";
358  proposed_length <= x"0000";
359  elsif (s_tlast = '1') and (s_tvalid = '1') then
360  proposed_crc20 <= s_tdata(63 downto 44);
361  proposed_length <= s_tdata(15 downto 0);
362  end if;
363  end if;
364 end process;
365 
366 
367 --header error flag
368 
369 rod_test3: if fex_check = 0 generate
370 with pkt_type select
371  crc9_samp <= (s_third_cyc and in_progress) when debug,
372  (s_fourth_cyc and in_progress) when others;
373 
374 
375 
376 process(clock) begin
377  if rising_edge (clock) then
378  if (reset = '1') then --or (s_first_cyc = '1') then ---make this sticky for the whole sim
379  header_error_i <= '0';
380  elsif (crc9_samp = '1') and (proposed_crc9 /= crc9_out) then
381  header_error_i <= '1';
382  else
383  header_error_i <= header_error_i;
384  end if;
385  end if;
386 end process;
387 
388 end generate rod_test3;
389 
390 fex_test3: if fex_check = 1 generate
391 
392  crc9_samp <= (s_third_cyc and in_progress);
393 -- crc9_samp <= s_third_cyc;
394 
395 
396  process(clock) begin
397  if rising_edge (clock) then
398  if (reset = '1') then --or (s_first_cyc = '1') then ---make this sticky for the whole sim
399  header_error_i <= '0';
400  elsif (crc9_samp = '1') and (proposed_crc9 /= crc9_out_64) then
401  header_error_i <= '1';
402  else
403  header_error_i <= header_error_i;
404  end if;
405  end if;
406 end process;
407 
408  end generate fex_test3;
409 
410 
411 
412 
413 header_error <= header_error_i;
414 
415 process(clock) begin
416  if rising_edge (clock) then
417  if (reset = '1') then --or (s_first_cyc = '1') then ---make this sticky for the whole sim
418  payload_error_i <= '0';
419  elsif (s_tlast_del2 = '1') and (in_progress_del2 = '1') and (proposed_crc20 /= crc20_out) then
420  payload_error_i <= '1';
421  else
422  payload_error_i <= payload_error_i;
423  end if;
424  end if;
425 end process;
426 
427 payload_error <= payload_error_i;
428 
429 ---length counter -----
430 process(clock) begin
431  if rising_edge (clock) then
432  if (reset = '1') or (s_first_cyc = '1') then
433  length_counter <= x"0000";
434  elsif (crc20_Calc = '1') then
435  length_counter <= (length_counter + 2);
436  else
437  length_counter <= length_counter;
438  end if;
439  end if;
440 end process;
441 
442 process(clock) begin
443  if rising_edge (clock) then
444  if (reset = '1') then
445  measured_length <= x"0000";
446  elsif (s_tlast = '1') and (s_tvalid = '1') then
447  measured_length <= length_counter;
448  else
449  measured_length <= measured_length;
450  end if;
451  end if;
452 end process;
453 
454 
455 process(clock) begin
456  if rising_edge (clock) then
457  if (reset = '1') then
458  length_error_i <= '0';
459  elsif (s_tlast_del = '1') and (in_progress_del1 = '1') and (measured_length /= proposed_length) then
460  length_error_i <= '1';
461  else
462  length_error_i <= length_error_i;
463  end if;
464  end if;
465 end process;
466 
467  length_error <= length_error_i;
468 end rtl;
Definition: crc.vhd:25