00001 --**************************************************************
00002 --* *
00003 --* The source code for the ATLAS BCM "AAA" FPGA is made *
00004 --* available via the GNU General Public License (GPL) *
00005 --* unless otherwise stated below. *
00006 --* *
00007 --* In case of problems/questions/bug reports etc. please *
00008 --* contact michael.niegl@cern.ch *
00009 --* *
00010 --**************************************************************
00011
00012 --**************************************************************
00013 --* *
00014 --* $Source: /local/reps/bcmfpga/bcm_aaa/bcm_aaa/eth/auto_receiver.vhd,v $
00015 --* $Revision: 2.7.2.3 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 17:57:46 $ *
00019
00020
00021 --* *
00022 --**************************************************************
00023 ---------------------------------------------------------------------------------
00024 -- Company:
00025 -- Engineer:
00026 --
00027 -- Create Date: 22:11:55 12/28/2006
00028 -- Design Name: NCM basic
00029 -- Module Name: auto_receiver - auto_receiver_arc
00030 -- Project Name: NCM
00031 -- Target Devices:
00032 -- Tool versions:
00033 -- Description: receives packets from EMAC & decodes variables into receive channels
00034 -- en is used to turn on/off receivers
00035 -- receive channels are reset automatically
00036 -- sync packet is decoded and shown as pulse
00037 --
00038 -- Dependencies:
00039 --
00040 -- Revision:
00041 -- Revision 0.01 - File Created
00042 -- Additional Comments:
00043 --
00044 ----------------------------------------------------------------------------------
00045
00046 library ieee;
00047
00048 use ieee.std_logic_1164.all;
00049
00050 use ieee.std_logic_arith.all;
00051
00052 use ieee.std_logic_unsigned.all;
00053
00054 use ieee.numeric_std.all;
00055
00056
00057 library unisim;
00058
00059 use unisim.vcomponents.all;
00060 library work;
00061 use work.udp_addresses.all;
00062 use work.ncm_package.all;
00063
00064
00065
00066
00067 entity auto_receiver is
00068 port (clk : in ;
00069 en : in ;
00070 busy : out ;
00071 -- emac interface
00072 rx_fifo_rst : out ;
00073 rx_fifo_data : in (7 downto 0);
00074 rx_fifo_en : out ;
00075 rx_good_packet : in ;
00076 rx_bad_packet : in ;
00077 rx_valid : in ;
00078 rx_rderr : in ;
00079 ncm_sync : out ;
00080 ncm_rcv_channel : out (3 downto 0);
00081 ncm_rcv_en : out ;
00082 ncm_rcv_data : out (7 downto 0);
00083 ncm_rcv_reset : out ;
00084 lastpacketlen : out (15 downto 0);
00085 goodcnt : out (31 downto 0);
00086 nobroadcst : out (15 downto 0);
00087 badcnt : out (31 downto 0);
00088 -- ARP
00089 ARP_vld : out ;
00090 SHA : out (47 downto 0);
00091 SPA : out (31 downto 0);
00092 -- packet number and datatype
00093 packet : out (19 downto 0);
00094 data_type : out (11 downto 0)
00095 );
00096 end auto_receiver;
00097
00098
00099
00100
00101 architecture auto_receiver_arc of auto_receiver is
00102
00103 type states is (s_init, s_idle, s_wait, s_cnt, s_lenh, s_lenl, s_data, s_bad, s_rest, s_rdy, s_packet, s_datatype, s_arpreq);
00104 signal currentstate : states := s_init;
00105
00106 signal good_i : ; -- combine en and rx_good_packet
00107 signal bad_i : ; -- ...
00108 signal busy_i : := '0';
00109 signal good_ff : := '0';
00110 signal bad_ff : := '0';
00111 signal lastpacketlen_i : (15 downto 0) := (others => '0');
00112 signal sha_req : (47 downto 0) := (others => '0');
00113 signal spa_req : (31 downto 0) := (others => '0');
00114
00115 attribute fsm_encoding : ;
00116 attribute safe_implementation : ;
00117 attribute fsm_encoding of currentstate : signal is "gray";
00118 attribute safe_implementation of currentstate : signal is "yes";
00119
00120 begin
00121
00122 busy <= busy_i;
00123
00124 latch_good : process(clk)
00125 begin
00126 if clk'event and clk = '1' then
00127 if (en and rx_good_packet) = '1' then
00128 good_ff <= '1';
00129 elsif (good_i and (not busy_i)) = '1' then
00130 good_ff <= '0';
00131 end if;
00132 end if;
00133 end process latch_good;
00134
00135 latch_bad : process(clk)
00136 begin
00137 if clk'event and clk = '1' then
00138 if (en and rx_bad_packet) = '1' then
00139 bad_ff <= '1';
00140 elsif (bad_i and (not busy_i)) = '1' then
00141 bad_ff <= '0';
00142 end if;
00143 end if;
00144 end process latch_bad;
00145 good_i <= good_ff when busy_i <= '0'; -- triggers
00146 bad_i <= bad_ff when busy_i <= '0';
00147
00148 lastpacketlen <= lastpacketlen_i; -- statistics
00149 goodcnt <= (others => '0');
00150 badcnt <= (others => '0');
00151 nobroadcst <= (others => '0');
00152 ncm_sync <= '0';
00153 ncm_rcv_reset <= '0';
00154 ncm_rcv_channel <= (others => '0');
00155 rx_fifo_rst <= '1' when currentstate = s_init else '0';
00156
00157
00158 FSM : process(clk)
00159 variable nextstate : states := s_init;
00160 variable cnt : range 0 to 1500 := 0;
00161 variable byte : (1 downto 0) := "00";
00162 variable rxbuf : (7 downto 0);
00163 begin
00164
00165 if (rising_edge(clk)) then
00166
00167 nextstate := currentstate;
00168 ARP_vld <= '0';
00169
00170 if (rx_rderr = '0') then -- in case of rderr we keep the current state
00171
00172 case currentstate is
00173
00174 when s_init =>
00175
00176 cnt := 0;
00177 rx_fifo_en <= '0';
00178 ncm_rcv_data <= (others => '0');
00179 ncm_rcv_en <= '0';
00180 busy_i <= '0';
00181 lastpacketlen_i <= (others => '0');
00182 ARP_vld <= '0';
00183 SHA <= (others => '0');
00184 SPA <= (others => '0');
00185 sha_req <= (others => '0');
00186 spa_req <= (others => '0');
00187
00188 nextstate := s_idle;
00189
00190 when s_idle =>
00191
00192 ncm_rcv_data <= (others => '0');
00193 data_type <= (others => '0');
00194 ncm_rcv_en <= '0';
00195 busy_i <= '0';
00196 cnt := 0;
00197
00198 if (good_i = '1') then -- good packet is in queue - read it out
00199 busy_i <= '1';
00200 rx_fifo_en <= '1'; -- init rcv process
00201 nextstate := s_wait; -- wait one cycle to get data
00202 elsif (bad_i = '1') then -- bad packet is in queue - reset queue
00203 busy_i <= '1';
00204 nextstate := s_bad;
00205 else
00206 rx_fifo_en <= '0';
00207 end if;
00208
00209 when s_wait =>
00210
00211 cnt := 0;
00212 nextstate := s_cnt;
00213
00214 when s_cnt =>
00215
00216 if (rx_valid = '0') then
00217 rx_fifo_en <= '0';
00218 nextstate := s_rdy;
00219 else
00220
00221 if cnt = 13 then
00222 if rx_fifo_data = x"06" then
00223 nextstate := s_arpreq;
00224 cnt := 0;
00225 end if;
00226 elsif cnt = 41 then --* step through Ethernet header (14
00227 nextstate := s_lenh; --* bytes), IP header (20 bytes), UDP
00228 else --* header (8 bytes)
00229 nextstate := s_cnt;
00230 end if;
00231 end if;
00232
00233 -- if cnt = 25 then --* check src ip
00234 -- if rx_fifo_data /= rxsrcip(31 downto 24) then
00235 -- nextstate := s_bad;
00236 -- end if;
00237 -- elsif cnt = 26 then
00238 -- if rx_fifo_data /= rxsrcip(23 downto 16) then
00239 -- nextstate := s_bad;
00240 -- end if;
00241 -- elsif cnt = 27 then
00242 -- if rx_fifo_data /= rxsrcip(15 downto 8) then
00243 -- nextstate := s_bad;
00244 -- end if;
00245 -- elsif cnt = 28 then
00246 -- if rx_fifo_data /= rxsrcip(7 downto 0) then
00247 -- nextstate := s_bad;
00248 -- end if;
00249 -- end if;
00250
00251 if cnt = 30 then --* check dest ip
00252 if rx_fifo_data /= rxdestip(31 downto 24) then
00253 nextstate := s_bad;
00254 end if;
00255 elsif cnt = 31 then
00256 if rx_fifo_data /= rxdestip(23 downto 16) then
00257 nextstate := s_bad;
00258 end if;
00259 elsif cnt = 32 then
00260 if rx_fifo_data /= rxdestip(15 downto 8) then
00261 nextstate := s_bad;
00262 end if;
00263 elsif cnt = 33 then
00264 if rx_fifo_data /= rxdestip(7 downto 0) then
00265 nextstate := s_bad;
00266 end if;
00267 end if;
00268
00269 -- if cnt = 35 then --* check src port
00270 -- if rx_fifo_data /= rxsrc_port(15 downto 8) then
00271 -- nextstate := s_bad;
00272 -- end if;
00273 -- elsif cnt = 36 then
00274 -- if rx_fifo_data /= rxsrc_port(7 downto 0) then
00275 -- nextstate := s_bad;
00276 -- end if;
00277 -- end if;
00278
00279 if cnt = 36 then --* check dest port
00280 if rx_fifo_data /= rxdest_port(15 downto 8) then
00281 nextstate := s_bad;
00282 end if;
00283 elsif cnt = 37 then
00284 if rx_fifo_data /= rxdest_port(7 downto 0) then
00285 nextstate := s_bad;
00286 end if;
00287 end if;
00288 cnt := cnt + 1;
00289
00290 when s_lenh => --* len of real data, expect length of
00291 cnt := 0; --* packet in first 2 bytes of data block
00292 if (rx_valid = '0') then
00293 rx_fifo_en <= '0';
00294 nextstate := s_rdy;
00295 else
00296 lastpacketlen_i(15 downto 8) <= rx_fifo_data;
00297 nextstate := s_lenl;
00298 end if;
00299
00300 when s_lenl => -- len of real data
00301
00302 if (rx_valid = '0') then
00303 rx_fifo_en <= '0';
00304 nextstate := s_rdy;
00305 else
00306 lastpacketlen_i(7 downto 0) <= rx_fifo_data;
00307 cnt := 0;
00308 nextstate := s_packet;
00309 end if;
00310
00311 when s_packet => --read the number of packet
00312 if (rx_valid = '0') then
00313 rx_fifo_en <= '0';
00314 nextstate := s_rdy;
00315 else
00316 if cnt = 0 then
00317 packet(19 downto 12) <= rx_fifo_data;
00318 elsif cnt = 1 then
00319 packet(11 downto 4) <= rx_fifo_data;
00320 elsif cnt = 2 then
00321 packet(3 downto 0) <= rx_fifo_data(7 downto 4);
00322 data_type(11 downto 8) <= rx_fifo_data(3 downto 0);
00323 nextstate := s_datatype;
00324 end if;
00325 cnt := cnt + 1;
00326 end if;
00327
00328 when s_datatype =>
00329 if (rx_valid = '0') then
00330 rx_fifo_en <= '0';
00331 nextstate := s_rdy;
00332 else
00333 data_type(7 downto 0) <= rx_fifo_data;
00334 cnt := conv_integer(lastpacketlen_i);
00335 cnt := cnt; -- -2
00336 nextstate := s_data;
00337 end if;
00338
00339 when s_data => -- read data and assemble dwords
00340
00341 if (rx_valid = '0') then
00342 rx_fifo_en <= '0';
00343 ncm_rcv_en <= '0';
00344 nextstate := s_rdy;
00345
00346 else
00347 rx_fifo_en <= '1';
00348
00349 rxbuf(7 downto 0) := rx_fifo_data;
00350 -- write to ncm fifo
00351 ncm_rcv_en <= '1';
00352 ncm_rcv_data <= rxbuf;
00353
00354 cnt := cnt - 1;
00355
00356 if (cnt = 0) then -- all got
00357 nextstate := s_rest;
00358 end if;
00359 end if;
00360
00361 when s_arpreq =>
00362
00363 if (rx_valid = '0') then
00364 rx_fifo_en <= '0';
00365 ncm_rcv_en <= '0';
00366 nextstate := s_rdy;
00367
00368 else
00369
00370 case cnt is
00371 when 1 =>
00372 if rx_fifo_data /= x"00" then
00373 nextstate := s_bad;
00374 end if;
00375 when 2 =>
00376 if rx_fifo_data /= x"01" then
00377 nextstate := s_bad;
00378 end if;
00379 when 3 =>
00380 if rx_fifo_data /= x"08" then
00381 nextstate := s_bad;
00382 end if;
00383 when 4 =>
00384 if rx_fifo_data /= x"00" then
00385 nextstate := s_bad;
00386 end if;
00387 when 5 =>
00388 if rx_fifo_data /= x"06" then
00389 nextstate := s_bad;
00390 end if;
00391 when 6 =>
00392 if rx_fifo_data /= x"04" then
00393 nextstate := s_bad;
00394 end if;
00395 when 7 =>
00396 if rx_fifo_data /= x"00" then
00397 nextstate := s_bad;
00398 end if;
00399 when 8 =>
00400 if rx_fifo_data /= x"01" then
00401 nextstate := s_bad;
00402 end if;
00403 when 9 =>
00404 sha_req(47 downto 40) <= rx_fifo_data;
00405 when 10 =>
00406 sha_req(39 downto 32) <= rx_fifo_data;
00407 when 11 =>
00408 sha_req(31 downto 24) <= rx_fifo_data;
00409 when 12 =>
00410 sha_req(23 downto 16) <= rx_fifo_data;
00411 when 13 =>
00412 sha_req(15 downto 8) <= rx_fifo_data;
00413 when 14 =>
00414 sha_req(7 downto 0) <= rx_fifo_data;
00415 when 15 =>
00416 spa_req(31 downto 24) <= rx_fifo_data;
00417 when 16 =>
00418 spa_req(23 downto 16) <= rx_fifo_data;
00419 when 17 =>
00420 spa_req(15 downto 8) <= rx_fifo_data;
00421 when 18 =>
00422 spa_req(7 downto 0) <= rx_fifo_data;
00423 when 19 =>
00424 if rx_fifo_data /= x"00" then
00425 nextstate := s_bad;
00426 end if;
00427 when 20 =>
00428 if rx_fifo_data /= x"00" then
00429 nextstate := s_bad;
00430 end if;
00431 when 21 =>
00432 if rx_fifo_data /= x"00" then
00433 nextstate := s_bad;
00434 end if;
00435 when 22 =>
00436 if rx_fifo_data /= x"00" then
00437 nextstate := s_bad;
00438 end if;
00439 when 23 =>
00440 if rx_fifo_data /= x"00" then
00441 nextstate := s_bad;
00442 end if;
00443 when 24 =>
00444 if rx_fifo_data /= x"00" then
00445 nextstate := s_bad;
00446 end if;
00447 when 25 =>
00448 if rx_fifo_data /= rxdestip(31 downto 24) then
00449 nextstate := s_bad;
00450 end if;
00451 when 26 =>
00452 if rx_fifo_data /= rxdestip(23 downto 16) then
00453 nextstate := s_bad;
00454 end if;
00455 when 27 =>
00456 if rx_fifo_data /= rxdestip(15 downto 8) then
00457 nextstate := s_bad;
00458 end if;
00459 when 28 =>
00460 if rx_fifo_data /= rxdestip(7 downto 0) then
00461 nextstate := s_bad;
00462 else
00463 ARP_vld <= '1';
00464 SHA <= sha_req;
00465 SPA <= spa_req;
00466 nextstate := s_rest;
00467 end if;
00468 when others => null;
00469 end case;
00470
00471 cnt := cnt + 1;
00472 end if;
00473
00474
00475 when s_bad => -- bad packet in queue - read out rest until valid = 0
00476
00477 rx_fifo_en <= '1';
00478 nextstate := s_rest;
00479
00480 when s_rest => -- read out rest of packet until valid = 0
00481
00482 ncm_rcv_en <= '0';
00483 ncm_rcv_data <= (others => '0');
00484
00485 if (rx_valid = '0') then
00486 nextstate := s_rdy;
00487 rx_fifo_en <= '0';
00488 else
00489 rx_fifo_en <= '1';
00490 end if;
00491
00492 when s_rdy => -- we made it
00493
00494 cnt := 0;
00495 rx_fifo_en <= '0';
00496 busy_i <= '0';
00497 nextstate := s_idle;
00498
00499 when others =>
00500
00501 nextstate := s_init; -- to be safe
00502
00503 end case;
00504
00505 end if; -- rderr
00506
00507 currentstate <= nextstate;
00508
00509 end if;
00510
00511 end process;
00512
00513 end auto_receiver_arc;
00514