OpenCores
URL https://opencores.org/ocsvn/udp_ip_stack/udp_ip_stack/trunk

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [rtl/] [vhdl/] [IPv4_TX.vhd] - Diff between revs 2 and 4

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 4
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- Company: 
-- Company: 
-- Engineer:            Peter Fall
-- Engineer:            Peter Fall
-- 
-- 
-- Create Date:    16:20:42 06/01/2011 
-- Create Date:    16:20:42 06/01/2011 
-- Design Name: 
-- Design Name: 
-- Module Name:    IPv4_TX - Behavioral 
-- Module Name:    IPv4_TX - Behavioral 
-- Project Name: 
-- Project Name: 
-- Target Devices: 
-- Target Devices: 
-- Tool versions: 
-- Tool versions: 
-- Description: 
-- Description: 
--              handle simple IP TX
--              handle simple IP TX
--              doesnt handle segmentation
--              doesnt handle segmentation
--              dest MAC addr resolution through ARP layer
--              dest MAC addr resolution through ARP layer
--              Handle IPv4 protocol
--              Handle IPv4 protocol
-- Dependencies: 
-- Dependencies: 
--
--
-- Revision: 
-- Revision: 
-- Revision 0.01 - File Created
-- Revision 0.01 - File Created
-- Revision 0.02 - fixed up setting of tx_result control defaults
-- Revision 0.02 - fixed up setting of tx_result control defaults
 
-- Revision 0.03 - Added data_out_first
-- Additional Comments: 
-- Additional Comments: 
--
--
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.axi.all;
use work.axi.all;
use work.ipv4_types.all;
use work.ipv4_types.all;
use work.arp_types.all;
use work.arp_types.all;
 
 
entity IPv4_TX is
entity IPv4_TX is
    Port (
    Port (
                        -- IP Layer signals
                        -- IP Layer signals
                        ip_tx_start                             : in std_logic;
                        ip_tx_start                             : in std_logic;
                        ip_tx                                           : in ipv4_tx_type;                                                              -- IP tx cxns
                        ip_tx                                           : in ipv4_tx_type;                                                              -- IP tx cxns
                        ip_tx_result                    : out std_logic_vector (1 downto 0);             -- tx status (changes during transmission)
                        ip_tx_result                    : out std_logic_vector (1 downto 0);             -- tx status (changes during transmission)
                        ip_tx_data_out_ready    : out std_logic;                                                                        -- indicates IP TX is ready to take data
                        ip_tx_data_out_ready    : out std_logic;                                                                        -- indicates IP TX is ready to take data
 
 
                        -- system signals
                        -- system signals
                        clk                                             : in  STD_LOGIC;                                                                        -- same clock used to clock mac data and ip data
                        clk                                             : in  STD_LOGIC;                                                                        -- same clock used to clock mac data and ip data
                        reset                                   : in  STD_LOGIC;
                        reset                                   : in  STD_LOGIC;
                        our_ip_address          : in STD_LOGIC_VECTOR (31 downto 0);
                        our_ip_address          : in STD_LOGIC_VECTOR (31 downto 0);
                        our_mac_address                 : in std_logic_vector (47 downto 0);
                        our_mac_address                 : in std_logic_vector (47 downto 0);
                        -- ARP lookup signals
                        -- ARP lookup signals
                        arp_req_req                             : out arp_req_req_type;
                        arp_req_req                             : out arp_req_req_type;
                        arp_req_rslt                    : in arp_req_rslt_type;
                        arp_req_rslt                    : in arp_req_rslt_type;
                        -- MAC layer TX signals
                        -- MAC layer TX signals
                        mac_tx_req                              : out std_logic;                                                                        -- indicates that ip wants access to channel (stays up for as long as tx)
                        mac_tx_req                              : out std_logic;                                                                        -- indicates that ip wants access to channel (stays up for as long as tx)
                        mac_tx_granted                  : in std_logic;                                                                 -- indicates that access to channel has been granted            
                        mac_tx_granted                  : in std_logic;                                                                 -- indicates that access to channel has been granted            
                        mac_data_out_ready      : in std_logic;                                                                 -- indicates system ready to consume data
                        mac_data_out_ready      : in std_logic;                                                                 -- indicates system ready to consume data
                        mac_data_out_valid      : out std_logic;                                                                -- indicates data out is valid
                        mac_data_out_valid      : out std_logic;                                                                -- indicates data out is valid
 
                        mac_data_out_first      : out std_logic;                                                                        -- with data out valid indicates the first byte of a frame
                        mac_data_out_last               : out std_logic;                                                                        -- with data out valid indicates the last byte of a frame
                        mac_data_out_last               : out std_logic;                                                                        -- with data out valid indicates the last byte of a frame
                        mac_data_out                    : out std_logic_vector (7 downto 0)              -- ethernet frame (from dst mac addr through to last byte of frame)      
                        mac_data_out                    : out std_logic_vector (7 downto 0)              -- ethernet frame (from dst mac addr through to last byte of frame)      
                        );
                        );
