AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
rcv_pckt_s.vhd
1 
2 ------------------------------------------------------
3 -- Receive packet
4 --
5 -- Ver 1.00
6 --
7 -- Dominique Gigi Feb 2012
8 ------------------------------------------------------
9 --
10 --
11 --
12 --
13 ------------------------------------------------------
14 LIBRARY ieee;
15 -- LIBRARY altera_mf;
16 -- LIBRARY altera;
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 rcv_pckt_s is
27 
28 port (
29  reset_clk : in std_logic;
30  reset_clkT : in std_logic;
31  Greset_clk : in std_logic;
32  Greset_clkT : in std_logic;
33  clock : in std_logic;
34  clock_t : in std_logic;
35 
36  datai : in std_logic_vector(31 downto 0); -- data and K bit send from SERDES
37  k_byte : in std_logic_vector( 3 downto 0);
38 
39  error_gen : in std_logic; -- 1 will emulate an error in one ack packet
40 
41  cmd : out std_logic_vector(31 downto 0); -- command from DAQ
42  data : out std_logic_vector(31 downto 0); -- data from DAQ
43  ena_cmd : out std_logic; -- validate command
44 
45  status : out std_logic_vector(63 downto 0); -- value return from read command request
46  seqnb : out std_logic_vector(30 downto 0); -- seq numb from ack (received an ack)
47  ena_ack : out std_logic;
48 
49  card_ID : out std_logic_vector(15 downto 0);
50  cnt_pckt_rcv : out std_logic_vector(31 downto 0)
51  );
52 
53 end rcv_pckt_s;
54 
55 architecture behavioral of rcv_pckt_s is
56 
57 component crc_gen_usb_32to16
58  PORT(
59  clock : IN STD_LOGIC;
60  reset : IN STD_LOGIC;
61  data : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
62  data_valid : IN STD_LOGIC;
63  eoc : IN STD_LOGIC;
64  crc : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
65  crc_valid : OUT STD_LOGIC
66  );
67 end component;
68 
69 component resync
70 port (
71  reset : in std_logic;
72  Free_clki : in std_logic;
73  clocki : in std_logic;
74  clocko : in std_logic;
75  input : in std_logic;
76  output : out std_logic
77  );
78 end component;
79 
80 signal pipe_a : std_logic_vector(31 downto 0);
81 signal pipe_b : std_logic_vector(31 downto 0);
82 signal pipe_c : std_logic_vector(31 downto 0);
83 signal pipe_K : std_logic_vector(3 downto 0);
84 
85 signal align : std_logic_vector(3 downto 0);
86 signal SOF : std_logic_vector(2 downto 0);
87 signal EOF : std_logic_vector(2 downto 0);
88 signal stage : std_logic_vector(4 downto 0);
89 
90 signal cmd_reg : std_logic_vector(31 downto 0);
91 signal data_reg : std_logic_vector(31 downto 0);
92 signal ena_cmd_reg : std_logic;
93 
94 signal status_reg : std_logic_vector(63 downto 0);
95 signal ena_ack_reg : std_logic;
96 
97 
98 signal seqnb_reg : std_logic_vector(30 downto 0);
99 signal ID_reg : std_logic_vector(15 downto 0);
100 signal length_reg : std_logic_vector(15 downto 0);
101 
102 signal cmp_crc : std_logic;
103 
104 signal eoc : std_logic;
105 signal crc_val : std_logic_vector(15 downto 0);
106 signal crc_valid : std_logic;
107 signal crc_to_be_check : std_logic_vector(15 downto 0);
108 signal end_check : std_logic;
109 signal cmd_pckt : std_logic;
110 signal ack_pckt : std_logic;
111 signal latch_crc_in : std_logic_vector(1 downto 0);
112 signal mem_error_gen : std_logic_vector(1 downto 0);
113 signal pack_counter : std_logic_vector(31 downto 0);
114 
115 --*******************************************************
116 --************** BEGIN ********************************
117 --*******************************************************
118 begin
119 
120 --****** error gen ********
121 process(reset_clk,clock)
122 begin
123  if reset_clk = '0' then
124  mem_error_gen <= (others => '0');
125  elsif rising_edge(clock) then
126  if SOF(0) = '1' then
127  mem_error_gen(1) <= mem_error_gen(0);
128  elsif crc_valid = '1' then
129  mem_error_gen(1) <= '0';
130  end if;
131 
132  if error_gen = '1' then
133  mem_error_gen(0) <= '1';
134  elsif SOF(0) = '1' then
135  mem_error_gen(0) <= '0';
136  end if;
137  end if;
138 end process;
139 --*************************
140 
141 process(reset_clk,clock) -- alignment on the start of frame
142 begin
143 if reset_clk = '0' then
144  align <= (others => '0');
145 elsif rising_edge(clock) then
146  SOF(0) <= '0';
147  SOF(2 downto 1) <= SOF(1 downto 0);
148  if align /= "0000" and end_check = '1' then
149  align <= "0000";
150  elsif datai(23 downto 16) = x"FB" and k_byte(2) = '1' and align = "0000" then
151  align <= "1000";
152  SOF(0) <= '1';
153  elsif datai(07 downto 00) = x"FB" and k_byte(0) = '1' and align = "0000" then
154  align <= "0010";
155  SOF(0) <= '1';
156  end if;
157 end if;
158 end process;
159 
160 -- Swapp bytes in case of alignement need
161 -- And Pipe data
162 process(clock)
163 begin
164 if rising_edge(clock) then
165  pipe_c <= pipe_b;
166  if align(1) = '1' then
167  pipe_b(31 downto 24) <= pipe_a(31 downto 24);-- normal
168  pipe_b(23 downto 16) <= pipe_a(23 downto 16);
169  pipe_b(15 downto 08) <= pipe_a(15 downto 08);
170  pipe_b(07 downto 00) <= pipe_a(07 downto 00);
171  elsif align(3) = '1' then
172  pipe_b(31 downto 24) <= datai (15 downto 08);-- half_word swapped
173  pipe_b(23 downto 16) <= datai (07 downto 00);
174  pipe_b(15 downto 08) <= pipe_a(31 downto 24);
175  pipe_b(07 downto 00) <= pipe_a(23 downto 16);
176  end if;
177  pipe_a <= datai;
178  pipe_K <= k_byte;
179 end if;
180 end process;
181 
182 
183 process(clock)
184 begin
185 if rising_edge(clock) then
186  stage(4 downto 1) <= stage(3 downto 0);
187  stage(0) <= SOF(1);
188 end if;
189 end process;
190 
191 
192 -- Envelop the data to be used to compute the CRC
193 process(reset_clk,clock)
194 begin
195 if reset_clk = '0' then
196  cmp_crc <= '0';
197 elsif rising_edge(clock) then
198  if SOF(2) = '1' then
199  cmp_crc <= '1';
200  elsif EOF(1) = '1' or (EOF(0) = '1' and latch_crc_in = "11" ) then
201  cmp_crc <= '0';
202  end if;
203 end if;
204 end process;
205 
206 -- latch the CRC received in the packet
207 process(reset_clk,clock)
208 begin
209 if rising_edge(clock) then
210  if latch_crc_in = "01" then
211  crc_to_be_check(15 downto 8) <= pipe_a(31 downto 24);
212  crc_to_be_check(07) <= pipe_a(23) xor mem_error_gen(1);
213  crc_to_be_check(06 downto 0) <= pipe_a(22 downto 16);
214  elsif latch_crc_in = "11" then
215  crc_to_be_check(15 downto 8) <= pipe_a(15 downto 08);
216  crc_to_be_check(07) <= pipe_a(07) xor mem_error_gen(1);
217  crc_to_be_check(06 downto 0) <= pipe_a(06 downto 00);
218  end if;
219 end if;
220 end process;
221 
222 
223 -- check where is the CRC in the packet
224 -- according the alignment of the data
225 process(reset_clk,clock)
226 begin
227 if reset_clk = '0' then
228  EOF <= (others => '0');
229 elsif rising_edge(clock) then
230  EOF(2 downto 1) <= EOF(1 downto 0);
231  EOF(0) <= '0';
232  latch_crc_in <= "00";
233  if (datai(15 downto 08) = x"FD" and k_byte(1) = '1') then --normal wait
234  EOF(0) <= '1';
235  latch_crc_in <= "01";
236  elsif (pipe_a(31 downto 24) = x"FD" and pipe_K(3) = '1') then -- met half_word swapped
237  EOF(0) <= '1';
238  latch_crc_in <= "11";
239  elsif k_byte = "1111" and cmp_crc = '1' then -- in case of we lost the synchronization
240  EOF(0) <= '1';
241  end if;
242 end if;
243 end process;
244 
245 EOC <= '1' when EOF(1) = '1' or (EOF(0) = '1' and latch_crc_in = "11" ) else '0';
246 
247 --********************************************************
248 -- instantiation to Compute the CRC
249 CRC_generate:crc_gen_usb_32to16
250 PORT MAP(
251  clock => clock,
252  reset => SOF(1),
253  data => pipe_c ,
254  data_valid => cmp_crc,
255  eoc => EOC,
256  crc => crc_val,
257  crc_valid => crc_valid
258  );
259 --********************************************************
260 
261 -- recover the values from the packet
262 -- Sequence#,
263 -- Ack nit,
264 --Status,....
265 process(reset_clk,clock)
266 begin
267 if reset_clk = '0' then
268  cmd_pckt <= '0';
269  ack_pckt <= '0';
270 elsif rising_edge(clock) then
271  if stage(0) = '1' then
272  seqnb_reg <= pipe_b(30 downto 0);
273  ack_pckt <= pipe_b(31);
274  cmd_pckt <= not(pipe_b(31));
275  elsif stage(1) = '1' then
276  ID_reg <= pipe_b(31 downto 16);
277  length_reg <= pipe_b(15 downto 00);
278  elsif stage(2) = '1' and ack_pckt = '0' then
279  status_reg(63 downto 32) <= pipe_b;
280  cmd_reg <= pipe_b;
281  elsif stage(3) = '1' then
282  status_reg(31 downto 00) <= pipe_b;
283  data_reg <= pipe_b;
284  elsif end_check = '1' then
285  cmd_pckt <= '0';
286  ack_pckt <= '0';
287  end if;
288 end if;
289 end process;
290 
291 -- validate or unvalidate the packet according the CRC check
292 process(reset_clk,clock)
293 begin
294 if reset_clk = '0' then
295  ena_cmd_reg <= '0';
296  ena_ack_reg <= '0';
297  end_check <= '0';
298 elsif rising_edge(clock) then
299  ena_cmd_reg <= '0';
300  ena_ack_reg <= '0';
301  end_check <= '0';
302  if crc_valid = '1' then
303  end_check <= '1';
304  if crc_val = crc_to_be_check then
305  if ack_pckt = '1' then
306  ena_ack_reg <= '1';
307  elsif cmd_pckt = '1' then
308  ena_cmd_reg <= '1';
309  end if;
310  end if;
311  end if;
312 end if;
313 end process;
314 
315 process(Greset_clk,clock)
316 begin
317 if Greset_clk = '0' then
318  pack_counter <= (others => '0');
319 elsif rising_edge(clock) then
320  if crc_valid = '1' then
321  if crc_val = crc_to_be_check then
322  if ack_pckt = '1' then
323  pack_counter <= pack_counter + '1';
324  end if;
325  end if;
326  end if;
327 end if;
328 end process;
329 
330 -- resynchronisation between clock domains
331 resync_ena_ack:resync
332 port map(
333  reset => reset_clk,
334  Free_clki => '1',
335  clocki => clock,
336  clocko => clock_t,
337  input => ena_ack_reg,
338  output => ena_ack
339  );
340 
341 resync_ena_cmd:resync
342 port map(
343  reset => reset_clk,
344  Free_clki => '1',
345  clocki => clock,
346  clocko => clock_t,
347  input => ena_cmd_reg,
348  output => ena_cmd
349  );
350 
351 
352 cmd <= cmd_reg;
353 data <= data_reg;
354 status <= status_reg;
355 seqnb <= seqnb_reg;
356 card_ID <= ID_reg;
357 
358 cnt_pckt_rcv <= pack_counter; -- count only the ack (not the command received
359 
360 end behavioral;
361