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/ethernet_top.vhd,v $
00015 --* $Revision: 2.32.2.3 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 17:57:46 $ *
00019
00020
00021 --* *
00022 --**************************************************************
00023
00024 library ieee;
00025
00026 use ieee.std_logic_1164.all;
00027
00028 use ieee.std_logic_arith.all;
00029
00030 use ieee.std_logic_unsigned.all;
00031
00032 use ieee.numeric_std.all;
00033
00034
00035 library unisim;
00036
00037
00038 use unisim.vcomponents.all;
00039
00040 library work;
00041
00042 use work.main_components.all;
00043
00044 use work.udp_addresses.all;
00045
00046
00047
00048
00049 entity ethernet_top is
00050 port(
00051 RESET : in ;
00052 PKT_CNT_RST : in ;
00053 ETH_EN : in ;
00054 CYCLE : in ;
00055 INC_PKTCNT : in ;
00056 STATUS_PKT : in ;
00057 TDAQ_STATUS_PKT : in ;
00058 START : in ;
00059 SEND_PKT_SE : in ;
00060 ARP_ANN : in ;
00061 RD_READY : in ;
00062 RD_OVER : in ;
00063 DATATYPE : in ;
00064 BYTE_IN : in (7 downto 0);
00065 GET_BYTE : out ;
00066 GET_UDPCHK : out ;
00067 UDPCHK_IN_1 : in (15 downto 0);
00068 UDPCHK_IN_2 : in (15 downto 0);
00069 PKT_DONE : out ;
00070 CHK_DONE : out ;
00071 SYSCLK : in ;
00072 gmii_rx_clk : in ;
00073 gmii_rx_dv : in ;
00074 gmii_rx_er : in ;
00075 gmii_rxd : in (0 to 7);
00076 mdio : inout ;
00077 mii_tx_clk : in ;
00078 gmii_tx_en : out ;
00079 gmii_tx_er : out ;
00080 gmii_txd : out (0 to 3);
00081 MDC_0 : out ;
00082 phy_rst_n : out ;
00083 RXDATA : out (7 downto 0);
00084 RXVLD : out ;
00085 PACKET_NR : out (19 downto 0);
00086 DATA_TYPE : out (11 downto 0);
00087 LOCK : out ;
00088 -- TX_SOF,TX_EOF : out std_logic;
00089 -- ARP_REP_i : in std_logic;
00090 -- DATA_EMAC : out std_logic_vector(7 downto 0);
00091 CONTR_LED : out
00092 );
00093 end ethernet_top;
00094
00095
00096
00097
00098
00099
00100 architecture ethernet_top_arc of ethernet_top is
00101
00102 ------------------------------------- signals -------------------------------------
00103 type states is (idle, wr_dest_mac, wr_src_mac, wr_ethertype, wr_data, waitwrite, wr_iphead, wr_udphead, zeros, slow, pktnr,
00104 arp_body, rand_pkt, wr_dcs, arp_reply, tmp, wr_tdaq);
00105 type ipstates is (version_IHL, desip, srcip, protc, ttls, frag, flag_frag, iden, len1, len2, tos, ipchk);
00106 type udpstates is (srcp, desp, ulen, uchk);
00107 signal cs : states;
00108 signal ips : ipstates;
00109 signal udps : udpstates;
00110 signal txclk : := '0';
00111 signal txclk2 : := '0';
00112 signal tx_sof : := '0';
00113 signal tx_eof : := '0';
00114 signal frame_out : := '0';
00115 signal start_chk : := '0';
00116 signal res_n, lock_i, en_mac : := '0';
00117 signal empty_tx : := '0';
00118 signal start_new : := '0';
00119 signal inhibit_arp_rep : := '0';
00120 signal arp_rep_start : := '0';
00121 signal arp_rep_i : := '0';
00122 signal arp_rep : := '0';
00123 signal arp_pkt : := '0';
00124 signal rdy_pkt : := '0';
00125 signal ovr_pkt : := '0';
00126 signal dcs_pkt : := '0';
00127 signal tdaq_pkt : := '0';
00128 signal dump_pkt : := '0';
00129 signal get_chk_i : := '0';
00130 signal arp_rep_end : := '1';
00131 signal arp_pkt_end : := '1';
00132 signal rdy_pkt_end : := '1';
00133 signal ovr_pkt_end : := '1';
00134 signal dcs_pkt_end : := '1';
00135 signal tdaq_pkt_end : := '1';
00136 signal dump_pkt_end : := '1';
00137 signal inc_pktcnt_sync : := '0';
00138 signal tha_i : (47 downto 0) := (others => '0');
00139 signal tpa_i : (31 downto 0) := (others => '0');
00140 signal data_emac : (7 downto 0) := (others => '0');
00141 signal datacnt : (7 downto 0) := (others => '0');
00142 signal cnt : (cntwidth-1 downto 0) := (others => '0');
00143 signal cntpkt : (20 downto 0) := (others => '0');
00144 signal arpcnt : (3 downto 0) := (others => '0');
00145 signal datatype_i : (2 downto 0) := (others => '0');
00146 signal cal1, cal2, valin, addval1, addval2 : (31 downto 0) := (others => '0');
00147 signal valin1, base, valin_a, valin_b : (31 downto 0) := (others => '0');
00148 signal udp_chksum, udp_chksum_n : (15 downto 0);
00149
00150 attribute fsm_encoding : ;
00151 attribute fsm_encoding of cs : signal is "gray";
00152 attribute fsm_encoding of ips : signal is "gray";
00153 attribute fsm_encoding of udps : signal is "gray";
00154 attribute safe_implementation : ;
00155 attribute safe_implementation of cs : signal is "yes";
00156 attribute safe_implementation of ips : signal is "yes";
00157 attribute safe_implementation of udps : signal is "yes";
00158
00159 ------------------------------------ components -----------------------------------
00160
00161
00162 component ncm_temac
00163 port(
00164 TXVLD_N : out ;
00165 sys_clk : in ;
00166 rst_n : in ;
00167 data_in : in (7 downto 0);
00168 SOF : in ;
00169 EOF : in ;
00170 EN : in ;
00171 gmii_rx_clk : in ;
00172 gmii_rx_dv : in ;
00173 gmii_rx_er : in ;
00174 gmii_rxd : in (0 to 7);
00175 mii_tx_clk : in ;
00176 mdio : inout ;
00177 gmii_tx_en : out ;
00178 gmii_tx_er : out ;
00179 gmii_txd : out (0 to 3);
00180 MDC_0 : out ;
00181 phy_rst_n : out ;
00182 DATA_OUT : out (7 downto 0);
00183 DATAVLD : out ;
00184 PAUSE : out ;
00185 EMPTY : out ;
00186 ARP_vld : out ;
00187 SHA : out (47 downto 0);
00188 SPA : out (31 downto 0);
00189 PACKET : out (19 downto 0);
00190 DATA_TYPE : out (11 downto 0);
00191 led1 : out ;
00192 led2 : out
00193 );
00194 end component;
00195
00196 ------------------------------------ main code -----------------------------------
00197
00198 begin
00199
00200 CHK_DONE <= '0';
00201 GET_UDPCHK <= get_chk_i;
00202 LOCK <= lock_i;
00203
00204 frame_out <= start_new or START or ARP_ANN or SEND_PKT_SE or RD_READY when rising_edge(txclk);
00205 start_chk <= frame_out when rising_edge(txclk);
00206 --PKT_DONE <= frame_out;
00207
00208
00209 EMAC_CLKBUF : BUFG port map (O => txclk, I => SYSCLK);
00210
00211 --EMAC_CLKBUF2 : BUFG port map (O => txclk2, I => SYSCLK);
00212 txclk2 <= txclk;
00213
00214
00215 arp_pkt_indicator : process (txclk)
00216 begin -- process arp_pkt_indicator
00217 if txclk'event and txclk = '1' then -- rising clock edge
00218 if RESET = '1' then
00219 arp_pkt <= '0';
00220 elsif ARP_ANN = '1' then
00221 arp_pkt <= '1';
00222 elsif arp_pkt_end = '0' then
00223 arp_pkt <= '0';
00224 end if;
00225 end if;
00226 end process arp_pkt_indicator;
00227
00228
00229 arp_rep_indicator : process (txclk)
00230 begin -- process arp_pkt_indicator
00231 if txclk'event and txclk = '1' then -- rising clock edge
00232 if RESET = '1' then
00233 arp_rep <= '0';
00234 elsif (arp_rep_start = '1' and inhibit_arp_rep = '0') then
00235 arp_rep <= '1';
00236 elsif arp_rep_end = '0' then
00237 arp_rep <= '0';
00238 end if;
00239 end if;
00240 end process arp_rep_indicator;
00241
00242
00243 rdy_pkt_indicator : process (txclk)
00244 begin -- process arp_pkt_indicator
00245 if txclk'event and txclk = '1' then -- rising clock edge
00246 if RESET = '1' then
00247 rdy_pkt <= '0';
00248 elsif RD_READY = '1' then
00249 rdy_pkt <= '1';
00250 elsif rdy_pkt_end = '0' then
00251 rdy_pkt <= '0';
00252 end if;
00253 end if;
00254 end process rdy_pkt_indicator;
00255
00256
00257 ovr_pkt_indicator : process (txclk)
00258 begin -- process arp_pkt_indicator
00259 if txclk'event and txclk = '1' then -- rising clock edge
00260 if RESET = '1' then
00261 ovr_pkt <= '0';
00262 elsif RD_OVER = '1' then
00263 ovr_pkt <= '1';
00264 elsif ovr_pkt_end = '0' then
00265 ovr_pkt <= '0';
00266 end if;
00267 end if;
00268 end process ovr_pkt_indicator;
00269
00270
00271 dcs_pkt_indicator : process (txclk)
00272 begin -- process arp_pkt_indicator
00273 if txclk'event and txclk = '1' then -- rising clock edge
00274 if RESET = '1' then
00275 dcs_pkt <= '0';
00276 elsif STATUS_PKT = '1' then
00277 dcs_pkt <= '1';
00278 elsif dcs_pkt_end = '0' then
00279 dcs_pkt <= '0';
00280 end if;
00281 end if;
00282 end process dcs_pkt_indicator;
00283
00284
00285 tdaq_pkt_indicator : process (txclk)
00286 begin -- process arp_pkt_indicator
00287 if txclk'event and txclk = '1' then -- rising clock edge
00288 if RESET = '1' then
00289 tdaq_pkt <= '0';
00290 elsif TDAQ_STATUS_PKT = '1' then
00291 tdaq_pkt <= '1';
00292 elsif tdaq_pkt_end = '0' then
00293 tdaq_pkt <= '0';
00294 end if;
00295 end if;
00296 end process tdaq_pkt_indicator;
00297
00298
00299 dump_pkt_indicator : process (txclk)
00300 begin -- process dump_pkt_indicator
00301 if txclk'event and txclk = '1' then -- rising clock edge
00302 if RESET = '1' then
00303 dump_pkt <= '0';
00304 elsif start_chk = '1' then
00305 dump_pkt <= '1';
00306 elsif dump_pkt_end = '0' then
00307 dump_pkt <= '0';
00308 end if;
00309 end if;
00310 end process dump_pkt_indicator;
00311
00312
00313 arp_rep_delay : process (txclk, RESET)
00314 begin -- process arp_rep_delay
00315 if RESET = '1' then -- asynchronous reset (active high)
00316 arp_rep_start <= '0';
00317 elsif txclk'event and txclk = '1' then -- rising clock edge
00318 if arp_rep = '1' then
00319 arp_rep_start <= '0';
00320 elsif arp_rep_i = '1' then
00321 arp_rep_start <= '1';
00322 end if;
00323 end if;
00324 end process arp_rep_delay;
00325
00326
00327 rd_rdy_sync : edge
00328 port map (
00329 CLK => txclk,
00330 A => INC_PKTCNT,
00331 PULSE => inc_pktcnt_sync
00332 );
00333
00334
00335 cntpkts : process(txclk)
00336 begin
00337 if txclk'event and txclk = '1' then
00338 if PKT_CNT_RST = '1' then
00339 cntpkt <= (others => '0');
00340 else
00341 if inc_pktcnt_sync = '1' then
00342 cntpkt <= cntpkt + 1;
00343 else
00344 cntpkt <= cntpkt;
00345 end if;
00346 end if;
00347 end if;
00348 end process cntpkts;
00349
00350 inhibit_arp_rep <= dcs_pkt or rdy_pkt or ovr_pkt or dump_pkt or tdaq_pkt;
00351 datatype_i <= "111" when DATATYPE = '0' else "000"; --* 1 = ddr2, 0 = ddr,others
00352 en_mac <= ETH_EN or arp_pkt or rdy_pkt or dcs_pkt or arp_rep or tdaq_pkt or ovr_pkt;
00353 --CONTR_LED <= tx_eof;
00354
00355
00356
00357
00358
00359
00360 tx_fsm_main : process(txclk)
00361 begin
00362
00363 --data_emac_i <= reverse_any_vector(data_emac);
00364
00365 if txclk'event and txclk = '1' then
00366 if RESET = '1' then
00367 cs <= idle;
00368 ips <= version_IHL;
00369 udps <= srcp;
00370 cnt <= (others => '0');
00371 arpcnt <= (others => '0');
00372 cal1 <= (others => '0');
00373 cal2 <= (others => '0');
00374 valin <= (others => '0');
00375 valin1 <= (others => '0');
00376 base <= (others => '0');
00377 addval1 <= (others => '0');
00378 addval2 <= (others => '0');
00379 udp_chksum <= (others => '0');
00380 udp_chksum_n <= (others => '0');
00381 arp_pkt_end <= '1';
00382 arp_rep_end <= '1';
00383 rdy_pkt_end <= '1';
00384 ovr_pkt_end <= '1';
00385 dcs_pkt_end <= '1';
00386 tdaq_pkt_end <= '1';
00387 dump_pkt_end <= '1';
00388 GET_BYTE <= '0';
00389 PKT_DONE <= '0';
00390 get_chk_i <= '0';
00391 else
00392 tx_sof <= '1';
00393 tx_eof <= '1';
00394 arp_pkt_end <= '1';
00395 arp_rep_end <= '1';
00396 rdy_pkt_end <= '1';
00397 ovr_pkt_end <= '1';
00398 dcs_pkt_end <= '1';
00399 tdaq_pkt_end <= '1';
00400 dump_pkt_end <= '1';
00401 start_new <= '0';
00402 get_chk_i <= '0';
00403 PKT_DONE <= '0';
00404 GET_BYTE <= '0';
00405
00406 case cs is
00407
00408 when idle =>
00409 --* start transmission of packet
00410 if (((start_chk and ETH_EN) or arp_pkt or arp_rep or rdy_pkt or ovr_pkt or STATUS_PKT or TDAQ_STATUS_PKT) and lock_i) = '1' then
00411 cs <= wr_dest_mac;
00412 cnt <= (others => '0');
00413 cal1 <= (others => '0');
00414 cal2 <= (others => '0');
00415 valin <= (others => '0');
00416 valin1 <= (others => '0');
00417 base <= (others => '0');
00418 addval1 <= (others => '0');
00419 addval2 <= (others => '0');
00420 udp_chksum <= (others => '0');
00421 udp_chksum_n <= (others => '0');
00422 datacnt <= (others => '0');
00423 PKT_DONE <= '0';
00424 elsif SEND_PKT_SE = '1' then
00425 cs <= rand_pkt;
00426 tx_sof <= '0';
00427 else
00428 cs <= idle;
00429 end if;
00430
00431 --* write destination MAC address
00432 when wr_dest_mac =>
00433 cnt <= cnt + 1;
00434 if cnt = 0 then
00435 data_emac <= x"00";
00436 -- tx_sof <= '0';
00437 elsif cnt = 1 then
00438 data_emac <= x"00";
00439 tx_sof <= '0';
00440 elsif cnt = 2 then
00441 if (arp_pkt or arp_rep) = '1' then
00442 data_emac <= x"FF";
00443 elsif STATUS_PKT = '1' then
00444 data_emac <= dcs_MAC(47 downto 40);
00445 elsif TDAQ_STATUS_PKT = '1' then
00446 data_emac <= tdaq_MAC(47 downto 40);
00447 else
00448 data_emac <= des_MAC(47 downto 40);
00449 end if;
00450 elsif cnt = 3 then
00451 if (arp_pkt or arp_rep) = '1' then
00452 data_emac <= x"FF";
00453 elsif STATUS_PKT = '1' then
00454 data_emac <= dcs_MAC(39 downto 32);
00455 elsif TDAQ_STATUS_PKT = '1' then
00456 data_emac <= tdaq_MAC(39 downto 32);
00457 else
00458 data_emac <= des_MAC(39 downto 32);
00459 end if;
00460 elsif cnt = 4 then
00461 if (arp_pkt or arp_rep) = '1' then
00462 data_emac <= x"FF";
00463 elsif STATUS_PKT = '1' then
00464 data_emac <= dcs_MAC(31 downto 24);
00465 elsif TDAQ_STATUS_PKT = '1' then
00466 data_emac <= tdaq_MAC(31 downto 24);
00467 else
00468 data_emac <= des_MAC(31 downto 24);
00469 end if;
00470 elsif cnt = 5 then
00471 if (arp_pkt or arp_rep) = '1' then
00472 data_emac <= x"FF";
00473 elsif STATUS_PKT = '1' then
00474 data_emac <= dcs_MAC(23 downto 16);
00475 elsif TDAQ_STATUS_PKT = '1' then
00476 data_emac <= tdaq_MAC(23 downto 16);
00477 else
00478 data_emac <= des_MAC(23 downto 16);
00479 end if;
00480 elsif cnt = 6 then
00481 if (arp_pkt or arp_rep) = '1' then
00482 data_emac <= x"FF";
00483 elsif STATUS_PKT = '1' then
00484 data_emac <= dcs_MAC(15 downto 8);
00485 elsif TDAQ_STATUS_PKT = '1' then
00486 data_emac <= tdaq_MAC(15 downto 8);
00487 else
00488 data_emac <= des_MAC(15 downto 8);
00489 end if;
00490 elsif cnt = 7 then
00491 if (arp_pkt or arp_rep) = '1' then
00492 data_emac <= x"FF";
00493 elsif STATUS_PKT = '1' then
00494 data_emac <= dcs_MAC(7 downto 0);
00495 elsif TDAQ_STATUS_PKT = '1' then
00496 data_emac <= tdaq_MAC(7 downto 0);
00497 else
00498 data_emac <= des_MAC(7 downto 0);
00499 end if;
00500 cs <= wr_src_mac;
00501 cnt <= (others => '0');
00502 end if;
00503
00504 --* write source MAC address
00505 when wr_src_mac =>
00506 cnt <= cnt + 1;
00507 cs <= wr_src_mac;
00508 if cnt = 0 then
00509 data_emac <= src_MAC_1(47 downto 40);
00510 elsif cnt = 1 then
00511 data_emac <= src_MAC_1(39 downto 32);
00512 elsif cnt = 2 then
00513 data_emac <= src_MAC_1(31 downto 24);
00514 elsif cnt = 3 then
00515 data_emac <= src_MAC_1(23 downto 16);
00516 elsif cnt = 4 then
00517 data_emac <= src_MAC_1(15 downto 8);
00518 elsif cnt = 5 then
00519 data_emac <= src_MAC_1(7 downto 0);
00520 cs <= wr_ethertype;
00521 cnt <= (others => '0');
00522 end if;
00523
00524 --* write Ethertype field
00525 when wr_ethertype =>
00526 cnt <= cnt + 1;
00527 if cnt = 0 then
00528 if (arp_pkt or arp_rep) = '1' then
00529 data_emac <= arptype(15 downto 8);
00530 else
00531 data_emac <= ethertype(15 downto 8);
00532 end if;
00533 cs <= wr_ethertype;
00534 elsif cnt = 1 then
00535 if (arp_pkt or arp_rep) = '1' then
00536 data_emac <= arptype(7 downto 0);
00537 else
00538 data_emac <= ethertype(7 downto 0);
00539 end if;
00540 if arp_pkt = '1' then
00541 cs <= arp_body;
00542 ips <= version_IHL;
00543 elsif arp_rep = '1' then
00544 cs <= arp_reply;
00545 ips <= version_IHL;
00546 else
00547 cs <= wr_iphead;
00548 ips <= version_IHL;
00549 end if;
00550 cnt <= (others => '0');
00551 end if;
00552
00553 --* write IP Header
00554 when wr_iphead =>
00555 cs <= wr_iphead;
00556 case ips is
00557 when version_IHL =>
00558 data_emac <= IPV4 & IHL;
00559 ips <= tos;
00560 when tos =>
00561 data_emac <= type_of_ser;
00562 ips <= len1;
00563 when len1 =>
00564 if STATUS_PKT = '1' then
00565 data_emac <= tot_dcs_length(15 downto 8);
00566 elsif TDAQ_STATUS_PKT = '1' then
00567 data_emac <= tot_tdaq_length(15 downto 8);
00568 else
00569 data_emac <= tot_length(15 downto 8);
00570 end if;
00571 ips <= len2;
00572 when len2 =>
00573 if STATUS_PKT = '1' then
00574 data_emac <= tot_dcs_length(7 downto 0);
00575 elsif TDAQ_STATUS_PKT = '1' then
00576 data_emac <= tot_tdaq_length(7 downto 0);
00577 else
00578 data_emac <= tot_length(7 downto 0);
00579 end if;
00580 ips <= iden;
00581 when iden =>
00582 cnt <= cnt + 1;
00583 if cnt = 1 then
00584 data_emac <= id(7 downto 0);
00585 cnt <= (others => '0');
00586 ips <= flag_frag;
00587 else
00588 data_emac <= id(15 downto 8);
00589 ips <= ips;
00590 end if;
00591 when flag_frag =>
00592 data_emac <= flags & offset(12 downto 8);
00593 ips <= frag;
00594 when frag =>
00595 data_emac <= offset(7 downto 0);
00596 ips <= ttls;
00597 when ttls =>
00598 data_emac <= TTL;
00599 ips <= protc;
00600 when protc =>
00601 data_emac <= protocol;
00602 ips <= ipchk;
00603 when ipchk =>
00604 cnt <= cnt + 1;
00605 if cnt = 0 then
00606 if STATUS_PKT = '1' then
00607 data_emac <= ip_chksum_dcs(15 downto 8);
00608 elsif TDAQ_STATUS_PKT = '1' then
00609 data_emac <= ip_chksum_tdaq(15 downto 8);
00610 else
00611 data_emac <= ip_chksum(15 downto 8);
00612 end if;
00613 elsif cnt = 1 then
00614 if STATUS_PKT = '1' then
00615 data_emac <= ip_chksum_dcs(7 downto 0);
00616 elsif TDAQ_STATUS_PKT = '1' then
00617 data_emac <= ip_chksum_tdaq(7 downto 0);
00618 else
00619 data_emac <= ip_chksum(7 downto 0);
00620 end if;
00621 cnt <= (others => '0');
00622 ips <= srcip;
00623 end if;
00624 when srcip =>
00625 cnt <= cnt + 1;
00626 if cnt = 0 then
00627 data_emac <= src_IP_addr(31 downto 24);
00628 elsif cnt = 1 then
00629 data_emac <= src_IP_addr(23 downto 16);
00630 elsif cnt = 2 then
00631 data_emac <= src_IP_addr(15 downto 8);
00632 elsif cnt = 3 then
00633 data_emac <= src_IP_addr(7 downto 0);
00634 cnt <= (others => '0');
00635 ips <= desip;
00636 end if;
00637 when desip =>
00638 cnt <= cnt + 1;
00639 if cnt = 0 then
00640 if STATUS_PKT = '1' then
00641 data_emac <= dcs_IP_addr(31 downto 24);
00642 elsif TDAQ_STATUS_PKT = '1' then
00643 data_emac <= tdaq_IP_addr(31 downto 24);
00644 else
00645 data_emac <= dest_IP_addr(31 downto 24);
00646 end if;
00647 elsif cnt = 1 then
00648 if STATUS_PKT = '1' then
00649 data_emac <= dcs_IP_addr(23 downto 16);
00650 elsif TDAQ_STATUS_PKT = '1' then
00651 data_emac <= tdaq_IP_addr(23 downto 16);
00652 else
00653 data_emac <= dest_IP_addr(23 downto 16);
00654 end if;
00655 get_chk_i <= '1'; --* Get Checksum
00656 elsif cnt = 2 then
00657 if STATUS_PKT = '1' then
00658 data_emac <= dcs_IP_addr(15 downto 8);
00659 elsif TDAQ_STATUS_PKT = '1' then
00660 data_emac <= tdaq_IP_addr(15 downto 8);
00661 else
00662 data_emac <= dest_IP_addr(15 downto 8);
00663 end if;
00664 get_chk_i <= '1'; --* Get Checksum
00665 elsif cnt = 3 then
00666 if STATUS_PKT = '1' then
00667 data_emac <= dcs_IP_addr(7 downto 0);
00668 elsif TDAQ_STATUS_PKT = '1' then
00669 data_emac <= tdaq_IP_addr(7 downto 0);
00670 else
00671 data_emac <= dest_IP_addr(7 downto 0);
00672 end if;
00673 cnt <= (others => '0');
00674 valin1 <= x"0000_0000";
00675 valin <= x"0000_0000";
00676 valin_a <= x"0000" & UDPCHK_IN_1; --* add 0s to chksum
00677 valin_b <= x"0000" & UDPCHK_IN_2; --* add 0s to chksum
00678 if STATUS_PKT = '1' then
00679 addval1 <= (others => '0');
00680 addval2 <= (others => '0');
00681 base <= x"0000" & udp_chksum_base_dcs;
00682 elsif TDAQ_STATUS_PKT = '1' then
00683 addval1 <= (others => '0');
00684 addval2 <= (others => '0');
00685 base <= x"0000" & udp_chksum_base_tdaq;
00686 else
00687 addval1 <= x"0000" & datatype_i & cntpkt(20 downto 8); --* build vector out of remainder of packet
00688 addval2 <= x"0000" & cntpkt(7 downto 0) & zero_byte;
00689 base <= x"0000" & udp_chksum_base;
00690 end if;
00691 cs <= wr_udphead;
00692 udps <= srcp;
00693 end if;
00694
00695 when others =>
00696 cs <= idle;
00697 cnt <= (others => '0');
00698 end case;
00699
00700 --* write UDP Header
00701 when wr_udphead =>
00702 cs <= wr_udphead;
00703 case udps is
00704 when srcp =>
00705 cnt <= cnt + 1;
00706 if cnt = 0 then
00707 data_emac <= src_port(15 downto 8);
00708 valin <= valin_a + valin_b; --* combine chksum inputs
00709 elsif cnt = 1 then
00710 data_emac <= src_port(7 downto 0);
00711 valin1 <= valin + base; --* add constant sum of header fields
00712 cnt <= (others => '0');
00713 udps <= desp;
00714 end if;
00715 when desp =>
00716 cnt <= cnt + 1;
00717 if cnt = 0 then
00718 if STATUS_PKT = '1' then
00719 data_emac <= dcs_port(15 downto 8);
00720 elsif TDAQ_STATUS_PKT = '1' then
00721 data_emac <= tdaq_port(15 downto 8);
00722 else
00723 data_emac <= dest_port(15 downto 8);
00724 end if;
00725 cal1 <= valin1 + addval1; --* add base value from outside with rem of packet
00726 elsif cnt = 1 then
00727 if STATUS_PKT = '1' then
00728 data_emac <= dcs_port(7 downto 0);
00729 elsif TDAQ_STATUS_PKT = '1' then
00730 data_emac <= tdaq_port(7 downto 0);
00731 else
00732 data_emac <= dest_port(7 downto 0);
00733 end if;
00734 cal2 <= cal1 + addval2; --* add base value from outside with rem of packet
00735 cnt <= (others => '0');
00736 udps <= ulen;
00737 end if;
00738 when ulen =>
00739 cnt <= cnt + 1;
00740 if cnt = 0 then
00741 if STATUS_PKT = '1' then
00742 data_emac <= udp_dcs_length(15 downto 8);
00743 elsif TDAQ_STATUS_PKT = '1' then
00744 data_emac <= udp_tdaq_length(15 downto 8);
00745 else
00746 data_emac <= udp_length(15 downto 8);
00747 end if;
00748 udp_chksum <= cal2(31 downto 16) + cal2(15 downto 0); --* add upper 16 bits to lower for 1s comp addition
00749 elsif cnt = 1 then
00750 if STATUS_PKT = '1' then
00751 data_emac <= udp_dcs_length(7 downto 0);
00752 elsif TDAQ_STATUS_PKT = '1' then
00753 data_emac <= udp_tdaq_length(7 downto 0);
00754 else
00755 data_emac <= udp_length(7 downto 0);
00756 end if;
00757 if udp_chksum = x"ffff" then --* invert chksum
00758 udp_chksum_n <= udp_chksum;
00759 else
00760 udp_chksum_n <= not udp_chksum;
00761 end if;
00762 cnt <= (others => '0');
00763 GET_BYTE <= '1';
00764 udps <= uchk;
00765 end if;
00766 when uchk =>
00767 cnt <= cnt + 1;
00768 GET_BYTE <= '1';
00769 if cnt = 1 then
00770 cnt <= (others => '0');
00771 if rdy_pkt = '1' then
00772 data_emac <= rdy_chksum(7 downto 0);
00773 elsif ovr_pkt = '1' then
00774 data_emac <= ovr_chksum(7 downto 0);
00775 elsif (cntpkt = 1) and (STATUS_PKT = '0') and (TDAQ_STATUS_PKT = '0') then
00776 data_emac <= start_chksum(7 downto 0);
00777 else
00778 data_emac <= udp_chksum_n(7 downto 0);
00779 end if;
00780 if STATUS_PKT = '1' then
00781 cs <= wr_dcs;
00782 elsif TDAQ_STATUS_PKT = '1' then
00783 cs <= wr_tdaq;
00784 else
00785 cs <= wr_data;
00786 end if;
00787 udps <= srcp;
00788 cal1 <= (others => '0');
00789 cal2 <= (others => '0');
00790 valin <= (others => '0');
00791 valin1 <= (others => '0');
00792 base <= (others => '0');
00793 addval1 <= (others => '0');
00794 addval2 <= (others => '0');
00795 udp_chksum <= (others => '0');
00796 udp_chksum_n <= (others => '0');
00797 else
00798 if rdy_pkt = '1' then
00799 data_emac <= rdy_chksum(15 downto 8);
00800 elsif ovr_pkt = '1' then
00801 data_emac <= ovr_chksum(15 downto 8);
00802 elsif (cntpkt = 1) and (STATUS_PKT = '0') and (TDAQ_STATUS_PKT = '0') then
00803 data_emac <= start_chksum(15 downto 8);
00804 else
00805 data_emac <= udp_chksum_n(15 downto 8);
00806 end if;
00807 udps <= udps;
00808 end if;
00809
00810 when others =>
00811 cs <= idle;
00812 cnt <= (others => '0');
00813 end case;
00814
00815 --* write actual data
00816 when wr_data =>
00817 datacnt <= datacnt + 1;
00818 if cnt = (realdatalen-1) then
00819 if rdy_pkt = '1' then
00820 data_emac <= rd_rdy_pat;
00821 elsif ovr_pkt = '1' then
00822 data_emac <= rd_ovr_pat;
00823 elsif cntpkt = 1 then
00824 data_emac <= data(7 downto 0);
00825 else
00826 data_emac <= BYTE_IN;
00827 end if;
00828 GET_BYTE <= '0';
00829 cnt <= (others => '0');
00830 cs <= pktnr;
00831 else
00832 if rdy_pkt = '1' then
00833 data_emac <= rd_rdy_pat;
00834 elsif ovr_pkt = '1' then
00835 data_emac <= rd_ovr_pat;
00836 elsif cntpkt = 1 then
00837 data_emac <= data(7 downto 0);
00838 else
00839 data_emac <= BYTE_IN;
00840 end if;
00841 if cnt = (realdatalen-2) then
00842 GET_BYTE <= '0';
00843 else
00844 GET_BYTE <= '1';
00845 end if;
00846 cnt <= cnt + 1;
00847 cs <= wr_data;
00848 end if;
00849
00850 when wr_dcs =>
00851 if STATUS_PKT = '0' then
00852 cnt <= cnt + 1;
00853 GET_BYTE <= '0';
00854 if cnt = 1 then
00855 cnt <= (others => '0');
00856 tx_eof <= '0';
00857 PKT_DONE <= '1';
00858 cs <= waitwrite;
00859 end if;
00860 else
00861 GET_BYTE <= '1';
00862 cs <= wr_dcs;
00863 end if;
00864 data_emac <= BYTE_IN;
00865
00866 when wr_tdaq =>
00867 if TDAQ_STATUS_PKT = '0' then
00868 cnt <= cnt + 1;
00869 GET_BYTE <= '0';
00870 if cnt = 1 then
00871 cnt <= (others => '0');
00872 tx_eof <= '0';
00873 PKT_DONE <= '1';
00874 cs <= waitwrite;
00875 end if;
00876 else
00877 GET_BYTE <= '1';
00878 cs <= wr_tdaq;
00879 end if;
00880 data_emac <= BYTE_IN;
00881
00882 --* write packet ID
00883 when pktnr =>
00884 cnt <= cnt + 1;
00885 if (rdy_pkt or ovr_pkt) = '1' then
00886 data_emac <= zero_byte;
00887 else
00888 if cnt = 0 then
00889 data_emac <= datatype_i & cntpkt(20 downto 16);
00890 cs <= pktnr;
00891 elsif cnt = 1 then
00892 data_emac <= cntpkt(15 downto 8);
00893 cs <= pktnr;
00894 elsif cnt = 2 then
00895 data_emac <= cntpkt(7 downto 0);
00896 cnt <= (others => '0');
00897 end if;
00898 end if;
00899 if cnt = 2 then
00900 cs <= zeros;
00901 end if;
00902
00903 --* zero padding
00904 when zeros =>
00905 data_emac <= zero_byte;
00906 cnt <= cnt + 1;
00907 if cnt = 6 then
00908 tx_eof <= '0'; --* end of transmission!
00909 cnt <= (others => '0');
00910 cs <= waitwrite;
00911 PKT_DONE <= '1';
00912 end if;
00913
00914 --* wait til FIFO is empty
00915 when waitwrite =>
00916 if empty_tx = '1' then
00917 cs <= tmp;
00918 cnt <= (others => '0');
00919 rdy_pkt_end <= '0';
00920 ovr_pkt_end <= '0';
00921 dcs_pkt_end <= '0';
00922 tdaq_pkt_end <= '0';
00923 dump_pkt_end <= '0';
00924 end if;
00925
00926 when tmp =>
00927 cnt <= (others => '0');
00928 if CYCLE = '1' then
00929 cs <= slow;
00930 else
00931 cs <= idle;
00932 end if;
00933
00934 --* wait between packets to let PC catch up
00935 when slow =>
00936 cnt <= cnt + 1;
00937 if cnt = conv_std_logic_vector(pause, cntwidth) then
00938 start_new <= '1';
00939 cnt <= (others => '0');
00940 cs <= idle;
00941 end if;
00942
00943 when arp_body =>
00944 cnt <= cnt + 1;
00945 case conv_integer(cnt) is
00946 when 0 => data_emac <= arp_ann_c.htype(15 downto 8);
00947 when 1 => data_emac <= arp_ann_c.htype(7 downto 0);
00948 when 2 => data_emac <= arp_ann_c.ptype(15 downto 8);
00949 when 3 => data_emac <= arp_ann_c.ptype(7 downto 0);
00950 when 4 => data_emac <= arp_ann_c.hlen;
00951 when 5 => data_emac <= arp_ann_c.plen;
00952 when 6 => data_emac <= arp_ann_c.operation(15 downto 8);
00953 when 7 => data_emac <= arp_ann_c.operation(7 downto 0);
00954 when 8 => data_emac <= arp_ann_c.sha(47 downto 40);
00955 when 9 => data_emac <= arp_ann_c.sha(39 downto 32);
00956 when 10 => data_emac <= arp_ann_c.sha(31 downto 24);
00957 when 11 => data_emac <= arp_ann_c.sha(23 downto 16);
00958 when 12 => data_emac <= arp_ann_c.sha(15 downto 8);
00959 when 13 => data_emac <= arp_ann_c.sha(7 downto 0);
00960 when 14 => data_emac <= arp_ann_c.spa(31 downto 24);
00961 when 15 => data_emac <= arp_ann_c.spa(23 downto 16);
00962 when 16 => data_emac <= arp_ann_c.spa(15 downto 8);
00963 when 17 => data_emac <= arp_ann_c.spa(7 downto 0);
00964 when 18 => data_emac <= arp_ann_c.tha(47 downto 40);
00965 when 19 => data_emac <= arp_ann_c.tha(39 downto 32);
00966 when 20 => data_emac <= arp_ann_c.tha(31 downto 24);
00967 when 21 => data_emac <= arp_ann_c.tha(23 downto 16);
00968 when 22 => data_emac <= arp_ann_c.tha(15 downto 8);
00969 when 23 => data_emac <= arp_ann_c.tha(7 downto 0);
00970 when 24 => data_emac <= arp_ann_c.tpa(31 downto 24);
00971 when 25 => data_emac <= arp_ann_c.tpa(23 downto 16);
00972 when 26 => data_emac <= arp_ann_c.tpa(15 downto 8);
00973 when 27 => data_emac <= arp_ann_c.tpa(7 downto 0);
00974 when 28 => arpcnt <= arpcnt + 1;
00975 tx_eof <= '0';
00976 if arpcnt = 10 then
00977 arp_pkt_end <= '0';
00978 end if;
00979 cs <= waitwrite;
00980 when others => null;
00981 end case;
00982
00983 when arp_reply =>
00984 cnt <= cnt + 1;
00985 case conv_integer(cnt) is
00986 when 0 => data_emac <= zero_byte;
00987 when 1 => data_emac <= x"01";
00988 when 2 => data_emac <= x"08";
00989 when 3 => data_emac <= zero_byte;
00990 when 4 => data_emac <= x"06";
00991 when 5 => data_emac <= x"04";
00992 when 6 => data_emac <= zero_byte;
00993 when 7 => data_emac <= x"02";
00994 when 8 => data_emac <= src_MAC_1(47 downto 40);
00995 when 9 => data_emac <= src_MAC_1(39 downto 32);
00996 when 10 => data_emac <= src_MAC_1(31 downto 24);
00997 when 11 => data_emac <= src_MAC_1(23 downto 16);
00998 when 12 => data_emac <= src_MAC_1(15 downto 8);
00999 when 13 => data_emac <= src_MAC_1(7 downto 0);
01000 when 14 => data_emac <= src_IP_addr(31 downto 24);
01001 when 15 => data_emac <= src_IP_addr(23 downto 16);
01002 when 16 => data_emac <= src_IP_addr(15 downto 8);
01003 when 17 => data_emac <= src_IP_addr(7 downto 0);
01004 when 18 => data_emac <= tha_i(47 downto 40);
01005 when 19 => data_emac <= tha_i(39 downto 32);
01006 when 20 => data_emac <= tha_i(31 downto 24);
01007 when 21 => data_emac <= tha_i(23 downto 16);
01008 when 22 => data_emac <= tha_i(15 downto 8);
01009 when 23 => data_emac <= tha_i(7 downto 0);
01010 when 24 => data_emac <= tpa_i(31 downto 24);
01011 when 25 => data_emac <= tpa_i(23 downto 16);
01012 when 26 => data_emac <= tpa_i(15 downto 8);
01013 when 27 => data_emac <= tpa_i(7 downto 0);
01014 tx_eof <= '0';
01015 arp_rep_end <= '0';
01016 cs <= waitwrite;
01017 when others => null;
01018 end case;
01019
01020 when rand_pkt =>
01021 if SEND_PKT_SE = '1' then
01022 tx_eof <= '0';
01023 cs <= idle;
01024 else
01025 data_emac <= BYTE_IN;
01026 cs <= rand_pkt;
01027 end if;
01028
01029 when others =>
01030 cs <= idle;
01031
01032 end case;
01033 end if;
01034 end if;
01035 end process tx_fsm_main;
01036
01037 -- PACKET_NR(19) <= tx_sof;
01038 -- PACKET_NR(18) <= tx_eof;
01039 -- --PACKET_NR(17 downto 10) <= data_emac;
01040 -- PACKET_NR(17 downto 10) <= "00000001" when cs = idle else
01041 -- "00000010" when cs = waitwrite else
01042 -- "00000100" when cs = arp_reply else
01043 -- "00001000" when cs = arp_body else
01044 -- "00010000" when cs = wr_dest_mac else
01045 -- "00100000" when cs = wr_iphead else
01046 -- "01000000" when cs = wr_udphead else
01047 -- "10000000" when cs = wr_dcs else
01048 -- "00000011" when cs = wr_src_mac else
01049 -- "00000101" when cs = wr_ethertype else
01050 -- "00000110" when cs = wr_data else
01051 -- "00001001" when cs = wr_udphead else
01052 -- "00001010" when cs = tmp else
01053 -- "00001010" when ips = version_IHL else
01054 -- "00001011" when ips = tos else
01055 -- "00001100" when ips = len1 else
01056 -- "00001101" when ips = len2 else
01057 -- "00001110" when ips = iden else
01058 -- "00001111" when ips = flag_frag else
01059 -- "00010001" when ips = frag else
01060 -- "00010010" when ips = ttls else
01061 -- "00010011" when ips = protc else
01062 -- "00010100" when ips = ipchk else
01063 -- "00010101" when ips = srcip else
01064 -- "00010110" when ips = desip else
01065 -- "00010111" when udps = srcp else
01066 -- "00011000" when udps = desp else
01067 -- "00011001" when udps = ulen else
01068 -- "00011010" when udps = uchk else
01069 -- "00011100" when cs = pktnr else
01070 -- "00011101" when cs = zeros else
01071 -- "00011110" when cs = rand_pkt else
01072 -- "00000000";
01073 -- PACKET_NR(9) <= arp_rep_i;
01074 -- PACKET_NR(8) <= arp_rep;
01075 PACKET_NR(19 downto 0) <= (others => '0');
01076 CONTR_LED <= '0';
01077 -- empty_tx <= '1';
01078 -- lock_i <= '1';
01079 res_n <= not RESET;
01080
01081
01082 emac_trausi : ncm_temac
01083 port map
01084 (
01085 TXVLD_N => open,
01086 sys_clk => txclk2,
01087 rst_n => res_n,
01088 data_in => data_emac,
01089 SOF => tx_sof,
01090 EOF => tx_eof,
01091 EN => en_mac,
01092 gmii_rx_clk => GMII_RX_CLK,
01093 gmii_rx_dv => GMII_RX_DV,
01094 gmii_rx_er => GMII_RX_ER,
01095 gmii_rxd => GMII_RXD,
01096 mii_tx_clk => MII_TX_CLK,
01097 gmii_tx_en => GMII_TX_EN,
01098 gmii_tx_er => GMII_TX_ER,
01099 gmii_txd => GMII_TXD,
01100 MDC_0 => MDC_0,
01101 mdio => MDIO,
01102 phy_rst_n => PHY_RST_N,
01103 DATA_OUT => RXDATA,
01104 DATAVLD => RXVLD,
01105 PAUSE => open,
01106 EMPTY => empty_tx,
01107 ARP_VLD => arp_rep_i,
01108 SHA => tha_i,
01109 SPA => tpa_i,
01110 PACKET => open, --PACKET_NR,
01111 DATA_TYPE => DATA_TYPE,
01112 led1 => open,
01113 led2 => lock_i
01114 );
01115
01116 end ethernet_top_arc;
01117