end IPv4_TX;
end IPv4_TX;
 
 
architecture Behavioral of IPv4_TX is
architecture Behavioral of IPv4_TX is
 
 
        type tx_state_type is (
        type tx_state_type is (
                        IDLE,
                        IDLE,
                        WAIT_MAC,                               -- waiting for response from ARP for mac lookup
                        WAIT_MAC,                               -- waiting for response from ARP for mac lookup
                        WAIT_CHN,                               -- waiting for tx access to MAC channel
                        WAIT_CHN,                               -- waiting for tx access to MAC channel
                        SEND_ETH_HDR,                   -- sending the ethernet header
                        SEND_ETH_HDR,                   -- sending the ethernet header
                        SEND_IP_HDR,                    -- sending the IP header
                        SEND_IP_HDR,                    -- sending the IP header
                        SEND_USER_DATA                  -- sending the users data
                        SEND_USER_DATA                  -- sending the users data
                        );
                        );
 
 
        type crc_state_type is (IDLE,TOT_LEN,ID,FLAGS,TTL,CKS,SAH,SAL,DAH,DAL,FINAL,WAIT_END);
        type crc_state_type is (IDLE,TOT_LEN,ID,FLAGS,TTL,CKS,SAH,SAL,DAH,DAL,FINAL,WAIT_END);
 
 
        type count_mode_type is (RST, INCR, HOLD);
        type count_mode_type is (RST, INCR, HOLD);
        type settable_cnt_type is (RST, SET, INCR, HOLD);
        type settable_cnt_type is (RST, SET, INCR, HOLD);
        type set_clr_type is (SET, CLR, HOLD);
        type set_clr_type is (SET, CLR, HOLD);
 
 
        -- Configuration
        -- Configuration
 
 
        constant IP_TTL                 : std_logic_vector (7 downto 0) := x"80";
        constant IP_TTL                 : std_logic_vector (7 downto 0) := x"80";
 
 
        -- TX state variables
        -- TX state variables
        signal tx_state                 : tx_state_type;
        signal tx_state                 : tx_state_type;
        signal tx_count                         : unsigned (11 downto 0);
        signal tx_count                         : unsigned (11 downto 0);
        signal tx_result_reg            : std_logic_vector (1 downto 0);
        signal tx_result_reg            : std_logic_vector (1 downto 0);
        signal tx_mac                           : std_logic_vector (47 downto 0);
        signal tx_mac                           : std_logic_vector (47 downto 0);
        signal tx_mac_chn_reqd  : std_logic;
        signal tx_mac_chn_reqd  : std_logic;
        signal tx_hdr_cks                       : std_logic_vector (23 downto 0);
        signal tx_hdr_cks                       : std_logic_vector (23 downto 0);
        signal mac_lookup_req   : std_logic;
        signal mac_lookup_req   : std_logic;
        signal crc_state                        : crc_state_type;
        signal crc_state                        : crc_state_type;
        signal arp_req_ip_reg   : std_logic_vector (31 downto 0);
        signal arp_req_ip_reg   : std_logic_vector (31 downto 0);
        signal mac_data_out_ready_reg   : std_logic;
        signal mac_data_out_ready_reg   : std_logic;
 
 
        -- tx control signals
        -- tx control signals
        signal next_tx_state    : tx_state_type;
        signal next_tx_state    : tx_state_type;
        signal set_tx_state             : std_logic;
        signal set_tx_state             : std_logic;
        signal next_tx_result   : std_logic_vector (1 downto 0);
        signal next_tx_result   : std_logic_vector (1 downto 0);
        signal set_tx_result            : std_logic;
        signal set_tx_result            : std_logic;
        signal set_tx_mac                       : std_logic;
        signal set_tx_mac                       : std_logic;
        signal tx_count_val             : unsigned (11 downto 0);
        signal tx_count_val             : unsigned (11 downto 0);
        signal tx_count_mode            : settable_cnt_type;
        signal tx_count_mode            : settable_cnt_type;
        signal tx_data                          : std_logic_vector (7 downto 0);
        signal tx_data                          : std_logic_vector (7 downto 0);
        signal set_last                 : std_logic;
        signal set_last                 : std_logic;
        signal set_chn_reqd             : set_clr_type;
        signal set_chn_reqd             : set_clr_type;
        signal set_mac_lku_req  : set_clr_type;
        signal set_mac_lku_req  : set_clr_type;
        signal tx_data_valid            : std_logic;                    -- indicates whether data is valid to tx or not
        signal tx_data_valid            : std_logic;                    -- indicates whether data is valid to tx or not
 
 
        -- tx temp signals
        -- tx temp signals
        signal total_length             : std_logic_vector (15 downto 0);        -- computed combinatorially from header size
        signal total_length             : std_logic_vector (15 downto 0);        -- computed combinatorially from header size
 
 
 
 
        FUNCTION inv_if_one(s1:std_logic_vector;en:std_logic) return std_logic_vector is
        FUNCTION inv_if_one(s1:std_logic_vector;en:std_logic) return std_logic_vector is
                  --this function inverts all the bits of a vector if
                  --this function inverts all the bits of a vector if
                  --'en' is '1'.
                  --'en' is '1'.
        VARIABLE Z : std_logic_vector(s1'high downto s1'low);
        VARIABLE Z : std_logic_vector(s1'high downto s1'low);
        BEGIN
        BEGIN
        FOR i IN (s1'low) to s1'high LOOP
        FOR i IN (s1'low) to s1'high LOOP
            Z(i) := en XOR s1(i);
            Z(i) := en XOR s1(i);
        END LOOP;
        END LOOP;
        RETURN Z;
        RETURN Z;
        END inv_if_one; -- end function
        END inv_if_one; -- end function
 
 
 
 
-- IP datagram header format
-- IP datagram header format
--
--
--      0          4          8                      16      19             24                    31
--      0          4          8                      16      19             24                    31
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      | Version  | *Header  |    Service Type      |        Total Length including header        |
--      | Version  | *Header  |    Service Type      |        Total Length including header        |
--      |   (4)    |  Length  |     (ignored)        |                 (in bytes)                  |
--      |   (4)    |  Length  |     (ignored)        |                 (in bytes)                  |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      |           Identification                   | Flags |       Fragment Offset               |
--      |           Identification                   | Flags |       Fragment Offset               |
--      |                                            |       |      (in 32 bit words)              |
--      |                                            |       |      (in 32 bit words)              |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      |    Time To Live     |       Protocol       |             Header Checksum                 |
--      |    Time To Live     |       Protocol       |             Header Checksum                 |
--      |     (ignored)       |                      |                                             |
--      |     (ignored)       |                      |                                             |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      |                                   Source IP Address                                      |
--      |                                   Source IP Address                                      |
--      |                                                                                          |
--      |                                                                                          |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      |                                 Destination IP Address                                   |
--      |                                 Destination IP Address                                   |
--      |                                                                                          |
--      |                                                                                          |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      |                          Options (if any - ignored)               |       Padding        |
--      |                          Options (if any - ignored)               |       Padding        |
--      |                                                                   |      (if needed)     |
--      |                                                                   |      (if needed)     |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      |                                          Data                                            |
--      |                                          Data                                            |
--      |                                                                                          |
--      |                                                                                          |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--      |                                          ....                                            |
--      |                                          ....                                            |
--      |                                                                                          |
--      |                                                                                          |
--      --------------------------------------------------------------------------------------------
--      --------------------------------------------------------------------------------------------
--
--
-- * - in 32 bit words 
-- * - in 32 bit words 
 
 
begin
begin
        -----------------------------------------------------------------------
        -----------------------------------------------------------------------
        -- combinatorial process to implement FSM and determine control signals
        -- combinatorial process to implement FSM and determine control signals
        -----------------------------------------------------------------------
        -----------------------------------------------------------------------
 
 
        tx_combinatorial : process(
        tx_combinatorial : process(
                -- input signals
                -- input signals
                ip_tx_start, ip_tx, clk, our_ip_address, our_mac_address, arp_req_rslt,
                ip_tx_start, ip_tx, clk, our_ip_address, our_mac_address, arp_req_rslt,
                mac_tx_granted, mac_data_out_ready,
                mac_tx_granted, mac_data_out_ready,
                -- state variables
                -- state variables
                tx_state, tx_count, tx_result_reg, tx_mac, tx_mac_chn_reqd,
                tx_state, tx_count, tx_result_reg, tx_mac, tx_mac_chn_reqd,
                mac_lookup_req, tx_hdr_cks, arp_req_ip_reg, mac_data_out_ready_reg,
                mac_lookup_req, tx_hdr_cks, arp_req_ip_reg, mac_data_out_ready_reg,
                -- control signals
                -- control signals
                next_tx_state, set_tx_state, next_tx_result, set_tx_result, set_tx_mac, tx_count_mode,
                next_tx_state, set_tx_state, next_tx_result, set_tx_result, set_tx_mac, tx_count_mode,
                tx_data, set_last, set_chn_reqd, set_mac_lku_req, total_length,
                tx_data, set_last, set_chn_reqd, set_mac_lku_req, total_length,
                tx_data_valid, tx_count_val
                tx_data_valid, tx_count_val
                )
                )
        begin
        begin
                -- set output followers
                -- set output followers
                ip_tx_result <= tx_result_reg;
                ip_tx_result <= tx_result_reg;
                mac_tx_req <= tx_mac_chn_reqd;
                mac_tx_req <= tx_mac_chn_reqd;
                arp_req_req.lookup_req <= mac_lookup_req;
                arp_req_req.lookup_req <= mac_lookup_req;
                arp_req_req.ip <= arp_req_ip_reg;
                arp_req_req.ip <= arp_req_ip_reg;
 
 
 
                -- set initial values for combinatorial outputs
 
                mac_data_out_first <= '0';
 
 
                case tx_state is
                case tx_state is
                        when SEND_ETH_HDR | SEND_IP_HDR =>
                        when SEND_ETH_HDR | SEND_IP_HDR =>
                                mac_data_out <= tx_data;
                                mac_data_out <= tx_data;
                                tx_data_valid <= mac_data_out_ready;    -- generated internally
                                tx_data_valid <= mac_data_out_ready;    -- generated internally
                                mac_data_out_last <= set_last;
                                mac_data_out_last <= set_last;
 
 
                        when SEND_USER_DATA =>
                        when SEND_USER_DATA =>
                                mac_data_out <= ip_tx.data.data_out;
                                mac_data_out <= ip_tx.data.data_out;
                                tx_data_valid <= ip_tx.data.data_out_valid;
                                tx_data_valid <= ip_tx.data.data_out_valid;
                                mac_data_out_last <= ip_tx.data.data_out_last;
                                mac_data_out_last <= ip_tx.data.data_out_last;
 
 
                        when others =>
                        when others =>
                                mac_data_out <= (others => '0');
                                mac_data_out <= (others => '0');
                                tx_data_valid <= '0';                                            -- not transmitting during this phase
                                tx_data_valid <= '0';                                            -- not transmitting during this phase
                                mac_data_out_last <= '0';
                                mac_data_out_last <= '0';
                end case;
                end case;
 
 
                mac_data_out_valid <= tx_data_valid and mac_data_out_ready;
                mac_data_out_valid <= tx_data_valid and mac_data_out_ready;
 
 
                -- set signal defaults
                -- set signal defaults
                next_tx_state <= IDLE;
                next_tx_state <= IDLE;
                set_tx_state <= '0';
                set_tx_state <= '0';
                tx_count_mode <= HOLD;
                tx_count_mode <= HOLD;
                tx_data <= x"00";
                tx_data <= x"00";
                set_last <= '0';
                set_last <= '0';
                set_tx_mac <= '0';
                set_tx_mac <= '0';
                set_chn_reqd <= HOLD;
                set_chn_reqd <= HOLD;
                set_mac_lku_req <= HOLD;
                set_mac_lku_req <= HOLD;
                next_tx_result <= IPTX_RESULT_NONE;
                next_tx_result <= IPTX_RESULT_NONE;
                set_tx_result <= '0';
                set_tx_result <= '0';
                tx_count_val <= (others => '0');
                tx_count_val <= (others => '0');
 
 
                -- set temp signals
                -- set temp signals
                total_length <= std_logic_vector(unsigned(ip_tx.hdr.data_length) + 20);         -- total length = user data length + header length (bytes)
                total_length <= std_logic_vector(unsigned(ip_tx.hdr.data_length) + 20);         -- total length = user data length + header length (bytes)
 
 
                -- TX FSM
                -- TX FSM
                case tx_state is
                case tx_state is
                        when IDLE =>
                        when IDLE =>
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                tx_count_mode <= RST;
                                tx_count_mode <= RST;
                                set_chn_reqd <= CLR;
                                set_chn_reqd <= CLR;
                                if ip_tx_start = '1' then
                                if ip_tx_start = '1' then
                                        -- check header count for error if too high
                                        -- check header count for error if too high
                                        if unsigned(ip_tx.hdr.data_length) > 1480 then
                                        if unsigned(ip_tx.hdr.data_length) > 1480 then
                                                next_tx_result <= IPTX_RESULT_ERR;
                                                next_tx_result <= IPTX_RESULT_ERR;
                                                set_tx_result <= '1';
                                                set_tx_result <= '1';
                                        else
                                        else
                                                -- TODO - check if we already have the mac addr for this ip, if so, bypass the WAIT_MAC state
                                                -- TODO - check if we already have the mac addr for this ip, if so, bypass the WAIT_MAC state
 
 
                                                -- req the mac address for this ip
                                                -- req the mac address for this ip
                                                set_mac_lku_req <= SET;
                                                set_mac_lku_req <= SET;
                                                next_tx_result <= IPTX_RESULT_SENDING;
                                                next_tx_result <= IPTX_RESULT_SENDING;
                                                set_tx_result <= '1';
                                                set_tx_result <= '1';
                                                next_tx_state <= WAIT_MAC;
                                                next_tx_state <= WAIT_MAC;
                                                set_tx_state <= '1';
                                                set_tx_state <= '1';
                                        end if;
                                        end if;
                                else
                                else
                                        set_mac_lku_req <= CLR;
                                        set_mac_lku_req <= CLR;
                                end if;
                                end if;
 
 
                        when WAIT_MAC =>
                        when WAIT_MAC =>
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                if arp_req_rslt.got_mac = '1' then
                                if arp_req_rslt.got_mac = '1' then
                                        -- save the MAC we got back from the ARP lookup
                                        -- save the MAC we got back from the ARP lookup
                                        set_tx_mac <= '1';
                                        set_tx_mac <= '1';
                                        set_chn_reqd <= SET;
                                        set_chn_reqd <= SET;
                                        set_mac_lku_req <= CLR;
                                        set_mac_lku_req <= CLR;
                                        -- check for optimise when already have the channel
                                        -- check for optimise when already have the channel
                                        if mac_tx_granted = '1' then
                                        if mac_tx_granted = '1' then
                                                -- ready to send data
                                                -- ready to send data
                                                next_tx_state <= SEND_ETH_HDR;
                                                next_tx_state <= SEND_ETH_HDR;
                                                set_tx_state <= '1';
                                                set_tx_state <= '1';
                                        else
                                        else
                                                next_tx_state <= WAIT_CHN;
                                                next_tx_state <= WAIT_CHN;
                                                set_tx_state <= '1';
                                                set_tx_state <= '1';
                                        end if;
                                        end if;
                                elsif arp_req_rslt.got_err = '1' then
                                elsif arp_req_rslt.got_err = '1' then
                                        set_mac_lku_req <= CLR;
                                        set_mac_lku_req <= CLR;
                                        next_tx_result <= IPTX_RESULT_ERR;
                                        next_tx_result <= IPTX_RESULT_ERR;
                                        set_tx_result <= '1';
                                        set_tx_result <= '1';
                                        next_tx_state <= IDLE;
                                        next_tx_state <= IDLE;
                                        set_tx_state <= '1';
                                        set_tx_state <= '1';
                                end if;
                                end if;
 
 
                        when WAIT_CHN =>
                        when WAIT_CHN =>
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                if mac_tx_granted = '1' then
                                if mac_tx_granted = '1' then
                                        -- ready to send data
                                        -- ready to send data
                                        next_tx_state <= SEND_ETH_HDR;
                                        next_tx_state <= SEND_ETH_HDR;
                                        set_tx_state <= '1';
                                        set_tx_state <= '1';
                                end if;
                                end if;
                                -- probably should handle a timeout here
                                -- probably should handle a timeout here
 
 
                        when SEND_ETH_HDR =>
                        when SEND_ETH_HDR =>
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                if mac_data_out_ready = '1' then
                                if mac_data_out_ready = '1' then
                                        if tx_count = x"00d" then
                                        if tx_count = x"00d" then
                                                tx_count_mode <= RST;
                                                tx_count_mode <= RST;
                                                next_tx_state <= SEND_IP_HDR;
                                                next_tx_state <= SEND_IP_HDR;
                                                set_tx_state <= '1';
                                                set_tx_state <= '1';
                                        else
                                        else
                                                tx_count_mode <= INCR;
                                                tx_count_mode <= INCR;
                                        end if;
                                        end if;
                                        case tx_count is
                                        case tx_count is
                                                when x"000"  => tx_data <= tx_mac (47 downto 40);                       -- trg = mac from ARP lookup
                                                when x"000"  =>
 
                                                        mac_data_out_first <= mac_data_out_ready;
 
                                                        tx_data <= tx_mac (47 downto 40);                       -- trg = mac from ARP lookup                                            
 
 
                                                when x"001"  => tx_data <= tx_mac (39 downto 32);
                                                when x"001"  => tx_data <= tx_mac (39 downto 32);
                                                when x"002"  => tx_data <= tx_mac (31 downto 24);
                                                when x"002"  => tx_data <= tx_mac (31 downto 24);
                                                when x"003"  => tx_data <= tx_mac (23 downto 16);
                                                when x"003"  => tx_data <= tx_mac (23 downto 16);
                                                when x"004"  => tx_data <= tx_mac (15 downto 8);
                                                when x"004"  => tx_data <= tx_mac (15 downto 8);
                                                when x"005"  => tx_data <= tx_mac (7 downto 0);
                                                when x"005"  => tx_data <= tx_mac (7 downto 0);
                                                when x"006"  => tx_data <= our_mac_address (47 downto 40);      -- src = our mac
                                                when x"006"  => tx_data <= our_mac_address (47 downto 40);      -- src = our mac
                                                when x"007"  => tx_data <= our_mac_address (39 downto 32);
                                                when x"007"  => tx_data <= our_mac_address (39 downto 32);
                                                when x"008"  => tx_data <= our_mac_address (31 downto 24);
                                                when x"008"  => tx_data <= our_mac_address (31 downto 24);
                                                when x"009"  => tx_data <= our_mac_address (23 downto 16);
                                                when x"009"  => tx_data <= our_mac_address (23 downto 16);
                                                when x"00a"  => tx_data <= our_mac_address (15 downto 8);
                                                when x"00a"  => tx_data <= our_mac_address (15 downto 8);
                                                when x"00b"  => tx_data <= our_mac_address (7 downto 0);
                                                when x"00b"  => tx_data <= our_mac_address (7 downto 0);
                                                when x"00c"  => tx_data <= x"08";                                                                       -- pkt type = 0800 : IP                                         
                                                when x"00c"  => tx_data <= x"08";                                                                       -- pkt type = 0800 : IP                                         
                                                when x"00d"  => tx_data <= x"00";
                                                when x"00d"  => tx_data <= x"00";
                                                when others =>
                                                when others =>
                                                        -- shouldnt get here - handle as error
                                                        -- shouldnt get here - handle as error
                                                        next_tx_result <= IPTX_RESULT_ERR;
                                                        next_tx_result <= IPTX_RESULT_ERR;
                                                        set_tx_result <= '1';
                                                        set_tx_result <= '1';
                                                        next_tx_state <= IDLE;
                                                        next_tx_state <= IDLE;
                                                        set_tx_state <= '1';
                                                        set_tx_state <= '1';
                                        end case;
                                        end case;
                                end if;
                                end if;
 
 
                        when SEND_IP_HDR =>
                        when SEND_IP_HDR =>
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                ip_tx_data_out_ready <= '0';             -- in this state, we are unable to accept user data for tx
                                if mac_data_out_ready    = '1' then
                                if mac_data_out_ready    = '1' then
                                        if tx_count = x"013" then
                                        if tx_count = x"013" then
                                                tx_count_val <= x"001";
                                                tx_count_val <= x"001";
                                                tx_count_mode <= SET;
                                                tx_count_mode <= SET;
                                                next_tx_state <= SEND_USER_DATA;
                                                next_tx_state <= SEND_USER_DATA;
                                                set_tx_state <= '1';
                                                set_tx_state <= '1';
                                        else
                                        else
                                                tx_count_mode <= INCR;
                                                tx_count_mode <= INCR;
                                        end if;
                                        end if;
                                        case tx_count is
                                        case tx_count is
                                                when x"000"  => tx_data <= x"45";                                                                       -- v4, 5 words in hdr
                                                when x"000"  => tx_data <= x"45";                                                                       -- v4, 5 words in hdr
                                                when x"001"  => tx_data <= x"00";                                                                       -- service type
                                                when x"001"  => tx_data <= x"00";                                                                       -- service type
                                                when x"002"  => tx_data <= total_length (15 downto 8);          -- total length
                                                when x"002"  => tx_data <= total_length (15 downto 8);          -- total length
                                                when x"003"  => tx_data <= total_length (7 downto 0);
                                                when x"003"  => tx_data <= total_length (7 downto 0);
                                                when x"004"  => tx_data <= x"00";                                                                       -- identification
                                                when x"004"  => tx_data <= x"00";                                                                       -- identification
                                                when x"005"  => tx_data <= x"00";
                                                when x"005"  => tx_data <= x"00";
                                                when x"006"  => tx_data <= x"00";                                                                       -- flags and fragment offset
                                                when x"006"  => tx_data <= x"00";                                                                       -- flags and fragment offset
                                                when x"007"  => tx_data <= x"00";
                                                when x"007"  => tx_data <= x"00";
                                                when x"008"  => tx_data <= IP_TTL;                                                                      -- TTL
                                                when x"008"  => tx_data <= IP_TTL;                                                                      -- TTL
                                                when x"009"  => tx_data <= ip_tx.hdr.protocol;                                  -- protocol
                                                when x"009"  => tx_data <= ip_tx.hdr.protocol;                                  -- protocol
                                                when x"00a"  => tx_data <= tx_hdr_cks (15 downto 8);                    -- HDR checksum
                                                when x"00a"  => tx_data <= tx_hdr_cks (15 downto 8);                    -- HDR checksum
                                                when x"00b"  => tx_data <= tx_hdr_cks (7 downto 0);                      -- HDR checksum
                                                when x"00b"  => tx_data <= tx_hdr_cks (7 downto 0);                      -- HDR checksum
                                                when x"00c" => tx_data <= our_ip_address (31 downto 24);                -- src ip
                                                when x"00c" => tx_data <= our_ip_address (31 downto 24);                -- src ip
                                                when x"00d" => tx_data <= our_ip_address (23 downto 16);
                                                when x"00d" => tx_data <= our_ip_address (23 downto 16);
                                                when x"00e" => tx_data <= our_ip_address (15 downto 8);
                                                when x"00e" => tx_data <= our_ip_address (15 downto 8);
                                                when x"00f" => tx_data <= our_ip_address (7 downto 0);
                                                when x"00f" => tx_data <= our_ip_address (7 downto 0);
                                                when x"010" => tx_data <= ip_tx.hdr.dst_ip_addr (31 downto 24); -- dst ip
                                                when x"010" => tx_data <= ip_tx.hdr.dst_ip_addr (31 downto 24); -- dst ip
                                                when x"011" => tx_data <= ip_tx.hdr.dst_ip_addr (23 downto 16);
                                                when x"011" => tx_data <= ip_tx.hdr.dst_ip_addr (23 downto 16);
                                                when x"012" => tx_data <= ip_tx.hdr.dst_ip_addr (15 downto 8);
                                                when x"012" => tx_data <= ip_tx.hdr.dst_ip_addr (15 downto 8);
                                                when x"013" => tx_data <= ip_tx.hdr.dst_ip_addr (7 downto 0);
                                                when x"013" => tx_data <= ip_tx.hdr.dst_ip_addr (7 downto 0);
                                                when others =>
                                                when others =>
                                                        -- shouldnt get here - handle as error
                                                        -- shouldnt get here - handle as error
                                                        next_tx_result <= IPTX_RESULT_ERR;
                                                        next_tx_result <= IPTX_RESULT_ERR;
                                                        set_tx_result <= '1';
                                                        set_tx_result <= '1';
                                                        next_tx_state <= IDLE;
                                                        next_tx_state <= IDLE;
                                                        set_tx_state <= '1';
                                                        set_tx_state <= '1';
                                        end case;
                                        end case;
                                end if;
                                end if;
 
 
                        when SEND_USER_DATA =>
                        when SEND_USER_DATA =>
                                ip_tx_data_out_ready <= mac_data_out_ready and mac_data_out_ready_reg;          -- in this state, we are always ready to accept user data for tx
                                ip_tx_data_out_ready <= mac_data_out_ready and mac_data_out_ready_reg;          -- in this state, we are always ready to accept user data for tx
                                if mac_data_out_ready = '1' then
                                if mac_data_out_ready = '1' then
                                        if ip_tx.data.data_out_valid = '1' or tx_count = x"000" then
                                        if ip_tx.data.data_out_valid = '1' or tx_count = x"000" then
                                                -- only increment if ready and valid has been subsequently established, otherwise data count moves on too fast
                                                -- only increment if ready and valid has been subsequently established, otherwise data count moves on too fast
                                                if unsigned(tx_count) = unsigned(ip_tx.hdr.data_length) then
                                                if unsigned(tx_count) = unsigned(ip_tx.hdr.data_length) then
                                                        set_last <= '1';
                                                        set_last <= '1';
                                                        set_chn_reqd <= CLR;
                                                        set_chn_reqd <= CLR;
                                                        tx_data <= ip_tx.data.data_out;
                                                        tx_data <= ip_tx.data.data_out;
                                                        next_tx_result <= IPTX_RESULT_SENT;
                                                        next_tx_result <= IPTX_RESULT_SENT;
                                                        set_tx_result <= '1';
                                                        set_tx_result <= '1';
                                                        next_tx_state <= IDLE;
                                                        next_tx_state <= IDLE;
                                                        set_tx_state <= '1';
                                                        set_tx_state <= '1';
                                                else
                                                else
                                                        tx_count_mode <= INCR;
                                                        tx_count_mode <= INCR;
                                                        tx_data <= ip_tx.data.data_out;
                                                        tx_data <= ip_tx.data.data_out;
                                                end if;
                                                end if;
                                        end if;
                                        end if;
                                end if;
                                end if;
 
 
                end case;
                end case;
        end process;
        end process;
 
 
        -----------------------------------------------------------------------------
        -----------------------------------------------------------------------------
        -- sequential process to action control signals and change states and outputs
        -- sequential process to action control signals and change states and outputs
        -----------------------------------------------------------------------------
        -----------------------------------------------------------------------------
 
 
        tx_sequential : process (clk,reset,mac_data_out_ready_reg)
        tx_sequential : process (clk,reset,mac_data_out_ready_reg)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        mac_data_out_ready_reg <= mac_data_out_ready;
                        mac_data_out_ready_reg <= mac_data_out_ready;
                else
                else
                        mac_data_out_ready_reg <= mac_data_out_ready_reg;
                        mac_data_out_ready_reg <= mac_data_out_ready_reg;
                end if;
                end if;
 
 
                if rising_edge(clk) then
                if rising_edge(clk) then
                        if reset = '1' then
                        if reset = '1' then
                                -- reset state variables
                                -- reset state variables
                                tx_state <= IDLE;
                                tx_state <= IDLE;
                                tx_count <= x"000";
                                tx_count <= x"000";
                                tx_result_reg <= IPTX_RESULT_NONE;
                                tx_result_reg <= IPTX_RESULT_NONE;
                                tx_mac <= (others => '0');
                                tx_mac <= (others => '0');
                                tx_mac_chn_reqd <= '0';
                                tx_mac_chn_reqd <= '0';
 
                                mac_lookup_req <= '0';
 
 
                        else
                        else
                                -- Next tx_state processing
                                -- Next tx_state processing
                                if set_tx_state = '1' then
                                if set_tx_state = '1' then
                                        tx_state <= next_tx_state;
                                        tx_state <= next_tx_state;
                                else
                                else
                                        tx_state <= tx_state;
                                        tx_state <= tx_state;
                                end if;
                                end if;
 
 
                                -- tx result processing
                                -- tx result processing
                                if set_tx_result = '1' then
                                if set_tx_result = '1' then
                                        tx_result_reg <= next_tx_result;
                                        tx_result_reg <= next_tx_result;
                                else
                                else
                                        tx_result_reg <= tx_result_reg;
                                        tx_result_reg <= tx_result_reg;
                                end if;
                                end if;
 
 
                                -- control arp lookup request
                                -- control arp lookup request
                                case set_mac_lku_req is
                                case set_mac_lku_req is
                                        when SET =>
                                        when SET =>
                                                arp_req_ip_reg <= ip_tx.hdr.dst_ip_addr;
                                                arp_req_ip_reg <= ip_tx.hdr.dst_ip_addr;
                                                mac_lookup_req <= '1';
                                                mac_lookup_req <= '1';
 
 
                                        when CLR =>
                                        when CLR =>
                                                mac_lookup_req <= '0';
                                                mac_lookup_req <= '0';
                                                arp_req_ip_reg <= arp_req_ip_reg;
                                                arp_req_ip_reg <= arp_req_ip_reg;
 
 
                                        when HOLD =>
                                        when HOLD =>
                                                mac_lookup_req <= mac_lookup_req;
                                                mac_lookup_req <= mac_lookup_req;
                                                arp_req_ip_reg <= arp_req_ip_reg;
                                                arp_req_ip_reg <= arp_req_ip_reg;
                                end case;
                                end case;
 
 
                                -- save MAC
                                -- save MAC
                                if set_tx_mac = '1' then
                                if set_tx_mac = '1' then
                                        tx_mac <= arp_req_rslt.mac;
                                        tx_mac <= arp_req_rslt.mac;
                                else
                                else
                                        tx_mac <= tx_mac;
                                        tx_mac <= tx_mac;
                                end if;
                                end if;
 
 
                                -- control access request to mac tx chn
                                -- control access request to mac tx chn
                                case set_chn_reqd is
                                case set_chn_reqd is
                                        when SET => tx_mac_chn_reqd <= '1';
                                        when SET => tx_mac_chn_reqd <= '1';
                                        when CLR => tx_mac_chn_reqd <= '0';
                                        when CLR => tx_mac_chn_reqd <= '0';
                                        when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
                                        when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
                                end case;
                                end case;
 
 
                                -- tx_count processing
                                -- tx_count processing
                                case tx_count_mode is
                                case tx_count_mode is
                                        when RST  =>    tx_count <= x"000";
                                        when RST  =>    tx_count <= x"000";
                                        when SET  =>    tx_count <= tx_count_val;
                                        when SET  =>    tx_count <= tx_count_val;
                                        when INCR =>    tx_count <= tx_count + 1;
                                        when INCR =>    tx_count <= tx_count + 1;
                                        when HOLD =>    tx_count <= tx_count;
                                        when HOLD =>    tx_count <= tx_count;
                                end case;
                                end case;
 
 
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
        -----------------------------------------------------------------------------
        -----------------------------------------------------------------------------
        -- Process to calculate CRC in parallel with pkt out processing
        -- Process to calculate CRC in parallel with pkt out processing
        -- this process must yield a valid CRC before it is required to be used in the hdr
        -- this process must yield a valid CRC before it is required to be used in the hdr
        -----------------------------------------------------------------------------
        -----------------------------------------------------------------------------
 
 
        crc : process (clk,reset)
        crc : process (clk,reset)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(clk) then
                        case crc_state is
                        case crc_state is
                                when IDLE =>
                                when IDLE =>
                                        if ip_tx_start = '1' then
                                        if ip_tx_start = '1' then
                                                tx_hdr_cks <= x"004500";                        -- vers & hdr len & service
                                                tx_hdr_cks <= x"004500";                        -- vers & hdr len & service
                                                crc_state <= TOT_LEN;
                                                crc_state <= TOT_LEN;
                                        end if;
                                        end if;
 
 
                                when TOT_LEN =>
                                when TOT_LEN =>
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(total_length));
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(total_length));
                                        crc_state <= ID;
                                        crc_state <= ID;
 
 
                                when ID =>
                                when ID =>
                                        tx_hdr_cks <= tx_hdr_cks;
                                        tx_hdr_cks <= tx_hdr_cks;
                                        crc_state <= FLAGS;
                                        crc_state <= FLAGS;
 
 
                                when FLAGS =>
                                when FLAGS =>
                                        tx_hdr_cks <= tx_hdr_cks;
                                        tx_hdr_cks <= tx_hdr_cks;
                                        crc_state <= TTL;
                                        crc_state <= TTL;
 
 
                                when TTL =>
                                when TTL =>
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(IP_TTL & ip_tx.hdr.protocol));
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(IP_TTL & ip_tx.hdr.protocol));
                                        crc_state <= CKS;
                                        crc_state <= CKS;
 
 
                                when CKS =>
                                when CKS =>
                                        tx_hdr_cks <= tx_hdr_cks;
                                        tx_hdr_cks <= tx_hdr_cks;
                                        crc_state <= SAH;
                                        crc_state <= SAH;
 
 
                                when SAH =>
                                when SAH =>
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(our_ip_address(31 downto 16)));
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(our_ip_address(31 downto 16)));
                                        crc_state <= SAL;
                                        crc_state <= SAL;
 
 
                                when SAL =>
                                when SAL =>
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(our_ip_address(15 downto 0)));
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(our_ip_address(15 downto 0)));
                                        crc_state <= DAH;
                                        crc_state <= DAH;
 
 
                                when DAH =>
                                when DAH =>
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(ip_tx.hdr.dst_ip_addr(31 downto 16)));
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(ip_tx.hdr.dst_ip_addr(31 downto 16)));
                                        crc_state <= DAL;
                                        crc_state <= DAL;
 
 
                                when DAL =>
                                when DAL =>
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(ip_tx.hdr.dst_ip_addr(15 downto 0)));
                                        tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(ip_tx.hdr.dst_ip_addr(15 downto 0)));
                                        crc_state <= FINAL;
                                        crc_state <= FINAL;
 
 
                                when FINAL =>
                                when FINAL =>
                                        tx_hdr_cks <= inv_if_one(std_logic_vector (unsigned(tx_hdr_cks) + unsigned(tx_hdr_cks(23 downto 16))),'1');
                                        tx_hdr_cks <= inv_if_one(std_logic_vector (unsigned(tx_hdr_cks) + unsigned(tx_hdr_cks(23 downto 16))),'1');
                                        crc_state <= WAIT_END;
                                        crc_state <= WAIT_END;
 
 
                                when WAIT_END =>
                                when WAIT_END =>
                                        tx_hdr_cks <= tx_hdr_cks;
                                        tx_hdr_cks <= tx_hdr_cks;
                                        if ip_tx_start = '0' then
                                        if ip_tx_start = '0' then
                                                crc_state <= IDLE;
                                                crc_state <= IDLE;
                                        else
                                        else
                                                crc_state <= WAIT_END;
                                                crc_state <= WAIT_END;
                                        end if;
                                        end if;
 
 
 
 
                        end case;
                        end case;
                end if;
                end if;
  end process;
  end process;
 
 
 
 
end Behavioral;
end Behavioral;
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.