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

Back to eFEX documentation
efex_packet_builder.vhd
Go to the documentation of this file.
1 
6 
8 library ieee;
9 use ieee.std_logic_1164.all;
10 use ieee.numeric_std.all;
11 
14  port (
15  clk : in std_logic;
16  rst_clk : in std_logic;
18  packet_data : IN std_logic_vector (63 DOWNTO 0) ;
19  packet_valid : IN std_logic;
20  packet_last : IN std_logic;
21  packet_ready : OUT std_logic;
23  payload_data : OUT std_logic_vector (63 DOWNTO 0) ;
24  payload_valid : OUT std_logic;
25  payload_last : OUT std_logic;
26  tready_data : IN std_logic
27  );
29 
31 architecture universal of efex_packet_builder is
32 
33  TYPE STATE_TYPE IS (
34  idle,
35  capture_l1id,
36  do_hdr_crc,
37  wait_hdr_crc,
38  send_l1id,
39  send_payload,
40  build_trailer,
41  do_trailer_crc,
42  wait_trailer_crc,
43  send_trailer,
44  wait_end
45  );
46 
47 Component CRC20 is
48  generic(
49  Nbits : positive := 64;
50  CRC_Width : positive := 20;
51  G_Poly : Std_Logic_Vector :=x"8349f";
52  G_InitVal : std_logic_vector :=x"fffff"
53  );
54  port(
55  CRC : out std_logic_vector(CRC_Width-1 downto 0);
56  Calc : in std_logic;
57  Clk : in std_logic;
58  DIn : in std_logic_vector(Nbits-1 downto 0);
59  Reset : in std_logic);
60 end Component CRC20;
61 
62  signal valid_sig, last_sig, ready_sig, force_ready_sig, input_active_sig: std_logic;
63  signal do_crc9, calc_crc20, reset_crc20, send_crc9, send_crc20: std_logic;
64  signal input_valid_sig, input_data_end_sig, prefetch_sig: std_logic;
65  signal data_sig, inputdata_sig, crc_word: std_logic_vector(63 DOWNTO 0);
66  signal crc9val: std_logic_vector(8 DOWNTO 0);
67  signal crc20val: std_logic_vector(19 DOWNTO 0);
68  signal state_sig: STATE_TYPE;
69 
70 begin
71  payload_data <= data_sig;
72  payload_valid <= valid_sig;
73  payload_last <= last_sig;
74  ready_sig <= tready_data and valid_sig;
75 
76  packet_ready <= ((ready_sig or force_ready_sig) and input_active_sig) or prefetch_sig;
77 
78 crc9_block : CRC20
79  GENERIC MAP (
80  Nbits => 64,
81  CRC_Width => 9,
82  G_Poly => "011111011",
83  G_InitVal => "111111111"
84  )
85  PORT MAP (
86  CRC => crc9val,
87  Calc => do_crc9,
88  Clk => clk,
89  DIn => crc_word,
90  Reset => do_crc9
91  );
92 
93 crc20_block : CRC20
94  GENERIC MAP (
95  Nbits => 64,
96  CRC_Width => 20,
97  G_Poly => x"8359f",
98  G_InitVal => x"fffff"
99  )
100  PORT MAP (
101  CRC => crc20val,
102  Calc => calc_crc20,
103  Clk => clk,
104  DIn => crc_word,
105  Reset => reset_crc20
106  );
107 
108 buffer_input: process(clk)
109  variable valid_int, valid_buf, data_end_int: std_logic := '0';
110  variable data_int, data_buf: std_logic_vector(63 DOWNTO 0) := (others => '0');
111  variable input_active_int: std_logic := '0';
112  begin
113  if rising_edge(clk) then
114  if rst_clk = '1' then
115  valid_int := '0';
116  valid_buf := '0';
117  input_active_int := '0';
118  elsif ((state_sig = idle) and (input_active_int = '0')) or (prefetch_sig = '1') or (ready_sig = '1') or (force_ready_sig = '1') then
119  data_int := data_buf;
120  data_buf := packet_data;
121  valid_int := valid_buf;
122  valid_buf := packet_valid;
123  data_end_int := packet_last; -- catch packet_last on penultimate word!
124  elsif state_sig = wait_hdr_crc then -- Starting new frame...
125  input_active_int := '1';
126  end if;
127  if (input_active_sig = '1') and (packet_valid = '0') then -- End of incoming frame...
128  input_active_int := '0';
129  end if;
130  inputdata_sig <= data_int
131 -- pragma translate_off
132  after 2 ns
133 -- pragma translate_on
134  ;
135  input_valid_sig <= valid_int
136 -- pragma translate_off
137  after 2 ns
138 -- pragma translate_on
139  ;
140  input_data_end_sig <= data_end_int
141 -- pragma translate_off
142  after 2 ns
143 -- pragma translate_on
144  ;
145  input_active_sig <= input_active_int
146 -- pragma translate_off
147  after 2 ns
148 -- pragma translate_on
149  ;
150  end if;
151  end process buffer_input;
152 
153 build_crc_word: process(clk)
154  variable do_crc9_int, calc_crc20_int, reset_crc20_int, send_crc9_int, send_crc20_int: std_logic := '0';
155  variable crc_word_int: std_logic_vector(63 downto 0) := (others => '0');
156  variable payload_length: unsigned(7 downto 0) := (Others => '0');
157  begin
158  if rising_edge(clk) then
159  do_crc9_int := '0';
160  calc_crc20_int := '0';
161  reset_crc20_int := '0';
162  send_crc9_int := '0';
163  send_crc20_int := '0';
164  case state_sig is
165  when capture_l1id =>
166  do_crc9_int := '1';
167  crc_word_int := inputdata_sig(31 downto 29) & "000000000" & inputdata_sig(19 downto 0) & inputdata_sig(63 downto 32);
168  when do_hdr_crc =>
169  when wait_hdr_crc =>
170  send_crc9_int := '1'; -- to match CRC arriving
171  when send_l1id =>
172  reset_crc20_int := '1';
173  payload_length := (Others => '0');
174  when send_payload => -- NB low and high words are swapped for CRC calculation!
175  if ready_sig = '1' then
176  crc_word_int := inputdata_sig(31 downto 0) & inputdata_sig(63 downto 32);
177  calc_crc20_int := '1';
178  payload_length := payload_length + 1;
179  end if;
180  when build_trailer => -- NB low and high words are swapped for CRC calculation!
181  crc_word_int := inputdata_sig(31 downto 9) & std_logic_vector(payload_length) & "0" & x"00000" & inputdata_sig(43 downto 32) ;
182  calc_crc20_int := ready_sig;
183  when do_trailer_crc =>
184  when wait_trailer_crc =>
185  send_crc20_int := '1'; -- to match CRC arriving
186  when Others =>
187  crc_word_int := (Others => '0');
188  end case;
189  do_crc9 <= do_crc9_int
190 -- pragma translate_off
191  after 2 ns
192 -- pragma translate_on
193  ;
194  calc_crc20 <= calc_crc20_int
195 -- pragma translate_off
196  after 2 ns
197 -- pragma translate_on
198  ;
199  reset_crc20 <= reset_crc20_int
200 -- pragma translate_off
201  after 2 ns
202 -- pragma translate_on
203  ;
204  send_crc9 <= send_crc9_int
205 -- pragma translate_off
206  after 2 ns
207 -- pragma translate_on
208  ;
209  send_crc20 <= send_crc20_int
210 -- pragma translate_off
211  after 2 ns
212 -- pragma translate_on
213  ;
214  crc_word <= crc_word_int
215 -- pragma translate_off
216  after 2 ns
217 -- pragma translate_on
218  ;
219  end if;
220  end process build_crc_word;
221 
222 send_data: process(clk)
223  variable data_int, next_data, next_data_buf: std_logic_vector(63 DOWNTO 0) := (others => '0');
224  variable ready_buf: std_logic := '0';
225  begin
226  if rising_edge(clk) then
227  if send_crc9 = '1' then -- NB low and high words were swapped for CRC calculation!
228  next_data_buf := crc_word(31 downto 0) & crc_word(63 downto 61) & crc9val & crc_word(51 downto 32);
229  elsif send_crc20 = '1' then -- NB low and high words were swapped for CRC calculation!
230  next_data_buf := crc20val & crc_word(11 downto 0) & crc_word(63 downto 32);
231  elsif input_valid_sig = '1' then
232  next_data_buf := inputdata_sig;
233  else
234  next_data_buf := (Others => '0');
235  end if;
236  if ready_buf = '1' or force_ready_sig = '1' then
237  next_data := next_data_buf;
238  end if;
239  if ready_sig = '1' and last_sig = '1' then
240  data_int := (Others => '0');
241  elsif ready_sig = '1' or force_ready_sig = '1' then
242  ready_buf := '1';
243  data_int := next_data;
244  else
245  ready_buf := '0';
246  end if;
247  data_sig <= data_int
248 -- pragma translate_off
249  after 2 ns
250 -- pragma translate_on
251  ;
252  end if;
253  end process send_data;
254 
255 state_machine: process(clk)
256  variable got_data_end: std_logic := '0';
257  variable valid_int, last_int, prefetch_int, force_ready_int: std_logic := '0';
258  variable next_state: STATE_TYPE := idle;
259  begin
260  if rising_edge(clk) then
261  if rst_clk = '1' then
262  next_state := idle;
263  end if;
264  valid_int := '0';
265  last_int := '0';
266  prefetch_int := '0';
267  force_ready_int := '0';
268  if input_data_end_sig = '1' then -- latch end of incoming payload
269  got_data_end := '1';
270  end if;
271  case state_sig is
272  when capture_l1id =>
273  prefetch_int := '1';
274  next_state := do_hdr_crc;
275  when do_hdr_crc =>
276  next_state := wait_hdr_crc;
277  when wait_hdr_crc =>
278  force_ready_int := '1';
279  next_state := send_l1id;
280  when send_l1id =>
281  valid_int := '1';
282  if got_data_end = '1' then -- empty packet...
283  next_state := build_trailer;
284  else
285  next_state := send_payload;
286  end if;
287  when send_payload =>
288  valid_int := '1';
289  if got_data_end = '1' and ready_sig = '1' then
290  next_state := build_trailer;
291  end if;
292  when build_trailer =>
293  if ready_sig = '1' then
294  next_state := do_trailer_crc;
295  else
296  valid_int := '1';
297  end if;
298  when do_trailer_crc =>
299  next_state := wait_trailer_crc;
300  when wait_trailer_crc =>
301  next_state := send_trailer;
302  force_ready_int := '1';
303  when send_trailer =>
304  valid_int := '1';
305  last_int := '1';
306  next_state := wait_end;
307  when wait_end =>
308  if ready_sig = '1' then
309  next_state := idle;
310  else
311  valid_int := '1';
312  last_int := '1';
313  end if;
314  when others => -- idle
315  got_data_end := '0';
316  if (input_valid_sig = '1') then
317  prefetch_int := '1';
318  next_state := capture_l1id;
319  end if;
320  end case;
321  state_sig <= next_state
322 -- pragma translate_off
323  after 2 ns
324 -- pragma translate_on
325  ;
326  prefetch_sig <= prefetch_int
327 -- pragma translate_off
328  after 2 ns
329 -- pragma translate_on
330  ;
331  force_ready_sig <= force_ready_int
332 -- pragma translate_off
333  after 2 ns
334 -- pragma translate_on
335  ;
336  last_sig <= last_int
337 -- pragma translate_off
338  after 2 ns
339 -- pragma translate_on
340  ;
341  valid_sig <= valid_int
342 -- pragma translate_off
343  after 2 ns
344 -- pragma translate_on
345  ;
346  end if;
347  end process state_machine;
348 
349 end universal;
Definition: crc-20.vhd:15
AXI-stream version of packet engine...
AXI-stream version of packet engine...
in packet_data std_logic_vector( 63 DOWNTO 0)
FIFO signals.
out payload_data std_logic_vector( 63 DOWNTO 0)
towards Aurora readout