Processes | |
arp_pkt_indicator | ( txclk ) |
buffer 100 MHz clock for FSM | |
arp_rep_indicator | ( txclk ) |
extend pulse that triggers reply ARP | |
rdy_pkt_indicator | ( txclk ) |
extend pulse that triggers read-out ready packet | |
ovr_pkt_indicator | ( txclk ) |
extend pulse that triggers read-out over packet | |
dcs_pkt_indicator | ( txclk ) |
extend pulse that triggers status packet | |
tdaq_pkt_indicator | ( txclk ) |
extend pulse that triggers status packet | |
dump_pkt_indicator | ( txclk ) |
extend pulse that dump packet | |
arp_rep_delay | ( txclk , RESET ) |
delay triggering of arp reply if we're in middle of other packet | |
cntpkts | ( txclk ) |
increment packet number | |
tx_fsm_main | ( txclk ) |
main control FSM for sending data | |
Components | |
ncm_temac | <Entity ncm_temac> |
EMAC with support logic. | |
Types | |
states | ( idle , wr_dest_mac , wr_src_mac , wr_ethertype , wr_data , waitwrite , wr_iphead , wr_udphead , zeros , slow , pktnr , arp_body , rand_pkt , wr_dcs , arp_reply , tmp , wr_tdaq ) |
ipstates | ( version_IHL , desip , srcip , protc , ttls , frag , flag_frag , iden , len1 , len2 , tos , ipchk ) |
udpstates | ( srcp , desp , ulen , uchk ) |
Signals | |
cs | states |
ips | ipstates |
udps | udpstates |
txclk | std_logic := ' 0 ' |
txclk2 | std_logic := ' 0 ' |
tx_sof | std_logic := ' 0 ' |
tx_eof | std_logic := ' 0 ' |
frame_out | std_logic := ' 0 ' |
start_chk | std_logic := ' 0 ' |
en_mac | std_logic := ' 0 ' |
lock_i | std_logic := ' 0 ' |
res_n | std_logic := ' 0 ' |
empty_tx | std_logic := ' 0 ' |
start_new | std_logic := ' 0 ' |
inhibit_arp_rep | std_logic := ' 0 ' |
arp_rep_start | std_logic := ' 0 ' |
arp_rep_i | std_logic := ' 0 ' |
arp_rep | std_logic := ' 0 ' |
arp_pkt | std_logic := ' 0 ' |
rdy_pkt | std_logic := ' 0 ' |
ovr_pkt | std_logic := ' 0 ' |
dcs_pkt | std_logic := ' 0 ' |
tdaq_pkt | std_logic := ' 0 ' |
dump_pkt | std_logic := ' 0 ' |
get_chk_i | std_logic := ' 0 ' |
arp_rep_end | std_logic := ' 1 ' |
arp_pkt_end | std_logic := ' 1 ' |
rdy_pkt_end | std_logic := ' 1 ' |
ovr_pkt_end | std_logic := ' 1 ' |
dcs_pkt_end | std_logic := ' 1 ' |
tdaq_pkt_end | std_logic := ' 1 ' |
dump_pkt_end | std_logic := ' 1 ' |
inc_pktcnt_sync | std_logic := ' 0 ' |
tha_i | std_logic_vector ( 47 downto 0 ) := ( others = > ' 0 ' ) |
tpa_i | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
data_emac | std_logic_vector ( 7 downto 0 ) := ( others = > ' 0 ' ) |
datacnt | std_logic_vector ( 7 downto 0 ) := ( others = > ' 0 ' ) |
cnt | std_logic_vector ( cntwidth -1 downto 0 ) := ( others = > ' 0 ' ) |
cntpkt | std_logic_vector ( 20 downto 0 ) := ( others = > ' 0 ' ) |
arpcnt | std_logic_vector ( 3 downto 0 ) := ( others = > ' 0 ' ) |
datatype_i | std_logic_vector ( 2 downto 0 ) := ( others = > ' 0 ' ) |
addval2 | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
addval1 | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
valin | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
cal2 | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
cal1 | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
valin_b | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
valin_a | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
base | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
valin1 | std_logic_vector ( 31 downto 0 ) := ( others = > ' 0 ' ) |
udp_chksum_n | std_logic_vector ( 15 downto 0 ) |
udp_chksum | std_logic_vector ( 15 downto 0 ) |
Attributes | |
fsm_encoding | string |
fsm_encoding | " gray " |
safe_implementation | string |
safe_implementation | " yes " |
Component Instantiations | |
EMAC_CLKBUF | BUFG |
buffer 100 MHz clock for FSM | |
rd_rdy_sync | edge <Entity edge> |
emac_trausi | ncm_temac <Entity ncm_temac> |
This architecture contains a big FSM for building the packets to be sent via Ethernet. It also fetches the data from the small buffers after the big RAMs accordingly. TX needs to be enabled for sending (ARP announcement excluded), RX is active all the time.
Definition at line 100 of file ethernet_top.vhd.
arp_pkt_indicator | ( txclk ) |
buffer 100 MHz clock for FSM
extend pulse that triggers gratuitous ARP
Definition at line 215 of file ethernet_top.vhd.
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;
arp_rep_delay | ( txclk , | |
RESET ) |
delay triggering of arp reply if we're in middle of other packet
Definition at line 313 of file ethernet_top.vhd.
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;
arp_rep_indicator | ( txclk ) |
extend pulse that triggers reply ARP
Definition at line 229 of file ethernet_top.vhd.
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;
cntpkts | ( txclk ) |
increment packet number
Definition at line 335 of file ethernet_top.vhd.
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;
dcs_pkt_indicator | ( txclk ) |
extend pulse that triggers status packet
Definition at line 271 of file ethernet_top.vhd.
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;
dump_pkt_indicator | ( txclk ) |
extend pulse that dump packet
Definition at line 299 of file ethernet_top.vhd.
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;
ovr_pkt_indicator | ( txclk ) |
extend pulse that triggers read-out over packet
Definition at line 257 of file ethernet_top.vhd.
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;
rdy_pkt_indicator | ( txclk ) |
extend pulse that triggers read-out ready packet
Definition at line 243 of file ethernet_top.vhd.
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;
tdaq_pkt_indicator | ( txclk ) |
extend pulse that triggers status packet
Definition at line 285 of file ethernet_top.vhd.
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;
tx_fsm_main | ( txclk ) |
main control FSM for sending data
This FSM takes care of building packets in the right order. It also provides the control lines to the buffers, getting the data in the right positions. Special case is the sending of gratuitous ARP packets. Contains a wait state to artificially slow down buffer dumps.
Definition at line 360 of file ethernet_top.vhd.
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;
EMAC_CLKBUF BUFG [Component Instantiation] |
emac_trausi ncm_temac [Component Instantiation] |
EMAC instance
Definition at line 1082 of file ethernet_top.vhd.
ncm_temac [Component] |
rd_rdy_sync edge [Component Instantiation] |
synchronize pktcnt pulse
Definition at line 327 of file ethernet_top.vhd.