URL
https://opencores.org/ocsvn/tcp_ip_core_w_dhcp/tcp_ip_core_w_dhcp/trunk
Subversion Repositories tcp_ip_core_w_dhcp
[/] [tcp_ip_core_w_dhcp/] [trunk/] [eth_mod.vhd] - Rev 2
Compare with Previous | Blame | View Log
---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 21:09:04 12/10/2014 -- Design Name: -- Module Name: eth_mod - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- -- TODO: Have 'G_ENABLE_DHCP' Generic and comment all statements that rely on dhcp with '#ifdef end' -- TODO: Get correct version of 'sf.conf' and add it to repository -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity eth_mod is Generic ( G_FUNCTION :string :="client" ); Port ( CLK_IN : in STD_LOGIC; CLK_1HZ_IN : in STD_LOGIC; -- Command interface INIT_ENC28J60 : in STD_LOGIC; DHCP_CONNECT : in STD_LOGIC; ERROR_OUT : out STD_LOGIC_VECTOR (7 downto 0); -- Debug Interface DEBUG_IN : in STD_LOGIC_VECTOR(2 downto 0); DEBUG_OUT : out STD_LOGIC_VECTOR (15 downto 0); -- TCP Connection Interface TCP_CONNECTION_ACTIVE_OUT : out STD_LOGIC; TCP_RD_DATA_AVAIL_OUT : out STD_LOGIC; TCP_RD_DATA_EN_IN : in STD_LOGIC; TCP_RD_DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0); TCP_WR_DATA_POSSIBLE_OUT : out STD_LOGIC; TCP_WR_DATA_EN_IN : in STD_LOGIC; TCP_WR_DATA_FLUSH_IN : in STD_LOGIC; TCP_WR_DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); -- Eth SPI interface SDI_OUT : out STD_LOGIC; SDO_IN : in STD_LOGIC; SCLK_OUT : out STD_LOGIC; CS_OUT : out STD_LOGIC ); end eth_mod; architecture Behavioral of eth_mod is COMPONENT spi_mod Port ( CLK_IN : in STD_LOGIC; RST_IN : in STD_LOGIC; WR_CONTINUOUS_IN : in STD_LOGIC; WE_IN : in STD_LOGIC; WR_ADDR_IN : in STD_LOGIC_VECTOR (7 downto 0); WR_DATA_IN : in STD_LOGIC_VECTOR (7 downto 0); WR_DATA_CMPLT_OUT : out STD_LOGIC; RD_CONTINUOUS_IN : in STD_LOGIC; RD_IN : in STD_LOGIC; RD_WIDTH_IN : in STD_LOGIC; RD_ADDR_IN : in STD_LOGIC_VECTOR (7 downto 0); RD_DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0); RD_DATA_CMPLT_OUT : out STD_LOGIC; SLOW_CS_EN_IN : in STD_LOGIC; OPER_CMPLT_POST_CS_OUT : out STD_LOGIC; SDI_OUT : out STD_LOGIC; SDO_IN : in STD_LOGIC; SCLK_OUT : out STD_LOGIC; CS_OUT : out STD_LOGIC); END COMPONENT; COMPONENT checksum_calc Port ( CLK_IN : in STD_LOGIC; RST_IN : in STD_LOGIC; CHECKSUM_CALC_IN : in STD_LOGIC; START_ADDR_IN : in STD_LOGIC_VECTOR (10 downto 0); COUNT_IN : in STD_LOGIC_VECTOR (10 downto 0); VALUE_IN : in STD_LOGIC_VECTOR (7 downto 0); VALUE_ADDR_OUT : out STD_LOGIC_VECTOR (10 downto 0); CHECKSUM_INIT_IN : in STD_LOGIC_VECTOR (15 downto 0); CHECKSUM_SET_INIT_IN : in STD_LOGIC; CHECKSUM_ODD_LENGTH_IN : in STD_LOGIC; CHECKSUM_OUT : out STD_LOGIC_VECTOR (15 downto 0); CHECKSUM_DONE_OUT : out STD_LOGIC); END COMPONENT; COMPONENT TCP_FIFO PORT ( clk : IN STD_LOGIC; din : IN STD_LOGIC_VECTOR(7 DOWNTO 0); wr_en : IN STD_LOGIC; rd_en : IN STD_LOGIC; dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); full : OUT STD_LOGIC; almost_full : OUT STD_LOGIC; empty : OUT STD_LOGIC; data_count : OUT STD_LOGIC_VECTOR(11 DOWNTO 0)); END COMPONENT; COMPONENT lfsr32_mod Port ( CLK_IN : in STD_LOGIC; SEED_IN : in STD_LOGIC_VECTOR(31 downto 0); SEED_EN_IN : in STD_LOGIC; VAL_OUT : out STD_LOGIC_VECTOR(31 downto 0)); END COMPONENT; COMPONENT TDP_RAM Generic (G_DATA_A_SIZE :natural :=32; G_ADDR_A_SIZE :natural :=9; G_RELATION :natural :=3; G_INIT_ZERO :boolean := true; G_INIT_FILE :string :="");--log2(SIZE_A/SIZE_B) Port ( CLK_A_IN : in STD_LOGIC; WE_A_IN : in STD_LOGIC; ADDR_A_IN : in STD_LOGIC_VECTOR (G_ADDR_A_SIZE-1 downto 0); DATA_A_IN : in STD_LOGIC_VECTOR (G_DATA_A_SIZE-1 downto 0); DATA_A_OUT : out STD_LOGIC_VECTOR (G_DATA_A_SIZE-1 downto 0); CLK_B_IN : in STD_LOGIC; WE_B_IN : in STD_LOGIC; ADDR_B_IN : in STD_LOGIC_VECTOR (G_ADDR_A_SIZE+G_RELATION-1 downto 0); DATA_B_IN : in STD_LOGIC_VECTOR (G_DATA_A_SIZE/(2**G_RELATION)-1 downto 0); DATA_B_OUT : out STD_LOGIC_VECTOR (G_DATA_A_SIZE/(2**G_RELATION)-1 downto 0)); END COMPONENT; COMPONENT Packet_Definition PORT ( clka : IN STD_LOGIC; addra : IN STD_LOGIC_VECTOR(10 DOWNTO 0); douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)); END COMPONENT; subtype slv is std_logic_vector; constant C_250us : unsigned(15 downto 0) := X"61A8"; constant C_200ms : unsigned(24 downto 0) := '1'&X"312D00"; constant C_100ms : unsigned(23 downto 0) := X"989680"; constant C_20ms : unsigned(20 downto 0) := '1'&X"E8480"; constant C_init_cmnds_start_addr : std_logic_vector(7 downto 0) := X"01"; constant C_init_cmnds_max_addr : std_logic_vector(7 downto 0) := X"7F"; constant C_arp_reply_frame_addr : std_logic_vector(10 downto 0) := "000"&X"80"; constant C_icmp_reply_frame_addr : std_logic_vector(10 downto 0) := "000"&X"AB"; constant C_dhcp_discover_frame_addr : std_logic_vector(10 downto 0) := "001"&X"24"; constant C_dhcp_request_frame_addr : std_logic_vector(10 downto 0) := "010"&X"86"; constant C_arp_request_frame_addr : std_logic_vector(10 downto 0) := "100"&X"67"; constant C_tcp_packet_frame_addr : std_logic_vector(10 downto 0) := "100"&X"92"; constant C_tcp_tx_packet_frame_addr : std_logic_vector(10 downto 0) := "100"&X"F4"; constant C_arp_reply_length : std_logic_vector(15 downto 0) := X"002A"; constant C_icmp_reply_length : std_logic_vector(15 downto 0) := X"0062"; constant C_dhcp_discover_length : std_logic_vector(15 downto 0) := X"0156"; constant C_dhcp_request_length : std_logic_vector(15 downto 0) := X"015C"; constant C_arp_request_length : std_logic_vector(15 downto 0) := X"002A"; constant C_tcp_packet_length : std_logic_vector(15 downto 0) := X"0042"; constant C_ARP_Packet_Type : std_logic_vector(15 downto 0) := X"0806"; constant C_IP_Packet_Type : std_logic_vector(15 downto 0) := X"0800"; constant C_ICMP_Protocol_Number : std_logic_vector(7 downto 0) := X"01"; constant C_UDP_Protocol_Number : std_logic_vector(7 downto 0) := X"11"; constant C_TCP_Protocol_Number : std_logic_vector(7 downto 0) := X"06"; constant C_IPV4_Protocol_Number : std_logic_vector(3 downto 0) := X"4"; constant C_DHCP_Source_Port : std_logic_vector(15 downto 0) := X"0043"; constant C_DHCP_Dest_Port : std_logic_vector(15 downto 0) := X"0044"; constant C_dhcp_magic_cookie : std_logic_vector(31 downto 0) := X"63825363"; constant C_tcp_syn_ack_flags : std_logic_vector(7 downto 0) := X"12"; constant C_tcp_syn_flags : std_logic_vector(7 downto 0) := X"02"; constant C_tcp_ack_flags : std_logic_vector(7 downto 0) := X"10"; constant C_tcp_fin_ack_flags : std_logic_vector(7 downto 0) := X"11"; constant C_tcp_psh_ack_flags : std_logic_vector(7 downto 0) := X"18"; constant C_ICMP_Ping_Length : std_logic_vector(15 downto 0) := X"0054"; constant C_ARP_Request : std_logic_vector(7 downto 0) := X"01"; constant C_ARP_Reply : std_logic_vector(7 downto 0) := X"02"; constant C_rx_pointer_min : unsigned(15 downto 0) := X"0000"; constant C_rx_pointer_max : unsigned(15 downto 0) := X"0FFF"; constant C_tx_base_addr1 : unsigned(15 downto 0) := X"1000"; constant C_tx_base_addr2 : unsigned(15 downto 0) := X"1800"; signal spi_we, spi_wr_continuous, spi_wr_cmplt, spi_rd_continuous : std_logic := '0'; signal spi_rd, spi_rd_width, spi_rd_cmplt, spi_oper_cmplt : std_logic := '0'; signal spi_wr_addr, spi_wr_data, spi_rd_addr, spi_data_rd : std_logic_vector(7 downto 0) := (others => '0'); signal frame_addr : std_logic_vector(10 downto 0); signal frame_data : std_logic_vector(15 downto 0); signal frame_data_rd, frame_rd_cmplt, slow_cs_en : std_logic := '0'; signal network_interface_enabled : std_logic := '0'; signal command_cmplt, command_trig, command_en_in_p : std_logic := '0'; signal init_cmnd_addr : unsigned(7 downto 0); signal interrupt_counter : unsigned(15 downto 0) := (others => '0'); signal next_packet_pointer : std_logic_vector(15 downto 0) := (others => '0'); signal previous_packet_pointer : unsigned(15 downto 0) := (others => '0'); signal eir_register : std_logic_vector(7 downto 0) := (others => '0'); signal rx_packet_ram_we, handle_rx_packet, rx_packet_handled : std_logic := '0'; signal debug_rx_flag, debug_rx_flag1, debug_rx_flag2 : std_logic := '0'; signal rx_packet_ram_we_addr, rx_packet_ram_we_addr_buf : unsigned(10 downto 0) := (others => '0'); signal rx_packet_ram_rd_addr : unsigned(10 downto 0) := (others => '0'); signal rx_packet_rd2_addr : unsigned(10 downto 0) := (others => '0'); signal rx_packet_rd_data, rx_packet_rd_data2 : std_logic_vector(7 downto 0); signal rx_packet_status_vector, arp_target_ip_addr, arp_source_ip_addr : std_logic_vector(31 downto 0); signal rx_packet_type : std_logic_vector(15 downto 0); signal rx_packet_source_mac : std_logic_vector(47 downto 0); signal send_arp_reply, send_arp_request : std_logic := '0'; signal send_icmp_reply, send_dhcp_discover, send_dhcp_request : std_logic := '0'; signal arp_opcode : std_logic_vector(7 downto 0); signal tx_packet_ram_we, tx_packet_config_cmplt : std_logic := '0'; signal tx_packet_ram_we_addr, tx_packet_ram_rd_addr : unsigned(10 downto 0) := (others => '0'); signal tx_packet_ram_we_addr_buf : unsigned(10 downto 0) := (others => '0'); signal tx_packet_rd_data, tx_packet_ram_data : std_logic_vector(7 downto 0); signal tx_packet_rd_data2 : std_logic_vector(7 downto 0); signal handle_tx_packet : std_logic := '0'; signal ip_addr : std_logic_vector(31 downto 0) := X"C0A80166"; -- 192.168.1.102 signal mac_addr : std_logic_vector(47 downto 0) := X"8066F23D547A"; signal ip_identification : std_logic_vector(15 downto 0); signal ping_enable : std_logic := '1'; signal dhcp_enable : std_logic := '0'; signal dhcp_addr_locked, static_addr_locked : std_logic := '0'; signal client_ip_addr : std_logic_vector(31 downto 0) := X"C0A80100"; -- 192.168.1.0 should be set dynamically upon TCP connection ?? signal client_mac_addr : std_logic_vector(47 downto 0) := X"000000000000"; --signal cloud_ip_addr : std_logic_vector(31 downto 0) := X"76D2707C"; -- 118.210.112.124 signal cloud_ip_addr : std_logic_vector(31 downto 0) := X"C0A80100"; -- 192.168.1.0 signal tx_packet_frame_addr :unsigned(10 downto 0); signal tx_packet_length, tx_packet_length_counter, tx_packet_end_pointer :unsigned(15 downto 0); signal prev_tx_packet_end_pointer :unsigned(15 downto 0); signal doing_tx_packet_config, tx_packet_frame_data_rd : std_logic := '0'; signal packet_instruction, packet_data : std_logic_vector(7 downto 0); signal tx_packet_ready_for_transmission : std_logic := '0'; signal send_prev_packet_waiting, trigger_send_prev_packet : std_logic := '0'; signal trigger_close_connection, wait_for_tcp_window_size_update : std_logic := '0'; signal tx_base_addr, tx_base_addr_prev : unsigned(15 downto 0); signal tx_base_addr_select : std_logic := '0'; signal ip_packet_version : std_logic_vector(3 downto 0); signal ip_packet_protocol : std_logic_vector(7 downto 0); signal ip_packet_header_length : std_logic_vector(7 downto 0); signal ip_packet_destination_ip : std_logic_vector(31 downto 0); signal ip_packet_length, ip_packet_length_debug : std_logic_vector(15 downto 0); -- TODO remove debug signal total_packet_length : unsigned(15 downto 0); signal lfsr_val : std_logic_vector(31 downto 0); signal calc_checksum, checksum_calc_done : std_logic := '0'; signal checksum_start_addr, checksum_addr, checksum_wr_addr : std_logic_vector(10 downto 0); signal checksum_count : unsigned(10 downto 0); signal checksum : std_logic_vector(15 downto 0); signal checksum_initial_value : std_logic_vector(15 downto 0); signal checksum_set_initial_value, checksum_odd_length : std_logic; signal command : std_logic_vector(3 downto 0); signal poll_interrupt_reg, command_waiting : std_logic; signal poll_counter : unsigned(3 downto 0) := (others => '1'); signal dhcp_transaction_id : std_logic_vector(31 downto 0) := X"CA805562"; signal transaction_id_rd : std_logic_vector(31 downto 0) := X"00000000"; signal udp_source_port, udp_dest_port : std_logic_vector(15 downto 0); signal dhcp_your_ip_addr, dhcp_server_ip_addr, dhcp_magic_cookie : std_logic_vector(31 downto 0); signal expecting_dhcp_offer, expecting_dhcp_ack, expecting_arp_reply : std_logic := '0'; signal expecting_syn_ack, ack_required, trigger_ack : std_logic := '0'; signal dhcp_option_addr : unsigned(10 downto 0); signal dhcp_option, dhcp_option_length, dhcp_message_type : std_logic_vector(7 downto 0); signal packet_definition_addr : std_logic_vector(10 downto 0); signal packet_definition_data : std_logic_vector(15 downto 0); signal client_port : std_logic_vector(15 downto 0) := (others => '0'); signal listen_port : std_logic_vector(15 downto 0) := X"0DA2"; signal tcp_sequence_number, tcp_acknowledge_number : unsigned(31 downto 0) := (others => '0'); signal tcp_sequence_number_previous_ack, tcp_ack_number_previous_ack : unsigned(31 downto 0) := (others => '0'); signal tcp_ack_number_previous_ack1, tcp_ack_number_previous_ack2, tcp_ack_number_previous_ack3 : unsigned(31 downto 0) := (others => '0'); signal tcp_ack_number_previous_ack4, tcp_ack_number_previous_ack5, tcp_ack_number_previous_ack6 : unsigned(31 downto 0) := (others => '0'); signal tcp_sequence_number_p1 : unsigned(31 downto 0) := (others => '0'); signal tcp_flags : std_logic_vector(7 downto 0) := (others => '0'); signal window_size : unsigned(11 downto 0) := X"E00"; signal requested_data_size : unsigned(11 downto 0); signal send_tcp_ack_packet, cancel_dhcp_connect : std_logic := '0'; signal send_tcp_tx_packet : std_logic := '0'; signal tcp_connection_active, close_tcp_connection, cancel_tcp_connection : std_logic := '0'; signal tcp_ip_identification : unsigned(15 downto 0); signal rx_tcp_source_port, rx_tcp_dest_port : std_logic_vector(15 downto 0) := (others => '0'); signal rx_tcp_seq_number, rx_tcp_ack_number : std_logic_vector(31 downto 0) := (others => '0'); signal rx_tcp_window_size_shifted : std_logic_vector(31 downto 0) := (others => '0'); signal rx_tcp_window_size, rx_tcp_checksum : std_logic_vector(15 downto 0) := (others => '0'); signal rx_tcp_flags, rx_tcp_option, rx_tcp_header_length : std_logic_vector(7 downto 0) := (others => '0'); signal rx_tcp_option_length : unsigned(7 downto 0); signal rx_tcp_window_shift : std_logic_vector(3 downto 0); signal tcp_option_addr, next_protocol_start_addr : unsigned(10 downto 0); signal rx_data_length, prev_rx_data_length : unsigned(15 downto 0); signal rx_data_start_addr : unsigned(10 downto 0); signal resend_ack_packet, fin_received, syn_ack_packet : std_logic := '0'; signal sent_syn_ack : std_logic := '0'; signal fin_received_p, trigger_fin_ack : std_logic := '0'; signal tcp_rx_data_we, tcp_rd_data_available, tcp_data_rd_en : std_logic := '0'; signal tcp_rx_ram_almost_full : std_logic := '0'; signal tcp_rd_data_count, tcp_wr_data_count : std_logic_vector(11 downto 0) := (others => '0'); signal tcp_rx_data : unsigned(7 downto 0) := (others => '0'); signal tcp_rx_data_rd_data : std_logic_vector(7 downto 0) := (others => '0'); signal tcp_wr_data_possible, tcp_wr_data_en, tcp_tx_data_rd : std_logic := '0'; signal tcp_wr_data_flush, tcp_data_flush_waiting : std_logic := '0'; signal large_tx_packet_waiting : std_logic := '0'; signal tcp_wr_data, tcp_tx_data : std_logic_vector(7 downto 0) := (others => '0'); signal tx_bytes_to_send, tx_total_packet_length, tx_packet_data_counter : unsigned(11 downto 0) := (others => '0'); signal tx_total_packet_length_inc_mac, tx_total_packet_length_checksum : unsigned(11 downto 0) := (others => '0'); signal tx_packet_no_ack_timeout : unsigned(23 downto 0) := C_100ms; signal tx_packet_timeout_counter, tx_packet_timeout_counter_prev : unsigned(7 downto 0) := X"00"; signal tx_timeout_counter : unsigned(20 downto 0); signal tx_packets_no_ack : unsigned(3 downto 0) := X"0"; signal clk_1hz, clk_1hz_prev : std_logic := '0'; signal init_enc28j60_waiting, dhcp_connect_waiting, tcp_connect_waiting : std_logic := '0'; signal rx_kbytes_sec, tx_kbytes_sec : unsigned(11 downto 0); signal rx_bytes_counter, tx_bytes_counter : unsigned(21 downto 0); signal ack_countdown : unsigned(15 downto 0); signal num_packets : std_logic_vector(7 downto 0) := (others => '0'); type ETH_ST is ( IDLE, TRIGGER_DHCP_DISCOVER, TRIGGER_ARP_REQUEST, TRIGGER_CANCEL_DHCP_CONNECT, TRIGGER_CLOSE_TCP_CONNECTION, TRIGGER_CANCEL_TCP_CONNECTION, HANDLE_INIT_CMND0, HANDLE_INIT_CMND1, HANDLE_INIT_CMND2, HANDLE_INIT_CMND3, HANDLE_INIT_CMND4, HANDLE_INIT_CMND5, HANDLE_INIT_CMND6, SERVICE_INTERRUPT0, SERVICE_INTERRUPT1, SERVICE_INTERRUPT2, SERVICE_INTERRUPT3, SERVICE_INTERRUPT4, SERVICE_INTERRUPT5, SERVICE_INTERRUPT6, SERVICE_INTERRUPT7, SERVICE_INTERRUPT8, HANDLE_TX_INTERRUPT0, HANDLE_TX_INTERRUPT1, HANDLE_TX_INTERRUPT2, HANDLE_RX_INTERRUPT0, HANDLE_RX_INTERRUPT1, HANDLE_RX_INTERRUPT2, HANDLE_RX_INTERRUPT3, HANDLE_RX_INTERRUPT4, HANDLE_RX_INTERRUPT5, HANDLE_RX_INTERRUPT6, HANDLE_RX_INTERRUPT7, HANDLE_RX_INTERRUPT8, HANDLE_RX_INTERRUPT9, HANDLE_RX_INTERRUPT10, HANDLE_RX_INTERRUPT11, HANDLE_RX_INTERRUPT12, HANDLE_RX_INTERRUPT13, HANDLE_RX_INTERRUPT14, HANDLE_RX_INTERRUPT15, HANDLE_RX_INTERRUPT16, HANDLE_RX_INTERRUPT17, CHECK_IF_ACK_WAITING, TRIGGER_ACK_PACKET, TRIGGER_TCP_TX0, TRIGGER_TCP_TX1, TRIGGER_TCP_TX2, COPY_RX_PACKET_TO_BUF0, COPY_RX_PACKET_TO_BUF1, COPY_RX_PACKET_TO_BUF2, COPY_RX_PACKET_TO_BUF3, COPY_RX_PACKET_TO_BUF4, COPY_RX_PACKET_TO_BUF5, COPY_RX_PACKET_TO_BUF6, PRE_TX_TRANSMIT0, PRE_TX_TRANSMIT1, PRE_TX_TRANSMIT2, PRE_TX_TRANSMIT3, PRE_TX_TRANSMIT4, PRE_TX_TRANSMIT5, HANDLE_TX_TRANSMIT0, HANDLE_TX_TRANSMIT1, HANDLE_TX_TRANSMIT2, HANDLE_TX_TRANSMIT3, HANDLE_TX_TRANSMIT4, HANDLE_TX_TRANSMIT5, HANDLE_TX_TRANSMIT6, HANDLE_TX_TRANSMIT7, HANDLE_TX_TRANSMIT8, HANDLE_TX_TRANSMIT9, HANDLE_TX_TRANSMIT10, HANDLE_TX_TRANSMIT_PRE11, HANDLE_TX_TRANSMIT11, HANDLE_TX_TRANSMIT12, HANDLE_TX_TRANSMIT13, HANDLE_TX_TRANSMIT14, HANDLE_TX_TRANSMIT15, HANDLE_TX_TRANSMIT16, HANDLE_TX_TRANSMIT17, HANDLE_TX_TRANSMIT18, HANDLE_TX_TRANSMIT19, HANDLE_TX_TRANSMIT20, HANDLE_TX_TRANSMIT21, HANDLE_TX_TRANSMIT22, HANDLE_TX_TRANSMIT_PREV0, HANDLE_TX_TRANSMIT_PREV1, HANDLE_TX_TRANSMIT_PREV2, HANDLE_TX_TRANSMIT_PREV3, HANDLE_TX_TRANSMIT_PREV4, HANDLE_TX_TRANSMIT_PREV5, HANDLE_TX_TRANSMIT_PREV6, HANDLE_TX_TRANSMIT_PREV7, HANDLE_TX_TRANSMIT_PREV8, HANDLE_TX_TRANSMIT_PREV9, HANDLE_TX_TRANSMIT_PREV10, HANDLE_TX_TRANSMIT_PREV11, HANDLE_TX_TRANSMIT_PREV12, HANDLE_TX_TRANSMIT_PREV13, HANDLE_TX_TRANSMIT_PREV14, HANDLE_TX_TRANSMIT_PREV15, HANDLE_TX_TRANSMIT_PREV16, WAIT_FOR_TRANSMIT_CMPLT, RESEND_ACK_IN_BUFFER); signal eth_state, eth_next_state : ETH_ST := IDLE; signal state_debug_sig : unsigned(7 downto 0); type PACKET_HANDLER_ST is ( IDLE, PARSE_SOURCE_MAC0, PARSE_SOURCE_MAC1, PARSE_SOURCE_MAC2, PARSE_SOURCE_MAC3, PARSE_SOURCE_MAC4, PARSE_SOURCE_MAC5, PARSE_SOURCE_MAC6, PARSE_SOURCE_MAC7, PARSE_PACKET_TYPE0, PARSE_PACKET_TYPE1, PARSE_PACKET_TYPE2, PARSE_PACKET_TYPE3, PARSE_PACKET_TYPE4, HANDLE_ARP_PACKET0, HANDLE_ARP_PACKET1, HANDLE_ARP_PACKET2, HANDLE_ARP_PACKET3, HANDLE_ARP_REQUEST0, HANDLE_ARP_REQUEST1, HANDLE_ARP_REQUEST2, HANDLE_ARP_REQUEST3, HANDLE_ARP_REQUEST4, HANDLE_ARP_REQUEST5, HANDLE_ARP_REQUEST6, HANDLE_ARP_REQUEST7, HANDLE_ARP_REQUEST8, HANDLE_ARP_REQUEST9, HANDLE_ARP_REQUEST10, HANDLE_ARP_REQUEST11, HANDLE_ARP_REQUEST12, HANDLE_ARP_REQUEST13, HANDLE_ARP_REPLY0, HANDLE_ARP_REPLY1, HANDLE_ARP_REPLY2, HANDLE_ARP_REPLY3, HANDLE_ARP_REPLY4, HANDLE_ARP_REPLY5, HANDLE_ARP_REPLY6, HANDLE_ARP_REPLY7, TRIGGER_ARP_REPLY, HANDLE_IP_PACKET0, HANDLE_IP_PACKET1, HANDLE_IP_PACKET2, HANDLE_IP_PACKET3, HANDLE_IP_PACKET4, HANDLE_IP_PACKET5, HANDLE_IP_PACKET6, HANDLE_IP_PACKET7, HANDLE_IP_PACKET8, HANDLE_IP_PACKET9, HANDLE_IP_PACKET10, HANDLE_IP_PACKET11, HANDLE_IP_PACKET12, PRE_ICMP_PACKET_REPLY, TRIGGER_ICMP_PACKET_REPLY, PARSE_UDP_PACKET0, PARSE_UDP_PACKET1, PARSE_UDP_PACKET2, PARSE_UDP_PACKET3, PARSE_UDP_PACKET4, PARSE_UDP_PACKET5, PARSE_UDP_PACKET_TYPE0, PARSE_UDP_PACKET_TYPE1, PARSE_DHCP_PACKET0, PARSE_DHCP_PACKET1, PARSE_DHCP_PACKET2, PARSE_DHCP_PACKET3, PARSE_DHCP_PACKET4, PARSE_DHCP_PACKET5, PARSE_DHCP_PACKET6, PARSE_DHCP_PACKET7, PARSE_DHCP_PACKET8, PARSE_DHCP_PACKET9, PARSE_DHCP_PACKET10, PARSE_DHCP_PACKET11, PARSE_DHCP_PACKET12, PARSE_DHCP_PACKET13, PARSE_DHCP_PACKET14, PARSE_DHCP_PACKET15, PARSE_DHCP_PACKET16, PARSE_DHCP_PACKET17, PARSE_DHCP_PACKET18, PARSE_DHCP_PACKET19, PARSE_DHCP_PACKET20, PARSE_DHCP_PACKET21, PARSE_DHCP_PACKET22, PARSE_DHCP_PACKET23, PARSE_DHCP_PACKET24, CHECK_OFFER_EXPECTED, TRIGGER_DHCP_REQUEST, HANDLE_DHCP_ACK0, HANDLE_DHCP_ACK1, HANDLE_DHCP_ACK2, HANDLE_DHCP_ACK3, HANDLE_DHCP_ACK4, HANDLE_DHCP_ACK5, HANDLE_DHCP_ACK6, HANDLE_DHCP_ACK7, HANDLE_DHCP_ACK8, PARSE_TCP_PACKET0, PARSE_TCP_PACKET1, PARSE_TCP_PACKET2, PARSE_TCP_PACKET3, PARSE_TCP_PACKET4, PARSE_TCP_PACKET5, PARSE_TCP_PACKET6, PARSE_TCP_PACKET7, PARSE_TCP_PACKET8, PARSE_TCP_PACKET9, PARSE_TCP_PACKET10, PARSE_TCP_PACKET11, PARSE_TCP_PACKET12, PARSE_TCP_PACKET13, PARSE_TCP_PACKET14, PARSE_TCP_PACKET15, PARSE_TCP_PACKET16, PARSE_TCP_PACKET17, PARSE_TCP_PACKET18, PARSE_TCP_PACKET19, PARSE_TCP_PACKET20, PARSE_TCP_PACKET21, PARSE_TCP_PACKET22, PARSE_TCP_PACKET23, PARSE_TCP_PACKET24, PARSE_TCP_PACKET25, PARSE_TCP_PACKET26, PARSE_TCP_PACKET27, CHECK_TCP_SYN_PACKET0, CHECK_TCP_SYN_PACKET1, CHECK_TCP_SYN_PACKET2, CHECK_TCP_SYN_PACKET3, CHECK_TCP_SYN_PACKET4, CHECK_TCP_SYN_PACKET5, CHECK_TCP_PSH_ACK_PACKET0, CHECK_TCP_PSH_ACK_PACKET1, CHECK_TCP_PSH_ACK_PACKET2, CHECK_TCP_PSH_ACK_PACKET3, READ_TCP_RX_DATA, TRIGGER_TCP_ACK0, TRIGGER_TCP_ACK1, TRIGGER_TCP_ACK2, TRIGGER_TCP_ACK3, RESEND_ACK, CHECK_IF_DATA_TO_SEND, TRIGGER_TCP_PSH_ACK0, TRIGGER_TCP_PSH_ACK1, CHECK_TCP_WINDOW_SIZE, RX_TCP_WINDOW_TOO_SMALL, TRIGGER_TCP_PSH_ACK2, TRIGGER_TCP_PSH_ACK3, COMPLETE ); signal packet_handler_state, packet_handler_next_state : PACKET_HANDLER_ST := IDLE; type TX_PACKET_CONFIG_ST is ( IDLE, INIT_ARP_REPLY_METADATA, INIT_ARP_REQUEST_METADATA, INIT_ICMP_REPLY_METADATA, INIT_DHCP_DISCOVER_METADATA, INIT_DHCP_REQUEST_METADATA, INIT_TCP_PACKET_METADATA, INIT_TCP_TX_PACKET_METADATA, CANCEL_DHCP_CONNECT_ST, TCP_CONNECTION_CLOSED, CANCEL_TCP_CONNECTION_ST, READ_PACKET_BYTE0, READ_PACKET_BYTE1, HANDLE_PACKET_INSTRUCTION0, HANDLE_PACKET_INSTRUCTION1, SET_RX_PACKET_ADDR_LOWER_BYTE, SET_RX_PACKET_ADDR_UPPER_BYTE, SET_CHECKSUM_LENGTH_LSB, SET_CHECKSUM_LENGTH_MSB, SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH0, SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH1, SET_CHECKSUM_START_ADDR_LSB, SET_CHECKSUM_START_ADDR_MSB, SET_CHECKSUM_WR_ADDR_LSB, SET_CHECKSUM_WR_ADDR_MSB, MOVE_TX_PACKET_WR_ADDR, SET_NEW_TRANSACTION_ID, SET_CHECKSUM_START_VAL_LSB, SET_CHECKSUM_START_VAL_MSB, SET_CHECKSUM_INITIAL_VALUE_TX_PACKET, TRIGGER_CHECKSUM_LOAD_INITIAL_VALUE, TRIG_CHECKSUM_CALC, WAIT_FOR_CHECKSUM_CMPLT, INIT_LOAD_TX_PACKET_DATA, LOAD_TX_PACKET_DATA, COMPLETE ); signal tx_packet_state, tx_packet_next_state : TX_PACKET_CONFIG_ST := IDLE; begin --DEBUG_OUT(15 downto 8) <= X"00"; --DEBUG_OUT(15 downto 4) <= X"000"; --DEBUG_OUT(15 downto 12) <= (others => '0'); --DEBUG_OUT(15 downto 12) <= slv(interrupt_counter(3 downto 0)); --DEBUG_OUT <= slv(rx_data_length); --DEBUG_OUT <= udp_source_port when DEBUG_IN = '0' else udp_dest_port; --DEBUG_OUT <= rx_tcp_source_port when DEBUG_IN = '0' else rx_tcp_dest_port; --DEBUG_OUT <= rx_tcp_window_size when DEBUG_IN(0) = '0' else X"000"&rx_tcp_window_shift; --DEBUG_OUT <= rx_tcp_window_size_shifted(31 downto 16) when DEBUG_IN(0) = '0' else rx_tcp_window_size_shifted(15 downto 0); --DEBUG_OUT(11 downto 0) <= slv(window_size); --DEBUG_OUT(7 downto 0) <= slv(rx_tcp_option_length); --DEBUG_OUT <= "00000"&slv(tcp_option_addr); --DEBUG_OUT(7 downto 4) <= X"0"; --DEBUG_OUT(15 downto 8) <= ip_packet_protocol; --DEBUG_OUT(15 downto 8) <= rx_tcp_option; --DEBUG_OUT <= X"00" & slv(rx_tcp_option) when DEBUG_IN = '0' else rx_tcp_window_shift & slv(rx_tcp_option_length); --DEBUG_OUT <= dhcp_option & dhcp_option_length; --DEBUG_OUT(7 downto 0) <= slv(init_cmnd_addr); --DEBUG_OUT(7 downto 0) <= slv(state_debug_sig); --DEBUG_OUT(7 downto 0) <= slv(eir_register); --DEBUG_OUT <= spi_wr_addr & spi_wr_data; --DEBUG_OUT <= next_packet_pointer; --DEBUG_OUT <= rx_packet_status_vector(15 downto 0) when DEBUG_IN = '0' else rx_packet_status_vector(31 downto 16); --DEBUG_OUT <= rx_packet_source_mac(15 downto 0) when DEBUG_IN = '0' else rx_packet_source_mac(31 downto 16); --DEBUG_OUT <= arp_target_ip_addr(15 downto 0) when DEBUG_IN = '0' else arp_target_ip_addr(31 downto 16); --DEBUG_OUT <= arp_source_ip_addr(15 downto 0) when DEBUG_IN = '0' else arp_source_ip_addr(31 downto 16); --DEBUG_OUT <= dhcp_your_ip_addr(15 downto 0) when DEBUG_IN = '0' else dhcp_your_ip_addr(31 downto 16); --DEBUG_OUT <= slv(tcp_acknowledge_number(15 downto 0)) when DEBUG_IN(1) = '0' else slv(tcp_acknowledge_number(31 downto 16)); --DEBUG_OUT <= slv(tcp_ack_number_previous_ack(15 downto 0)) when DEBUG_IN = '0' else slv(tcp_ack_number_previous_ack(31 downto 16)); --DEBUG_OUT(11 downto 0) <= slv(requested_data_size); --DEBUG_OUT(7 downto 0) <= tx_packet_rd_data; --DEBUG_OUT <= rx_packet_type; --DEBUG_OUT <= slv(tx_packet_end_pointer); --DEBUG_OUT(3 downto 0) <= ip_packet_version; --DEBUG_OUT(7 downto 0) <= X"0"&"0"&debug_rx_flag2&debug_rx_flag1&debug_rx_flag; --DEBUG_OUT(7 downto 0) <= slv(num_packets); --DEBUG_OUT(7 downto 0) <= slv(tcp_tx_data); --DEBUG_OUT(3 downto 0) <= slv(tx_packet_ack_timeout_occur); --DEBUG_OUT(11 downto 0) <= slv(rx_kbytes_sec); DEBUG_OUT(15 downto 0) <= slv(interrupt_counter); --DEBUG_OUT(15 downto 0) <= slv(tx_base_addr); --DEBUG_OUT(15 downto 0) <= slv(checksum); --DEBUG_OUT(15 downto 0) <= slv(checksum_initial_value); --DEBUG_OUT(10 downto 0) <= slv(rx_data_start_addr); --DEBUG_OUT(11 downto 0) <= slv(tcp_wr_data_count); packet_definition_addr <= frame_addr when doing_tx_packet_config = '0' else slv(tx_packet_frame_addr); frame_data <= packet_definition_data; frame_rd_cmplt <= '1'; clk_1hz <= CLK_1HZ_IN; ---- HANDLE COMMANDS ---- INT_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if packet_handler_state = CHECK_TCP_SYN_PACKET0 then interrupt_counter <= interrupt_counter + 1; end if; end if; end process; SYNC_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then eth_state <= eth_next_state; end if; end process; NEXT_STATE_DECODE: process (eth_state, command, command_waiting, init_cmnd_addr, poll_interrupt_reg, frame_data, tx_packet_ready_for_transmission, spi_oper_cmplt, eir_register, previous_packet_pointer, next_packet_pointer, rx_packet_handled, tx_packet_length_counter, spi_rd_cmplt, spi_wr_cmplt) begin eth_next_state <= eth_state; --default is to stay in current state case (eth_state) is when IDLE => if init_enc28j60_waiting = '1' then eth_next_state <= HANDLE_INIT_CMND0; elsif dhcp_connect_waiting = '1' then eth_next_state <= TRIGGER_DHCP_DISCOVER; elsif send_prev_packet_waiting = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV0; elsif resend_ack_packet = '1' then eth_next_state <= RESEND_ACK_IN_BUFFER; elsif tx_packet_ready_for_transmission = '1' then eth_next_state <= PRE_TX_TRANSMIT0; elsif tcp_data_flush_waiting = '1' then eth_next_state <= TRIGGER_TCP_TX0; elsif large_tx_packet_waiting = '1' then eth_next_state <= TRIGGER_TCP_TX0; else eth_next_state <= SERVICE_INTERRUPT0; end if; when HANDLE_INIT_CMND0 => eth_next_state <= HANDLE_INIT_CMND1; when HANDLE_INIT_CMND1 => eth_next_state <= HANDLE_INIT_CMND2; when HANDLE_INIT_CMND2 => if frame_rd_cmplt = '1' then if frame_data = X"0000" then eth_next_state <= HANDLE_INIT_CMND6; else eth_next_state <= HANDLE_INIT_CMND3; end if; end if; when HANDLE_INIT_CMND3 => eth_next_state <= HANDLE_INIT_CMND4; when HANDLE_INIT_CMND4 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_INIT_CMND5; end if; when HANDLE_INIT_CMND5 => if slv(init_cmnd_addr) = C_init_cmnds_max_addr then eth_next_state <= HANDLE_INIT_CMND6; else eth_next_state <= HANDLE_INIT_CMND1; end if; when HANDLE_INIT_CMND6 => eth_next_state <= IDLE; when TRIGGER_DHCP_DISCOVER => eth_next_state <= IDLE; when TRIGGER_ARP_REQUEST => eth_next_state <= IDLE; when TRIGGER_CANCEL_DHCP_CONNECT => eth_next_state <= IDLE; when TRIGGER_CLOSE_TCP_CONNECTION => eth_next_state <= IDLE; when TRIGGER_CANCEL_TCP_CONNECTION => eth_next_state <= IDLE; when SERVICE_INTERRUPT0 => eth_next_state <= SERVICE_INTERRUPT1; when SERVICE_INTERRUPT1 => if spi_oper_cmplt = '1' then eth_next_state <= SERVICE_INTERRUPT2; end if; when SERVICE_INTERRUPT2 => eth_next_state <= SERVICE_INTERRUPT3; when SERVICE_INTERRUPT3 => if spi_oper_cmplt = '1' then eth_next_state <= SERVICE_INTERRUPT4; end if; when SERVICE_INTERRUPT4 => eth_next_state <= SERVICE_INTERRUPT5; when SERVICE_INTERRUPT5 => if eir_register(6) = '1' then eth_next_state <= HANDLE_RX_INTERRUPT0; elsif eir_register(3) = '1' then eth_next_state <= HANDLE_TX_INTERRUPT0; else eth_next_state <= SERVICE_INTERRUPT6; end if; when HANDLE_TX_INTERRUPT0 => eth_next_state <= HANDLE_TX_INTERRUPT1; when HANDLE_TX_INTERRUPT1 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_INTERRUPT2; end if; when HANDLE_TX_INTERRUPT2 => eth_next_state <= SERVICE_INTERRUPT6; when HANDLE_RX_INTERRUPT0 => eth_next_state <= HANDLE_RX_INTERRUPT1; when HANDLE_RX_INTERRUPT1 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT2; end if; when HANDLE_RX_INTERRUPT2 => eth_next_state <= HANDLE_RX_INTERRUPT3; when HANDLE_RX_INTERRUPT3 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT4; end if; when HANDLE_RX_INTERRUPT4 => eth_next_state <= COPY_RX_PACKET_TO_BUF0; when COPY_RX_PACKET_TO_BUF0 => eth_next_state <= COPY_RX_PACKET_TO_BUF1; when COPY_RX_PACKET_TO_BUF1 => eth_next_state <= COPY_RX_PACKET_TO_BUF2; when COPY_RX_PACKET_TO_BUF2 => if spi_rd_cmplt = '1' then eth_next_state <= COPY_RX_PACKET_TO_BUF3; end if; when COPY_RX_PACKET_TO_BUF3 => eth_next_state <= COPY_RX_PACKET_TO_BUF4; when COPY_RX_PACKET_TO_BUF4 => if slv(previous_packet_pointer) = next_packet_pointer then eth_next_state <= COPY_RX_PACKET_TO_BUF5; else eth_next_state <= COPY_RX_PACKET_TO_BUF1; end if; when COPY_RX_PACKET_TO_BUF5 => if spi_oper_cmplt = '1' then eth_next_state <= COPY_RX_PACKET_TO_BUF6; end if; when COPY_RX_PACKET_TO_BUF6 => if rx_packet_handled = '1' then eth_next_state <= HANDLE_RX_INTERRUPT5; end if; when HANDLE_RX_INTERRUPT5 => eth_next_state <= HANDLE_RX_INTERRUPT6; when HANDLE_RX_INTERRUPT6 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT7; end if; when HANDLE_RX_INTERRUPT7 => eth_next_state <= HANDLE_RX_INTERRUPT8; when HANDLE_RX_INTERRUPT8 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT9; end if; when HANDLE_RX_INTERRUPT9 => eth_next_state <= HANDLE_RX_INTERRUPT10; when HANDLE_RX_INTERRUPT10 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT11; end if; when HANDLE_RX_INTERRUPT11 => eth_next_state <= HANDLE_RX_INTERRUPT12; when HANDLE_RX_INTERRUPT12 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT13; end if; when HANDLE_RX_INTERRUPT13 => eth_next_state <= HANDLE_RX_INTERRUPT14; when HANDLE_RX_INTERRUPT14 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT15; end if; when HANDLE_RX_INTERRUPT15 => eth_next_state <= HANDLE_RX_INTERRUPT16; when HANDLE_RX_INTERRUPT16 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_RX_INTERRUPT17; end if; when HANDLE_RX_INTERRUPT17 => eth_next_state <= SERVICE_INTERRUPT6; when CHECK_IF_ACK_WAITING => if ack_required = '1' then eth_next_state <= TRIGGER_ACK_PACKET; else eth_next_state <= IDLE; end if; when TRIGGER_ACK_PACKET => if packet_handler_state = TRIGGER_TCP_ACK0 then eth_next_state <= IDLE; end if; when TRIGGER_TCP_TX0 => if tcp_wr_data_count = X"000" or tx_packets_no_ack > X"1" then eth_next_state <= IDLE; else eth_next_state <= TRIGGER_TCP_TX1; end if; when TRIGGER_TCP_TX1 => if packet_handler_state = RX_TCP_WINDOW_TOO_SMALL then eth_next_state <= IDLE; elsif packet_handler_state = TRIGGER_TCP_PSH_ACK2 then eth_next_state <= TRIGGER_TCP_TX2; end if; when TRIGGER_TCP_TX2 => if tx_packet_ready_for_transmission = '1' then eth_next_state <= PRE_TX_TRANSMIT0; end if; when SERVICE_INTERRUPT6 => eth_next_state <= SERVICE_INTERRUPT7; when SERVICE_INTERRUPT7 => if spi_oper_cmplt = '1' then eth_next_state <= SERVICE_INTERRUPT8; end if; when SERVICE_INTERRUPT8 => eth_next_state <= CHECK_IF_ACK_WAITING; when PRE_TX_TRANSMIT0 => eth_next_state <= PRE_TX_TRANSMIT1; when PRE_TX_TRANSMIT1 => if spi_oper_cmplt = '1' then eth_next_state <= PRE_TX_TRANSMIT2; end if; when PRE_TX_TRANSMIT2 => eth_next_state <= PRE_TX_TRANSMIT3; when PRE_TX_TRANSMIT3 => if spi_oper_cmplt = '1' then eth_next_state <= PRE_TX_TRANSMIT4; end if; when PRE_TX_TRANSMIT4 => eth_next_state <= PRE_TX_TRANSMIT5; when PRE_TX_TRANSMIT5 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT0; end if; when HANDLE_TX_TRANSMIT0 => eth_next_state <= HANDLE_TX_TRANSMIT1; when HANDLE_TX_TRANSMIT1 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT2; end if; when HANDLE_TX_TRANSMIT2 => eth_next_state <= HANDLE_TX_TRANSMIT3; when HANDLE_TX_TRANSMIT3 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT4; end if; when HANDLE_TX_TRANSMIT4 => eth_next_state <= HANDLE_TX_TRANSMIT5; when HANDLE_TX_TRANSMIT5 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT6; end if; when HANDLE_TX_TRANSMIT6 => eth_next_state <= HANDLE_TX_TRANSMIT7; when HANDLE_TX_TRANSMIT7 => if tx_packet_length_counter = X"0000" then eth_next_state <= HANDLE_TX_TRANSMIT_PRE11; else eth_next_state <= HANDLE_TX_TRANSMIT8; end if; when HANDLE_TX_TRANSMIT8 => eth_next_state <= HANDLE_TX_TRANSMIT9; when HANDLE_TX_TRANSMIT9 => eth_next_state <= HANDLE_TX_TRANSMIT10; when HANDLE_TX_TRANSMIT10 => if spi_wr_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT7; end if; when HANDLE_TX_TRANSMIT_PRE11 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT11; end if; when HANDLE_TX_TRANSMIT11 => eth_next_state <= HANDLE_TX_TRANSMIT12; when HANDLE_TX_TRANSMIT12 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT13; end if; when HANDLE_TX_TRANSMIT13 => eth_next_state <= HANDLE_TX_TRANSMIT14; when HANDLE_TX_TRANSMIT14 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT15; end if; when HANDLE_TX_TRANSMIT15 => eth_next_state <= HANDLE_TX_TRANSMIT16; when HANDLE_TX_TRANSMIT16 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT17; end if; when HANDLE_TX_TRANSMIT17 => eth_next_state <= HANDLE_TX_TRANSMIT18; when HANDLE_TX_TRANSMIT18 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT19; end if; when HANDLE_TX_TRANSMIT19 => eth_next_state <= HANDLE_TX_TRANSMIT20; when HANDLE_TX_TRANSMIT20 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT21; end if; when HANDLE_TX_TRANSMIT21 => if spi_data_rd(3) = '1' then -- TX has completed eth_next_state <= HANDLE_TX_TRANSMIT22; else eth_next_state <= HANDLE_TX_TRANSMIT19; end if; when HANDLE_TX_TRANSMIT22 => eth_next_state <= IDLE; when HANDLE_TX_TRANSMIT_PREV0 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV1; when HANDLE_TX_TRANSMIT_PREV1 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV2; end if; when HANDLE_TX_TRANSMIT_PREV2 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV3; when HANDLE_TX_TRANSMIT_PREV3 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV4; end if; when HANDLE_TX_TRANSMIT_PREV4 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV5; when HANDLE_TX_TRANSMIT_PREV5 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV6; end if; when HANDLE_TX_TRANSMIT_PREV6 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV7; when HANDLE_TX_TRANSMIT_PREV7 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV8; end if; when HANDLE_TX_TRANSMIT_PREV8 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV9; when HANDLE_TX_TRANSMIT_PREV9 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV10; end if; when HANDLE_TX_TRANSMIT_PREV10 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV11; when HANDLE_TX_TRANSMIT_PREV11 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV12; end if; when HANDLE_TX_TRANSMIT_PREV12 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV13; when HANDLE_TX_TRANSMIT_PREV13 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV14; end if; when HANDLE_TX_TRANSMIT_PREV14 => eth_next_state <= HANDLE_TX_TRANSMIT_PREV15; when HANDLE_TX_TRANSMIT_PREV15 => if spi_oper_cmplt = '1' then eth_next_state <= HANDLE_TX_TRANSMIT_PREV16; end if; when HANDLE_TX_TRANSMIT_PREV16 => eth_next_state <= WAIT_FOR_TRANSMIT_CMPLT; when WAIT_FOR_TRANSMIT_CMPLT => if tx_timeout_counter = '0'&X"00000" then eth_next_state <= PRE_TX_TRANSMIT0; end if; when RESEND_ACK_IN_BUFFER => eth_next_state <= HANDLE_TX_TRANSMIT15; end case; end process; WR_CONTINUOUS_PROC :process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_TX_TRANSMIT6 then spi_wr_continuous <= '1'; elsif tx_packet_length_counter = X"0000" then spi_wr_continuous <= '0'; end if; end if; end process; POLL_INT_PROC :process(CLK_IN) begin if rising_edge(CLK_IN) then poll_counter <= poll_counter - 1; if poll_counter = X"0" then poll_interrupt_reg <= '1'; else poll_interrupt_reg <= '0'; end if; if INIT_ENC28J60 = '1' then init_enc28j60_waiting <= '1'; elsif eth_state = HANDLE_INIT_CMND0 then init_enc28j60_waiting <= '0'; end if; if DHCP_CONNECT = '1' then dhcp_connect_waiting <= '1'; elsif eth_state = TRIGGER_DHCP_DISCOVER then dhcp_connect_waiting <= '0'; end if; if eth_state = TRIGGER_TCP_TX0 or tx_packets_no_ack > X"1" or wait_for_tcp_window_size_update = '1' then tcp_data_flush_waiting <= '0'; elsif tcp_wr_data_flush = '1' and tcp_connection_active = '1' then tcp_data_flush_waiting <= '1'; end if; if unsigned(tcp_wr_data_count) < X"580" or tcp_connection_active = '0' or tx_packets_no_ack > X"1" or wait_for_tcp_window_size_update = '1' then large_tx_packet_waiting <= '0'; else large_tx_packet_waiting <= '1'; end if; if trigger_send_prev_packet = '1' then send_prev_packet_waiting <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV0 then send_prev_packet_waiting <= '0'; end if; end if; end process; TX_PACKET_LENGTH_PROC :process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_TX_TRANSMIT5 then tx_packet_length_counter <= tx_packet_length; elsif eth_state = HANDLE_TX_TRANSMIT9 then tx_packet_length_counter <= tx_packet_length_counter - 1; end if; if eth_state = HANDLE_TX_TRANSMIT5 then tx_packet_ram_rd_addr <= "00000000000"; elsif eth_state = HANDLE_TX_TRANSMIT9 then tx_packet_ram_rd_addr <= tx_packet_ram_rd_addr + 1; end if; end if; end process; INIT_ADDR_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_INIT_CMND0 then init_cmnd_addr <= unsigned(C_init_cmnds_start_addr); elsif eth_state = HANDLE_INIT_CMND3 then init_cmnd_addr <= init_cmnd_addr + 1; end if; end if; end process; SLOW_CS_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_INIT_CMND0 then slow_cs_en <= '1'; elsif eth_state = IDLE then slow_cs_en <= '0'; end if; end if; end process; FRAME_ADDR_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_INIT_CMND1 then frame_addr <= "000" & slv(init_cmnd_addr); end if; end if; end process; SETTINGS_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_INIT_CMND0 then network_interface_enabled <= '0'; elsif eth_state = HANDLE_INIT_CMND6 then network_interface_enabled <= '1'; -- TODO add disable code end if; end if; end process; SPI_WR_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_INIT_CMND3 then spi_we <= '1'; elsif eth_state = SERVICE_INTERRUPT0 then spi_we <= '1'; elsif eth_state = SERVICE_INTERRUPT6 then spi_we <= '1'; elsif eth_state = HANDLE_TX_INTERRUPT0 then spi_we <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT5 then spi_we <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT7 then spi_we <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT9 then spi_we <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT11 then spi_we <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT13 then spi_we <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT15 then spi_we <= '1'; elsif eth_state = PRE_TX_TRANSMIT0 then spi_we <= '1'; elsif eth_state = PRE_TX_TRANSMIT2 then spi_we <= '1'; elsif eth_state = PRE_TX_TRANSMIT4 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT0 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT2 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT4 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT6 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT11 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT13 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT15 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT17 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV0 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV2 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV4 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV6 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV8 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV10 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV12 then spi_we <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT_PREV14 then spi_we <= '1'; else spi_we <= '0'; end if; end if; end process; SPI_ADDR_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_INIT_CMND3 then spi_wr_addr <= frame_data(15 downto 8); elsif eth_state = SERVICE_INTERRUPT0 then spi_wr_addr <= X"BB"; elsif eth_state = HANDLE_TX_INTERRUPT0 then spi_wr_addr <= X"BC"; elsif eth_state = HANDLE_RX_INTERRUPT5 then spi_wr_addr <= X"BF"; elsif eth_state = HANDLE_RX_INTERRUPT7 then spi_wr_addr <= X"4C"; elsif eth_state = HANDLE_RX_INTERRUPT9 then spi_wr_addr <= X"4D"; elsif eth_state = HANDLE_RX_INTERRUPT11 then spi_wr_addr <= X"40"; elsif eth_state = HANDLE_RX_INTERRUPT13 then spi_wr_addr <= X"41"; elsif eth_state = HANDLE_RX_INTERRUPT15 then spi_wr_addr <= X"9E"; elsif eth_state = SERVICE_INTERRUPT6 then spi_wr_addr <= X"9B"; elsif eth_state = PRE_TX_TRANSMIT0 then spi_wr_addr <= X"BF"; elsif eth_state = PRE_TX_TRANSMIT2 then spi_wr_addr <= X"42"; elsif eth_state = PRE_TX_TRANSMIT4 then spi_wr_addr <= X"43"; elsif eth_state = HANDLE_TX_TRANSMIT0 then spi_wr_addr <= X"44"; elsif eth_state = HANDLE_TX_TRANSMIT2 then spi_wr_addr <= X"45"; elsif eth_state = HANDLE_TX_TRANSMIT4 then spi_wr_addr <= X"7A"; elsif eth_state = HANDLE_TX_TRANSMIT6 then spi_wr_addr <= X"7A"; elsif eth_state = HANDLE_TX_TRANSMIT11 then spi_wr_addr <= X"46"; elsif eth_state = HANDLE_TX_TRANSMIT13 then spi_wr_addr <= X"47"; elsif eth_state = HANDLE_TX_TRANSMIT15 then spi_wr_addr <= X"BC"; elsif eth_state = HANDLE_TX_TRANSMIT17 then spi_wr_addr <= X"9F"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV0 then spi_wr_addr <= X"BF"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV2 then spi_wr_addr <= X"42"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV4 then spi_wr_addr <= X"43"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV6 then spi_wr_addr <= X"44"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV8 then spi_wr_addr <= X"45"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV10 then spi_wr_addr <= X"46"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV12 then spi_wr_addr <= X"47"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV14 then spi_wr_addr <= X"9F"; end if; end if; end process; SPI_DATA_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_INIT_CMND3 then spi_wr_data <= frame_data(7 downto 0); elsif eth_state = SERVICE_INTERRUPT0 then spi_wr_data <= X"80"; elsif eth_state = HANDLE_TX_INTERRUPT0 then spi_wr_data <= X"08"; elsif eth_state = HANDLE_RX_INTERRUPT5 then spi_wr_data <= X"03"; elsif eth_state = HANDLE_RX_INTERRUPT7 then spi_wr_data <= next_packet_pointer(7 downto 0); elsif eth_state = HANDLE_RX_INTERRUPT9 then spi_wr_data <= next_packet_pointer(15 downto 8); elsif eth_state = HANDLE_RX_INTERRUPT11 then spi_wr_data <= next_packet_pointer(7 downto 0); elsif eth_state = HANDLE_RX_INTERRUPT13 then spi_wr_data <= next_packet_pointer(15 downto 8); elsif eth_state = HANDLE_RX_INTERRUPT15 then spi_wr_data <= X"40"; elsif eth_state = SERVICE_INTERRUPT6 then spi_wr_data <= X"80"; elsif eth_state = PRE_TX_TRANSMIT0 then spi_wr_data <= X"03"; elsif eth_state = PRE_TX_TRANSMIT2 then spi_wr_data <= slv(tx_base_addr(7 downto 0)); elsif eth_state = PRE_TX_TRANSMIT4 then spi_wr_data <= slv(tx_base_addr(15 downto 8)); elsif eth_state = HANDLE_TX_TRANSMIT0 then spi_wr_data <= slv(tx_base_addr(7 downto 0)); elsif eth_state = HANDLE_TX_TRANSMIT2 then spi_wr_data <= slv(tx_base_addr(15 downto 8)); elsif eth_state = HANDLE_TX_TRANSMIT4 then spi_wr_data <= X"00"; elsif eth_state = HANDLE_TX_TRANSMIT6 then spi_wr_data <= tx_packet_rd_data; elsif eth_state = HANDLE_TX_TRANSMIT10 then spi_wr_data <= tx_packet_rd_data; elsif eth_state = HANDLE_TX_TRANSMIT11 then spi_wr_data <= slv(tx_packet_end_pointer(7 downto 0)); elsif eth_state = HANDLE_TX_TRANSMIT13 then spi_wr_data <= slv(tx_packet_end_pointer(15 downto 8)); elsif eth_state = HANDLE_TX_TRANSMIT15 then spi_wr_data <= X"08"; elsif eth_state = HANDLE_TX_TRANSMIT17 then spi_wr_data <= X"08"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV0 then spi_wr_data <= X"03"; elsif eth_state = HANDLE_TX_TRANSMIT_PREV2 then spi_wr_data <= slv(tx_base_addr(7 downto 0)); elsif eth_state = HANDLE_TX_TRANSMIT_PREV4 then spi_wr_data <= slv(tx_base_addr(15 downto 8)); elsif eth_state = HANDLE_TX_TRANSMIT_PREV6 then spi_wr_data <= slv(tx_base_addr(7 downto 0)); elsif eth_state = HANDLE_TX_TRANSMIT_PREV8 then spi_wr_data <= slv(tx_base_addr(15 downto 8)); elsif eth_state = HANDLE_TX_TRANSMIT_PREV10 then spi_wr_data <= slv(prev_tx_packet_end_pointer(7 downto 0)); elsif eth_state = HANDLE_TX_TRANSMIT_PREV12 then spi_wr_data <= slv(prev_tx_packet_end_pointer(15 downto 8)); elsif eth_state = HANDLE_TX_TRANSMIT_PREV14 then spi_wr_data <= X"08"; end if; end if; end process; COMMAND_CMPLT_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state /= IDLE and eth_next_state = IDLE then command_cmplt <= '1'; elsif eth_state /= IDLE and eth_next_state /= IDLE then command_cmplt <= '0'; end if; end if; end process; SPI_RD_ADDR_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = SERVICE_INTERRUPT2 then spi_rd_addr <= X"1C"; elsif eth_state = HANDLE_RX_INTERRUPT0 then spi_rd_addr <= X"3A"; elsif eth_state = HANDLE_RX_INTERRUPT2 then spi_rd_addr <= X"3A"; elsif eth_state = COPY_RX_PACKET_TO_BUF1 then spi_rd_addr <= X"3A"; elsif eth_state = HANDLE_TX_TRANSMIT19 then spi_rd_addr <= X"1C"; end if; end if; end process; SPI_RD_FLAG_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = SERVICE_INTERRUPT2 then spi_rd <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT0 then spi_rd <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT2 then spi_rd <= '1'; elsif eth_state = COPY_RX_PACKET_TO_BUF1 then spi_rd <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT19 then spi_rd <= '1'; else spi_rd <= '0'; end if; end if; end process; RD_CONTINUOUS_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = COPY_RX_PACKET_TO_BUF1 then spi_rd_continuous <= '1'; elsif eth_state = COPY_RX_PACKET_TO_BUF5 then spi_rd_continuous <= '0'; end if; end if; end process; ENC_VERSION_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = SERVICE_INTERRUPT4 then eir_register <= spi_data_rd; end if; if eth_state = HANDLE_RX_INTERRUPT2 then next_packet_pointer(7 downto 0) <= spi_data_rd; end if; if eth_state = HANDLE_RX_INTERRUPT4 then next_packet_pointer(15 downto 8) <= spi_data_rd; end if; end if; end process; ------------------------- RX PACKET -------------------------------- handle_rx_packet <= '1' when eth_state = COPY_RX_PACKET_TO_BUF6 else '0'; trigger_ack <= '1' when eth_state = TRIGGER_ACK_PACKET else '0'; handle_tx_packet <= '1' when eth_state = TRIGGER_TCP_TX1 else '0'; process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_RX_INTERRUPT0 then debug_rx_flag <= '1'; elsif eth_state = HANDLE_RX_INTERRUPT17 then debug_rx_flag <= '0'; end if; end if; end process; RX_PACKET_WR_ADDR: process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = COPY_RX_PACKET_TO_BUF0 then rx_packet_ram_we_addr_buf <= "00000000000"; elsif eth_state = COPY_RX_PACKET_TO_BUF3 then rx_packet_ram_we_addr_buf <= rx_packet_ram_we_addr_buf + 1; end if; if eth_state = HANDLE_RX_INTERRUPT5 then previous_packet_pointer <= unsigned(next_packet_pointer); elsif eth_state = COPY_RX_PACKET_TO_BUF3 then if previous_packet_pointer = C_rx_pointer_max then previous_packet_pointer <= C_rx_pointer_min; else previous_packet_pointer <= previous_packet_pointer + 1; end if; end if; end if; end process; rx_packet_ram_we <= '1' when eth_state = COPY_RX_PACKET_TO_BUF3 else '0'; rx_packet_ram_we_addr <= rx_packet_ram_we_addr_buf when doing_tx_packet_config = '0' else rx_packet_rd2_addr; RX_PACKET_RAM : TDP_RAM Generic Map ( G_DATA_A_SIZE => spi_data_rd'length, G_ADDR_A_SIZE => rx_packet_ram_we_addr'length, G_RELATION => 0, --log2(SIZE_A/SIZE_B) G_INIT_ZERO => true, G_INIT_FILE => "") Port Map ( CLK_A_IN => CLK_IN, WE_A_IN => rx_packet_ram_we, ADDR_A_IN => slv(rx_packet_ram_we_addr), DATA_A_IN => spi_data_rd, DATA_A_OUT => rx_packet_rd_data2, CLK_B_IN => CLK_IN, WE_B_IN => '0', ADDR_B_IN => slv(rx_packet_ram_rd_addr), DATA_B_IN => X"00", DATA_B_OUT => rx_packet_rd_data); PH_SYNC_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then packet_handler_state <= packet_handler_next_state; end if; end process; rx_packet_handled <= '1' when packet_handler_state = COMPLETE else '0'; send_arp_reply <= '1' when packet_handler_state = TRIGGER_ARP_REPLY else '0'; send_icmp_reply <= '1' when packet_handler_state = TRIGGER_ICMP_PACKET_REPLY else '0'; send_dhcp_request <= '1' when packet_handler_state = TRIGGER_DHCP_REQUEST else '0'; send_tcp_ack_packet <= '1' when packet_handler_state = TRIGGER_TCP_ACK3 else '0'; send_tcp_tx_packet <= '1' when packet_handler_state = TRIGGER_TCP_PSH_ACK2 else '0'; send_arp_request <= '1' when eth_state = TRIGGER_ARP_REQUEST else '0'; send_dhcp_discover <= '1' when eth_state = TRIGGER_DHCP_DISCOVER else '0'; cancel_dhcp_connect <= '1' when eth_state = TRIGGER_CANCEL_DHCP_CONNECT else '0'; close_tcp_connection <= '1' when eth_state = TRIGGER_CLOSE_TCP_CONNECTION else '0'; cancel_tcp_connection <= '1' when eth_state = TRIGGER_CANCEL_TCP_CONNECTION else '0'; PH_NEXT_STATE_DECODE: process (packet_handler_state, handle_rx_packet, rx_packet_status_vector(23), rx_tcp_flags, rx_packet_type, arp_target_ip_addr, rx_tcp_option, tcp_option_addr, total_packet_length, rx_tcp_option_length, arp_opcode, expecting_arp_reply, ip_addr, tx_packet_config_cmplt, ip_packet_version, ip_packet_destination_ip, dhcp_enable, dhcp_addr_locked, ip_packet_protocol, ip_packet_length, udp_source_port, udp_dest_port, dhcp_transaction_id, transaction_id_rd, dhcp_magic_cookie, dhcp_option, dhcp_option_length, dhcp_option_addr, expecting_syn_ack, dhcp_message_type, expecting_dhcp_offer, expecting_dhcp_ack, rx_tcp_source_port, listen_port, rx_tcp_dest_port, client_port, ping_enable, rx_tcp_header_length, tcp_sequence_number_p1, rx_tcp_ack_number, tcp_sequence_number, tcp_acknowledge_number, rx_tcp_seq_number, rx_packet_ram_rd_addr, tx_packet_state) begin packet_handler_next_state <= packet_handler_state; --default is to stay in current state case (packet_handler_state) is when IDLE => if tx_packet_state = IDLE then -- only configure new packet if currently not transmitting a packet if handle_rx_packet = '1' then packet_handler_next_state <= PARSE_SOURCE_MAC0; elsif trigger_ack = '1' then packet_handler_next_state <= TRIGGER_TCP_ACK0; elsif handle_tx_packet = '1' then packet_handler_next_state <= CHECK_IF_DATA_TO_SEND; end if; end if; when PARSE_SOURCE_MAC0 => packet_handler_next_state <= PARSE_SOURCE_MAC1; when PARSE_SOURCE_MAC1 => packet_handler_next_state <= PARSE_SOURCE_MAC2; when PARSE_SOURCE_MAC2 => packet_handler_next_state <= PARSE_SOURCE_MAC3; when PARSE_SOURCE_MAC3 => packet_handler_next_state <= PARSE_SOURCE_MAC4; when PARSE_SOURCE_MAC4 => packet_handler_next_state <= PARSE_SOURCE_MAC5; when PARSE_SOURCE_MAC5 => packet_handler_next_state <= PARSE_SOURCE_MAC6; when PARSE_SOURCE_MAC6 => packet_handler_next_state <= PARSE_SOURCE_MAC7; when PARSE_SOURCE_MAC7 => packet_handler_next_state <= PARSE_PACKET_TYPE0; when PARSE_PACKET_TYPE0 => packet_handler_next_state <= PARSE_PACKET_TYPE1; when PARSE_PACKET_TYPE1 => packet_handler_next_state <= PARSE_PACKET_TYPE2; when PARSE_PACKET_TYPE2 => packet_handler_next_state <= PARSE_PACKET_TYPE3; when PARSE_PACKET_TYPE3 => packet_handler_next_state <= PARSE_PACKET_TYPE4; when PARSE_PACKET_TYPE4 => if rx_packet_type = C_ARP_Packet_Type then packet_handler_next_state <= HANDLE_ARP_PACKET0; elsif rx_packet_type = C_IP_Packet_Type then packet_handler_next_state <= HANDLE_IP_PACKET0; else packet_handler_next_state <= COMPLETE; end if; when HANDLE_ARP_PACKET0 => packet_handler_next_state <= HANDLE_ARP_PACKET1; when HANDLE_ARP_PACKET1 => packet_handler_next_state <= HANDLE_ARP_PACKET2; when HANDLE_ARP_PACKET2 => packet_handler_next_state <= HANDLE_ARP_PACKET3; when HANDLE_ARP_PACKET3 => if arp_opcode = C_ARP_Request then packet_handler_next_state <= HANDLE_ARP_REQUEST0; elsif arp_opcode = C_ARP_Reply then packet_handler_next_state <= HANDLE_ARP_REPLY0; else packet_handler_next_state <= COMPLETE; end if; when HANDLE_ARP_REPLY0 => if expecting_arp_reply = '1' then packet_handler_next_state <= HANDLE_ARP_REPLY1; else packet_handler_next_state <= COMPLETE; end if; when HANDLE_ARP_REPLY1 => packet_handler_next_state <= HANDLE_ARP_REPLY2; when HANDLE_ARP_REPLY2 => packet_handler_next_state <= HANDLE_ARP_REPLY3; when HANDLE_ARP_REPLY3 => packet_handler_next_state <= HANDLE_ARP_REPLY4; when HANDLE_ARP_REPLY4 => packet_handler_next_state <= HANDLE_ARP_REPLY5; when HANDLE_ARP_REPLY5 => packet_handler_next_state <= HANDLE_ARP_REPLY6; when HANDLE_ARP_REPLY6 => packet_handler_next_state <= HANDLE_ARP_REPLY7; when HANDLE_ARP_REPLY7 => packet_handler_next_state <= COMPLETE; when HANDLE_ARP_REQUEST0 => packet_handler_next_state <= HANDLE_ARP_REQUEST1; when HANDLE_ARP_REQUEST1 => packet_handler_next_state <= HANDLE_ARP_REQUEST2; when HANDLE_ARP_REQUEST2 => packet_handler_next_state <= HANDLE_ARP_REQUEST3; when HANDLE_ARP_REQUEST3 => packet_handler_next_state <= HANDLE_ARP_REQUEST4; when HANDLE_ARP_REQUEST4 => packet_handler_next_state <= HANDLE_ARP_REQUEST5; when HANDLE_ARP_REQUEST5 => packet_handler_next_state <= HANDLE_ARP_REQUEST6; when HANDLE_ARP_REQUEST6 => if arp_target_ip_addr = ip_addr then packet_handler_next_state <= HANDLE_ARP_REQUEST7; else packet_handler_next_state <= COMPLETE; end if; when HANDLE_ARP_REQUEST7 => packet_handler_next_state <= HANDLE_ARP_REQUEST8; when HANDLE_ARP_REQUEST8 => packet_handler_next_state <= HANDLE_ARP_REQUEST9; when HANDLE_ARP_REQUEST9 => packet_handler_next_state <= HANDLE_ARP_REQUEST10; when HANDLE_ARP_REQUEST10 => packet_handler_next_state <= HANDLE_ARP_REQUEST11; when HANDLE_ARP_REQUEST11 => packet_handler_next_state <= HANDLE_ARP_REQUEST12; when HANDLE_ARP_REQUEST12 => packet_handler_next_state <= HANDLE_ARP_REQUEST13; when HANDLE_ARP_REQUEST13 => packet_handler_next_state <= TRIGGER_ARP_REPLY; when TRIGGER_ARP_REPLY => if tx_packet_config_cmplt = '1' then packet_handler_next_state <= COMPLETE; end if; when HANDLE_IP_PACKET0 => packet_handler_next_state <= HANDLE_IP_PACKET1; when HANDLE_IP_PACKET1 => packet_handler_next_state <= HANDLE_IP_PACKET2; when HANDLE_IP_PACKET2 => packet_handler_next_state <= HANDLE_IP_PACKET3; when HANDLE_IP_PACKET3 => packet_handler_next_state <= HANDLE_IP_PACKET4; when HANDLE_IP_PACKET4 => packet_handler_next_state <= HANDLE_IP_PACKET5; when HANDLE_IP_PACKET5 => packet_handler_next_state <= HANDLE_IP_PACKET6; when HANDLE_IP_PACKET6 => packet_handler_next_state <= HANDLE_IP_PACKET7; when HANDLE_IP_PACKET7 => packet_handler_next_state <= HANDLE_IP_PACKET8; when HANDLE_IP_PACKET8 => packet_handler_next_state <= HANDLE_IP_PACKET9; when HANDLE_IP_PACKET9 => packet_handler_next_state <= HANDLE_IP_PACKET10; when HANDLE_IP_PACKET10 => if ip_packet_version = C_IPV4_Protocol_Number then packet_handler_next_state <= HANDLE_IP_PACKET11; else packet_handler_next_state <= COMPLETE; end if; when HANDLE_IP_PACKET11 => if ip_packet_destination_ip = ip_addr then packet_handler_next_state <= HANDLE_IP_PACKET12; elsif dhcp_enable = '1' and dhcp_addr_locked = '0' then packet_handler_next_state <= HANDLE_IP_PACKET12; else packet_handler_next_state <= COMPLETE; end if; when HANDLE_IP_PACKET12 => if ip_packet_protocol = C_ICMP_Protocol_Number then packet_handler_next_state <= PRE_ICMP_PACKET_REPLY; elsif ip_packet_protocol = C_UDP_Protocol_Number then packet_handler_next_state <= PARSE_UDP_PACKET0; elsif ip_packet_protocol = C_TCP_Protocol_Number then packet_handler_next_state <= PARSE_TCP_PACKET0; else packet_handler_next_state <= COMPLETE; end if; when PRE_ICMP_PACKET_REPLY => if ip_packet_length = C_ICMP_Ping_Length and ping_enable = '1' then packet_handler_next_state <= TRIGGER_ICMP_PACKET_REPLY; else packet_handler_next_state <= COMPLETE; end if; when TRIGGER_ICMP_PACKET_REPLY => if tx_packet_config_cmplt = '1' then packet_handler_next_state <= COMPLETE; end if; when PARSE_UDP_PACKET0 => packet_handler_next_state <= PARSE_UDP_PACKET1; when PARSE_UDP_PACKET1 => packet_handler_next_state <= PARSE_UDP_PACKET2; when PARSE_UDP_PACKET2 => packet_handler_next_state <= PARSE_UDP_PACKET3; when PARSE_UDP_PACKET3 => packet_handler_next_state <= PARSE_UDP_PACKET4; when PARSE_UDP_PACKET4 => packet_handler_next_state <= PARSE_UDP_PACKET5; when PARSE_UDP_PACKET5 => packet_handler_next_state <= PARSE_UDP_PACKET_TYPE0; when PARSE_UDP_PACKET_TYPE0 => if udp_source_port = C_DHCP_Source_Port then packet_handler_next_state <= PARSE_UDP_PACKET_TYPE1; else packet_handler_next_state <= COMPLETE; end if; when PARSE_UDP_PACKET_TYPE1 => if udp_dest_port = C_DHCP_Dest_Port then packet_handler_next_state <= PARSE_DHCP_PACKET0; else packet_handler_next_state <= COMPLETE; end if; when PARSE_DHCP_PACKET0 => packet_handler_next_state <= PARSE_DHCP_PACKET1; when PARSE_DHCP_PACKET1 => packet_handler_next_state <= PARSE_DHCP_PACKET2; when PARSE_DHCP_PACKET2 => packet_handler_next_state <= PARSE_DHCP_PACKET3; when PARSE_DHCP_PACKET3 => packet_handler_next_state <= PARSE_DHCP_PACKET4; when PARSE_DHCP_PACKET4 => packet_handler_next_state <= PARSE_DHCP_PACKET5; when PARSE_DHCP_PACKET5 => packet_handler_next_state <= PARSE_DHCP_PACKET6; when PARSE_DHCP_PACKET6 => if dhcp_transaction_id = transaction_id_rd then packet_handler_next_state <= PARSE_DHCP_PACKET7; else packet_handler_next_state <= COMPLETE; end if; when PARSE_DHCP_PACKET7 => packet_handler_next_state <= PARSE_DHCP_PACKET8; when PARSE_DHCP_PACKET8 => packet_handler_next_state <= PARSE_DHCP_PACKET9; when PARSE_DHCP_PACKET9 => packet_handler_next_state <= PARSE_DHCP_PACKET10; when PARSE_DHCP_PACKET10 => packet_handler_next_state <= PARSE_DHCP_PACKET11; when PARSE_DHCP_PACKET11 => packet_handler_next_state <= PARSE_DHCP_PACKET12; when PARSE_DHCP_PACKET12 => packet_handler_next_state <= PARSE_DHCP_PACKET13; when PARSE_DHCP_PACKET13 => packet_handler_next_state <= PARSE_DHCP_PACKET14; when PARSE_DHCP_PACKET14 => packet_handler_next_state <= PARSE_DHCP_PACKET15; when PARSE_DHCP_PACKET15 => packet_handler_next_state <= PARSE_DHCP_PACKET16; when PARSE_DHCP_PACKET16 => packet_handler_next_state <= PARSE_DHCP_PACKET17; when PARSE_DHCP_PACKET17 => packet_handler_next_state <= PARSE_DHCP_PACKET18; when PARSE_DHCP_PACKET18 => if C_dhcp_magic_cookie = dhcp_magic_cookie then packet_handler_next_state <= PARSE_DHCP_PACKET19; else packet_handler_next_state <= COMPLETE; end if; when PARSE_DHCP_PACKET19 => packet_handler_next_state <= PARSE_DHCP_PACKET20; when PARSE_DHCP_PACKET20 => packet_handler_next_state <= PARSE_DHCP_PACKET21; when PARSE_DHCP_PACKET21 => packet_handler_next_state <= PARSE_DHCP_PACKET22; when PARSE_DHCP_PACKET22 => packet_handler_next_state <= PARSE_DHCP_PACKET23; when PARSE_DHCP_PACKET23 => if dhcp_option = X"35" and dhcp_option_length = X"01" then packet_handler_next_state <= PARSE_DHCP_PACKET24; elsif dhcp_option = X"FF" then packet_handler_next_state <= COMPLETE; elsif RESIZE(dhcp_option_addr, 16) > total_packet_length then packet_handler_next_state <= COMPLETE; else packet_handler_next_state <= PARSE_DHCP_PACKET19; end if; when PARSE_DHCP_PACKET24 => if dhcp_message_type = X"02" then -- dhcp offer packet_handler_next_state <= CHECK_OFFER_EXPECTED; elsif dhcp_message_type = X"04" then -- dhcp decline packet_handler_next_state <= COMPLETE; elsif dhcp_message_type = X"05" then -- dhcp acknowledge packet_handler_next_state <= HANDLE_DHCP_ACK0; elsif dhcp_message_type = X"06" then -- dhcp negative acknowledge packet_handler_next_state <= COMPLETE; elsif dhcp_message_type = X"07" then -- dhcp release packet_handler_next_state <= COMPLETE; else packet_handler_next_state <= COMPLETE; end if; when CHECK_OFFER_EXPECTED => if expecting_dhcp_offer = '1' then packet_handler_next_state <= TRIGGER_DHCP_REQUEST; else packet_handler_next_state <= COMPLETE; end if; when TRIGGER_DHCP_REQUEST => if tx_packet_config_cmplt = '1' then packet_handler_next_state <= COMPLETE; end if; when HANDLE_DHCP_ACK0 => if expecting_dhcp_ack = '1' then packet_handler_next_state <= HANDLE_DHCP_ACK1; else packet_handler_next_state <= COMPLETE; end if; when HANDLE_DHCP_ACK1 => packet_handler_next_state <= HANDLE_DHCP_ACK2; when HANDLE_DHCP_ACK2 => packet_handler_next_state <= HANDLE_DHCP_ACK3; when HANDLE_DHCP_ACK3 => packet_handler_next_state <= HANDLE_DHCP_ACK4; when HANDLE_DHCP_ACK4 => packet_handler_next_state <= HANDLE_DHCP_ACK5; when HANDLE_DHCP_ACK5 => packet_handler_next_state <= HANDLE_DHCP_ACK6; when HANDLE_DHCP_ACK6 => packet_handler_next_state <= HANDLE_DHCP_ACK7; when HANDLE_DHCP_ACK7 => packet_handler_next_state <= HANDLE_DHCP_ACK8; when HANDLE_DHCP_ACK8 => packet_handler_next_state <= COMPLETE; when PARSE_TCP_PACKET0 => packet_handler_next_state <= PARSE_TCP_PACKET1; when PARSE_TCP_PACKET1 => packet_handler_next_state <= PARSE_TCP_PACKET2; when PARSE_TCP_PACKET2 => packet_handler_next_state <= PARSE_TCP_PACKET3; when PARSE_TCP_PACKET3 => packet_handler_next_state <= PARSE_TCP_PACKET4; when PARSE_TCP_PACKET4 => packet_handler_next_state <= PARSE_TCP_PACKET5; when PARSE_TCP_PACKET5 => if rx_tcp_source_port = client_port then packet_handler_next_state <= PARSE_TCP_PACKET6; else packet_handler_next_state <= COMPLETE; end if; when PARSE_TCP_PACKET6 => if rx_tcp_dest_port = listen_port then packet_handler_next_state <= PARSE_TCP_PACKET7; else packet_handler_next_state <= COMPLETE; end if; when PARSE_TCP_PACKET7 => packet_handler_next_state <= PARSE_TCP_PACKET8; when PARSE_TCP_PACKET8 => packet_handler_next_state <= PARSE_TCP_PACKET9; when PARSE_TCP_PACKET9 => packet_handler_next_state <= PARSE_TCP_PACKET10; when PARSE_TCP_PACKET10 => packet_handler_next_state <= PARSE_TCP_PACKET11; when PARSE_TCP_PACKET11 => packet_handler_next_state <= PARSE_TCP_PACKET12; when PARSE_TCP_PACKET12 => packet_handler_next_state <= PARSE_TCP_PACKET13; when PARSE_TCP_PACKET13 => packet_handler_next_state <= PARSE_TCP_PACKET14; when PARSE_TCP_PACKET14 => packet_handler_next_state <= PARSE_TCP_PACKET15; when PARSE_TCP_PACKET15 => packet_handler_next_state <= PARSE_TCP_PACKET16; when PARSE_TCP_PACKET16 => packet_handler_next_state <= PARSE_TCP_PACKET17; when PARSE_TCP_PACKET17 => packet_handler_next_state <= PARSE_TCP_PACKET18; when PARSE_TCP_PACKET18 => packet_handler_next_state <= PARSE_TCP_PACKET19; when PARSE_TCP_PACKET19 => if rx_tcp_flags(4 downto 1) = X"1" and tcp_connection_active = '0' then -- SYN PACKET (READ OPTIONS) packet_handler_next_state <= PARSE_TCP_PACKET20; else packet_handler_next_state <= PARSE_TCP_PACKET25; end if; when PARSE_TCP_PACKET20 => packet_handler_next_state <= PARSE_TCP_PACKET21; when PARSE_TCP_PACKET21 => packet_handler_next_state <= PARSE_TCP_PACKET22; when PARSE_TCP_PACKET22 => packet_handler_next_state <= PARSE_TCP_PACKET23; when PARSE_TCP_PACKET23 => packet_handler_next_state <= PARSE_TCP_PACKET24; when PARSE_TCP_PACKET24 => if rx_tcp_option = X"03" then packet_handler_next_state <= PARSE_TCP_PACKET25; elsif rx_tcp_option = X"01" then packet_handler_next_state <= PARSE_TCP_PACKET26; elsif RESIZE(tcp_option_addr, 16) > total_packet_length then packet_handler_next_state <= COMPLETE; else packet_handler_next_state <= PARSE_TCP_PACKET27; end if; when PARSE_TCP_PACKET25 => if rx_tcp_flags(4 downto 1) = X"1" and tcp_connection_active = '0' then packet_handler_next_state <= CHECK_TCP_SYN_PACKET0; elsif rx_tcp_flags(4 downto 1) = X"C" or rx_tcp_flags(4 downto 1) = X"8" then packet_handler_next_state <= CHECK_TCP_PSH_ACK_PACKET0; else packet_handler_next_state <= COMPLETE; end if; when PARSE_TCP_PACKET26 => packet_handler_next_state <= PARSE_TCP_PACKET20; when PARSE_TCP_PACKET27 => if rx_tcp_option_length = X"00" then packet_handler_next_state <= COMPLETE; else packet_handler_next_state <= PARSE_TCP_PACKET20; end if; when CHECK_TCP_SYN_PACKET0 => packet_handler_next_state <= CHECK_TCP_SYN_PACKET1; when CHECK_TCP_SYN_PACKET1 => packet_handler_next_state <= CHECK_TCP_SYN_PACKET2; when CHECK_TCP_SYN_PACKET2 => packet_handler_next_state <= CHECK_TCP_SYN_PACKET3; when CHECK_TCP_SYN_PACKET3 => packet_handler_next_state <= CHECK_TCP_SYN_PACKET4; when CHECK_TCP_SYN_PACKET4 => packet_handler_next_state <= CHECK_TCP_SYN_PACKET5; when CHECK_TCP_SYN_PACKET5 => packet_handler_next_state <= TRIGGER_TCP_ACK0; when CHECK_TCP_PSH_ACK_PACKET0 => if tcp_sequence_number = unsigned(rx_tcp_ack_number) then packet_handler_next_state <= CHECK_TCP_PSH_ACK_PACKET1; else packet_handler_next_state <= COMPLETE; end if; when CHECK_TCP_PSH_ACK_PACKET1 => if tcp_acknowledge_number = unsigned(rx_tcp_seq_number) then packet_handler_next_state <= CHECK_TCP_PSH_ACK_PACKET2; else packet_handler_next_state <= RESEND_ACK; -- ACK failed to reach target, resend end if; when CHECK_TCP_PSH_ACK_PACKET2 => if rx_data_length /= X"0000" then packet_handler_next_state <= CHECK_TCP_PSH_ACK_PACKET3; else packet_handler_next_state <= COMPLETE; -- This was just an ACK end if; when CHECK_TCP_PSH_ACK_PACKET3 => packet_handler_next_state <= READ_TCP_RX_DATA; when READ_TCP_RX_DATA => if RESIZE(rx_packet_ram_rd_addr, 16) > total_packet_length then packet_handler_next_state <= COMPLETE; end if; when TRIGGER_TCP_ACK0 => packet_handler_next_state <= TRIGGER_TCP_ACK1; when TRIGGER_TCP_ACK1 => if window_size > X"136" then packet_handler_next_state <= TRIGGER_TCP_ACK2; end if; when TRIGGER_TCP_ACK2 => packet_handler_next_state <= TRIGGER_TCP_ACK3; when TRIGGER_TCP_ACK3 => if tx_packet_state = INIT_TCP_PACKET_METADATA then packet_handler_next_state <= COMPLETE; end if; when RESEND_ACK => packet_handler_next_state <= COMPLETE; when CHECK_IF_DATA_TO_SEND => if tcp_wr_data_count /= X"000" then packet_handler_next_state <= TRIGGER_TCP_PSH_ACK0; else packet_handler_next_state <= COMPLETE; end if; when TRIGGER_TCP_PSH_ACK0 => packet_handler_next_state <= TRIGGER_TCP_PSH_ACK1; when TRIGGER_TCP_PSH_ACK1 => if rx_tcp_window_size_shifted(31 downto 12) = X"00000" then packet_handler_next_state <= CHECK_TCP_WINDOW_SIZE; else packet_handler_next_state <= TRIGGER_TCP_PSH_ACK2; end if; when CHECK_TCP_WINDOW_SIZE => if tx_bytes_to_send > unsigned(rx_tcp_window_size_shifted(11 downto 0)) then -- server is not ready to receive data yet packet_handler_next_state <= RX_TCP_WINDOW_TOO_SMALL; else packet_handler_next_state <= TRIGGER_TCP_PSH_ACK2; end if; when TRIGGER_TCP_PSH_ACK2 => if tx_packet_state = SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH0 then -- wait until packet is formed before incrementing sequence number packet_handler_next_state <= TRIGGER_TCP_PSH_ACK3; end if; when TRIGGER_TCP_PSH_ACK3 => packet_handler_next_state <= COMPLETE; when RX_TCP_WINDOW_TOO_SMALL => packet_handler_next_state <= IDLE; when COMPLETE => packet_handler_next_state <= IDLE; end case; end process; ACK_TIMER_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if packet_handler_state = CHECK_TCP_PSH_ACK_PACKET3 then ack_countdown <= C_250us; elsif ack_countdown /= X"0000" then ack_countdown <= ack_countdown - 1; end if; if ack_countdown = X"0001" then ack_required <= '1'; elsif trigger_fin_ack = '1' then ack_required <= '1'; elsif packet_handler_state = TRIGGER_TCP_ACK0 then ack_required <= '0'; end if; if packet_handler_state = RESEND_ACK then resend_ack_packet <= '1'; elsif eth_state = RESEND_ACK_IN_BUFFER then resend_ack_packet <= '0'; end if; if packet_handler_state = RX_TCP_WINDOW_TOO_SMALL then wait_for_tcp_window_size_update <= '1'; elsif packet_handler_state = PARSE_TCP_PACKET25 then wait_for_tcp_window_size_update <= '0'; end if; end if; end process; RX_PACKET_RD_ADDR: process(CLK_IN) begin if rising_edge(CLK_IN) then if packet_handler_state = PARSE_SOURCE_MAC0 then rx_packet_ram_rd_addr <= "000"&X"0A"; elsif packet_handler_state = PARSE_PACKET_TYPE0 then rx_packet_ram_rd_addr <= "000"&X"10"; elsif packet_handler_state = HANDLE_ARP_REQUEST0 then rx_packet_ram_rd_addr <= "000"&X"2A"; elsif packet_handler_state = HANDLE_ARP_REQUEST7 then rx_packet_ram_rd_addr <= "000"&X"20"; elsif packet_handler_state = HANDLE_IP_PACKET0 then rx_packet_ram_rd_addr <= "000"&X"12"; elsif packet_handler_state = HANDLE_IP_PACKET1 then rx_packet_ram_rd_addr <= "000"&X"1B"; elsif packet_handler_state = HANDLE_IP_PACKET2 then rx_packet_ram_rd_addr <= "000"&X"22"; elsif packet_handler_state = HANDLE_IP_PACKET6 then rx_packet_ram_rd_addr <= "000"&X"14"; elsif packet_handler_state = PARSE_UDP_PACKET0 then rx_packet_ram_rd_addr <= "000"&X"26"; elsif packet_handler_state = PARSE_DHCP_PACKET0 then rx_packet_ram_rd_addr <= "000"&X"32"; elsif packet_handler_state = PARSE_DHCP_PACKET4 then rx_packet_ram_rd_addr <= "000"&X"3E"; elsif packet_handler_state = PARSE_DHCP_PACKET12 then rx_packet_ram_rd_addr <= "001"&X"1A"; elsif packet_handler_state = PARSE_DHCP_PACKET19 then rx_packet_ram_rd_addr <= dhcp_option_addr; elsif packet_handler_state = HANDLE_ARP_PACKET0 then rx_packet_ram_rd_addr <= "000"&X"19"; elsif packet_handler_state = HANDLE_ARP_REPLY0 then rx_packet_ram_rd_addr <= "000"&X"1A"; elsif packet_handler_state = PARSE_TCP_PACKET0 then rx_packet_ram_rd_addr <= next_protocol_start_addr; elsif packet_handler_state = PARSE_TCP_PACKET20 then rx_packet_ram_rd_addr <= tcp_option_addr; elsif packet_handler_state = CHECK_TCP_PSH_ACK_PACKET1 then rx_packet_ram_rd_addr <= rx_data_start_addr; elsif packet_handler_state = HANDLE_DHCP_ACK1 then rx_packet_ram_rd_addr <= "000"&X"0A"; else rx_packet_ram_rd_addr <= rx_packet_ram_rd_addr + 1; end if; if packet_handler_state = HANDLE_ARP_PACKET2 then arp_opcode <= rx_packet_rd_data; end if; if packet_handler_state = HANDLE_ARP_REQUEST9 then arp_source_ip_addr(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_ARP_REQUEST10 then arp_source_ip_addr(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_ARP_REQUEST11 then arp_source_ip_addr(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_ARP_REQUEST12 then arp_source_ip_addr(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = HANDLE_ARP_REQUEST2 then arp_target_ip_addr(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_ARP_REQUEST3 then arp_target_ip_addr(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_ARP_REQUEST4 then arp_target_ip_addr(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_ARP_REQUEST5 then arp_target_ip_addr(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_SOURCE_MAC2 then rx_packet_source_mac(47 downto 40) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_SOURCE_MAC3 then rx_packet_source_mac(39 downto 32) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_SOURCE_MAC4 then rx_packet_source_mac(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_SOURCE_MAC5 then rx_packet_source_mac(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_SOURCE_MAC6 then rx_packet_source_mac(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_SOURCE_MAC7 then rx_packet_source_mac(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_PACKET_TYPE2 then rx_packet_type(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_PACKET_TYPE3 then rx_packet_type(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = HANDLE_IP_PACKET2 then ip_packet_version <= rx_packet_rd_data(7 downto 4); end if; if packet_handler_state = HANDLE_IP_PACKET3 then ip_packet_protocol <= rx_packet_rd_data; end if; if packet_handler_state = HANDLE_IP_PACKET2 then ip_packet_header_length(3 downto 0) <= rx_packet_rd_data(3 downto 0); ip_packet_header_length(7 downto 4) <= X"0"; elsif packet_handler_state = HANDLE_IP_PACKET3 then ip_packet_header_length <= ip_packet_header_length(5 downto 0) & "00"; end if; if packet_handler_state = HANDLE_IP_PACKET4 then next_protocol_start_addr <= RESIZE(unsigned(ip_packet_header_length), 11) + "00000010010"; -- src/dest mac + protocol + status reg (4 bytes) end if; if packet_handler_state = HANDLE_IP_PACKET4 then ip_packet_destination_ip(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_IP_PACKET5 then ip_packet_destination_ip(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_IP_PACKET6 then ip_packet_destination_ip(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_IP_PACKET7 then ip_packet_destination_ip(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = HANDLE_IP_PACKET8 then ip_packet_length(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = HANDLE_IP_PACKET9 then ip_packet_length(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = HANDLE_IP_PACKET10 then -- TODO Rename ip_packet_length ? total_packet_length <= unsigned(ip_packet_length) + X"0012"; -- src/dest mac + protocol + status reg (4 bytes) end if; if packet_handler_state = PARSE_UDP_PACKET2 then udp_source_port(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_UDP_PACKET3 then udp_source_port(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_UDP_PACKET4 then udp_dest_port(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_UDP_PACKET5 then udp_dest_port(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_DHCP_PACKET2 then transaction_id_rd(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET3 then transaction_id_rd(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET4 then transaction_id_rd(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET5 then transaction_id_rd(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_DHCP_PACKET6 then dhcp_your_ip_addr(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET7 then dhcp_your_ip_addr(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET8 then dhcp_your_ip_addr(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET9 then dhcp_your_ip_addr(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_DHCP_PACKET10 then dhcp_server_ip_addr(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET11 then dhcp_server_ip_addr(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET12 then dhcp_server_ip_addr(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET13 then dhcp_server_ip_addr(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_DHCP_PACKET14 then dhcp_magic_cookie(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET15 then dhcp_magic_cookie(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET16 then dhcp_magic_cookie(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_DHCP_PACKET17 then dhcp_magic_cookie(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_DHCP_PACKET21 then dhcp_option <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_DHCP_PACKET22 then dhcp_option_length <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_DHCP_PACKET18 then dhcp_option_addr <= "001"&X"1E"; elsif packet_handler_state = PARSE_DHCP_PACKET23 then dhcp_option_addr <= dhcp_option_addr + RESIZE(unsigned(dhcp_option_length), 11); end if; if packet_handler_state = PARSE_DHCP_PACKET23 then dhcp_message_type <= rx_packet_rd_data; end if; if (packet_handler_state = CHECK_TCP_SYN_PACKET0) then client_mac_addr(47 downto 40) <= rx_packet_source_mac(47 downto 40); elsif (packet_handler_state = CHECK_TCP_SYN_PACKET1) then client_mac_addr(39 downto 32) <= rx_packet_source_mac(39 downto 32); elsif (packet_handler_state = CHECK_TCP_SYN_PACKET2) then client_mac_addr(31 downto 24) <= rx_packet_source_mac(31 downto 24); elsif (packet_handler_state = CHECK_TCP_SYN_PACKET3) then client_mac_addr(23 downto 16) <= rx_packet_source_mac(23 downto 16); elsif (packet_handler_state = CHECK_TCP_SYN_PACKET4) then client_mac_addr(15 downto 8) <= rx_packet_source_mac(15 downto 8); elsif (packet_handler_state = CHECK_TCP_SYN_PACKET5) then client_mac_addr(7 downto 0) <= rx_packet_source_mac(7 downto 0); end if; if packet_handler_state = PARSE_TCP_PACKET2 then rx_tcp_source_port(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET3 then rx_tcp_source_port(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET4 then rx_tcp_dest_port(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET5 then rx_tcp_dest_port(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET6 then rx_tcp_seq_number(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET7 then rx_tcp_seq_number(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET8 then rx_tcp_seq_number(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET9 then rx_tcp_seq_number(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET10 then rx_tcp_ack_number(31 downto 24) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET11 then rx_tcp_ack_number(23 downto 16) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET12 then rx_tcp_ack_number(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET13 then rx_tcp_ack_number(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET14 then rx_tcp_header_length <= "00"&rx_packet_rd_data(7 downto 2); end if; if packet_handler_state = PARSE_TCP_PACKET15 then rx_tcp_flags <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET14 then rx_data_length <= unsigned(ip_packet_length); elsif packet_handler_state = PARSE_TCP_PACKET15 then rx_data_length <= rx_data_length - RESIZE(unsigned(rx_tcp_header_length), 16); elsif packet_handler_state = PARSE_TCP_PACKET16 then rx_data_length <= rx_data_length - RESIZE(unsigned(ip_packet_header_length), 16); end if; if packet_handler_state = PARSE_TCP_PACKET15 then rx_data_start_addr <= next_protocol_start_addr; elsif packet_handler_state = PARSE_TCP_PACKET16 then rx_data_start_addr <= rx_data_start_addr + RESIZE(unsigned(rx_tcp_header_length), 11); end if; if packet_handler_state = PARSE_TCP_PACKET16 then rx_tcp_window_size(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET17 then rx_tcp_window_size(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET18 then rx_tcp_checksum(15 downto 8) <= rx_packet_rd_data; elsif packet_handler_state = PARSE_TCP_PACKET19 then rx_tcp_checksum(7 downto 0) <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET19 then tcp_option_addr <= rx_packet_ram_rd_addr + "00000000010"; -- skip 2 blanks after checksum elsif packet_handler_state = PARSE_TCP_PACKET26 then tcp_option_addr <= tcp_option_addr + 1; elsif packet_handler_state = PARSE_TCP_PACKET27 then tcp_option_addr <= tcp_option_addr + RESIZE(rx_tcp_option_length, 11); end if; if packet_handler_state = PARSE_TCP_PACKET22 then rx_tcp_option <= rx_packet_rd_data; end if; if packet_handler_state = PARSE_TCP_PACKET23 then rx_tcp_option_length <= unsigned(rx_packet_rd_data); end if; if packet_handler_state = PARSE_TCP_PACKET24 then rx_tcp_window_shift <= rx_packet_rd_data(3 downto 0); end if; end if; end process; -- TODO Could disable window shift via linux kernel..? with rx_tcp_window_shift select rx_tcp_window_size_shifted <= "0000000000000000"&rx_tcp_window_size when X"0", "000000000000000"&rx_tcp_window_size&"0" when X"1", "00000000000000"&rx_tcp_window_size&"00" when X"2", "0000000000000"&rx_tcp_window_size&"000" when X"3", "000000000000"&rx_tcp_window_size&"0000" when X"4", "00000000000"&rx_tcp_window_size&"00000" when X"5", "0000000000"&rx_tcp_window_size&"000000" when X"6", "000000000"&rx_tcp_window_size&"0000000" when X"7", "00000000"&rx_tcp_window_size&"00000000" when X"8", "0000000"&rx_tcp_window_size&"000000000" when X"9", "000000"&rx_tcp_window_size&"0000000000" when X"A", "00000"&rx_tcp_window_size&"00000000000" when X"B", "0000"&rx_tcp_window_size&"000000000000" when X"C", "000"&rx_tcp_window_size&"0000000000000" when X"D", "00"&rx_tcp_window_size&"00000000000000" when X"E", "0"&rx_tcp_window_size&"000000000000000" when others; DHCP_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if packet_handler_state = HANDLE_DHCP_ACK1 then ip_addr <= dhcp_your_ip_addr; client_ip_addr <= dhcp_server_ip_addr; end if; if tx_packet_state = INIT_DHCP_DISCOVER_METADATA then expecting_dhcp_offer <= '1'; elsif tx_packet_state = INIT_DHCP_REQUEST_METADATA then expecting_dhcp_offer <= '0'; elsif tx_packet_state = CANCEL_DHCP_CONNECT_ST then expecting_dhcp_offer <= '0'; end if; if tx_packet_state = INIT_DHCP_REQUEST_METADATA then expecting_dhcp_ack <= '1'; elsif packet_handler_state = HANDLE_DHCP_ACK1 then expecting_dhcp_ack <= '0'; elsif tx_packet_state = CANCEL_DHCP_CONNECT_ST then expecting_dhcp_ack <= '0'; end if; if eth_state = TRIGGER_DHCP_DISCOVER then dhcp_addr_locked <= '0'; elsif packet_handler_state = HANDLE_DHCP_ACK1 then dhcp_addr_locked <= '1'; end if; if eth_state = TRIGGER_ARP_REQUEST then expecting_arp_reply <= '1'; elsif packet_handler_state = HANDLE_ARP_REPLY1 then expecting_arp_reply <= '0'; end if; if packet_handler_state = HANDLE_ARP_REPLY7 then static_addr_locked <= '1'; elsif tx_packet_state = INIT_ARP_REQUEST_METADATA then static_addr_locked <= '0'; elsif tx_packet_state = CANCEL_DHCP_CONNECT_ST then static_addr_locked <= '0'; end if; end if; end process; --------------------- TX PACKET ------------------------------ TP_SYNC_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then tx_packet_state <= tx_packet_next_state; end if; end process; TP_NEXT_STATE_DECODE: process (tx_packet_state, send_arp_reply, send_arp_request, send_icmp_reply, send_dhcp_discover, send_dhcp_request, frame_rd_cmplt, send_tcp_ack_packet, cancel_dhcp_connect, close_tcp_connection, cancel_tcp_connection, packet_instruction, checksum_calc_done) begin tx_packet_next_state <= tx_packet_state; --default is to stay in current state case (tx_packet_state) is when IDLE => if send_arp_reply = '1' then tx_packet_next_state <= INIT_ARP_REPLY_METADATA; elsif send_arp_request = '1' then tx_packet_next_state <= INIT_ARP_REQUEST_METADATA; elsif send_icmp_reply = '1' then tx_packet_next_state <= INIT_ICMP_REPLY_METADATA; elsif send_dhcp_discover = '1' then tx_packet_next_state <= INIT_DHCP_DISCOVER_METADATA; elsif send_dhcp_request = '1' then tx_packet_next_state <= INIT_DHCP_REQUEST_METADATA; elsif send_tcp_ack_packet = '1' then tx_packet_next_state <= INIT_TCP_PACKET_METADATA; elsif cancel_dhcp_connect = '1' then tx_packet_next_state <= CANCEL_DHCP_CONNECT_ST; elsif close_tcp_connection = '1' then tx_packet_next_state <= TCP_CONNECTION_CLOSED; elsif cancel_tcp_connection = '1' then tx_packet_next_state <= CANCEL_TCP_CONNECTION_ST; elsif send_tcp_tx_packet = '1' then tx_packet_next_state <= INIT_TCP_TX_PACKET_METADATA; end if; when CANCEL_DHCP_CONNECT_ST => tx_packet_next_state <= IDLE; when CANCEL_TCP_CONNECTION_ST => tx_packet_next_state <= IDLE; when TCP_CONNECTION_CLOSED => tx_packet_next_state <= IDLE; when INIT_ARP_REPLY_METADATA => tx_packet_next_state <= READ_PACKET_BYTE0; when INIT_ARP_REQUEST_METADATA => tx_packet_next_state <= READ_PACKET_BYTE0; when INIT_ICMP_REPLY_METADATA => tx_packet_next_state <= READ_PACKET_BYTE0; when INIT_DHCP_DISCOVER_METADATA => tx_packet_next_state <= READ_PACKET_BYTE0; when INIT_DHCP_REQUEST_METADATA => tx_packet_next_state <= READ_PACKET_BYTE0; when INIT_TCP_PACKET_METADATA => tx_packet_next_state <= READ_PACKET_BYTE0; when INIT_TCP_TX_PACKET_METADATA => tx_packet_next_state <= READ_PACKET_BYTE0; when READ_PACKET_BYTE0 => tx_packet_next_state <= READ_PACKET_BYTE1; when READ_PACKET_BYTE1 => if frame_rd_cmplt = '1' then tx_packet_next_state <= HANDLE_PACKET_INSTRUCTION0; end if; when HANDLE_PACKET_INSTRUCTION0 => if packet_instruction = X"FF" then tx_packet_next_state <= COMPLETE; elsif packet_instruction = X"17" then tx_packet_next_state <= SET_RX_PACKET_ADDR_LOWER_BYTE; elsif packet_instruction = X"18" then tx_packet_next_state <= SET_RX_PACKET_ADDR_UPPER_BYTE; elsif packet_instruction = X"20" then tx_packet_next_state <= SET_CHECKSUM_LENGTH_LSB; elsif packet_instruction = X"21" then tx_packet_next_state <= SET_CHECKSUM_LENGTH_MSB; elsif packet_instruction = X"22" then tx_packet_next_state <= SET_CHECKSUM_START_ADDR_LSB; elsif packet_instruction = X"23" then tx_packet_next_state <= SET_CHECKSUM_START_ADDR_MSB; elsif packet_instruction = X"24" then tx_packet_next_state <= SET_CHECKSUM_WR_ADDR_LSB; elsif packet_instruction = X"25" then tx_packet_next_state <= SET_CHECKSUM_WR_ADDR_MSB; elsif packet_instruction = X"26" then tx_packet_next_state <= TRIG_CHECKSUM_CALC; elsif packet_instruction = X"29" then tx_packet_next_state <= MOVE_TX_PACKET_WR_ADDR; elsif packet_instruction = X"2E" then tx_packet_next_state <= SET_NEW_TRANSACTION_ID; elsif packet_instruction = X"50" then tx_packet_next_state <= SET_CHECKSUM_START_VAL_LSB; elsif packet_instruction = X"51" then tx_packet_next_state <= SET_CHECKSUM_START_VAL_MSB; elsif packet_instruction = X"52" then tx_packet_next_state <= TRIGGER_CHECKSUM_LOAD_INITIAL_VALUE; elsif packet_instruction = X"57" then tx_packet_next_state <= INIT_LOAD_TX_PACKET_DATA; elsif packet_instruction = X"58" then tx_packet_next_state <= SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH0; elsif packet_instruction = X"59" then tx_packet_next_state <= SET_CHECKSUM_INITIAL_VALUE_TX_PACKET; else tx_packet_next_state <= HANDLE_PACKET_INSTRUCTION1; end if; when HANDLE_PACKET_INSTRUCTION1 => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_RX_PACKET_ADDR_LOWER_BYTE => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_RX_PACKET_ADDR_UPPER_BYTE => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_LENGTH_LSB => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_LENGTH_MSB => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_START_ADDR_LSB => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_START_ADDR_MSB => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_WR_ADDR_LSB => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_WR_ADDR_MSB => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH0 => tx_packet_next_state <= SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH1; when SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH1 => tx_packet_next_state <= READ_PACKET_BYTE0; when TRIG_CHECKSUM_CALC => tx_packet_next_state <= WAIT_FOR_CHECKSUM_CMPLT; when WAIT_FOR_CHECKSUM_CMPLT => if checksum_calc_done = '1' then tx_packet_next_state <= READ_PACKET_BYTE0; end if; when MOVE_TX_PACKET_WR_ADDR => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_NEW_TRANSACTION_ID => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_START_VAL_LSB => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_START_VAL_MSB => tx_packet_next_state <= READ_PACKET_BYTE0; when TRIGGER_CHECKSUM_LOAD_INITIAL_VALUE => tx_packet_next_state <= READ_PACKET_BYTE0; when SET_CHECKSUM_INITIAL_VALUE_TX_PACKET => tx_packet_next_state <= READ_PACKET_BYTE0; when INIT_LOAD_TX_PACKET_DATA => tx_packet_next_state <= LOAD_TX_PACKET_DATA; when LOAD_TX_PACKET_DATA => if tx_packet_data_counter = X"001" then tx_packet_next_state <= HANDLE_PACKET_INSTRUCTION1; end if; when COMPLETE => tx_packet_next_state <= IDLE; end case; end process; packet_instruction <= frame_data(15 downto 8); with packet_instruction(6 downto 0) select packet_data <= frame_data(7 downto 0) when "000"&X"0", mac_addr(7 downto 0) when "000"&X"1", mac_addr(15 downto 8) when "000"&X"2", mac_addr(23 downto 16) when "000"&X"3", mac_addr(31 downto 24) when "000"&X"4", mac_addr(39 downto 32) when "000"&X"5", mac_addr(47 downto 40) when "000"&X"6", rx_packet_source_mac(7 downto 0) when "000"&X"7", rx_packet_source_mac(15 downto 8) when "000"&X"8", rx_packet_source_mac(23 downto 16) when "000"&X"9", rx_packet_source_mac(31 downto 24) when "000"&X"A", rx_packet_source_mac(39 downto 32) when "000"&X"B", rx_packet_source_mac(47 downto 40) when "000"&X"C", ip_addr(7 downto 0) when "000"&X"D", ip_addr(15 downto 8) when "000"&X"E", ip_addr(23 downto 16) when "000"&X"F", ip_addr(31 downto 24) when "001"&X"0", arp_source_ip_addr(7 downto 0) when "001"&X"1", arp_source_ip_addr(15 downto 8) when "001"&X"2", arp_source_ip_addr(23 downto 16) when "001"&X"3", arp_source_ip_addr(31 downto 24) when "001"&X"4", ip_identification(7 downto 0) when "001"&X"5", ip_identification(15 downto 8) when "001"&X"6", X"00" when "001"&X"7", -- set rx read lower byte X"00" when "001"&X"8", -- set rx read upper byte rx_packet_rd_data2 when "001"&X"9", cloud_ip_addr(7 downto 0) when "001"&X"A", cloud_ip_addr(15 downto 8) when "001"&X"B", cloud_ip_addr(23 downto 16) when "001"&X"C", cloud_ip_addr(31 downto 24) when "001"&X"D", X"00" when "010"&X"0", -- set checksum length lsb X"00" when "010"&X"1", -- set checksum length msb X"00" when "010"&X"2", -- set checksum start addr lsb X"00" when "010"&X"3", -- set checksum start addr msb X"00" when "010"&X"4", -- set checksum wr addr lsb X"00" when "010"&X"5", -- set checksum wr addr msb X"00" when "010"&X"6", -- trigger checksum calc checksum(7 downto 0) when "010"&X"7", checksum(15 downto 8) when "010"&X"8", X"00" when "010"&X"9", -- set tx write addr to checksum wr addr dhcp_transaction_id(7 downto 0) when "010"&X"A", dhcp_transaction_id(15 downto 8) when "010"&X"B", dhcp_transaction_id(23 downto 16) when "010"&X"C", dhcp_transaction_id(31 downto 24) when "010"&X"D", X"00" when "010"&X"E", -- set new transaction ID dhcp_server_ip_addr(7 downto 0) when "010"&X"F", dhcp_server_ip_addr(15 downto 8) when "011"&X"0", dhcp_server_ip_addr(23 downto 16) when "011"&X"1", dhcp_server_ip_addr(31 downto 24) when "011"&X"2", dhcp_your_ip_addr(7 downto 0) when "011"&X"3", dhcp_your_ip_addr(15 downto 8) when "011"&X"4", dhcp_your_ip_addr(23 downto 16) when "011"&X"5", dhcp_your_ip_addr(31 downto 24) when "011"&X"6", client_ip_addr(7 downto 0) when "011"&X"7", client_ip_addr(15 downto 8) when "011"&X"8", client_ip_addr(23 downto 16) when "011"&X"9", client_ip_addr(31 downto 24) when "011"&X"A", client_mac_addr(7 downto 0) when "011"&X"B", client_mac_addr(15 downto 8) when "011"&X"C", client_mac_addr(23 downto 16) when "011"&X"D", client_mac_addr(31 downto 24) when "011"&X"E", client_mac_addr(39 downto 32) when "011"&X"F", client_mac_addr(47 downto 40) when "100"&X"0", listen_port(7 downto 0) when "100"&X"1", listen_port(15 downto 8) when "100"&X"2", client_port(7 downto 0) when "100"&X"3", client_port(15 downto 8) when "100"&X"4", slv(tcp_sequence_number(7 downto 0)) when "100"&X"5", slv(tcp_sequence_number(15 downto 8)) when "100"&X"6", slv(tcp_sequence_number(23 downto 16)) when "100"&X"7", slv(tcp_sequence_number(31 downto 24)) when "100"&X"8", slv(tcp_acknowledge_number(7 downto 0)) when "100"&X"9", slv(tcp_acknowledge_number(15 downto 8)) when "100"&X"A", slv(tcp_acknowledge_number(23 downto 16)) when "100"&X"B", slv(tcp_acknowledge_number(31 downto 24)) when "100"&X"C", tcp_flags(7 downto 0) when "100"&X"D", slv(window_size(7 downto 0)) when "100"&X"E", slv(X"0"&window_size(11 downto 8)) when "100"&X"F", X"00" when "101"&X"0", -- Set initial checksum value X"00" when "101"&X"1", -- Set initial checksum value X"00" when "101"&X"2", -- Load initial checksum value slv(tcp_ip_identification(7 downto 0)) when "101"&X"3", slv(tcp_ip_identification(15 downto 8)) when "101"&X"4", slv(tx_total_packet_length(7 downto 0)) when "101"&X"5", -- Data packet length + headers slv(X"0"&tx_total_packet_length(11 downto 8)) when "101"&X"6", -- Data packet length + headers tcp_tx_data when "101"&X"7", -- TX Data X"00" when "101"&X"8", -- Set checksum length to tx data length X"00" when "101"&X"9", -- Set initial checksum value to length + protocol (6) X"00" when others; tcp_sequence_number_p1 <= tcp_sequence_number + 1; METADATA_PTOC: process(CLK_IN) begin if rising_edge(CLK_IN) then ip_identification <= lfsr_val(15 downto 0); if tx_packet_state = SET_NEW_TRANSACTION_ID then dhcp_transaction_id <= lfsr_val; end if; if packet_handler_state = CHECK_TCP_SYN_PACKET0 then tcp_ip_identification <= unsigned(lfsr_val(15 downto 0)); elsif packet_handler_state = CHECK_TCP_PSH_ACK_PACKET2 then tcp_ip_identification <= tcp_ip_identification + 1; end if; if packet_handler_state = PARSE_TCP_PACKET4 and tcp_connection_active = '0' then client_port <= rx_tcp_source_port; end if; if packet_handler_state = CHECK_TCP_SYN_PACKET0 then tcp_sequence_number <= unsigned(lfsr_val); elsif packet_handler_state = PARSE_TCP_PACKET0 and sent_syn_ack = '1' then tcp_sequence_number <= tcp_sequence_number + 1; elsif packet_handler_state = TRIGGER_TCP_PSH_ACK3 then tcp_sequence_number <= tcp_sequence_number + RESIZE(tx_bytes_to_send, 32); end if; if packet_handler_state = CHECK_TCP_SYN_PACKET0 then tcp_acknowledge_number <= unsigned(rx_tcp_seq_number) + 1; elsif packet_handler_state = TRIGGER_TCP_ACK0 and fin_received = '1' then tcp_acknowledge_number <= tcp_acknowledge_number + 1; elsif packet_handler_state = CHECK_TCP_PSH_ACK_PACKET3 then tcp_acknowledge_number <= tcp_acknowledge_number + RESIZE(rx_data_length, 32); end if; if packet_handler_state = TRIGGER_TCP_ACK0 then if fin_received = '1' then tcp_flags <= C_tcp_fin_ack_flags; elsif syn_ack_packet = '1' then tcp_flags <= C_tcp_syn_ack_flags; else tcp_flags <= C_tcp_ack_flags; end if; elsif packet_handler_state = TRIGGER_TCP_PSH_ACK2 then tcp_flags <= C_tcp_psh_ack_flags; end if; if packet_handler_state = TRIGGER_TCP_ACK0 then window_size <= X"FFF" - unsigned(tcp_rd_data_count); elsif packet_handler_state = TRIGGER_TCP_ACK1 then window_size <= X"FFF" - unsigned(tcp_rd_data_count); end if; if packet_handler_state = CHECK_TCP_SYN_PACKET0 then fin_received <= '0'; elsif rx_tcp_flags(0) = '1' then fin_received <= '1'; end if; fin_received_p <= fin_received; if fin_received = '1' and fin_received_p = '0' then trigger_fin_ack <= '1'; else trigger_fin_ack <= '0'; end if; if packet_handler_state = CHECK_TCP_SYN_PACKET0 then syn_ack_packet <= '1'; elsif packet_handler_state = TRIGGER_TCP_ACK0 then syn_ack_packet <= '0'; end if; if packet_handler_state = TRIGGER_TCP_ACK0 and syn_ack_packet = '1' then sent_syn_ack <= '1'; elsif packet_handler_state = CHECK_TCP_PSH_ACK_PACKET0 then sent_syn_ack <= '0'; end if; if packet_handler_state = CHECK_TCP_SYN_PACKET0 then tcp_connection_active <= '1'; elsif fin_received = '1' then tcp_connection_active <= '0'; elsif trigger_close_connection = '1' then tcp_connection_active <= '0'; end if; if packet_handler_state = TRIGGER_TCP_PSH_ACK0 then if unsigned(tcp_wr_data_count) > X"580" then tx_bytes_to_send <= X"580"; else tx_bytes_to_send <= unsigned(tcp_wr_data_count); end if; end if; if packet_handler_state = TRIGGER_TCP_PSH_ACK1 then tx_total_packet_length <= tx_bytes_to_send + X"030"; -- IP Header length (20 Bytes) + TCP Header length (28 Bytes) end if; if packet_handler_state = TRIGGER_TCP_PSH_ACK1 then tx_total_packet_length_inc_mac <= tx_bytes_to_send + X"03E"; -- IP Header length (20 Bytes) + TCP Header length (28 Bytes) + MAC length (14 bytes) end if; if packet_handler_state = TRIGGER_TCP_PSH_ACK1 then tx_total_packet_length_checksum <= tx_bytes_to_send + X"022"; -- TCP Header length (28 Bytes) + Protocol (value=6) end if; -- TODO need to 'lock' tx logic (so previous tx packet isn't overwritten by arp or something) -- Can be achieved by only responding to TCP packets when tx_packet_no_ack_timeout > X"1" if packet_handler_state = TRIGGER_TCP_PSH_ACK3 then tx_packets_no_ack <= tx_packets_no_ack + 1; elsif packet_handler_state = CHECK_TCP_PSH_ACK_PACKET2 then tx_packets_no_ack <= X"0"; end if; if tx_packets_no_ack > X"1" then tx_packet_no_ack_timeout <= tx_packet_no_ack_timeout - 1; else tx_packet_no_ack_timeout <= C_100ms; end if; if tx_packets_no_ack < X"2" then tx_packet_timeout_counter <= X"00"; elsif tx_packet_no_ack_timeout = X"000000" then tx_packet_timeout_counter <= tx_packet_timeout_counter + 1; end if; tx_packet_timeout_counter_prev <= tx_packet_timeout_counter; if tx_packet_timeout_counter = X"01" and tx_packet_timeout_counter_prev = X"00" then trigger_send_prev_packet <= '1'; elsif tx_packet_timeout_counter = X"03" and tx_packet_timeout_counter_prev = X"02" then trigger_send_prev_packet <= '1'; elsif tx_packet_timeout_counter = X"07" and tx_packet_timeout_counter_prev = X"06" then trigger_send_prev_packet <= '1'; elsif tx_packet_timeout_counter = X"0F" and tx_packet_timeout_counter_prev = X"0E" then trigger_send_prev_packet <= '1'; else trigger_send_prev_packet <= '0'; end if; if tx_packet_timeout_counter = X"1F" and tx_packet_timeout_counter_prev = X"1E" then trigger_close_connection <= '1'; else trigger_close_connection <= '0'; end if; end if; end process; FRAME_ADDR_LENGTH_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if tx_packet_state = INIT_ARP_REPLY_METADATA then tx_packet_frame_addr <= unsigned(C_arp_reply_frame_addr); elsif tx_packet_state = INIT_ARP_REQUEST_METADATA then tx_packet_frame_addr <= unsigned(C_arp_request_frame_addr); elsif tx_packet_state = INIT_ICMP_REPLY_METADATA then tx_packet_frame_addr <= unsigned(C_icmp_reply_frame_addr); elsif tx_packet_state = INIT_DHCP_DISCOVER_METADATA then tx_packet_frame_addr <= unsigned(C_dhcp_discover_frame_addr); elsif tx_packet_state = INIT_DHCP_REQUEST_METADATA then tx_packet_frame_addr <= unsigned(C_dhcp_request_frame_addr); elsif tx_packet_state = INIT_TCP_PACKET_METADATA then tx_packet_frame_addr <= unsigned(C_tcp_packet_frame_addr); elsif tx_packet_state = INIT_TCP_TX_PACKET_METADATA then tx_packet_frame_addr <= unsigned(C_tcp_tx_packet_frame_addr); elsif tx_packet_state = IDLE then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = READ_PACKET_BYTE0 then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = READ_PACKET_BYTE1 then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = HANDLE_PACKET_INSTRUCTION0 then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = WAIT_FOR_CHECKSUM_CMPLT then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = COMPLETE then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = INIT_LOAD_TX_PACKET_DATA then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = LOAD_TX_PACKET_DATA then tx_packet_frame_addr <= tx_packet_frame_addr; elsif tx_packet_state = SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH0 then tx_packet_frame_addr <= tx_packet_frame_addr; else tx_packet_frame_addr <= tx_packet_frame_addr + 1; end if; if tx_packet_state = INIT_ARP_REPLY_METADATA then tx_packet_length <= unsigned(C_arp_reply_length); elsif tx_packet_state = INIT_ARP_REQUEST_METADATA then tx_packet_length <= unsigned(C_arp_request_length); elsif tx_packet_state = INIT_ICMP_REPLY_METADATA then tx_packet_length <= unsigned(C_icmp_reply_length); elsif tx_packet_state = INIT_DHCP_DISCOVER_METADATA then tx_packet_length <= unsigned(C_dhcp_discover_length); elsif tx_packet_state = INIT_DHCP_REQUEST_METADATA then tx_packet_length <= unsigned(C_dhcp_request_length); elsif tx_packet_state = INIT_TCP_PACKET_METADATA then tx_packet_length <= unsigned(C_tcp_packet_length); elsif tx_packet_state = INIT_TCP_TX_PACKET_METADATA then tx_packet_length <= RESIZE(unsigned(tx_total_packet_length_inc_mac), 16); end if; if tx_packet_state = INIT_ARP_REPLY_METADATA then tx_packet_end_pointer <= tx_base_addr + unsigned(C_arp_reply_length); prev_tx_packet_end_pointer <= tx_packet_end_pointer; elsif tx_packet_state = INIT_ARP_REQUEST_METADATA then tx_packet_end_pointer <= tx_base_addr + unsigned(C_arp_request_length); prev_tx_packet_end_pointer <= tx_packet_end_pointer; elsif tx_packet_state = INIT_ICMP_REPLY_METADATA then tx_packet_end_pointer <= tx_base_addr + unsigned(C_icmp_reply_length); prev_tx_packet_end_pointer <= tx_packet_end_pointer; elsif tx_packet_state = INIT_DHCP_DISCOVER_METADATA then tx_packet_end_pointer <= tx_base_addr + unsigned(C_dhcp_discover_length); prev_tx_packet_end_pointer <= tx_packet_end_pointer; elsif tx_packet_state = INIT_DHCP_REQUEST_METADATA then tx_packet_end_pointer <= tx_base_addr + unsigned(C_dhcp_discover_length); prev_tx_packet_end_pointer <= tx_packet_end_pointer; elsif tx_packet_state = INIT_TCP_PACKET_METADATA then tx_packet_end_pointer <= tx_base_addr + unsigned(C_tcp_packet_length); prev_tx_packet_end_pointer <= tx_packet_end_pointer; elsif tx_packet_state = INIT_TCP_TX_PACKET_METADATA then tx_packet_end_pointer <= tx_base_addr + RESIZE(unsigned(tx_total_packet_length_inc_mac), 16); prev_tx_packet_end_pointer <= tx_packet_end_pointer; end if; if tx_packet_state = IDLE then doing_tx_packet_config <= '0'; else doing_tx_packet_config <= '1'; end if; if tx_packet_state = IDLE then tx_packet_ram_we_addr_buf <= "00000000000"; elsif tx_packet_state = HANDLE_PACKET_INSTRUCTION1 then tx_packet_ram_we_addr_buf <= tx_packet_ram_we_addr_buf + 1; elsif tx_packet_state = LOAD_TX_PACKET_DATA then tx_packet_ram_we_addr_buf <= tx_packet_ram_we_addr_buf + 1; elsif tx_packet_state = MOVE_TX_PACKET_WR_ADDR then tx_packet_ram_we_addr_buf <= unsigned(checksum_wr_addr); end if; if tx_packet_state = COMPLETE then tx_packet_ready_for_transmission <= '1'; elsif eth_state = HANDLE_TX_TRANSMIT22 then tx_packet_ready_for_transmission <= '0'; end if; if tx_packet_state = SET_RX_PACKET_ADDR_LOWER_BYTE then rx_packet_rd2_addr(7 downto 0) <= unsigned(frame_data(7 downto 0)); elsif tx_packet_state = SET_RX_PACKET_ADDR_UPPER_BYTE then rx_packet_rd2_addr(10 downto 8) <= unsigned(frame_data(2 downto 0)); elsif tx_packet_state = HANDLE_PACKET_INSTRUCTION1 then rx_packet_rd2_addr <= rx_packet_rd2_addr + 1; elsif tx_packet_state = LOAD_TX_PACKET_DATA then rx_packet_rd2_addr <= rx_packet_rd2_addr + 1; end if; end if; end process; tx_base_addr <= C_tx_base_addr1 when tx_base_addr_select = '0' else C_tx_base_addr2; process(CLK_IN) begin if rising_edge(CLK_IN) then if eth_state = HANDLE_TX_TRANSMIT22 or eth_state = HANDLE_TX_TRANSMIT_PREV16 then tx_base_addr_select <= not(tx_base_addr_select); end if; if eth_state = WAIT_FOR_TRANSMIT_CMPLT then tx_timeout_counter <= tx_timeout_counter - 1; else tx_timeout_counter <= C_20ms; end if; end if; end process; tx_packet_ram_data <= packet_data; tx_packet_ram_we <= '1' when (tx_packet_state = HANDLE_PACKET_INSTRUCTION1) or (tx_packet_state = LOAD_TX_PACKET_DATA) else '0'; tx_packet_config_cmplt <= '1' when tx_packet_state = COMPLETE else '0'; tx_packet_ram_we_addr <= unsigned(checksum_addr) when (tx_packet_state = WAIT_FOR_CHECKSUM_CMPLT) else tx_packet_ram_we_addr_buf; TX_PACKET_RAM : TDP_RAM Generic Map ( G_DATA_A_SIZE => tx_packet_ram_data'length, G_ADDR_A_SIZE => tx_packet_ram_we_addr'length, G_RELATION => 0, --log2(SIZE_A/SIZE_B) G_INIT_ZERO => true, G_INIT_FILE => "") Port Map ( CLK_A_IN => CLK_IN, WE_A_IN => tx_packet_ram_we, ADDR_A_IN => slv(tx_packet_ram_we_addr), DATA_A_IN => tx_packet_ram_data, DATA_A_OUT => tx_packet_rd_data2, CLK_B_IN => CLK_IN, WE_B_IN => '0', ADDR_B_IN => slv(tx_packet_ram_rd_addr), DATA_B_IN => X"00", DATA_B_OUT => tx_packet_rd_data); CHECKSUM_METADATA_PROC: process(CLK_IN) begin if rising_edge(CLK_IN) then if tx_packet_state = SET_CHECKSUM_LENGTH_LSB then checksum_count(7 downto 0) <= unsigned(frame_data(7 downto 0)); elsif tx_packet_state = SET_CHECKSUM_LENGTH_MSB then checksum_count(10 downto 8) <= unsigned(frame_data(2 downto 0)); elsif tx_packet_state = SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH0 then checksum_count(10 downto 0) <= unsigned('0'&tx_bytes_to_send(10 downto 1)) + "00000010010"; elsif tx_packet_state = SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH1 then checksum_count(10 downto 0) <= checksum_count(10 downto 0) + ("0000000000"&tx_bytes_to_send(0)); end if; if tx_packet_state = SET_CHECKSUM_LENGTH_TX_PACKET_LENGTH1 then checksum_odd_length <= tx_bytes_to_send(0); elsif tx_packet_state = MOVE_TX_PACKET_WR_ADDR then -- clear odd flag before next checksum is calcd checksum_odd_length <= '0'; end if; if tx_packet_state = SET_CHECKSUM_START_ADDR_LSB then checksum_start_addr(7 downto 0) <= frame_data(7 downto 0); elsif tx_packet_state = SET_CHECKSUM_START_ADDR_MSB then checksum_start_addr(10 downto 8) <= frame_data(2 downto 0); end if; if tx_packet_state = SET_CHECKSUM_WR_ADDR_LSB then checksum_wr_addr(7 downto 0) <= frame_data(7 downto 0); elsif tx_packet_state = SET_CHECKSUM_WR_ADDR_MSB then checksum_wr_addr(10 downto 8) <= frame_data(2 downto 0); end if; if tx_packet_state = SET_CHECKSUM_START_VAL_LSB then checksum_initial_value(7 downto 0) <= frame_data(7 downto 0); elsif tx_packet_state = SET_CHECKSUM_INITIAL_VALUE_TX_PACKET then checksum_initial_value(7 downto 0) <= slv(tx_total_packet_length_checksum(7 downto 0)); end if; if tx_packet_state = SET_CHECKSUM_START_VAL_MSB then checksum_initial_value(15 downto 8) <= frame_data(7 downto 0); elsif tx_packet_state = SET_CHECKSUM_INITIAL_VALUE_TX_PACKET then checksum_initial_value(11 downto 8) <= slv(tx_total_packet_length_checksum(11 downto 8)); checksum_initial_value(15 downto 12) <= X"0"; end if; if tx_packet_state = TRIGGER_CHECKSUM_LOAD_INITIAL_VALUE then checksum_set_initial_value <= '1'; else checksum_set_initial_value <= '0'; end if; if tx_packet_state = INIT_LOAD_TX_PACKET_DATA then tx_packet_data_counter <= tx_bytes_to_send - 1; else tx_packet_data_counter <= tx_packet_data_counter - 1; end if; end if; end process; calc_checksum <= '1' when tx_packet_state = TRIG_CHECKSUM_CALC else '0'; checksum_calc_mod : checksum_calc Port Map ( CLK_IN => CLK_IN, RST_IN => '0', CHECKSUM_CALC_IN => calc_checksum, START_ADDR_IN => checksum_start_addr, COUNT_IN => slv(checksum_count), VALUE_IN => tx_packet_rd_data2, VALUE_ADDR_OUT => checksum_addr, CHECKSUM_INIT_IN => checksum_initial_value, CHECKSUM_SET_INIT_IN => checksum_set_initial_value, CHECKSUM_ODD_LENGTH_IN => checksum_odd_length, CHECKSUM_OUT => checksum, CHECKSUM_DONE_OUT => checksum_calc_done); ------------------- PACKET DEFINITION ------------------------ Packet_Definition_Mod : Packet_Definition Port Map ( clka => CLK_IN, addra => packet_definition_addr, douta => packet_definition_data); ------------------------- SPI -------------------------------- spi_mod_inst : spi_mod Port Map ( CLK_IN => CLK_IN, RST_IN => '0', WR_CONTINUOUS_IN => spi_wr_continuous, WE_IN => spi_we, WR_ADDR_IN => spi_wr_addr, WR_DATA_IN => spi_wr_data, WR_DATA_CMPLT_OUT => spi_wr_cmplt, RD_CONTINUOUS_IN => spi_rd_continuous, RD_IN => spi_rd, RD_WIDTH_IN => spi_rd_width, RD_ADDR_IN => spi_rd_addr, RD_DATA_OUT => spi_data_rd, RD_DATA_CMPLT_OUT => spi_rd_cmplt, SLOW_CS_EN_IN => slow_cs_en, OPER_CMPLT_POST_CS_OUT => spi_oper_cmplt, SDI_OUT => SDI_OUT, SDO_IN => SDO_IN, SCLK_OUT => SCLK_OUT, CS_OUT => CS_OUT); ------------------------- LFSR ------------------------------- lfsr32_mod_inst : lfsr32_mod Port Map ( CLK_IN => CLK_IN, SEED_IN => X"00000000", SEED_EN_IN => '0', VAL_OUT => lfsr_val); --------------------- TCP RX DATA ---------------------------- TCP_CONNECTION_ACTIVE_OUT <= tcp_connection_active; tcp_data_rd_en <= TCP_RD_DATA_EN_IN; TCP_RD_DATA_AVAIL_OUT <= not(tcp_rd_data_available); TCP_RD_DATA_OUT <= tcp_rx_data_rd_data; tcp_rx_data_we <= '1' when (packet_handler_next_state = READ_TCP_RX_DATA) else '0'; TCP_RX_FIFO : TCP_FIFO PORT MAP ( clk => CLK_IN, din => rx_packet_rd_data, wr_en => tcp_rx_data_we, rd_en => tcp_data_rd_en, dout => tcp_rx_data_rd_data, full => open, almost_full => open, empty => tcp_rd_data_available, data_count => tcp_rd_data_count); --------------------- TCP TX DATA ---------------------------- TCP_WR_DATA_POSSIBLE_OUT <= tcp_wr_data_possible; tcp_wr_data_possible <= '1' when tcp_wr_data_count < X"FA0" else '0'; tcp_wr_data_en <= TCP_WR_DATA_EN_IN; tcp_wr_data <= TCP_WR_DATA_IN; tcp_wr_data_flush <= TCP_WR_DATA_FLUSH_IN; tcp_tx_data_rd <= '1' when (tx_packet_state = LOAD_TX_PACKET_DATA) or (tx_packet_state = INIT_LOAD_TX_PACKET_DATA) else '0'; -- TODO or previous state = LOAD_TX_PACKET_DATA TCP_TX_FIFO : TCP_FIFO PORT MAP ( clk => CLK_IN, din => tcp_wr_data, wr_en => tcp_wr_data_en, rd_en => tcp_tx_data_rd, dout => tcp_tx_data, full => open, almost_full => open, empty => open, data_count => tcp_wr_data_count); --- Network Stats --- -- process(CLK_IN) -- begin -- if rising_edge(CLK_IN) then -- clk_1hz_prev <= clk_1hz; -- if clk_1hz_prev = '0' and clk_1hz = '1' then -- rx_kbytes_sec <= rx_bytes_counter(21 downto 10); -- end if; -- if clk_1hz_prev = '0' and clk_1hz = '1' then -- rx_bytes_counter <= (others => '0'); -- elsif packet_handler_state = CHECK_TCP_PSH_ACK_PACKET2 then -- rx_bytes_counter <= rx_bytes_counter + RESIZE(total_packet_length, 22); -- end if; -- end if; -- end process; --- DATA I/O --- -- process(CLK_IN) -- begin -- if rising_edge(CLK_IN) then -- if ADDR_IN = X"00" then -- DATA_OUT <= "0000000" & network_interface_enabled; -- elsif ADDR_IN = X"01" then -- DATA_OUT <= mac_addr(47 downto 40); -- elsif ADDR_IN = X"02" then -- DATA_OUT <= mac_addr(39 downto 32); -- elsif ADDR_IN = X"03" then -- DATA_OUT <= mac_addr(31 downto 24); -- elsif ADDR_IN = X"04" then -- DATA_OUT <= mac_addr(23 downto 16); -- elsif ADDR_IN = X"05" then -- DATA_OUT <= mac_addr(15 downto 8); -- elsif ADDR_IN = X"06" then -- DATA_OUT <= mac_addr(7 downto 0); -- elsif ADDR_IN = X"07" then -- DATA_OUT <= "0000000" & dhcp_enable; -- elsif ADDR_IN = X"08" then -- DATA_OUT <= "000000" & static_addr_locked & dhcp_addr_locked; -- elsif ADDR_IN = X"09" then -- DATA_OUT <= ip_addr(31 downto 24); -- elsif ADDR_IN = X"0A" then -- DATA_OUT <= ip_addr(23 downto 16); -- elsif ADDR_IN = X"0B" then -- DATA_OUT <= ip_addr(15 downto 8); -- elsif ADDR_IN = X"0C" then -- DATA_OUT <= ip_addr(7 downto 0); -- elsif ADDR_IN = X"0D" then -- DATA_OUT <= cloud_ip_addr(31 downto 24); -- elsif ADDR_IN = X"0E" then -- DATA_OUT <= cloud_ip_addr(23 downto 16); -- elsif ADDR_IN = X"0F" then -- DATA_OUT <= cloud_ip_addr(15 downto 8); -- elsif ADDR_IN = X"10" then -- DATA_OUT <= cloud_ip_addr(7 downto 0); -- elsif ADDR_IN = X"11" then -- DATA_OUT <= "0000000" & tcp_connection_active; -- end if; -- end if; -- end process; end Behavioral;