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