AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
build_pckt_s.vhd
1 ------------------------------------------------------
2 -- encapsulate the data/ack/init for Opt Link
3 --
4 -- Ver 2.00
5 --
6 -- Dominique Gigi May 2015
7 ------------------------------------------------------
8 -- Move the logic to 10Gb interface (XGMII) &
9 --
10 --
11 --
12 ------------------------------------------------------
13 LIBRARY ieee;
14 USE ieee.std_logic_1164.all;
15 use ieee.numeric_std.all;
16 use ieee.std_logic_unsigned.all;
17 use work.mydefs.all;
18 
20 
21 port (
22  reset_CLK : in std_logic;
23  Greset_CLK : in std_logic;
24  clock : in std_logic;
25 
26  start_pckt : in std_logic; -- trigger the packet send
27  init_pckt : in std_logic; -- indicates that the packet is a Init packet
28  ack_pckt : in std_logic; -- indicates that the packet is a acknoldge packet
29  data_pckt : in std_logic; -- indicates that the packet is a data packet
30  data_evt : in std_logic_vector(63 downto 0); --data for data packet
31  read_bck : in std_logic_vector(63 downto 0); --data back for acknowledge packet
32  card_ID : in std_logic_vector(15 downto 0); -- CARD_ID
33  Seq_nb : in std_logic_vector(30 downto 0); -- sequence number
34  len_pckt : in std_logic_vector(15 downto 0); -- length of the packet (for data packet only) other 0
35  cmd : in std_logic_vector(63 downto 0); -- command bit for data packet only
36  error_gen : in std_logic_vector(3 downto 0);
37  rd_dt : out std_logic; -- request data for data packet only
38  end_pckt : out std_logic;
39 
40  datao : out std_logic_vector(63 downto 0); --- data and K bit send to SERDES
41  k_byte : out std_logic_vector( 7 downto 0);
42  idle_state : out std_logic;
43  status_state : out std_logic_vector(31 downto 0);
44  cnt_pckt_snd : out std_logic_vector(31 downto 0)
45  );
46 
47 end build_pckt_s_XGMII;
48 architecture behavioral of build_pckt_s_XGMII is
49 
50  type packet_type is ( idle,
51  preamble,
52  start_of_frame,
53  status_s,
54  command,
55  data,
56  CRC_end_frame,
57  wait_crc,
58  gap0,
59  gap1,
60  gap2,
61  gap3
62 
63  );
64 signal packet,packetNext:packet_type;
65 
66 component crc_gen_32b IS
67  PORT(
68  clock : IN STD_LOGIC;
69  reset : IN STD_LOGIC;
70  data : IN STD_LOGIC_VECTOR(63 DOWNTO 0);
71  data_valid : IN STD_LOGIC;
72  eoc : IN STD_LOGIC;
73 
74  crc : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
75  crc_valid : OUT STD_LOGIC
76  );
77 end component;
78 
79 signal cmp_crc : std_logic;
80 signal val_crc : std_logic_vector(31 downto 0);
81 signal crc_valid : std_logic;
82 signal end_crc : std_logic;
83 signal pckt_type : std_logic_vector(2 downto 0);
84 signal seqnb_mem : std_logic_vector(31 downto 0);
85 signal len_mem : std_logic_vector(15 downto 0);
86 signal cmd_mem : std_logic_vector(63 downto 0);
87 
88 signal del_crc : std_logic_vector(2 downto 0);
89 signal tmp_dt_crc : std_logic_vector(63 downto 0);
90 signal pipe_dta : std_logic_vector(63 downto 0);
91 signal pipe_dtb : std_logic_vector(63 downto 0);
92 signal pipe_dtc : std_logic_vector(63 downto 0);
93 signal pipe_ka : std_logic_vector( 7 downto 0);
94 signal pipe_kb : std_logic_vector( 7 downto 0);
95 signal pipe_kc : std_logic_vector( 7 downto 0);
96 
97 signal nxt_dt : std_logic;
98 signal wc_val : std_logic_vector(15 downto 0);
99 
100 signal mem_error :std_logic_vector(3 downto 0);
101 signal mem_error_gen :std_logic_vector(3 downto 0);
102 
103 signal cnt_pck : std_logic_vector(31 downto 0);
104 --*******************************************************
105 --************** BEGIN ********************************
106 --*******************************************************
107 begin
108 
109 
110 --***************** error gen ****************
111 -- 0 error on wc
112 -- 1 error on crc
113 -- 2 error on seq number
114 -- 3 error on frame
115 process(Greset_CLK,clock)
116 begin
117 if Greset_CLK = '0' then
118  mem_error <= (others => '0');
119  mem_error_gen <= (others => '0');
120 elsif rising_edge(clock) then
121  if error_gen /= "0000" then
122  mem_error <= error_gen;
123  elsif start_pckt = '1' and data_pckt = '1' then
124  mem_error <= (others => '0');
125  end if;
126 
127  if start_pckt = '1' and data_pckt = '1' then
128  mem_error_gen <= mem_error ;
129  elsif del_crc(1) = '1' and data_pckt = '1' then
130  mem_error_gen <= (others => '0');
131  end if;
132 end if;
133 end process;
134 --********************************************
135 
136 --Initiatlize some values
137  -- Sequence number insert in the packet
138  --length of the packet
139  --bit ACK on (1) or OFF (0)
140  --Packet type (001) INIT packet
141  -- (010) data packet
142  -- (100) ack packet
143 process(reset_CLK,clock)
144 begin
145 if reset_CLK = '0' then
146  pckt_type <= (others => '0');
147 elsif rising_edge(clock) then
148  if start_pckt = '1' then
149  pckt_type <= "000";
150  seqnb_mem(30 downto 0) <= Seq_nb;
151  seqnb_mem(31) <= '0';
152  len_mem <= len_pckt;
153  cmd_mem <= cmd;
154  if init_pckt = '1' then
155  pckt_type(0) <= '1';
156  seqnb_mem <= (others => '0');
157  len_mem <= (others => '0');
158  elsif ack_pckt = '1' then
159  pckt_type(2) <= '1';
160  seqnb_mem(31) <= '1';
161  len_mem <= (others => '0');
162  elsif data_pckt = '1' then
163  pckt_type(1) <= '1';
164  end if;
165  end if;
166 end if;
167 end process;
168 
169 -- compute the CRC on fly (64 bit data => result in 32 bit)
170 CRC_engine:crc_gen_32b
171 PORT MAP(
172  clock => clock,
173  reset => start_pckt,
174  data => tmp_dt_crc,
175  data_valid => cmp_crc,
176  eoc => end_crc,
177  crc => val_crc,
178  crc_valid => crc_valid
179  );
180 
181 
182 --Clock for state machine
183 state_clk:process(clock,reset_CLK)
184 begin
185 if reset_CLK = '0' then
186  packet <= idle;
187 elsif rising_edge(clock) then
188  packet <= packetNext;
189 end if;
190 end process;
191 
192 state_step:process(packet,start_pckt,pckt_type,wc_val,crc_valid)
193 begin
194 packetNext <= packet;
195 end_crc <= '0';
196 Case packet is
197  -- wait for a packet to send
198  when idle =>
199  status_state(0) <= '1';
200  if start_pckt = '1' then
201  packetNext <= preamble;
202  end if;
203 
204  when preamble =>
205  packetNext <= start_of_frame;
206  -- start the frame with a "START FRAME" + the SEQUENCE number +LSC/LDC_ID + LENGTH
207  when start_of_frame => -- and seq_number
208  status_state(1) <= '1';
209  if pckt_type(0) = '1' then -- init
210  packetNext <= CRC_end_frame;
211  elsif pckt_type(1) = '1' then -- data
212  packetNext <= command;
213  elsif pckt_type(2) = '1' then -- ack
214  packetNext <= status_s;
215  end if;
216  -- In case of a ACK include the STATUS
217  when status_s =>
218  status_state(2) <= '1';
219  packetNext <= CRC_end_frame;
220  -- In case of a DATA include the COMMAND
221  when command =>
222  status_state(3) <= '1';
223  packetNext <= data;
224  -- In case of a DATA include the DATA0
225  when data =>
226  status_state(4) <= '1';
227  if wc_val = x"0000" then
228  packetNext <= CRC_end_frame;
229  end if;
230  -- conclude by the CRC
231  when CRC_end_frame =>
232  status_state(5) <= '1';
233  end_crc <= '1';
234  packetNext <= wait_crc;
235  -- the CRC will arrive in a deterministic number of clock
236  -- wait is not the real case, but avoid to put multiple state between CEC_END_FRAME and WAIT_CRC
237  when wait_crc =>
238  status_state(6) <= '1';
239  if crc_valid = '1' then
240  packetNext <= gap0;
241  end if;
242  -- include some gap between packet like in ETHERNET
243  when gap0 =>
244  status_state(7) <= '1';
245  packetNext <= gap1;
246 
247  when gap1 =>
248  status_state(8) <= '1';
249  packetNext <= idle;--gap2;
250 
251  when gap2 =>
252  status_state(9) <= '1';
253  packetNext <= gap3;
254 
255  when gap3 =>
256  status_state(10) <= '1';
257  packetNext <= idle;
258 
259  when others =>
260  packetNext <= idle;
261  end case;
262 
263 end process;
264 
265 --generate the pulse to read data to include in the packet
266 process(reset_CLK,clock)
267 begin
268 if reset_CLK = '0' then
269  nxt_dt <= '0';
270 elsif rising_edge(clock) then
271  nxt_dt <= '0';
272  if packet = data or packet = command or (packet = start_of_frame and pckt_type(1) = '1')then
273  nxt_dt <= '1';
274  end if;
275 end if;
276 end process;
277 
278 rd_dt <= nxt_dt;
279 
280 -- count down starting from len_pckt (latch at the request "start_pckt")
281 process(reset_CLK,clock)
282 begin
283 if reset_CLK = '0' then
284  wc_val <= (others => '0');
285 elsif rising_edge(clock) then
286  if start_pckt = '1' then
287  wc_val <= len_pckt;
288  elsif nxt_dt = '1' then
289  wc_val <= std_logic_vector( TO_SIGNED ( TO_INTEGER ( UNSIGNED (wc_val) - 1),16) );
290  end if;
291 end if;
292 end process;
293 
294 -- MULTIPLEXER of values (SATRT_FRAME,Seq#,ID, DATA, Command,...) to create the packet
295 process(reset_CLK,clock)
296 variable status_wrd : std_logic_vector(63 downto 0);
297 variable local_v : std_logic_vector(63 downto 0);
298 begin
299  if reset_CLK = '0' then
300  pipe_ka <= "11111111";
301  pipe_dta <= x"0707070707070707"; --IDLE STATE
302  cmp_crc <= '0';
303  elsif rising_edge(clock) then
304  pipe_ka <= "11111111";
305  pipe_dta <= x"0707070707070707"; --IDLE STATE
306 
307  if packet = preamble then
308  pipe_ka <= "00000001";
309  pipe_dta <= x"D5555555555555FB"; -- preamble and start of frame
310 
311  elsif packet = start_of_frame then --ACK PACKET
312  cmp_crc <= '1';
313  local_v(63 downto 32) := Seqnb_mem;
314  local_v(45) := Seqnb_mem(13) xor mem_error_gen(2); -- error gen
315  local_v(31 downto 16) := card_ID;
316  local_v(15 downto 0) := len_mem;
317  local_v(5) := len_mem(5) xor mem_error_gen(0); -- error gen
318 
319  -- used to compute the CRC
320  tmp_dt_crc <= local_v;
321 
322  pipe_ka <= "00000000";
323  pipe_dta(63 downto 00) <= local_v(63 downto 00);
324  pipe_dta(63) <= local_v(63) xor mem_error_gen(3); -- error gen
325 
326  elsif packet = status_s then --ACK PACKET
327  status_wrd := read_bck; --status word; this value may change in futur
328  tmp_dt_crc <= status_wrd;
329 
330  pipe_ka <= "00000000";
331  pipe_dta(63 downto 00) <= status_wrd;
332 
333  elsif packet = command then -- CMD DATA read returned
334  tmp_dt_crc <= cmd_mem;
335 
336  pipe_ka <= "00000000";
337  pipe_dta(63 downto 00) <= cmd_mem;
338 
339  elsif packet = data then
340  tmp_dt_crc <= data_evt;
341 
342  pipe_ka <= "00000000";
343  pipe_dta(63 downto 00) <= data_evt;
344 
345  elsif packet = CRC_end_frame then
346 
347  cmp_crc <= '0';
348  pipe_ka <= "11110000";
349  pipe_dta(63 downto 32) <= x"070707FD"; -- place END of FRAME + idle
350  pipe_dta(31 downto 00) <= x"00000000"; --CRC place -- place for CRC32
351 
352  end if;
353  end if;
354 end process;
355 
356 -- create a delay to iintroduce the CRC result
357 process(clock)
358 begin
359 if rising_edge(clock) then
360  del_crc(2 downto 1) <= del_crc(1 downto 0);
361  del_crc(0) <= '0';
362  if packet = CRC_end_frame then
363  del_crc(0) <= '1';
364  end if;
365 end if;
366 end process;
367 
368 --pipe packet value until the CRC is ready
369 process(clock)
370 begin
371 if rising_edge(clock) then
372  pipe_kc <= pipe_kb;
373  pipe_kb <= pipe_ka;
374  pipe_dtc<= pipe_dtb;
375  pipe_dtb<= pipe_dta;
376  if del_crc(1) = '1' then
377  pipe_dtc(31 downto 00) <= val_crc;
378  pipe_dtc(9) <= val_crc(9) xor mem_error_gen(1); -- error gen
379  end if;
380 end if;
381 end process;
382 
383 -- generate the end of packet create
384 process(reset_CLK,clock)
385 begin
386  if reset_CLK = '0' then
387  end_pckt <= '0';
388  elsif rising_edge(clock) then
389  end_pckt <= '0';
390  if end_crc = '1' and pckt_type(1) = '1' then
391  end_pckt <= '1';
392  end if;
393  end if;
394 end process;
395 
396 process(Greset_CLK,clock)
397 begin
398  if Greset_CLK = '0' then
399  cnt_pck <= (others => '0');
400  elsif rising_edge(clock) then
401  if end_crc = '1' and pckt_type(1) = '1' then
402  cnt_pck <= cnt_pck + '1';
403  end if;
404  end if;
405 end process;
406 
407 idle_state <= '1' when packet = idle else '0';
408 
409 process(pipe_dtc,pipe_kc)
410 begin
411  if FPGA_Brand = "ALTERA" then
412  -- swapp bytes to be compliante to 10Gb (For Altera Only)
413  datao(63 downto 56) <= pipe_dtc(63 downto 56);
414  k_byte(7) <= pipe_kc(7);
415  datao(55 downto 48) <= pipe_dtc(31 downto 24);
416  k_byte(6) <= pipe_kc(3);
417  datao(47 downto 40) <= pipe_dtc(55 downto 48);
418  k_byte(5) <= pipe_kc(6);
419  datao(39 downto 32) <= pipe_dtc(23 downto 16);
420  k_byte(4) <= pipe_kc(2);
421  datao(31 downto 24) <= pipe_dtc(47 downto 40);
422  k_byte(3) <= pipe_kc(5);
423  datao(23 downto 16) <= pipe_dtc(15 downto 08);
424  k_byte(2) <= pipe_kc(1);
425  datao(15 downto 08) <= pipe_dtc(39 downto 32);
426  k_byte(1) <= pipe_kc(4);
427  datao(07 downto 00) <= pipe_dtc(07 downto 00);
428  k_byte(0) <= pipe_kc(0);
429  elsif FPGA_Brand = "XILINX" then
430  datao <= pipe_dtc;
431  k_byte <= pipe_kc;
432  end if;
433 end process;
434 
435 
436 
437 
438 
439 cnt_pckt_snd <= cnt_pck;
440 status_state(31 downto 11) <= (others => '0');
441 
442 end behavioral;
443 
444