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

Subversion Repositories udp_ip_stack

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /udp_ip_stack
    from Rev 24 to Rev 25
    Reverse comparison

Rev 24 → Rev 25

/tags/v2.3/rtl/vhdl/IPv4_RX.vhd
0,0 → 1,539
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 16:20:42 06/01/2011
-- Design Name:
-- Module Name: IPv4_RX - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle simple IP RX
-- doesnt handle reassembly
-- checks and filters for IP protocol
-- checks and filters for IP addr
-- Handle IPv4 protocol
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - Improved error handling
-- Revision 0.03 - Added handling of broadcast address
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
 
entity IPv4_RX is
port (
-- IP Layer signals
ip_rx : out ipv4_rx_type;
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
-- system signals
clk : in std_logic; -- same clock used to clock mac data and ip data
reset : in std_logic;
our_ip_address : in std_logic_vector (31 downto 0);
rx_pkt_count : out std_logic_vector(7 downto 0); -- number of IP pkts received for us
-- MAC layer RX signals
mac_data_in : in std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
mac_data_in_valid : in std_logic; -- indicates data_in valid on clock
mac_data_in_last : in std_logic -- indicates last data in frame
);
end IPv4_RX;
 
architecture Behavioral of IPv4_RX is
 
type rx_state_type is (IDLE, ETH_HDR, IP_HDR, USER_DATA, WAIT_END, ERR);
 
type rx_event_type is (NO_EVENT, DATA);
type count_mode_type is (RST, INCR, HOLD);
type settable_count_mode_type is (RST, INCR, SET_VAL, HOLD);
type set_clr_type is (SET, CLR, HOLD);
 
 
-- state variables
signal rx_state : rx_state_type;
signal rx_count : unsigned (15 downto 0);
signal src_ip : std_logic_vector (31 downto 0); -- src IP captured from input
signal dst_ip : std_logic_vector (23 downto 0); -- 1st 3 bytes of dst IP captured from input
signal is_broadcast_reg : std_logic;
signal protocol : std_logic_vector (7 downto 0); -- src protocol captured from input
signal data_len : std_logic_vector (15 downto 0); -- src data length captured from input
signal ip_rx_start_reg : std_logic; -- indicates start of user data
signal hdr_valid_reg : std_logic; -- indicates that hdr data is valid
signal frame_err_cnt : unsigned (7 downto 0); -- number of frame errors
signal error_code_reg : std_logic_vector (3 downto 0);
signal rx_pkt_counter : unsigned (7 downto 0); -- number of rx frames received for us
 
-- rx control signals
signal next_rx_state : rx_state_type;
signal set_rx_state : std_logic;
signal rx_event : rx_event_type;
signal rx_count_mode : settable_count_mode_type;
signal set_dst_ip3 : std_logic;
signal set_dst_ip2 : std_logic;
signal set_dst_ip1 : std_logic;
signal set_ip3 : std_logic;
signal set_ip2 : std_logic;
signal set_ip1 : std_logic;
signal set_ip0 : std_logic;
signal set_protocol : std_logic;
signal set_len_H : std_logic;
signal set_len_L : std_logic;
signal set_ip_rx_start : set_clr_type;
signal set_hdr_valid : set_clr_type;
signal set_frame_err_cnt : count_mode_type;
signal dataval : std_logic_vector (7 downto 0);
signal rx_count_val : unsigned (15 downto 0);
signal set_error_code : std_logic;
signal error_code_val : std_logic_vector (3 downto 0);
signal set_pkt_cnt : count_mode_type;
signal set_data_last : std_logic;
signal dst_ip_rx : std_logic_vector (31 downto 0);
signal set_is_broadcast : set_clr_type;
 
 
-- IP datagram header format
--
-- 0 4 8 16 19 24 31
-- --------------------------------------------------------------------------------------------
-- | Version | *Header | Service Type | Total Length including header |
-- | (4) | Length | (ignored) | (in bytes) |
-- --------------------------------------------------------------------------------------------
-- | Identification | Flags | Fragment Offset |
-- | | | (in 32 bit words) |
-- --------------------------------------------------------------------------------------------
-- | Time To Live | Protocol | Header Checksum |
-- | (ignored) | | |
-- --------------------------------------------------------------------------------------------
-- | Source IP Address |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Destination IP Address |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Options (if any - ignored) | Padding |
-- | | (if needed) |
-- --------------------------------------------------------------------------------------------
-- | Data |
-- | |
-- --------------------------------------------------------------------------------------------
-- | .... |
-- | |
-- --------------------------------------------------------------------------------------------
--
-- * - in 32 bit words
begin
 
-----------------------------------------------------------------------
-- combinatorial process to implement FSM and determine control signals
-----------------------------------------------------------------------
 
rx_combinatorial : process (
-- input signals
mac_data_in, mac_data_in_valid, mac_data_in_last, our_ip_address,
-- state variables
rx_state, rx_count, src_ip, dst_ip, protocol, data_len, ip_rx_start_reg, hdr_valid_reg,
frame_err_cnt, error_code_reg, rx_pkt_counter, is_broadcast_reg,
-- control signals
next_rx_state, set_rx_state, rx_event, rx_count_mode,
set_ip3, set_ip2, set_ip1, set_ip0, set_protocol, set_len_H, set_len_L,
set_dst_ip3, set_dst_ip2, set_dst_ip1,
set_ip_rx_start, set_hdr_valid, set_frame_err_cnt, dataval, rx_count_val,
set_error_code, error_code_val, set_pkt_cnt, set_data_last, dst_ip_rx, set_is_broadcast
)
begin
-- set output followers
ip_rx_start <= ip_rx_start_reg;
ip_rx.hdr.is_valid <= hdr_valid_reg;
ip_rx.hdr.protocol <= protocol;
ip_rx.hdr.data_length <= data_len;
ip_rx.hdr.src_ip_addr <= src_ip;
ip_rx.hdr.num_frame_errors <= std_logic_vector(frame_err_cnt);
ip_rx.hdr.last_error_code <= error_code_reg;
ip_rx.hdr.is_broadcast <= is_broadcast_reg;
rx_pkt_count <= std_logic_vector(rx_pkt_counter);
 
-- transfer data upstream if in user data phase
if rx_state = USER_DATA then
ip_rx.data.data_in <= mac_data_in;
ip_rx.data.data_in_valid <= mac_data_in_valid;
ip_rx.data.data_in_last <= set_data_last;
else
ip_rx.data.data_in <= (others => '0');
ip_rx.data.data_in_valid <= '0';
ip_rx.data.data_in_last <= '0';
end if;
 
-- set signal defaults
next_rx_state <= IDLE;
set_rx_state <= '0';
rx_event <= NO_EVENT;
rx_count_mode <= HOLD;
set_ip3 <= '0';
set_ip2 <= '0';
set_ip1 <= '0';
set_ip0 <= '0';
set_dst_ip3 <= '0';
set_dst_ip2 <= '0';
set_dst_ip1 <= '0';
set_protocol <= '0';
set_len_H <= '0';
set_len_L <= '0';
set_ip_rx_start <= HOLD;
set_hdr_valid <= HOLD;
set_frame_err_cnt <= HOLD;
rx_count_val <= x"0000";
set_error_code <= '0';
error_code_val <= RX_EC_NONE;
set_pkt_cnt <= HOLD;
dataval <= (others => '0');
set_data_last <= '0';
dst_ip_rx <= (others => '0');
set_is_broadcast <= HOLD;
 
-- determine event (if any)
if mac_data_in_valid = '1' then
rx_event <= DATA;
dataval <= mac_data_in;
end if;
 
-- RX FSM
case rx_state is
when IDLE =>
rx_count_mode <= RST;
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
rx_count_mode <= INCR;
set_hdr_valid <= CLR;
next_rx_state <= ETH_HDR;
set_rx_state <= '1';
end case;
 
when ETH_HDR =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if rx_count = x"000d" then
rx_count_mode <= RST;
next_rx_state <= IP_HDR;
set_rx_state <= '1';
else
rx_count_mode <= INCR;
end if;
-- handle early frame termination
if mac_data_in_last = '1' then
error_code_val <= RX_EC_ET_ETH;
set_error_code <= '1';
set_frame_err_cnt <= INCR;
set_ip_rx_start <= CLR;
set_data_last <= '1';
next_rx_state <= IDLE;
rx_count_mode <= RST;
set_rx_state <= '1';
else
case rx_count is
when x"000c" =>
if mac_data_in /= x"08" then -- ignore pkts that are not type=IP
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
when x"000d" =>
if mac_data_in /= x"00" then -- ignore pkts that are not type=IP
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
when others => -- ignore other bytes in eth header
end case;
end if;
end case;
 
when IP_HDR =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if rx_count = x"0013" then
rx_count_val <= x"0001"; -- start counter at 1
rx_count_mode <= SET_VAL;
else
rx_count_mode <= INCR;
end if;
-- handle early frame termination
if mac_data_in_last = '1' then
error_code_val <= RX_EC_ET_IP;
set_error_code <= '1';
set_frame_err_cnt <= INCR;
set_ip_rx_start <= CLR;
set_data_last <= '1';
next_rx_state <= IDLE;
rx_count_mode <= RST;
set_rx_state <= '1';
else
case rx_count is
when x"0000" =>
if mac_data_in /= x"45" then -- ignore pkts that are not v4 with 5 header words
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
when x"0002" => set_len_H <= '1';
when x"0003" => set_len_L <= '1';
 
when x"0006" =>
if (mac_data_in(7) = '1') or (mac_data_in (4 downto 0) /= "00000") then
-- ignore pkts that require reassembly (MF=1 or frag offst /= 0)
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
when x"0007" =>
if mac_data_in /= x"00" then -- ignore pkts that require reassembly (frag offst /= 0)
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
 
when x"0009" => set_protocol <= '1';
 
when x"000c" => set_ip3 <= '1';
when x"000d" => set_ip2 <= '1';
when x"000e" => set_ip1 <= '1';
when x"000f" => set_ip0 <= '1';
 
when x"0010" => set_dst_ip3 <= '1';
if ((mac_data_in /= our_ip_address(31 downto 24)) and
(mac_data_in /= IP_BC_ADDR(31 downto 24)))then -- ignore pkts that are not addressed to us
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
when x"0011" => set_dst_ip2 <= '1';
if ((mac_data_in /= our_ip_address(23 downto 16)) and
(mac_data_in /= IP_BC_ADDR(23 downto 16)))then -- ignore pkts that are not addressed to us
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
when x"0012" => set_dst_ip1 <= '1';
if ((mac_data_in /= our_ip_address(15 downto 8)) and
(mac_data_in /= IP_BC_ADDR(15 downto 8)))then -- ignore pkts that are not addressed to us
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
 
when x"0013" =>
if ((mac_data_in /= our_ip_address(7 downto 0)) and
(mac_data_in /= IP_BC_ADDR(7 downto 0)))then -- ignore pkts that are not addressed to us
next_rx_state <= WAIT_END;
set_rx_state <= '1';
else
next_rx_state <= USER_DATA;
set_pkt_cnt <= INCR; -- count another pkt
set_rx_state <= '1';
set_ip_rx_start <= SET;
end if;
 
-- now have the dst IP addr
dst_ip_rx <= dst_ip & mac_data_in;
if dst_ip_rx = IP_BC_ADDR then
set_is_broadcast <= SET;
else
set_is_broadcast <= CLR;
end if;
set_hdr_valid <= SET; -- header values are now valid, although the pkt may not be for us
 
--if dst_ip_rx = our_ip_address or dst_ip_rx = IP_BC_ADDR then
-- next_rx_state <= USER_DATA;
-- set_pkt_cnt <= INCR; -- count another pkt received
-- set_rx_state <= '1';
-- set_ip_rx_start <= SET;
--else
-- next_rx_state <= WAIT_END;
-- set_rx_state <= '1';
--end if;
when others => -- ignore other bytes in ip header
end case;
end if;
end case;
when USER_DATA =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
-- note: data gets transfered upstream as part of "output followers" processing
if rx_count = unsigned(data_len) then
set_ip_rx_start <= CLR;
rx_count_mode <= RST;
set_data_last <= '1';
if mac_data_in_last = '1' then
next_rx_state <= IDLE;
rx_count_mode <= RST;
set_ip_rx_start <= CLR;
else
next_rx_state <= WAIT_END;
end if;
set_rx_state <= '1';
else
rx_count_mode <= INCR;
-- check for early frame termination
if mac_data_in_last = '1' then
error_code_val <= RX_EC_ET_USER;
set_error_code <= '1';
set_frame_err_cnt <= INCR;
set_ip_rx_start <= CLR;
next_rx_state <= IDLE;
rx_count_mode <= RST;
set_rx_state <= '1';
end if;
end if;
end case;
 
when ERR =>
set_frame_err_cnt <= INCR;
set_ip_rx_start <= CLR;
if mac_data_in_last = '0' then
set_data_last <= '1';
next_rx_state <= WAIT_END;
set_rx_state <= '1';
else
next_rx_state <= IDLE;
rx_count_mode <= RST;
set_rx_state <= '1';
end if;
 
when WAIT_END =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if mac_data_in_last = '1' then
set_data_last <= '1';
next_rx_state <= IDLE;
rx_count_mode <= RST;
set_rx_state <= '1';
set_ip_rx_start <= CLR;
end if;
end case;
end case;
end process;
 
 
-----------------------------------------------------------------------------
-- sequential process to action control signals and change states and outputs
-----------------------------------------------------------------------------
 
rx_sequential : process (clk)--, reset)
begin
if rising_edge(clk) then
if reset = '1' then
-- reset state variables
rx_state <= IDLE;
rx_count <= x"0000";
src_ip <= (others => '0');
dst_ip <= (others => '0');
protocol <= (others => '0');
data_len <= (others => '0');
ip_rx_start_reg <= '0';
hdr_valid_reg <= '0';
is_broadcast_reg <= '0';
frame_err_cnt <= (others => '0');
error_code_reg <= RX_EC_NONE;
rx_pkt_counter <= x"00";
 
else
-- Next rx_state processing
if set_rx_state = '1' then
rx_state <= next_rx_state;
else
rx_state <= rx_state;
end if;
 
-- rx_count processing
case rx_count_mode is
when RST => rx_count <= x"0000";
when INCR => rx_count <= rx_count + 1;
when SET_VAL => rx_count <= rx_count_val;
when HOLD => rx_count <= rx_count;
end case;
 
-- frame error count processing
case set_frame_err_cnt is
when RST => frame_err_cnt <= x"00";
when INCR => frame_err_cnt <= frame_err_cnt + 1;
when HOLD => frame_err_cnt <= frame_err_cnt;
end case;
 
-- ip pkt processing
case set_pkt_cnt is
when RST => rx_pkt_counter <= x"00";
when INCR => rx_pkt_counter <= rx_pkt_counter + 1;
when HOLD => rx_pkt_counter <= rx_pkt_counter;
end case;
 
-- source ip capture
if (set_ip3 = '1') then src_ip(31 downto 24) <= dataval; end if;
if (set_ip2 = '1') then src_ip(23 downto 16) <= dataval; end if;
if (set_ip1 = '1') then src_ip(15 downto 8) <= dataval; end if;
if (set_ip0 = '1') then src_ip(7 downto 0) <= dataval; end if;
 
-- dst ip capture
if (set_dst_ip3 = '1') then dst_ip(23 downto 16) <= dataval; end if;
if (set_dst_ip2 = '1') then dst_ip(15 downto 8) <= dataval; end if;
if (set_dst_ip1 = '1') then dst_ip(7 downto 0) <= dataval; end if;
 
if (set_protocol = '1') then
protocol <= dataval;
else
protocol <= protocol;
end if;
 
if (set_len_H = '1') then
data_len (15 downto 8) <= dataval;
data_len (7 downto 0) <= x"00";
elsif (set_len_L = '1') then
-- compute data length, taking into account that we need to subtract the header length
data_len <= std_logic_vector(unsigned(data_len(15 downto 8) & dataval) - 20);
else
data_len <= data_len;
end if;
 
case set_ip_rx_start is
when SET => ip_rx_start_reg <= '1';
when CLR => ip_rx_start_reg <= '0';
when HOLD => ip_rx_start_reg <= ip_rx_start_reg;
end case;
 
case set_is_broadcast is
when SET => is_broadcast_reg <= '1';
when CLR => is_broadcast_reg <= '0';
when HOLD => is_broadcast_reg <= is_broadcast_reg;
end case;
 
case set_hdr_valid is
when SET => hdr_valid_reg <= '1';
when CLR => hdr_valid_reg <= '0';
when HOLD => hdr_valid_reg <= hdr_valid_reg;
end case;
 
-- set error code
if set_error_code = '1' then
error_code_reg <= error_code_val;
else
error_code_reg <= error_code_reg;
end if;
end if;
end if;
end process;
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/UDP_RX.vhd
0,0 → 1,343
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 5 June 2011
-- Design Name:
-- Module Name: UDP_RX - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle simple UDP RX
-- doesnt check the checsum
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - Improved error handling
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.axi.all;
use work.ipv4_types.all;
 
entity UDP_RX is
port (
-- UDP Layer signals
udp_rx_start : out std_logic; -- indicates receipt of udp header
udp_rxo : out udp_rx_type;
-- system signals
clk : in std_logic;
reset : in std_logic;
-- IP layer RX signals
ip_rx_start : in std_logic; -- indicates receipt of ip header
ip_rx : in ipv4_rx_type
);
end UDP_RX;
 
architecture Behavioral of UDP_RX is
 
type rx_state_type is (IDLE, UDP_HDR, USER_DATA, WAIT_END, ERR);
 
type rx_event_type is (NO_EVENT, DATA);
type count_mode_type is (RST, INCR, HOLD);
type settable_count_mode_type is (RST, INCR, SET_VAL, HOLD);
type set_clr_type is (SET, CLR, HOLD);
 
 
-- state variables
signal rx_state : rx_state_type;
signal rx_count : unsigned (15 downto 0);
signal src_port : std_logic_vector (15 downto 0); -- src port captured from input
signal dst_port : std_logic_vector (15 downto 0); -- dst port captured from input
signal data_len : std_logic_vector (15 downto 0); -- user data length captured from input
signal udp_rx_start_reg : std_logic; -- indicates start of user data
signal hdr_valid_reg : std_logic; -- indicates that hdr data is valid
signal src_ip_addr : std_logic_vector (31 downto 0); -- captured from IP hdr
 
-- rx control signals
signal next_rx_state : rx_state_type;
signal set_rx_state : std_logic;
signal rx_event : rx_event_type;
signal rx_count_mode : settable_count_mode_type;
signal rx_count_val : unsigned (15 downto 0);
signal set_sph : std_logic;
signal set_spl : std_logic;
signal set_dph : std_logic;
signal set_dpl : std_logic;
signal set_len_H : std_logic;
signal set_len_L : std_logic;
signal set_udp_rx_start : set_clr_type;
signal set_hdr_valid : set_clr_type;
signal dataval : std_logic_vector (7 downto 0);
signal set_pkt_cnt : count_mode_type;
signal set_src_ip : std_logic;
signal set_data_last : std_logic;
 
-- IP datagram header format
--
-- 0 4 8 16 19 24 31
-- --------------------------------------------------------------------------------------------
-- | source port number | dest port number |
-- | | |
-- --------------------------------------------------------------------------------------------
-- | length (bytes) | checksum |
-- | (header and data combined) | |
-- --------------------------------------------------------------------------------------------
-- | Data |
-- | |
-- --------------------------------------------------------------------------------------------
-- | .... |
-- | |
-- --------------------------------------------------------------------------------------------
 
 
begin
 
-----------------------------------------------------------------------
-- combinatorial process to implement FSM and determine control signals
-----------------------------------------------------------------------
 
rx_combinatorial : process (
-- input signals
ip_rx, ip_rx_start,
-- state variables
rx_state, rx_count, src_port, dst_port, data_len, udp_rx_start_reg, hdr_valid_reg, src_ip_addr,
-- control signals
next_rx_state, set_rx_state, rx_event, rx_count_mode, rx_count_val,
set_sph, set_spl, set_dph, set_dpl, set_len_H, set_len_L, set_data_last,
set_udp_rx_start, set_hdr_valid, dataval, set_pkt_cnt, set_src_ip
)
begin
-- set output followers
udp_rx_start <= udp_rx_start_reg;
udp_rxo.hdr.is_valid <= hdr_valid_reg;
udp_rxo.hdr.data_length <= data_len;
udp_rxo.hdr.src_port <= src_port;
udp_rxo.hdr.dst_port <= dst_port;
udp_rxo.hdr.src_ip_addr <= src_ip_addr;
 
-- transfer data upstream if in user data phase
if rx_state = USER_DATA then
udp_rxo.data.data_in <= ip_rx.data.data_in;
udp_rxo.data.data_in_valid <= ip_rx.data.data_in_valid;
udp_rxo.data.data_in_last <= set_data_last;
else
udp_rxo.data.data_in <= (others => '0');
udp_rxo.data.data_in_valid <= '0';
udp_rxo.data.data_in_last <= '0';
end if;
 
-- set signal defaults
next_rx_state <= IDLE;
set_rx_state <= '0';
rx_event <= NO_EVENT;
rx_count_mode <= HOLD;
set_sph <= '0';
set_spl <= '0';
set_dph <= '0';
set_dpl <= '0';
set_len_H <= '0';
set_len_L <= '0';
set_udp_rx_start <= HOLD;
set_hdr_valid <= HOLD;
dataval <= (others => '0');
set_src_ip <= '0';
rx_count_val <= (others => '0');
set_data_last <= '0';
 
-- determine event (if any)
if ip_rx.data.data_in_valid = '1' then
rx_event <= DATA;
dataval <= ip_rx.data.data_in;
end if;
 
-- RX FSM
case rx_state is
when IDLE =>
rx_count_mode <= RST;
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if ip_rx.hdr.protocol = x"11" then
-- UDP protocol
rx_count_mode <= INCR;
set_hdr_valid <= CLR;
set_src_ip <= '1';
set_sph <= '1';
next_rx_state <= UDP_HDR;
set_rx_state <= '1';
else
-- non-UDP protocol - ignore this pkt
set_hdr_valid <= CLR;
next_rx_state <= WAIT_END;
set_rx_state <= '1';
end if;
end case;
 
when UDP_HDR =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if rx_count = x"0007" then
rx_count_mode <= SET_VAL;
rx_count_val <= x"0001";
next_rx_state <= USER_DATA;
set_rx_state <= '1';
else
rx_count_mode <= INCR;
end if;
-- handle early frame termination
if ip_rx.data.data_in_last = '1' then
next_rx_state <= IDLE;
set_rx_state <= '1';
else
case rx_count is
when x"0000" => set_sph <= '1';
when x"0001" => set_spl <= '1';
when x"0002" => set_dph <= '1';
when x"0003" => set_dpl <= '1';
 
when x"0004" => set_len_H <= '1';
when x"0005" => set_len_L <= '1'; set_hdr_valid <= SET; -- header values are now valid, although the pkt may not be for us
 
when x"0006" => -- ignore checksum values
when x"0007" => set_udp_rx_start <= SET; -- indicate frame received
 
 
when others => -- ignore other bytes in udp header
end case;
end if;
end case;
when USER_DATA =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
-- note: data gets transfered upstream as part of "output followers" processing
if rx_count = unsigned(data_len) then
set_udp_rx_start <= CLR;
rx_count_mode <= RST;
set_data_last <= '1';
if ip_rx.data.data_in_last = '1' then
next_rx_state <= IDLE;
set_udp_rx_start <= CLR;
else
next_rx_state <= WAIT_END;
end if;
set_rx_state <= '1';
else
rx_count_mode <= INCR;
-- check for early frame termination
-- TODO need to mark frame as errored
if ip_rx.data.data_in_last = '1' then
next_rx_state <= IDLE;
set_rx_state <= '1';
set_data_last <= '1';
end if;
end if;
end case;
 
when ERR =>
if ip_rx.data.data_in_last = '0' then
next_rx_state <= WAIT_END;
set_rx_state <= '1';
else
next_rx_state <= IDLE;
set_rx_state <= '1';
end if;
 
when WAIT_END =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if ip_rx.data.data_in_last = '1' then
next_rx_state <= IDLE;
set_rx_state <= '1';
end if;
end case;
end case;
end process;
 
 
-----------------------------------------------------------------------------
-- sequential process to action control signals and change states and outputs
-----------------------------------------------------------------------------
 
rx_sequential : process (clk, reset)
begin
if rising_edge(clk) then
if reset = '1' then
-- reset state variables
rx_state <= IDLE;
rx_count <= x"0000";
src_port <= (others => '0');
dst_port <= (others => '0');
data_len <= (others => '0');
udp_rx_start_reg <= '0';
hdr_valid_reg <= '0';
src_ip_addr <= (others => '0');
else
-- Next rx_state processing
if set_rx_state = '1' then
rx_state <= next_rx_state;
else
rx_state <= rx_state;
end if;
 
-- rx_count processing
case rx_count_mode is
when RST => rx_count <= x"0000";
when INCR => rx_count <= rx_count + 1;
when SET_VAL => rx_count <= rx_count_val;
when HOLD => rx_count <= rx_count;
end case;
 
-- port number capture
if (set_sph = '1') then src_port(15 downto 8) <= dataval; end if;
if (set_spl = '1') then src_port(7 downto 0) <= dataval; end if;
if (set_dph = '1') then dst_port(15 downto 8) <= dataval; end if;
if (set_dpl = '1') then dst_port(7 downto 0) <= dataval; end if;
 
if (set_len_H = '1') then
data_len (15 downto 8) <= dataval;
data_len (7 downto 0) <= x"00";
elsif (set_len_L = '1') then
-- compute data length, taking into account that we need to subtract the header length
data_len <= std_logic_vector(unsigned(data_len(15 downto 8) & dataval) - 8);
else
data_len <= data_len;
end if;
 
case set_udp_rx_start is
when SET => udp_rx_start_reg <= '1';
when CLR => udp_rx_start_reg <= '0';
when HOLD => udp_rx_start_reg <= udp_rx_start_reg;
end case;
 
-- capture src IP address
if set_src_ip = '1' then
src_ip_addr <= ip_rx.hdr.src_ip_addr;
else
src_ip_addr <= src_ip_addr;
end if;
 
case set_hdr_valid is
when SET => hdr_valid_reg <= '1';
when CLR => hdr_valid_reg <= '0';
when HOLD => hdr_valid_reg <= hdr_valid_reg;
end case;
end if;
end if;
end process;
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/IP_complete_nomac.vhd
0,0 → 1,365
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 12:43:16 06/04/2011
-- Design Name:
-- Module Name: IP_complete_nomac - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description: Implements complete IP stack with ARP (but no MAC)
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - separated RX and TX clocks
-- Revision 0.03 - Added mac_tx_tfirst
-- Additional Comments:
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
use work.arp;
use work.arpv2;
 
entity IP_complete_nomac is
generic (
use_arpv2 : boolean := true; -- use ARP with multipule entries. for signel entry, set
-- to false
no_default_gateway : boolean := false; -- set to false if communicating with devices accessed
-- through a "default gateway or router"
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
port (
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
ip_rx : out ipv4_rx_type;
-- system signals
rx_clk : in std_logic;
tx_clk : in std_logic;
reset : in std_logic;
our_ip_address : in std_logic_vector (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in ip_control_type;
-- status signals
arp_pkt_count : out std_logic_vector(7 downto 0); -- count of arp pkts received
ip_pkt_count : out std_logic_vector(7 downto 0); -- number of IP pkts received for us
-- MAC Transmitter
mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : out std_logic; -- tdata is valid
mac_tx_tready : in std_logic; -- mac is ready to accept data
mac_tx_tfirst : out std_logic; -- indicates first byte of frame
mac_tx_tlast : out std_logic; -- indicates last byte of frame
-- MAC Receiver
mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : in std_logic; -- indicates tdata is valid
mac_rx_tready : out std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : in std_logic -- indicates last byte of the trame
);
end IP_complete_nomac;
 
 
architecture structural of IP_complete_nomac is
 
component IPv4
port(
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
ip_rx : out ipv4_rx_type;
-- system control signals
rx_clk : in std_logic;
tx_clk : in std_logic;
reset : in std_logic;
our_ip_address : in std_logic_vector (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
-- system status signals
rx_pkt_count : out std_logic_vector(7 downto 0); -- number of IP pkts received for us
-- ARP lookup signals
arp_req_req : out arp_req_req_type;
arp_req_rslt : in arp_req_rslt_type;
-- MAC layer RX signals
mac_data_in : in std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
mac_data_in_valid : in std_logic; -- indicates data_in valid on clock
mac_data_in_last : in std_logic; -- indicates last data in frame
-- 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_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_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 : out std_logic_vector (7 downto 0) -- ethernet frame (from dst mac addr through to last byte of frame)
);
end component;
 
component arp
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 1; -- (added for compatibility with arpv2. this value not used in this impl)
MAX_ARP_ENTRIES : integer := 1 -- (added for compatibility with arpv2. this value not used in this impl)
);
port (
-- lookup request signals
arp_req_req : in arp_req_req_type;
arp_req_rslt : out arp_req_rslt_type;
-- MAC layer RX signals
data_in_clk : in std_logic;
reset : in std_logic;
data_in : in std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
data_in_valid : in std_logic; -- indicates data_in valid on clock
data_in_last : in std_logic; -- indicates last data in frame
-- 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_granted : in std_logic; -- indicates that access to channel has been granted
data_out_clk : in std_logic;
data_out_ready : in std_logic; -- indicates system ready to consume data
data_out_valid : out std_logic; -- indicates data out is valid
data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame
data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame
data_out : out std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
-- system signals
our_mac_address : in std_logic_vector (47 downto 0);
our_ip_address : in std_logic_vector (31 downto 0);
control : in arp_control_type;
req_count : out std_logic_vector(7 downto 0) -- count of arp pkts received
);
end component;
 
component tx_arbitrator
port(
clk : in std_logic;
reset : in std_logic;
 
req_1 : in std_logic;
grant_1 : out std_logic;
data_1 : in std_logic_vector(7 downto 0); -- data byte to tx
valid_1 : in std_logic; -- tdata is valid
first_1 : in std_logic; -- indicates first byte of frame
last_1 : in std_logic; -- indicates last byte of frame
 
req_2 : in std_logic;
grant_2 : out std_logic;
data_2 : in std_logic_vector(7 downto 0); -- data byte to tx
valid_2 : in std_logic; -- tdata is valid
first_2 : in std_logic; -- indicates first byte of frame
last_2 : in std_logic; -- indicates last byte of frame
 
data : out std_logic_vector(7 downto 0); -- data byte to tx
valid : out std_logic; -- tdata is valid
first : out std_logic; -- indicates first byte of frame
last : out std_logic -- indicates last byte of frame
);
end component;
 
 
-------------------
-- Configuration
--
-- Enable one of the following to specify which
-- implementation of the ARP layer to use
-------------------
 
 
-- for arp_layer : arp use entity work.arp; -- single slot arbitrator
-- for arp_layer : arp use entity work.arpv2; -- multislot arbitrator
 
 
 
---------------------------
-- Signals
---------------------------
 
-- ARP REQUEST
signal arp_req_req_int : arp_req_req_type;
signal arp_req_rslt_int : arp_req_rslt_type;
-- MAC arbitration busses
signal ip_mac_req : std_logic;
signal ip_mac_grant : std_logic;
signal ip_mac_data_out : std_logic_vector (7 downto 0);
signal ip_mac_valid : std_logic;
signal ip_mac_first : std_logic;
signal ip_mac_last : std_logic;
signal arp_mac_req : std_logic;
signal arp_mac_grant : std_logic;
signal arp_mac_data_out : std_logic_vector (7 downto 0);
signal arp_mac_valid : std_logic;
signal arp_mac_first : std_logic;
signal arp_mac_last : std_logic;
-- MAC RX bus
signal mac_rx_tready_int : std_logic;
-- MAC TX bus
signal mac_tx_tdata_int : std_logic_vector (7 downto 0);
signal mac_tx_tvalid_int : std_logic;
signal mac_tx_tfirst_int : std_logic;
signal mac_tx_tlast_int : std_logic;
-- control signals
signal mac_tx_granted_int : std_logic;
 
begin
 
mac_rx_tready_int <= '1'; -- enable the mac receiver
 
-- set followers
mac_tx_tdata <= mac_tx_tdata_int;
mac_tx_tvalid <= mac_tx_tvalid_int;
mac_tx_tfirst <= mac_tx_tfirst_int;
mac_tx_tlast <= mac_tx_tlast_int;
 
mac_rx_tready <= mac_rx_tready_int;
 
------------------------------------------------------------------------------
-- Instantiate the IP layer
------------------------------------------------------------------------------
 
IP_layer : IPv4 port map
(
ip_tx_start => ip_tx_start,
ip_tx => ip_tx,
ip_tx_result => ip_tx_result,
ip_tx_data_out_ready => ip_tx_data_out_ready,
ip_rx_start => ip_rx_start,
ip_rx => ip_rx,
rx_clk => rx_clk,
tx_clk => tx_clk,
reset => reset,
our_ip_address => our_ip_address,
our_mac_address => our_mac_address,
rx_pkt_count => ip_pkt_count,
arp_req_req => arp_req_req_int,
arp_req_rslt => arp_req_rslt_int,
mac_tx_req => ip_mac_req,
mac_tx_granted => ip_mac_grant,
mac_data_out_ready => mac_tx_tready,
mac_data_out_valid => ip_mac_valid,
mac_data_out_first => ip_mac_first,
mac_data_out_last => ip_mac_last,
mac_data_out => ip_mac_data_out,
mac_data_in => mac_rx_tdata,
mac_data_in_valid => mac_rx_tvalid,
mac_data_in_last => mac_rx_tlast
);
 
------------------------------------------------------------------------------
-- Instantiate the ARP layer
------------------------------------------------------------------------------
signle_entry_arp: if (not use_arpv2) generate
arp_layer : entity work.arp
generic map (
CLOCK_FREQ => CLOCK_FREQ,
ARP_TIMEOUT => ARP_TIMEOUT,
ARP_MAX_PKT_TMO => ARP_MAX_PKT_TMO,
MAX_ARP_ENTRIES => MAX_ARP_ENTRIES
)
port map(
-- request signals
arp_req_req => arp_req_req_int,
arp_req_rslt => arp_req_rslt_int,
-- rx signals
data_in_clk => rx_clk,
reset => reset,
data_in => mac_rx_tdata,
data_in_valid => mac_rx_tvalid,
data_in_last => mac_rx_tlast,
-- tx signals
mac_tx_req => arp_mac_req,
mac_tx_granted => arp_mac_grant,
data_out_clk => tx_clk,
data_out_ready => mac_tx_tready,
data_out_valid => arp_mac_valid,
data_out_first => arp_mac_first,
data_out_last => arp_mac_last,
data_out => arp_mac_data_out,
-- system signals
our_mac_address => our_mac_address,
our_ip_address => our_ip_address,
control => control.arp_controls,
req_count => arp_pkt_count
);
end generate signle_entry_arp;
 
multi_entry_arp: if (use_arpv2) generate
arp_layer : entity work.arpv2
generic map (
no_default_gateway => no_default_gateway,
CLOCK_FREQ => CLOCK_FREQ,
ARP_TIMEOUT => ARP_TIMEOUT,
ARP_MAX_PKT_TMO => ARP_MAX_PKT_TMO,
MAX_ARP_ENTRIES => MAX_ARP_ENTRIES
)
port map(
-- request signals
arp_req_req => arp_req_req_int,
arp_req_rslt => arp_req_rslt_int,
-- rx signals
data_in_clk => rx_clk,
reset => reset,
data_in => mac_rx_tdata,
data_in_valid => mac_rx_tvalid,
data_in_last => mac_rx_tlast,
-- tx signals
mac_tx_req => arp_mac_req,
mac_tx_granted => arp_mac_grant,
data_out_clk => tx_clk,
data_out_ready => mac_tx_tready,
data_out_valid => arp_mac_valid,
data_out_first => arp_mac_first,
data_out_last => arp_mac_last,
data_out => arp_mac_data_out,
-- system signals
our_mac_address => our_mac_address,
our_ip_address => our_ip_address,
control => control.arp_controls,
req_count => arp_pkt_count
);
end generate multi_entry_arp;
 
------------------------------------------------------------------------------
-- Instantiate the TX Arbitrator
------------------------------------------------------------------------------
mac_tx_arb : tx_arbitrator
port map(
clk => tx_clk,
reset => reset,
 
req_1 => ip_mac_req,
grant_1 => ip_mac_grant,
data_1 => ip_mac_data_out,
valid_1 => ip_mac_valid,
first_1 => ip_mac_first,
last_1 => ip_mac_last,
 
req_2 => arp_mac_req,
grant_2 => arp_mac_grant,
data_2 => arp_mac_data_out,
valid_2 => arp_mac_valid,
first_2 => arp_mac_first,
last_2 => arp_mac_last,
 
data => mac_tx_tdata_int,
valid => mac_tx_tvalid_int,
first => mac_tx_tfirst_int,
last => mac_tx_tlast_int
);
 
end structural;
 
 
 
/tags/v2.3/rtl/vhdl/arp_SYNC.vhd
0,0 → 1,163
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 14:09:01 02/20/2012
-- Design Name:
-- Module Name: arp_SYNC - Behavioral - synchronises between rx and tx clock domains
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.arp_types.all;
 
entity arp_SYNC is
port (
-- REQ to TX
arp_nwk_req : in arp_nwk_request_t; -- request for a translation from IP to MAC
send_who_has : out std_logic;
ip_entry : out std_logic_vector (31 downto 0);
-- RX to TX
recv_who_has : in std_logic; -- this is for us, we will respond
arp_entry_for_who_has : in arp_entry_t;
send_I_have : out std_logic;
arp_entry : out arp_entry_t;
-- RX to REQ
I_have_received : in std_logic;
nwk_result_status : out arp_nwk_rslt_t;
-- System Signals
rx_clk : in std_logic;
tx_clk : in std_logic;
reset : in std_logic
);
end arp_SYNC;
 
architecture Behavioral of arp_SYNC is
 
type sync_state_t is (IDLE, HOLD1, HOLD2);
 
-- state registers
signal ip_entry_state : sync_state_t;
signal arp_entry_state : sync_state_t;
signal ip_entry_reg : std_logic_vector (31 downto 0);
signal arp_entry_reg : arp_entry_t;
 
-- synchronisation registers
signal send_who_has_r1 : std_logic;
signal send_who_has_r2 : std_logic;
signal send_I_have_r1 : std_logic;
signal send_I_have_r2 : std_logic;
begin
 
combinatorial : process (
-- input signals
arp_nwk_req, recv_who_has, arp_entry_for_who_has, I_have_received, reset,
-- state
ip_entry_state, ip_entry_reg, arp_entry_state, arp_entry_reg,
-- synchronisation registers
send_who_has_r1, send_who_has_r2,
send_I_have_r1, send_I_have_r2
)
begin
-- set output followers
send_who_has <= send_who_has_r2;
ip_entry <= ip_entry_reg;
send_I_have <= send_I_have_r2;
arp_entry <= arp_entry_reg;
 
-- combinaltorial outputs
if I_have_received = '1' then
nwk_result_status <= RECEIVED;
else
nwk_result_status <= IDLE;
end if;
end process;
 
-- process for stablisising RX clock domain data registers
-- essentially holds data registers ip_entry and arp_entry static for 2 rx clk cycles
-- during transfer to TX clk domain
rx_sequential : process (tx_clk)
begin
if rising_edge(tx_clk) then
if reset = '1' then
-- reset state variables
ip_entry_reg <= (others => '0');
arp_entry_reg.ip <= (others => '0');
arp_entry_reg.mac <= (others => '0');
else
-- normal (non reset) processing
case ip_entry_state is
when IDLE =>
if arp_nwk_req.req = '1' then
ip_entry_reg <= arp_nwk_req.ip;
ip_entry_state <= HOLD1;
else
ip_entry_reg <= ip_entry_reg;
ip_entry_state <= IDLE;
end if;
when HOLD1 =>
ip_entry_reg <= ip_entry_reg;
ip_entry_state <= HOLD2;
when HOLD2 =>
ip_entry_reg <= ip_entry_reg;
ip_entry_state <= IDLE;
end case;
 
case arp_entry_state is
when IDLE =>
if recv_who_has = '1' then
arp_entry_reg <= arp_entry_for_who_has;
arp_entry_state <= HOLD1;
else
arp_entry_reg <= arp_entry_reg;
arp_entry_state <= IDLE;
end if;
when HOLD1 =>
arp_entry_reg <= arp_entry_reg;
arp_entry_state <= HOLD2;
when HOLD2 =>
arp_entry_reg <= arp_entry_reg;
arp_entry_state <= IDLE;
end case;
end if;
end if;
end process;
 
-- process for syncing to the TX clock domain
-- clocks control signals through 2 layers of tx clocking
tx_sequential : process (tx_clk)
begin
if rising_edge(tx_clk) then
if reset = '1' then
-- reset state variables
send_who_has_r1 <= '0';
send_who_has_r2 <= '0';
send_I_have_r1 <= '0';
send_I_have_r2 <= '0';
else
-- normal (non reset) processing
send_who_has_r1 <= arp_nwk_req.req;
send_who_has_r2 <= send_who_has_r1;
 
send_I_have_r1 <= recv_who_has;
send_I_have_r2 <= send_I_have_r1;
end if;
end if;
end process;
 
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/arp_STORE_br.vhd
0,0 → 1,299
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 12:00:04 05/31/2011
-- Design Name:
-- Module Name: arp_STORE_br - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- ARP storage table using block ram with lookup based on IP address
-- implements upto 255 entries with sequential search
-- uses round robin overwrite when full (LRU would be better, but ...)
--
-- store may take a number of cycles and the request is latched
-- lookup may take a number of cycles. Assumes that request signals remain valid during lookup
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use ieee.std_logic_unsigned.all;
use work.arp_types.all;
 
entity arp_STORE_br is
generic (
MAX_ARP_ENTRIES : integer := 255 -- max entries in the store
);
port (
-- read signals
read_req : in arp_store_rdrequest_t; -- requesting a lookup or store
read_result : out arp_store_result_t; -- the result
-- write signals
write_req : in arp_store_wrrequest_t; -- requesting a lookup or store
-- control and status signals
clear_store : in std_logic; -- erase all entries
entry_count : out unsigned(7 downto 0); -- how many entries currently in store
-- system signals
clk : in std_logic;
reset : in std_logic
);
end arp_STORE_br;
 
architecture Behavioral of arp_STORE_br is
 
type st_state_t is (IDLE, PAUSE, SEARCH, FOUND, NOT_FOUND);
 
type ip_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(31 downto 0);
type mac_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(47 downto 0);
subtype addr_t is integer range 0 to MAX_ARP_ENTRIES;
 
type count_mode_t is (RST, INCR, HOLD);
 
type mode_t is (MREAD, MWRITE);
 
-- state variables
signal ip_ram : ip_ram_t; -- will be implemented as block ram
signal mac_ram : mac_ram_t; -- will be implemented as block ram
signal st_state : st_state_t;
signal next_write_addr : addr_t; -- where to make the next write
signal num_entries : addr_t; -- number of entries in the store
signal next_read_addr : addr_t; -- next addr to read from
signal entry_found : arp_entry_t; -- entry found in search
signal mode : mode_t; -- are we writing or reading?
signal req_entry : arp_entry_t; -- entry latched from req
 
-- busses
signal next_st_state : st_state_t;
signal arp_entry_val : arp_entry_t;
signal mode_val : mode_t;
signal write_addr : addr_t; -- actual write address to use
signal read_result_int : arp_store_result_t;
 
-- control signals
signal set_st_state : std_logic;
signal set_next_write_addr : count_mode_t;
signal set_num_entries : count_mode_t;
signal set_next_read_addr : count_mode_t;
signal write_ram : std_logic;
signal set_entry_found : std_logic;
signal set_mode : std_logic;
 
function read_status(status : arp_store_rslt_t; signal mode : mode_t) return arp_store_rslt_t is
variable ret : arp_store_rslt_t;
begin
case status is
when IDLE =>
ret := status;
when others =>
if mode = MWRITE then
ret := BUSY;
else
ret := status;
end if;
end case;
return ret;
end read_status;
 
begin
combinatorial : process (
-- input signals
read_req, write_req, clear_store, reset,
-- state variables
ip_ram, mac_ram, st_state, next_write_addr, num_entries,
next_read_addr, entry_found, mode, req_entry,
-- busses
next_st_state, arp_entry_val, mode_val, write_addr, read_result_int,
-- control signals
set_st_state, set_next_write_addr, set_num_entries, set_next_read_addr, set_entry_found,
write_ram, set_mode
)
begin
-- set output followers
read_result_int.status <= IDLE;
read_result_int.entry <= entry_found;
entry_count <= to_unsigned(num_entries, 8);
 
-- set bus defaults
next_st_state <= IDLE;
mode_val <= MREAD;
write_addr <= next_write_addr;
 
-- set signal defaults
set_st_state <= '0';
set_next_write_addr <= HOLD;
set_num_entries <= HOLD;
set_next_read_addr <= HOLD;
write_ram <= '0';
set_entry_found <= '0';
set_mode <= '0';
 
-- STORE FSM
case st_state is
when IDLE =>
if write_req.req = '1' then
-- need to search to see if this IP already there
set_next_read_addr <= RST; -- start lookup from beginning
mode_val <= MWRITE;
set_mode <= '1';
next_st_state <= PAUSE;
set_st_state <= '1';
elsif read_req.req = '1' then
set_next_read_addr <= RST; -- start lookup from beginning
mode_val <= MREAD;
set_mode <= '1';
next_st_state <= PAUSE;
set_st_state <= '1';
end if;
 
when PAUSE =>
-- wait until read addr is latched and we get first data out of the ram
read_result_int.status <= read_status(BUSY, mode);
set_next_read_addr <= INCR;
next_st_state <= SEARCH;
set_st_state <= '1';
when SEARCH =>
read_result_int.status <= read_status(SEARCHING, mode);
-- check if have a match at this entry
if req_entry.ip = arp_entry_val.ip and next_read_addr <= num_entries then
-- found it
set_entry_found <= '1';
next_st_state <= FOUND;
set_st_state <= '1';
elsif next_read_addr > num_entries or next_read_addr >= MAX_ARP_ENTRIES then
-- reached end of entry table
read_result_int.status <= read_status(NOT_FOUND, mode);
next_st_state <= NOT_FOUND;
set_st_state <= '1';
else
-- no match at this entry , go to next
set_next_read_addr <= INCR;
end if;
 
when FOUND =>
read_result_int.status <= read_status(FOUND, mode);
if mode = MWRITE then
write_addr <= next_read_addr - 1;
write_ram <= '1';
next_st_state <= IDLE;
set_st_state <= '1';
elsif read_req.req = '0' then -- wait in this state until request de-asserted
next_st_state <= IDLE;
set_st_state <= '1';
end if;
 
when NOT_FOUND =>
read_result_int.status <= read_status(NOT_FOUND, mode);
if mode = MWRITE then
-- need to write into the next free slot
write_addr <= next_write_addr;
write_ram <= '1';
set_next_write_addr <= INCR;
if num_entries < MAX_ARP_ENTRIES then
-- if not full, count another entry (if full, it just wraps)
set_num_entries <= INCR;
end if;
next_st_state <= IDLE;
set_st_state <= '1';
elsif read_req.req = '0' then -- wait in this state until request de-asserted
next_st_state <= IDLE;
set_st_state <= '1';
end if;
end case;
end process;
 
sequential : process (clk)
begin
if rising_edge(clk) then
-- ram processing
if write_ram = '1' then
ip_ram(write_addr) <= req_entry.ip;
mac_ram(write_addr) <= req_entry.mac;
end if;
if next_read_addr < MAX_ARP_ENTRIES then
arp_entry_val.ip <= ip_ram(next_read_addr);
arp_entry_val.mac <= mac_ram(next_read_addr);
else
arp_entry_val.ip <= (others => '0');
arp_entry_val.mac <= (others => '0');
end if;
 
read_result <= read_result_int;
 
if reset = '1' or clear_store = '1' then
-- reset state variables
st_state <= IDLE;
next_write_addr <= 0;
num_entries <= 0;
next_read_addr <= 0;
entry_found.ip <= (others => '0');
entry_found.mac <= (others => '0');
req_entry.ip <= (others => '0');
req_entry.mac <= (others => '0');
mode <= MREAD;
 
else
-- Next req_state processing
if set_st_state = '1' then
st_state <= next_st_state;
else
st_state <= st_state;
end if;
 
-- mode setting and write request latching
if set_mode = '1' then
mode <= mode_val;
if mode_val = MWRITE then
req_entry <= write_req.entry;
else
req_entry.ip <= read_req.ip;
req_entry.mac <= (others => '0');
end if;
else
mode <= mode;
req_entry <= req_entry;
end if;
 
-- latch entry found
if set_entry_found = '1' then
entry_found <= arp_entry_val;
else
entry_found <= entry_found;
end if;
 
-- next_write_addr counts and wraps
case set_next_write_addr is
when HOLD => next_write_addr <= next_write_addr;
when RST => next_write_addr <= 0;
when INCR => if next_write_addr < MAX_ARP_ENTRIES-1 then next_write_addr <= next_write_addr + 1; else next_write_addr <= 0; end if;
end case;
 
-- num_entries counts and holds at max
case set_num_entries is
when HOLD => num_entries <= num_entries;
when RST => num_entries <= 0;
when INCR => if next_write_addr < MAX_ARP_ENTRIES then num_entries <= num_entries + 1; else num_entries <= num_entries; end if;
end case;
 
-- next_read_addr counts and wraps
case set_next_read_addr is
when HOLD => next_read_addr <= next_read_addr;
when RST => next_read_addr <= 0;
when INCR => if next_read_addr < MAX_ARP_ENTRIES then next_read_addr <= next_read_addr + 1; else next_read_addr <= 0; end if;
end case;
end if;
end if;
end process;
 
end Behavioral;
/tags/v2.3/rtl/vhdl/arp_REQ.vhd
0,0 → 1,338
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 12:00:04 05/31/2011
-- Design Name:
-- Module Name: arp_REQ - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle requests for ARP resolution
-- responds from single entry cache or searches external arp store, or asks to send a request
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created from arp.vhd 0.2
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.arp_types.all;
 
entity arp_req is
generic (
no_default_gateway : boolean := true; -- set to false if communicating with devices accessed
-- through a "default gateway or router"
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5 -- # wrong nwk pkts received before set error
);
port (
-- lookup request signals
arp_req_req : in arp_req_req_type; -- request for a translation from IP to MAC
arp_req_rslt : out arp_req_rslt_type; -- the result
-- external arp store signals
arp_store_req : out arp_store_rdrequest_t; -- requesting a lookup or store
arp_store_result : in arp_store_result_t; -- the result
-- network request signals
arp_nwk_req : out arp_nwk_request_t; -- requesting resolution via the network
arp_nwk_result : in arp_nwk_result_t; -- the result
-- system signals
clear_cache : in std_logic; -- clear the internal cache
nwk_gateway : in std_logic_vector(31 downto 0); -- IP address of default gateway
nwk_mask : in std_logic_vector(31 downto 0); -- Net mask
clk : in std_logic;
reset : in std_logic
);
end arp_req;
 
architecture Behavioral of arp_req is
 
type req_state_t is (IDLE, LOOKUP, WAIT_REPLY, PAUSE1, PAUSE2, PAUSE3);
type set_cntr_t is (HOLD, CLR, INCR);
type set_clr_type is (SET, CLR, HOLD);
 
-- state variables
signal req_state : req_state_t;
signal req_ip_addr : std_logic_vector (31 downto 0); -- IP address to lookup
signal arp_entry_cache : arp_entry_t; -- single entry cache for fast response
signal cache_valid : std_logic; -- single entry cache is valid
signal nwk_rx_cntr : unsigned(7 downto 0); -- counts nwk rx pkts that dont satisfy
signal freq_scaler : unsigned (31 downto 0); -- scales data_in_clk downto 1Hz
signal timer : unsigned (7 downto 0); -- counts seconds timeout
signal timeout_reg : std_logic;
 
-- busses
signal next_req_state : req_state_t;
signal arp_entry_val : arp_entry_t;
 
-- requester control signals
signal set_req_state : std_logic;
signal set_req_ip : std_logic;
signal store_arp_cache : std_logic;
signal set_nwk_rx_cntr : set_cntr_t;
signal set_timer : set_cntr_t; -- timer reset, count, hold control
signal timer_enable : std_logic; -- enable the timer counting
signal set_timeout : set_clr_type; -- control the timeout register
signal clear_cache_valid : std_logic;
 
signal l_arp_req_req_ip : std_logic_vector(31 downto 0); -- local network IP address for resolution
 
begin
 
default_GW: if (not no_default_gateway) generate
default_gw_comb_p: process (arp_req_req.ip, nwk_gateway, nwk_mask) is
begin -- process default_gw_comb_p
-- translate IP addresses to local IP address if necessary
if ((nwk_mask and arp_req_req.ip) = (nwk_mask and nwk_gateway)) then
-- on local network
l_arp_req_req_ip <= arp_req_req.ip;
else
-- on remote network
l_arp_req_req_ip <= nwk_gateway;
end if;
end process default_gw_comb_p;
end generate default_GW;
no_default_GW: if (no_default_gateway) generate
no_default_gw_comb_p: process (arp_req_req.ip) is
begin -- process no_default_gw_comb_p
l_arp_req_req_ip <= arp_req_req.ip;
end process no_default_gw_comb_p;
end generate no_default_GW;
 
req_combinatorial : process (
arp_entry_cache.ip, arp_entry_cache.mac, arp_nwk_result.entry, arp_nwk_result.entry.ip,
arp_nwk_result.entry.mac, arp_nwk_result.status, arp_req_req.lookup_req,
arp_store_result.entry, arp_store_result.entry.mac, arp_store_result.status, cache_valid,
clear_cache, freq_scaler, l_arp_req_req_ip, nwk_rx_cntr, req_ip_addr, req_state,
timeout_reg, timer)
begin
-- set output followers
arp_req_rslt.got_mac <= '0'; -- set initial value of request result outputs
arp_req_rslt.got_err <= '0';
arp_req_rslt.mac <= (others => '0');
arp_store_req.req <= '0';
arp_store_req.ip <= (others => '0');
arp_nwk_req.req <= '0';
arp_nwk_req.ip <= (others => '0');
 
-- zero time response to lookup request if already in cache
if arp_req_req.lookup_req = '1' and l_arp_req_req_ip = arp_entry_cache.ip and cache_valid = '1' then
arp_req_rslt.got_mac <= '1';
arp_req_rslt.mac <= arp_entry_cache.mac;
elsif arp_req_req.lookup_req = '1' then
-- hold off got_mac while req is there as arp_entry will not be correct yet
arp_req_rslt.got_mac <= '0';
arp_req_rslt.mac <= arp_entry_cache.mac;
else
arp_req_rslt.got_mac <= cache_valid;
arp_req_rslt.mac <= arp_entry_cache.mac;
end if;
 
if arp_req_req.lookup_req = '1' then
-- ensure any existing error report is killed at the start of a request
arp_req_rslt.got_err <= '0';
else
arp_req_rslt.got_err <= timeout_reg;
end if;
 
-- set signal defaults
next_req_state <= IDLE;
set_req_state <= '0';
set_req_ip <= '0';
store_arp_cache <= '0';
arp_entry_val.ip <= (others => '0');
arp_entry_val.mac <= (others => '0');
set_nwk_rx_cntr <= HOLD;
set_timer <= INCR; -- default is timer running, unless we hold or reset it
set_timeout <= HOLD;
timer_enable <= '0';
clear_cache_valid <= clear_cache;
 
-- combinatorial logic
if freq_scaler = x"00000000" then
timer_enable <= '1';
end if;
 
-- REQ FSM
case req_state is
when IDLE =>
set_timer <= CLR;
if arp_req_req.lookup_req = '1' then
-- check if we already have the info in cache
if l_arp_req_req_ip = arp_entry_cache.ip and cache_valid = '1' then
-- already have this IP - feed output back
arp_req_rslt.got_mac <= '1';
arp_req_rslt.mac <= arp_entry_cache.mac;
else
clear_cache_valid <= '1'; -- remove cache entry
set_timeout <= CLR;
next_req_state <= LOOKUP;
set_req_state <= '1';
set_req_ip <= '1';
end if;
end if;
 
when LOOKUP =>
-- put request on the store
arp_store_req.ip <= req_ip_addr;
arp_store_req.req <= '1';
case arp_store_result.status is
when FOUND =>
-- update the cache
arp_entry_val <= arp_store_result.entry;
store_arp_cache <= '1';
-- and feed output back
arp_req_rslt.got_mac <= '1';
arp_req_rslt.mac <= arp_store_result.entry.mac;
next_req_state <= IDLE;
set_req_state <= '1';
when NOT_FOUND =>
-- need to request from the network
set_timer <= CLR;
set_nwk_rx_cntr <= CLR;
arp_nwk_req.req <= '1';
arp_nwk_req.ip <= req_ip_addr;
next_req_state <= WAIT_REPLY;
set_req_state <= '1';
when others =>
-- just keep waiting - no timeout (assumes lookup with either succeed or fail)
end case;
when WAIT_REPLY =>
case arp_nwk_result.status is
when RECEIVED =>
if arp_nwk_result.entry.ip = req_ip_addr then
-- store into cache
arp_entry_val <= arp_nwk_result.entry;
store_arp_cache <= '1';
-- and feed output back
arp_req_rslt.got_mac <= '1';
arp_req_rslt.mac <= arp_nwk_result.entry.mac;
next_req_state <= IDLE;
set_req_state <= '1';
else
if nwk_rx_cntr > ARP_MAX_PKT_TMO then
set_timeout <= SET;
next_req_state <= IDLE;
set_req_state <= '1';
else
set_nwk_rx_cntr <= INCR;
end if;
end if;
 
when error =>
set_timeout <= SET;
 
when others =>
if timer >= ARP_TIMEOUT then
set_timeout <= SET;
next_req_state <= PAUSE1;
set_req_state <= '1';
end if;
end case;
 
when PAUSE1 =>
next_req_state <= PAUSE2;
set_req_state <= '1';
 
when PAUSE2 =>
next_req_state <= PAUSE3;
set_req_state <= '1';
 
when PAUSE3 =>
next_req_state <= IDLE;
set_req_state <= '1';
end case;
end process;
 
req_sequential : process (clk)
begin
if rising_edge(clk) then
if reset = '1' then
-- reset state variables
req_state <= IDLE;
req_ip_addr <= (others => '0');
arp_entry_cache.ip <= (others => '0');
arp_entry_cache.mac <= (others => '0');
cache_valid <= '0';
nwk_rx_cntr <= (others => '0');
freq_scaler <= to_unsigned(CLOCK_FREQ, 32);
timer <= (others => '0');
timeout_reg <= '0';
else
-- Next req_state processing
if set_req_state = '1' then
req_state <= next_req_state;
else
req_state <= req_state;
end if;
 
-- Latch the requested IP address
if set_req_ip = '1' then
req_ip_addr <= l_arp_req_req_ip;
else
req_ip_addr <= req_ip_addr;
end if;
 
-- network received counter
case set_nwk_rx_cntr is
when CLR => nwk_rx_cntr <= (others => '0');
when INCR => nwk_rx_cntr <= nwk_rx_cntr + 1;
when HOLD => nwk_rx_cntr <= nwk_rx_cntr;
end case;
 
-- set the arp_entry_cache
if clear_cache_valid = '1' then
arp_entry_cache <= arp_entry_cache;
cache_valid <= '0';
elsif store_arp_cache = '1' then
arp_entry_cache <= arp_entry_val;
cache_valid <= '1';
else
arp_entry_cache <= arp_entry_cache;
cache_valid <= cache_valid;
end if;
 
-- freq scaling and 1-sec timer
if freq_scaler = x"00000000" then
freq_scaler <= to_unsigned(CLOCK_FREQ, 32);
else
freq_scaler <= freq_scaler - 1;
end if;
 
-- timer processing
case set_timer is
when CLR =>
timer <= x"00";
when INCR =>
if timer_enable = '1' then
timer <= timer + 1;
else
timer <= timer;
end if;
when HOLD =>
timer <= timer;
end case;
 
-- timeout latching
case set_timeout is
when CLR => timeout_reg <= '0';
when SET => timeout_reg <= '1';
when HOLD => timeout_reg <= timeout_reg;
end case;
 
end if;
end if;
end process;
 
end Behavioral;
/tags/v2.3/rtl/vhdl/arpv2.vhd
0,0 → 1,321
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 12:00:04 05/31/2011
-- Design Name:
-- Module Name: arpv2 - Structural
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle simple IP lookup in 1-deep cache and arp store
-- request cache fill through ARP protocol if required
-- Handle ARP protocol
-- Respond to ARP requests and replies
-- Ignore pkts that are not ARP
-- Ignore pkts that are not addressed to us
--
-- structural decomposition includes
-- arp TX block - encoding of ARP protocol
-- arp RX block - decoding of ARP protocol
-- arp REQ block - sequencing requests for resolution
-- arp STORE block - storing address resolution entries (indexed by IP addr)
-- arp sync block - sync between master RX clock and TX clock domains
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.arp_types.all;
 
entity arpv2 is
generic (
no_default_gateway : boolean := true; -- set to false if communicating with devices accessed
-- though a "default gateway or router"
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the arp store
);
port (
-- lookup request signals
arp_req_req : in arp_req_req_type;
arp_req_rslt : out arp_req_rslt_type;
-- MAC layer RX signals
data_in_clk : in std_logic;
reset : in std_logic;
data_in : in std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
data_in_valid : in std_logic; -- indicates data_in valid on clock
data_in_last : in std_logic; -- indicates last data in frame
-- 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_granted : in std_logic; -- indicates that access to channel has been granted
data_out_clk : in std_logic;
data_out_ready : in std_logic; -- indicates system ready to consume data
data_out_valid : out std_logic; -- indicates data out is valid
data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame
data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame
data_out : out std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
-- system signals
our_mac_address : in std_logic_vector (47 downto 0);
our_ip_address : in std_logic_vector (31 downto 0);
nwk_gateway : in std_logic_vector (31 downto 0) := (others => '0'); -- IP address of default gateway
nwk_mask : in std_logic_vector (31 downto 0) := (others => '0'); -- Net mask
control : in arp_control_type;
req_count : out std_logic_vector(7 downto 0) -- count of arp pkts received
);
end arpv2;
 
architecture structural of arpv2 is
 
component arp_req
generic (
no_default_gateway : boolean := true;
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5 -- # wrong nwk pkts received before set error
);
port (
-- lookup request signals
arp_req_req : in arp_req_req_type; -- request for a translation from IP to MAC
arp_req_rslt : out arp_req_rslt_type; -- the result
-- external arp store signals
arp_store_req : out arp_store_rdrequest_t; -- requesting a lookup or store
arp_store_result : in arp_store_result_t; -- the result
-- network request signals
arp_nwk_req : out arp_nwk_request_t; -- requesting resolution via the network
arp_nwk_result : in arp_nwk_result_t; -- the result
-- system signals
clear_cache : in std_logic; -- clear the internal cache
nwk_gateway : in std_logic_vector(31 downto 0); -- IP address of default gateway
nwk_mask : in std_logic_vector(31 downto 0); -- Net mask
clk : in std_logic;
reset : in std_logic
);
end component;
 
component arp_tx
port(
-- control signals
send_I_have : in std_logic; -- pulse will be latched
arp_entry : in arp_entry_t; -- arp target for I_have req (will be latched)
send_who_has : in std_logic; -- pulse will be latched
ip_entry : in std_logic_vector (31 downto 0); -- ip target for who_has req (will be latched)
-- 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_granted : in std_logic; -- indicates that access to channel has been granted
data_out_ready : in std_logic; -- indicates system ready to consume data
data_out_valid : out std_logic; -- indicates data out is valid
data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame
data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame
data_out : out std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
-- system signals
our_mac_address : in std_logic_vector (47 downto 0);
our_ip_address : in std_logic_vector (31 downto 0);
tx_clk : in std_logic;
reset : in std_logic
);
end component;
 
component arp_rx
port(
-- MAC layer RX signals
data_in : in std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
data_in_valid : in std_logic; -- indicates data_in valid on clock
data_in_last : in std_logic; -- indicates last data in frame
-- ARP output signals
recv_who_has : out std_logic; -- pulse will be latched
arp_entry_for_who_has : out arp_entry_t; -- target for who_has msg (Iie, who to reply to)
recv_I_have : out std_logic; -- pulse will be latched
arp_entry_for_I_have : out arp_entry_t; -- arp target for I_have msg
-- control and status signals
req_count : out std_logic_vector(7 downto 0); -- count of arp pkts received
-- system signals
our_ip_address : in std_logic_vector (31 downto 0);
rx_clk : in std_logic;
reset : in std_logic
);
end component;
 
 
component arp_store_br
generic (
MAX_ARP_ENTRIES : integer := 255 -- max entries in the store
);
port (
-- read signals
read_req : in arp_store_rdrequest_t; -- requesting a lookup or store
read_result : out arp_store_result_t; -- the result
-- write signals
write_req : in arp_store_wrrequest_t; -- requesting a lookup or store
-- control and status signals
clear_store : in std_logic; -- erase all entries
entry_count : out unsigned(7 downto 0); -- how many entries currently in store
-- system signals
clk : in std_logic;
reset : in std_logic
);
end component;
 
component arp_sync
port (
-- REQ to TX
arp_nwk_req : in arp_nwk_request_t; -- request for a translation from IP to MAC
send_who_has : out std_logic;
ip_entry : out std_logic_vector (31 downto 0);
-- RX to TX
recv_who_has : in std_logic; -- this is for us, we will respond
arp_entry_for_who_has : in arp_entry_t;
send_I_have : out std_logic;
arp_entry : out arp_entry_t;
-- RX to REQ
I_have_received : in std_logic;
nwk_result_status : out arp_nwk_rslt_t;
-- System Signals
rx_clk : in std_logic;
tx_clk : in std_logic;
reset : in std_logic
);
end component;
 
 
-- interconnect REQ -> ARP_TX
signal arp_nwk_req_int : arp_nwk_request_t; -- tx req from REQ
 
signal send_I_have_int : std_logic;
signal arp_entry_int : arp_entry_t;
signal send_who_has_int : std_logic;
signal ip_entry_int : std_logic_vector (31 downto 0);
 
-- interconnect REQ <-> ARP_STORE
signal arp_store_req_int : arp_store_rdrequest_t; -- lookup request
signal arp_store_result_int : arp_store_result_t; -- lookup result
 
-- interconnect ARP_RX -> REQ
signal nwk_result_status_int : arp_nwk_rslt_t; -- response from a TX req
 
-- interconnect ARP_RX -> ARP_STORE
signal recv_I_have_int : std_logic; -- path to store new arp entry
signal arp_entry_for_I_have_int : arp_entry_t;
 
-- interconnect ARP_RX -> ARP_TX
signal recv_who_has_int : std_logic; -- path for reply when we can anser
signal arp_entry_for_who_has_int : arp_entry_t; -- target for who_has msg (ie, who to reply to)
 
begin
 
 
req : arp_req
generic map (
no_default_gateway => no_default_gateway,
CLOCK_FREQ => CLOCK_FREQ,
ARP_TIMEOUT => ARP_TIMEOUT,
ARP_MAX_PKT_TMO => ARP_MAX_PKT_TMO
)
port map (
-- lookup request signals
arp_req_req => arp_req_req,
arp_req_rslt => arp_req_rslt,
-- external arp store signals
arp_store_req => arp_store_req_int,
arp_store_result => arp_store_result_int,
-- network request signals
arp_nwk_req => arp_nwk_req_int,
arp_nwk_result.status => nwk_result_status_int,
arp_nwk_result.entry => arp_entry_for_I_have_int,
-- system signals
clear_cache => control.clear_cache,
nwk_gateway => nwk_gateway,
nwk_mask => nwk_mask,
clk => data_in_clk,
reset => reset
);
 
sync : arp_sync port map (
-- REQ to TX
arp_nwk_req => arp_nwk_req_int,
send_who_has => send_who_has_int,
ip_entry => ip_entry_int,
-- RX to TX
recv_who_has => recv_who_has_int,
arp_entry_for_who_has => arp_entry_for_who_has_int,
send_I_have => send_I_have_int,
arp_entry => arp_entry_int,
-- RX to REQ
I_have_received => recv_I_have_int,
nwk_result_status => nwk_result_status_int,
-- system
rx_clk => data_in_clk,
tx_clk => data_out_clk,
reset => reset
);
 
tx : arp_tx port map (
-- control signals
send_I_have => send_I_have_int,
arp_entry => arp_entry_int,
send_who_has => send_who_has_int,
ip_entry => ip_entry_int,
-- MAC layer TX signals
mac_tx_req => mac_tx_req,
mac_tx_granted => mac_tx_granted,
data_out_ready => data_out_ready,
data_out_valid => data_out_valid,
data_out_first => data_out_first,
data_out_last => data_out_last,
data_out => data_out,
-- system signals
our_ip_address => our_ip_address,
our_mac_address => our_mac_address,
tx_clk => data_out_clk,
reset => reset
);
 
rx : arp_rx port map (
-- MAC layer RX signals
data_in => data_in,
data_in_valid => data_in_valid,
data_in_last => data_in_last,
-- ARP output signals
recv_who_has => recv_who_has_int,
arp_entry_for_who_has => arp_entry_for_who_has_int,
recv_I_have => recv_I_have_int,
arp_entry_for_I_have => arp_entry_for_I_have_int,
-- control and status signals
req_count => req_count,
-- system signals
our_ip_address => our_ip_address,
rx_clk => data_in_clk,
reset => reset
);
 
store : arp_store_br
generic map (
MAX_ARP_ENTRIES => MAX_ARP_ENTRIES
)
port map (
-- read signals
read_req => arp_store_req_int,
read_result => arp_store_result_int,
-- write signals
write_req.req => recv_I_have_int,
write_req.entry => arp_entry_for_I_have_int,
-- control and status signals
clear_store => control.clear_cache,
entry_count => open,
-- system signals
clk => data_in_clk,
reset => reset
);
 
 
end structural;
 
/tags/v2.3/rtl/vhdl/arp_RX.vhd
0,0 → 1,373
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 12:00:04 05/31/2011
-- Design Name:
-- Module Name: arp_rx - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle receipt of arp pkt
-- ignores other types of pkt
--
-- When it receives an ARP pkt that is either addressed to our IP or is a global request,
-- it outputs for a single clock cycle either recv_who_has or recv_I_have along
-- with associated mac or arp entry data.
--
-- Note that if recv who_has and we have it, then we also assert I_have so that we can cache the rev lookup
-- on the expectation that we will want to reply to this host.
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created - refactored from arp v0.02 module
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.arp_types.all;
 
entity arp_rx is
port (
-- MAC layer RX signals
data_in : in std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
data_in_valid : in std_logic; -- indicates data_in valid on clock
data_in_last : in std_logic; -- indicates last data in frame
-- ARP output signals
recv_who_has : out std_logic; -- pulse will be latched
arp_entry_for_who_has : out arp_entry_t; -- target for who_has msg (Iie, who to reply to)
recv_I_have : out std_logic; -- pulse will be latched
arp_entry_for_I_have : out arp_entry_t; -- arp target for I_have msg
-- control and status signals
req_count : out std_logic_vector(7 downto 0); -- count of arp pkts received
-- system signals
our_ip_address : in std_logic_vector (31 downto 0);
rx_clk : in std_logic;
reset : in std_logic
);
end arp_rx;
 
 
architecture Behavioral of arp_rx is
 
type rx_state_t is (IDLE, PARSE, PROCESS_ARP, WAIT_END);
type rx_event_t is (NO_EVENT, DATA);
type count_mode_t is (RST, INCR, HOLD);
type arp_oper_t is (NOP, REQUEST, REPLY);
 
type tx_state_type is (IDLE, WAIT_MAC, SEND);
 
-- state variables
signal send_request_needed : std_logic;
signal tx_mac_chn_reqd : std_logic;
 
signal rx_state : rx_state_t;
signal rx_count : unsigned (7 downto 0);
signal arp_operation : arp_oper_t;
signal arp_req_count : unsigned (7 downto 0);
signal new_arp_entry : arp_entry_t;
 
-- FIXME - remove these debug state signals
signal arp_err_data : std_logic_vector (7 downto 0);
signal set_err_data : std_logic;
 
attribute keep : string;
attribute keep of arp_err_data : signal is "true";
 
 
-- rx control signals
signal next_rx_state : rx_state_t;
signal set_rx_state : std_logic;
signal rx_event : rx_event_t;
signal rx_count_mode : count_mode_t;
signal set_arp_oper : std_logic;
signal arp_oper_set_val : arp_oper_t;
signal dataval : std_logic_vector (7 downto 0);
signal count_arp_rcvd : std_logic;
 
signal set_mac5 : std_logic;
signal set_mac4 : std_logic;
signal set_mac3 : std_logic;
signal set_mac2 : std_logic;
signal set_mac1 : std_logic;
signal set_mac0 : std_logic;
 
signal set_ip3 : std_logic;
signal set_ip2 : std_logic;
signal set_ip1 : std_logic;
signal set_ip0 : std_logic;
 
 
 
-- function to determine whether the rx pkt is an arp pkt and whether we want to process it
-- Returns 1 if we should discard
-- The following will make us ignore the frame (all values hexadecimal):
-- PDU type /= 0806
-- Protocol Type /= 0800
-- Hardware Type /= 1
-- Hardware Length /= 6
-- Protocol Length /= 4
-- Operation /= 1 or 2
-- Target IP /= our IP (i.er. message is not meant for us)
--
function not_our_arp(data : std_logic_vector; count : unsigned; our_ip : std_logic_vector) return std_logic is
begin
if
(count = 12 and data /= x"08") or -- PDU type 0806 : ARP
(count = 13 and data /= x"06") or
(count = 14 and data /= x"00") or -- HW type 1 : eth
(count = 15 and data /= x"01") or
(count = 16 and data /= x"08") or -- Protocol 0800 : IP
(count = 17 and data /= x"00") or
(count = 18 and data /= x"06") or -- HW Length 6
(count = 19 and data /= x"04") or -- protocol length 4
(count = 20 and data /= x"00") or -- operation 1 or 2 (req or reply)
(count = 21 and data /= x"01" and data /= x"02") or
(count = 38 and data /= our_ip(31 downto 24)) or -- target IP is ours
(count = 39 and data /= our_ip(23 downto 16)) or
(count = 40 and data /= our_ip(15 downto 8)) or
(count = 41 and data /= our_ip(7 downto 0))
then
return '1';
else
return '0';
end if;
end function not_our_arp;
 
begin
 
rx_combinatorial : process (
-- input signals
data_in, data_in_valid, data_in_last, our_ip_address,
-- state variables
rx_state, rx_count, arp_operation, arp_req_count, arp_err_data, new_arp_entry,
-- control signals
next_rx_state, set_rx_state, rx_event, rx_count_mode, set_arp_oper, arp_oper_set_val,
dataval, set_mac5, set_mac4, set_mac3, set_mac2, set_mac1, set_mac0, set_ip3, set_ip2, set_ip1, set_ip0, set_err_data,
count_arp_rcvd
)
begin
-- set output followers
req_count <= std_logic_vector(arp_req_count);
 
-- set defaults for combinatorial outputs
recv_who_has <= '0';
arp_entry_for_who_has.ip <= (others => '0');
arp_entry_for_who_has.mac <= (others => '0');
recv_I_have <= '0';
arp_entry_for_I_have.ip <= (others => '0');
arp_entry_for_I_have.mac <= (others => '0');
 
-- set signal defaults
next_rx_state <= IDLE;
set_rx_state <= '0';
rx_event <= NO_EVENT;
rx_count_mode <= HOLD;
set_arp_oper <= '0';
arp_oper_set_val <= NOP;
dataval <= (others => '0');
set_mac5 <= '0';
set_mac4 <= '0';
set_mac3 <= '0';
set_mac2 <= '0';
set_mac1 <= '0';
set_mac0 <= '0';
set_ip3 <= '0';
set_ip2 <= '0';
set_ip1 <= '0';
set_ip0 <= '0';
count_arp_rcvd <= '0';
set_err_data <= '0';
 
-- determine event (if any)
if data_in_valid = '1' then
rx_event <= DATA;
end if;
 
-- RX FSM
case rx_state is
when IDLE =>
rx_count_mode <= RST;
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
next_rx_state <= PARSE;
set_rx_state <= '1';
rx_count_mode <= INCR;
end case;
 
when PARSE =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
rx_count_mode <= INCR;
-- handle early frame termination
if data_in_last = '1' then
next_rx_state <= IDLE;
set_rx_state <= '1';
--else
end if;
-- check for end of frame. Also, detect and discard if not our frame
if rx_count = 41 then -- TB 2013-01-14 15:09:45 was 42
next_rx_state <= PROCESS_ARP;
set_rx_state <= '1';
elsif not_our_arp(data_in, rx_count, our_ip_address) = '1' then
dataval <= data_in;
set_err_data <= '1';
next_rx_state <= WAIT_END;
set_rx_state <= '1';
elsif rx_count = 21 then
-- capture ARP operation
case data_in is
when x"01" =>
arp_oper_set_val <= REQUEST;
set_arp_oper <= '1';
when x"02" =>
arp_oper_set_val <= REPLY;
set_arp_oper <= '1';
when others => -- ignore other values
end case;
-- capture source mac addr
elsif rx_count = 22 then
set_mac5 <= '1';
dataval <= data_in;
elsif rx_count = 23 then
set_mac4 <= '1';
dataval <= data_in;
elsif rx_count = 24 then
set_mac3 <= '1';
dataval <= data_in;
elsif rx_count = 25 then
set_mac2 <= '1';
dataval <= data_in;
elsif rx_count = 26 then
set_mac1 <= '1';
dataval <= data_in;
elsif rx_count = 27 then
set_mac0 <= '1';
dataval <= data_in;
-- capture source ip addr
elsif rx_count = 28 then
set_ip3 <= '1';
dataval <= data_in;
elsif rx_count = 29 then
set_ip2 <= '1';
dataval <= data_in;
elsif rx_count = 30 then
set_ip1 <= '1';
dataval <= data_in;
elsif rx_count = 31 then
set_ip0 <= '1';
dataval <= data_in;
end if;
-- end if;
end case;
 
when PROCESS_ARP =>
next_rx_state <= WAIT_END;
set_rx_state <= '1';
arp_oper_set_val <= NOP;
set_arp_oper <= '1';
case arp_operation is
when NOP => -- (nothing to do)
when REQUEST =>
count_arp_rcvd <= '1';
recv_who_has <= '1';
arp_entry_for_who_has <= new_arp_entry;
-- setting I_Have as well allows us to cache the remote node's entry immediately
recv_I_have <= '1';
arp_entry_for_I_have <= new_arp_entry;
when REPLY =>
count_arp_rcvd <= '1';
recv_I_have <= '1';
arp_entry_for_I_have <= new_arp_entry;
end case;
 
when WAIT_END =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if data_in_last = '1' then
next_rx_state <= IDLE;
set_rx_state <= '1';
end if;
end case;
end case;
end process;
 
rx_sequential : process (rx_clk)
begin
if rising_edge(rx_clk) then
if reset = '1' then
-- reset state variables
rx_state <= IDLE;
rx_count <= x"00";
arp_operation <= NOP;
arp_req_count <= x"00";
arp_err_data <= (others => '0');
else
-- Next rx_state processing
if set_rx_state = '1' then
rx_state <= next_rx_state;
else
rx_state <= rx_state;
end if;
 
-- rx_count processing
case rx_count_mode is
when RST =>
rx_count <= x"00";
when INCR =>
rx_count <= rx_count + 1;
when HOLD =>
rx_count <= rx_count;
end case;
 
-- err data
if set_err_data = '1' then
arp_err_data <= data_in;
else
arp_err_data <= arp_err_data;
end if;
 
-- arp operation processing
if set_arp_oper = '1' then
arp_operation <= arp_oper_set_val;
else
arp_operation <= arp_operation;
end if;
 
-- source mac capture
if (set_mac5 = '1') then new_arp_entry.mac(47 downto 40) <= dataval; end if;
if (set_mac4 = '1') then new_arp_entry.mac(39 downto 32) <= dataval; end if;
if (set_mac3 = '1') then new_arp_entry.mac(31 downto 24) <= dataval; end if;
if (set_mac2 = '1') then new_arp_entry.mac(23 downto 16) <= dataval; end if;
if (set_mac1 = '1') then new_arp_entry.mac(15 downto 8) <= dataval; end if;
if (set_mac0 = '1') then new_arp_entry.mac(7 downto 0) <= dataval; end if;
 
-- source ip capture
if (set_ip3 = '1') then new_arp_entry.ip(31 downto 24) <= dataval; end if;
if (set_ip2 = '1') then new_arp_entry.ip(23 downto 16) <= dataval; end if;
if (set_ip1 = '1') then new_arp_entry.ip(15 downto 8) <= dataval; end if;
if (set_ip0 = '1') then new_arp_entry.ip(7 downto 0) <= dataval; end if;
 
-- set arp entry request
if count_arp_rcvd = '1' then
-- count another ARP pkt received
arp_req_count <= arp_req_count + 1;
else
arp_req_count <= arp_req_count;
end if;
end if;
end if;
end process;
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/arp_TX.vhd
0,0 → 1,334
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 12:00:04 05/31/2011
-- Design Name:
-- Module Name: arp_tx - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle transmission of an ARP packet.
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created - refactored this arp_tx module from the complete arp v0.02 module
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.arp_types.all;
 
entity arp_tx is
port (
-- control signals
send_I_have : in std_logic; -- pulse will be latched
arp_entry : in arp_entry_t; -- arp target for I_have req (will be latched)
send_who_has : in std_logic; -- pulse will be latched
ip_entry : in std_logic_vector (31 downto 0); -- IP target for who_has req (will be latched)
-- 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_granted : in std_logic; -- indicates that access to channel has been granted
data_out_ready : in std_logic; -- indicates system ready to consume data
data_out_valid : out std_logic; -- indicates data out is valid
data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame
data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame
data_out : out std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
-- system signals
our_mac_address : in std_logic_vector (47 downto 0);
our_ip_address : in std_logic_vector (31 downto 0);
tx_clk : in std_logic;
reset : in std_logic
);
end arp_tx;
 
architecture Behavioral of arp_tx is
 
type count_mode_t is (RST, INCR, HOLD);
type set_clr_t is (SET, CLR, HOLD);
type tx_state_t is (IDLE, WAIT_MAC, SEND);
type tx_mode_t is (REPLY, REQUEST);
 
-- state variables
signal tx_mac_chn_reqd : std_logic;
signal tx_state : tx_state_t;
signal tx_count : unsigned (7 downto 0);
signal send_I_have_reg : std_logic;
signal send_who_has_reg : std_logic;
signal I_have_target : arp_entry_t; -- latched target for "I have" request
signal who_has_target : std_logic_vector (31 downto 0); -- latched IP for "who has" request
signal tx_mode : tx_mode_t; -- what sort of tx to make
signal target : arp_entry_t; -- target to send to
 
-- busses
signal next_tx_state : tx_state_t;
signal tx_mode_val : tx_mode_t;
signal target_val : arp_entry_t;
 
-- tx control signals
signal set_tx_state : std_logic;
signal tx_count_mode : count_mode_t;
signal set_chn_reqd : set_clr_t;
signal kill_data_out_valid : std_logic;
signal set_send_I_have : set_clr_t;
signal set_send_who_has : set_clr_t;
signal set_tx_mode : std_logic;
signal set_target : std_logic;
begin
 
tx_combinatorial : process (
-- input signals
send_I_have, send_who_has, arp_entry, ip_entry, data_out_ready, mac_tx_granted,
our_mac_address, our_ip_address, reset,
-- state variables
tx_state, tx_count, tx_mac_chn_reqd, I_have_target, who_has_target,
send_I_have_reg, send_who_has_reg, tx_mode, target,
-- busses
next_tx_state, tx_mode_val, target_val,
-- control signals
tx_count_mode, kill_data_out_valid, set_send_I_have, set_send_who_has,
set_chn_reqd, set_tx_mode, set_target
)
begin
-- set output followers
mac_tx_req <= tx_mac_chn_reqd;
 
-- set combinatorial output defaults
data_out_first <= '0';
 
case tx_state is
when SEND =>
if data_out_ready = '1' and kill_data_out_valid = '0' then
data_out_valid <= '1';
else
data_out_valid <= '0';
end if;
when others => data_out_valid <= '0';
end case;
 
-- set bus defaults
next_tx_state <= IDLE;
tx_mode_val <= REPLY;
target_val.ip <= (others => '0');
target_val.mac <= (others => '1');
 
-- set signal defaults
set_tx_state <= '0';
tx_count_mode <= HOLD;
data_out <= x"00";
data_out_last <= '0';
set_chn_reqd <= HOLD;
kill_data_out_valid <= '0';
set_send_I_have <= HOLD;
set_send_who_has <= HOLD;
set_tx_mode <= '0';
set_target <= '0';
 
-- process requests in regardless of FSM state
if send_I_have = '1' then
set_send_I_have <= SET;
end if;
if send_who_has = '1' then
set_send_who_has <= SET;
end if;
 
-- TX FSM
case tx_state is
when IDLE =>
tx_count_mode <= RST;
if send_I_have_reg = '1' then
set_chn_reqd <= SET;
tx_mode_val <= REPLY;
set_tx_mode <= '1';
target_val <= I_have_target;
set_target <= '1';
set_send_I_have <= CLR;
next_tx_state <= WAIT_MAC;
set_tx_state <= '1';
elsif send_who_has_reg = '1' then
set_chn_reqd <= SET;
tx_mode_val <= REQUEST;
set_tx_mode <= '1';
target_val.ip <= who_has_target;
target_val.mac <= (others => '1');
set_target <= '1';
set_send_who_has <= CLR;
next_tx_state <= WAIT_MAC;
set_tx_state <= '1';
else
set_chn_reqd <= CLR;
end if;
 
when WAIT_MAC =>
tx_count_mode <= RST;
if mac_tx_granted = '1' then
next_tx_state <= SEND;
set_tx_state <= '1';
end if;
-- TODO - should handle timeout here
when SEND =>
if data_out_ready = '1' then
tx_count_mode <= INCR;
end if;
case tx_count is
when x"00" => data_out_first <= data_out_ready;
data_out <= target.mac (47 downto 40); -- target mac--data_out <= x"ff"; -- dst = broadcast
when x"01" => data_out <= target.mac (39 downto 32); --data_out <= x"ff";
when x"02" => data_out <= target.mac (31 downto 24); --data_out <= x"ff";
when x"03" => data_out <= target.mac (23 downto 16); --data_out <= x"ff";
when x"04" => data_out <= target.mac (15 downto 8); --data_out <= x"ff";
when x"05" => data_out <= target.mac (7 downto 0); --data_out <= x"ff";
when x"06" => data_out <= our_mac_address (47 downto 40); -- src = our mac
when x"07" => data_out <= our_mac_address (39 downto 32);
when x"08" => data_out <= our_mac_address (31 downto 24);
when x"09" => data_out <= our_mac_address (23 downto 16);
when x"0a" => data_out <= our_mac_address (15 downto 8);
when x"0b" => data_out <= our_mac_address (7 downto 0);
when x"0c" => data_out <= x"08"; -- pkt type = 0806 : ARP
when x"0d" => data_out <= x"06";
when x"0e" => data_out <= x"00"; -- HW type = 0001 : eth
when x"0f" => data_out <= x"01";
when x"10" => data_out <= x"08"; -- protocol = 0800 : ip
when x"11" => data_out <= x"00";
when x"12" => data_out <= x"06"; -- HW size = 06
when x"13" => data_out <= x"04"; -- prot size = 04
 
when x"14" => data_out <= x"00"; -- opcode =
when x"15" =>
if tx_mode = REPLY then
data_out <= x"02"; -- 02 : REPLY
else
data_out <= x"01"; -- 01 : REQ
end if;
when x"16" => data_out <= our_mac_address (47 downto 40); -- sender mac
when x"17" => data_out <= our_mac_address (39 downto 32);
when x"18" => data_out <= our_mac_address (31 downto 24);
when x"19" => data_out <= our_mac_address (23 downto 16);
when x"1a" => data_out <= our_mac_address (15 downto 8);
when x"1b" => data_out <= our_mac_address (7 downto 0);
when x"1c" => data_out <= our_ip_address (31 downto 24); -- sender ip
when x"1d" => data_out <= our_ip_address (23 downto 16);
when x"1e" => data_out <= our_ip_address (15 downto 8);
when x"1f" => data_out <= our_ip_address (7 downto 0);
when x"20" => data_out <= target.mac (47 downto 40); -- target mac
when x"21" => data_out <= target.mac (39 downto 32);
when x"22" => data_out <= target.mac (31 downto 24);
when x"23" => data_out <= target.mac (23 downto 16);
when x"24" => data_out <= target.mac (15 downto 8);
when x"25" => data_out <= target.mac (7 downto 0);
when x"26" => data_out <= target.ip (31 downto 24); -- target ip
when x"27" => data_out <= target.ip (23 downto 16);
when x"28" => data_out <= target.ip (15 downto 8);
 
when x"29" =>
data_out <= target.ip(7 downto 0);
data_out_last <= '1';
when x"2a" =>
kill_data_out_valid <= '1'; -- data is no longer valid
next_tx_state <= IDLE;
set_tx_state <= '1';
 
when others =>
next_tx_state <= IDLE;
set_tx_state <= '1';
end case;
end case;
end process;
 
tx_sequential : process (tx_clk)
begin
if rising_edge(tx_clk) then
if reset = '1' then
-- reset state variables
tx_state <= IDLE;
tx_count <= (others => '0');
tx_mac_chn_reqd <= '0';
send_I_have_reg <= '0';
send_who_has_reg <= '0';
who_has_target <= (others => '0');
I_have_target.ip <= (others => '0');
I_have_target.mac <= (others => '0');
target.ip <= (others => '0');
target.mac <= (others => '1');
else
-- normal (non reset) processing
 
-- Next tx_state processing
if set_tx_state = '1' then
tx_state <= next_tx_state;
else
tx_state <= tx_state;
end if;
 
-- input request latching
case set_send_I_have is
when SET =>
send_I_have_reg <= '1';
I_have_target <= arp_entry;
when CLR =>
send_I_have_reg <= '0';
I_have_target <= I_have_target;
when HOLD =>
send_I_have_reg <= send_I_have_reg;
I_have_target <= I_have_target;
end case;
 
case set_send_who_has is
when SET =>
send_who_has_reg <= '1';
who_has_target <= ip_entry;
when CLR =>
send_who_has_reg <= '0';
who_has_target <= who_has_target;
when HOLD =>
send_who_has_reg <= send_who_has_reg;
who_has_target <= who_has_target;
end case;
 
-- tx mode
if set_tx_mode = '1' then
tx_mode <= tx_mode_val;
else
tx_mode <= tx_mode;
end if;
 
-- target latching
if set_target = '1' then
target <= target_val;
else
target <= target;
end if;
 
-- tx_count processing
case tx_count_mode is
when RST =>
tx_count <= x"00";
when INCR =>
tx_count <= tx_count + 1;
when HOLD =>
tx_count <= tx_count;
end case;
 
-- control access request to mac tx chn
case set_chn_reqd is
when SET => tx_mac_chn_reqd <= '1';
when CLR => tx_mac_chn_reqd <= '0';
when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
end case;
end if;
end if;
end process;
 
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/IPv4_TX.vhd
0,0 → 1,549
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 16:20:42 06/01/2011
-- Design Name:
-- Module Name: IPv4_TX - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle simple IP TX
-- doesnt handle segmentation
-- dest MAC addr resolution through ARP layer
-- Handle IPv4 protocol
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - fixed up setting of tx_result control defaults
-- Revision 0.03 - Added data_out_first
-- Revision 0.04 - Added handling of broadcast address
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
 
entity IPv4_TX is
port (
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
 
-- system signals
clk : in std_logic; -- same clock used to clock mac data and ip data
reset : in std_logic;
our_ip_address : in std_logic_vector (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
-- ARP lookup signals
arp_req_req : out arp_req_req_type;
arp_req_rslt : in arp_req_rslt_type;
-- 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_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_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 : out std_logic_vector (7 downto 0) -- ethernet frame (from dst mac addr through to last byte of frame)
);
end IPv4_TX;
 
architecture Behavioral of IPv4_TX is
 
type tx_state_type is (
IDLE,
WAIT_MAC, -- waiting for response from ARP for mac lookup
WAIT_CHN, -- waiting for tx access to MAC channel
SEND_ETH_HDR, -- sending the ethernet header
SEND_IP_HDR, -- sending the IP header
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 count_mode_type is (RST, INCR, HOLD);
type settable_cnt_type is (RST, SET, INCR, HOLD);
type set_clr_type is (SET, CLR, HOLD);
 
-- Configuration
 
constant IP_TTL : std_logic_vector (7 downto 0) := x"80";
 
-- TX state variables
signal tx_state : tx_state_type;
signal tx_count : unsigned (11 downto 0);
signal tx_result_reg : std_logic_vector (1 downto 0);
signal tx_mac : std_logic_vector (47 downto 0);
signal tx_mac_chn_reqd : std_logic;
signal tx_hdr_cks : std_logic_vector (23 downto 0);
signal mac_lookup_req : std_logic;
signal crc_state : crc_state_type;
signal arp_req_ip_reg : std_logic_vector (31 downto 0);
signal mac_data_out_ready_reg : std_logic;
 
-- tx control signals
signal next_tx_state : tx_state_type;
signal set_tx_state : std_logic;
signal next_tx_result : std_logic_vector (1 downto 0);
signal set_tx_result : std_logic;
signal tx_mac_value : std_logic_vector (47 downto 0);
signal set_tx_mac : std_logic;
signal tx_count_val : unsigned (11 downto 0);
signal tx_count_mode : settable_cnt_type;
signal tx_data : std_logic_vector (7 downto 0);
signal set_last : std_logic;
signal set_chn_reqd : 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
 
-- tx temp signals
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
--this function inverts all the bits of a vector if
--'en' is '1'.
variable Z : std_logic_vector(s1'high downto s1'low);
begin
for i in (s1'low) to s1'high loop
Z(i) := en xor s1(i);
end loop;
return Z;
end inv_if_one; -- end function
 
 
-- IP datagram header format
--
-- 0 4 8 16 19 24 31
-- --------------------------------------------------------------------------------------------
-- | Version | *Header | Service Type | Total Length including header |
-- | (4) | Length | (ignored) | (in bytes) |
-- --------------------------------------------------------------------------------------------
-- | Identification | Flags | Fragment Offset |
-- | | | (in 32 bit words) |
-- --------------------------------------------------------------------------------------------
-- | Time To Live | Protocol | Header Checksum |
-- | (ignored) | | |
-- --------------------------------------------------------------------------------------------
-- | Source IP Address |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Destination IP Address |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Options (if any - ignored) | Padding |
-- | | (if needed) |
-- --------------------------------------------------------------------------------------------
-- | Data |
-- | |
-- --------------------------------------------------------------------------------------------
-- | .... |
-- | |
-- --------------------------------------------------------------------------------------------
--
-- * - in 32 bit words
begin
-----------------------------------------------------------------------
-- combinatorial process to implement FSM and determine control signals
-----------------------------------------------------------------------
tx_combinatorial : process(
-- input signals
ip_tx_start, ip_tx, our_ip_address, our_mac_address, arp_req_rslt, --clk,
mac_tx_granted, mac_data_out_ready,
-- state variables
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,
-- control signals
next_tx_state, set_tx_state, next_tx_result, set_tx_result, tx_mac_value, set_tx_mac, tx_count_mode,
tx_data, set_last, set_chn_reqd, set_mac_lku_req, total_length,
tx_data_valid, tx_count_val
)
begin
-- set output followers
ip_tx_result <= tx_result_reg;
mac_tx_req <= tx_mac_chn_reqd;
arp_req_req.lookup_req <= mac_lookup_req;
arp_req_req.ip <= arp_req_ip_reg;
 
-- set initial values for combinatorial outputs
mac_data_out_first <= '0';
 
case tx_state is
when SEND_ETH_HDR | SEND_IP_HDR =>
mac_data_out <= tx_data;
tx_data_valid <= mac_data_out_ready; -- generated internally
mac_data_out_last <= set_last;
when SEND_USER_DATA =>
mac_data_out <= ip_tx.data.data_out;
tx_data_valid <= ip_tx.data.data_out_valid;
mac_data_out_last <= ip_tx.data.data_out_last;
 
when others =>
mac_data_out <= (others => '0');
tx_data_valid <= '0'; -- not transmitting during this phase
mac_data_out_last <= '0';
end case;
 
mac_data_out_valid <= tx_data_valid and mac_data_out_ready;
 
-- set signal defaults
next_tx_state <= IDLE;
set_tx_state <= '0';
tx_count_mode <= HOLD;
tx_data <= x"00";
set_last <= '0';
set_tx_mac <= '0';
set_chn_reqd <= HOLD;
set_mac_lku_req <= HOLD;
next_tx_result <= IPTX_RESULT_NONE;
set_tx_result <= '0';
tx_count_val <= (others => '0');
tx_mac_value <= (others => '0');
 
-- set temp signals
total_length <= std_logic_vector(unsigned(ip_tx.hdr.data_length) + 20); -- total length = user data length + header length (bytes)
 
-- TX FSM
case tx_state is
when IDLE =>
ip_tx_data_out_ready <= '0'; -- in this state, we are unable to accept user data for tx
tx_count_mode <= RST;
set_chn_reqd <= CLR;
if ip_tx_start = '1' then
-- check header count for error if too high
if unsigned(ip_tx.hdr.data_length) > 1480 then
next_tx_result <= IPTX_RESULT_ERR;
set_tx_result <= '1';
else
next_tx_result <= IPTX_RESULT_SENDING;
set_tx_result <= '1';
 
-- TODO - check if we already have the mac addr for this ip, if so, bypass the WAIT_MAC state
 
if ip_tx.hdr.dst_ip_addr = IP_BC_ADDR then
-- for IP broadcast, dont need to look up the MAC addr
tx_mac_value <= MAC_BC_ADDR;
set_tx_mac <= '1';
next_tx_state <= WAIT_CHN;
set_tx_state <= '1';
else
-- need to req the mac address for this ip
set_mac_lku_req <= SET;
next_tx_state <= WAIT_MAC;
set_tx_state <= '1';
end if;
end if;
else
set_mac_lku_req <= CLR;
end if;
 
when WAIT_MAC =>
ip_tx_data_out_ready <= '0'; -- in this state, we are unable to accept user data for tx
set_mac_lku_req <= CLR; -- clear the request - will have been latched in the ARP layer
if arp_req_rslt.got_mac = '1' then
-- save the MAC we got back from the ARP lookup
tx_mac_value <= arp_req_rslt.mac;
set_tx_mac <= '1';
set_chn_reqd <= SET;
-- check for optimise when already have the channel
if mac_tx_granted = '1' then
-- ready to send data
next_tx_state <= SEND_ETH_HDR;
set_tx_state <= '1';
else
next_tx_state <= WAIT_CHN;
set_tx_state <= '1';
end if;
elsif arp_req_rslt.got_err = '1' then
set_mac_lku_req <= CLR;
next_tx_result <= IPTX_RESULT_ERR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
end if;
when WAIT_CHN =>
ip_tx_data_out_ready <= '0'; -- in this state, we are unable to accept user data for tx
if mac_tx_granted = '1' then
-- ready to send data
next_tx_state <= SEND_ETH_HDR;
set_tx_state <= '1';
end if;
-- probably should handle a timeout here
when SEND_ETH_HDR =>
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 tx_count = x"00d" then
tx_count_mode <= RST;
next_tx_state <= SEND_IP_HDR;
set_tx_state <= '1';
else
tx_count_mode <= INCR;
end if;
case tx_count is
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"002" => tx_data <= tx_mac (31 downto 24);
when x"003" => tx_data <= tx_mac (23 downto 16);
when x"004" => tx_data <= tx_mac (15 downto 8);
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"007" => tx_data <= our_mac_address (39 downto 32);
when x"008" => tx_data <= our_mac_address (31 downto 24);
when x"009" => tx_data <= our_mac_address (23 downto 16);
when x"00a" => tx_data <= our_mac_address (15 downto 8);
when x"00b" => tx_data <= our_mac_address (7 downto 0);
when x"00c" => tx_data <= x"08"; -- pkt type = 0800 : IP
when x"00d" => tx_data <= x"00";
when others =>
-- shouldnt get here - handle as error
next_tx_result <= IPTX_RESULT_ERR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
end case;
end if;
when SEND_IP_HDR =>
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 tx_count = x"013" then
tx_count_val <= x"001";
tx_count_mode <= SET;
next_tx_state <= SEND_USER_DATA;
set_tx_state <= '1';
else
tx_count_mode <= INCR;
end if;
case tx_count is
when x"000" => tx_data <= x"45"; -- v4, 5 words in hdr
when x"001" => tx_data <= x"00"; -- service type
when x"002" => tx_data <= total_length (15 downto 8); -- total length
when x"003" => tx_data <= total_length (7 downto 0);
when x"004" => tx_data <= x"00"; -- identification
when x"005" => tx_data <= x"00";
when x"006" => tx_data <= x"00"; -- flags and fragment offset
when x"007" => tx_data <= x"00";
when x"008" => tx_data <= IP_TTL; -- TTL
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"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"00d" => tx_data <= our_ip_address (23 downto 16);
when x"00e" => tx_data <= our_ip_address (15 downto 8);
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"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"013" => tx_data <= ip_tx.hdr.dst_ip_addr (7 downto 0);
when others =>
-- shouldnt get here - handle as error
next_tx_result <= IPTX_RESULT_ERR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
end case;
end if;
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
if mac_data_out_ready = '1' 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
if unsigned(tx_count) = unsigned(ip_tx.hdr.data_length) then
-- TX terminated due to count - end normally
set_last <= '1';
set_chn_reqd <= CLR;
tx_data <= ip_tx.data.data_out;
next_tx_result <= IPTX_RESULT_SENT;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
if ip_tx.data.data_out_last = '0' then
next_tx_result <= IPTX_RESULT_ERR;
end if;
elsif ip_tx.data.data_out_last = '1' then
-- TX terminated due to receiving last indication from upstream - end with error
set_last <= '1';
set_chn_reqd <= CLR;
tx_data <= ip_tx.data.data_out;
next_tx_result <= IPTX_RESULT_ERR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
else
-- TX continues
tx_count_mode <= INCR;
tx_data <= ip_tx.data.data_out;
end if;
end if;
end if;
 
end case;
end process;
 
-----------------------------------------------------------------------------
-- sequential process to action control signals and change states and outputs
-----------------------------------------------------------------------------
 
tx_sequential : process (clk)--, reset, mac_data_out_ready_reg)
begin
-- if rising_edge(clk) then
-- mac_data_out_ready_reg <= mac_data_out_ready;
-- else
-- mac_data_out_ready_reg <= mac_data_out_ready_reg;
-- end if;
 
if rising_edge(clk) then
if reset = '1' then
-- reset state variables
tx_state <= IDLE;
tx_count <= x"000";
tx_result_reg <= IPTX_RESULT_NONE;
tx_mac <= (others => '0');
tx_mac_chn_reqd <= '0';
mac_lookup_req <= '0';
else
-- Next tx_state processing
if set_tx_state = '1' then
tx_state <= next_tx_state;
else
tx_state <= tx_state;
end if;
 
-- tx result processing
if set_tx_result = '1' then
tx_result_reg <= next_tx_result;
else
tx_result_reg <= tx_result_reg;
end if;
 
-- control arp lookup request
case set_mac_lku_req is
when SET =>
arp_req_ip_reg <= ip_tx.hdr.dst_ip_addr;
mac_lookup_req <= '1';
 
when CLR =>
mac_lookup_req <= '0';
arp_req_ip_reg <= arp_req_ip_reg;
when HOLD =>
mac_lookup_req <= mac_lookup_req;
arp_req_ip_reg <= arp_req_ip_reg;
end case;
 
-- save MAC
if set_tx_mac = '1' then
tx_mac <= tx_mac_value;
else
tx_mac <= tx_mac;
end if;
 
-- control access request to mac tx chn
case set_chn_reqd is
when SET => tx_mac_chn_reqd <= '1';
when CLR => tx_mac_chn_reqd <= '0';
when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
end case;
 
-- tx_count processing
case tx_count_mode is
when RST => tx_count <= x"000";
when SET => tx_count <= tx_count_val;
when INCR => tx_count <= tx_count + 1;
when HOLD => tx_count <= tx_count;
end case;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- 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
-----------------------------------------------------------------------------
 
crc : process (clk)--, reset)
begin
if rising_edge(clk) then
case crc_state is
when IDLE =>
if ip_tx_start = '1' then
tx_hdr_cks <= x"004500"; -- vers & hdr len & service
crc_state <= TOT_LEN;
end if;
when TOT_LEN =>
tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(total_length));
crc_state <= ID;
when ID =>
tx_hdr_cks <= tx_hdr_cks;
crc_state <= FLAGS;
when FLAGS =>
tx_hdr_cks <= tx_hdr_cks;
crc_state <= TTL;
when TTL =>
tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(IP_TTL & ip_tx.hdr.protocol));
crc_state <= CKS;
when CKS =>
tx_hdr_cks <= tx_hdr_cks;
crc_state <= SAH;
when SAH =>
tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(our_ip_address(31 downto 16)));
crc_state <= SAL;
when SAL =>
tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(our_ip_address(15 downto 0)));
crc_state <= DAH;
when DAH =>
tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(ip_tx.hdr.dst_ip_addr(31 downto 16)));
crc_state <= DAL;
when DAL =>
tx_hdr_cks <= std_logic_vector (unsigned(tx_hdr_cks) + unsigned(ip_tx.hdr.dst_ip_addr(15 downto 0)));
crc_state <= FINAL;
 
when FINAL =>
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;
when WAIT_END =>
tx_hdr_cks <= tx_hdr_cks;
if ip_tx_start = '0' then
crc_state <= IDLE;
else
crc_state <= WAIT_END;
end if;
 
end case;
end if;
end process;
 
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/UDP_TX.vhd
0,0 → 1,302
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 5 June 2011
-- Design Name:
-- Module Name: UDP_TX - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle simple UDP TX
-- doesnt generate the checksum(supposedly optional)
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - Added abort of tx when receive last from upstream
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.axi.all;
use work.ipv4_types.all;
 
entity UDP_TX is
Port (
-- UDP Layer signals
udp_tx_start : in std_logic; -- indicates req to tx UDP
udp_txi : in udp_tx_type; -- UDP tx cxns
udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission)
udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data
-- system signals
clk : in STD_LOGIC; -- same clock used to clock mac data and ip data
reset : in STD_LOGIC;
-- IP layer TX signals
ip_tx_start : out std_logic;
ip_tx : out ipv4_tx_type; -- IP tx cxns
ip_tx_result : in std_logic_vector (1 downto 0); -- tx status (changes during transmission)
ip_tx_data_out_ready : in std_logic -- indicates IP TX is ready to take data
);
end UDP_TX;
 
architecture Behavioral of UDP_TX is
type tx_state_type is (IDLE, PAUSE, SEND_UDP_HDR, SEND_USER_DATA);
type count_mode_type is (RST, INCR, HOLD);
type settable_cnt_type is (RST, SET, INCR, HOLD);
type set_clr_type is (SET, CLR, HOLD);
 
-- TX state variables
signal udp_tx_state : tx_state_type;
signal tx_count : unsigned (15 downto 0);
signal tx_result_reg : std_logic_vector (1 downto 0);
signal ip_tx_start_reg : std_logic;
signal data_out_ready_reg : std_logic;
 
-- tx control signals
signal next_tx_state : tx_state_type;
signal set_tx_state : std_logic;
signal next_tx_result : std_logic_vector (1 downto 0);
signal set_tx_result : std_logic;
signal tx_count_val : unsigned (15 downto 0);
signal tx_count_mode : settable_cnt_type;
signal tx_data : std_logic_vector (7 downto 0);
signal set_last : std_logic;
signal set_ip_tx_start : set_clr_type;
signal tx_data_valid : std_logic; -- indicates whether data is valid to tx or not
-- tx temp signals
signal total_length : std_logic_vector (15 downto 0); -- computed combinatorially from header size
 
-- IP datagram header format
--
-- 0 4 8 16 19 24 31
-- --------------------------------------------------------------------------------------------
-- | source port number | dest port number |
-- | | |
-- --------------------------------------------------------------------------------------------
-- | length (bytes) | checksum |
-- | (header and data combined) | |
-- --------------------------------------------------------------------------------------------
-- | Data |
-- | |
-- --------------------------------------------------------------------------------------------
-- | .... |
-- | |
-- --------------------------------------------------------------------------------------------
begin
-----------------------------------------------------------------------
-- combinatorial process to implement FSM and determine control signals
-----------------------------------------------------------------------
 
tx_combinatorial : process(
-- input signals
udp_tx_start, udp_txi, clk, ip_tx_result, ip_tx_data_out_ready,
-- state variables
udp_tx_state, tx_count, tx_result_reg, ip_tx_start_reg, data_out_ready_reg,
-- control signals
next_tx_state, set_tx_state, next_tx_result, set_tx_result, tx_count_mode, tx_count_val,
tx_data, set_last, total_length, set_ip_tx_start, tx_data_valid
)
begin
-- set output followers
ip_tx_start <= ip_tx_start_reg;
ip_tx.hdr.protocol <= x"11"; -- UDP protocol
ip_tx.hdr.data_length <= total_length;
ip_tx.hdr.dst_ip_addr <= udp_txi.hdr.dst_ip_addr;
if udp_tx_start = '1' and ip_tx_start_reg = '0' then
udp_tx_result <= UDPTX_RESULT_NONE; -- kill the result until have started the IP layer
else
udp_tx_result <= tx_result_reg;
end if;
case udp_tx_state is
when SEND_USER_DATA =>
ip_tx.data.data_out <= udp_txi.data.data_out;
tx_data_valid <= udp_txi.data.data_out_valid;
ip_tx.data.data_out_last <= udp_txi.data.data_out_last;
when SEND_UDP_HDR =>
ip_tx.data.data_out <= tx_data;
tx_data_valid <= ip_tx_data_out_ready;
ip_tx.data.data_out_last <= set_last;
when others =>
ip_tx.data.data_out <= (others => '0');
tx_data_valid <= '0';
ip_tx.data.data_out_last <= set_last;
end case;
ip_tx.data.data_out_valid <= tx_data_valid and ip_tx_data_out_ready;
-- set signal defaults
next_tx_state <= IDLE;
set_tx_state <= '0';
tx_count_mode <= HOLD;
tx_data <= x"00";
set_last <= '0';
next_tx_result <= UDPTX_RESULT_NONE;
set_tx_result <= '0';
set_ip_tx_start <= HOLD;
tx_count_val <= (others => '0');
udp_tx_data_out_ready <= '0';
-- set temp signals
total_length <= std_logic_vector(unsigned(udp_txi.hdr.data_length) + 8); -- total length = user data length + header length (bytes)
-- TX FSM
case udp_tx_state is
when IDLE =>
udp_tx_data_out_ready <= '0'; -- in this state, we are unable to accept user data for tx
tx_count_mode <= RST;
if udp_tx_start = '1' then
-- check header count for error if too high
if unsigned(udp_txi.hdr.data_length) > 1472 then
next_tx_result <= UDPTX_RESULT_ERR;
set_tx_result <= '1';
else
-- start to send UDP header
tx_count_mode <= RST;
next_tx_result <= UDPTX_RESULT_SENDING;
set_ip_tx_start <= SET;
set_tx_result <= '1';
next_tx_state <= PAUSE;
set_tx_state <= '1';
end if;
end if;
 
when PAUSE =>
-- delay one clock for IP layer to respond to ip_tx_start and remove any tx error result
next_tx_state <= SEND_UDP_HDR;
set_tx_state <= '1';
when SEND_UDP_HDR =>
udp_tx_data_out_ready <= '0'; -- in this state, we are unable to accept user data for tx
if ip_tx_result = IPTX_RESULT_ERR then
set_ip_tx_start <= CLR;
next_tx_result <= UDPTX_RESULT_ERR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
elsif ip_tx_data_out_ready = '1' then
if tx_count = x"0007" then
tx_count_val <= x"0001";
tx_count_mode <= SET;
next_tx_state <= SEND_USER_DATA;
set_tx_state <= '1';
else
tx_count_mode <= INCR;
end if;
case tx_count is
when x"0000" => tx_data <= udp_txi.hdr.src_port (15 downto 8); -- src port
when x"0001" => tx_data <= udp_txi.hdr.src_port (7 downto 0);
when x"0002" => tx_data <= udp_txi.hdr.dst_port (15 downto 8); -- dst port
when x"0003" => tx_data <= udp_txi.hdr.dst_port (7 downto 0);
when x"0004" => tx_data <= total_length (15 downto 8); -- length
when x"0005" => tx_data <= total_length (7 downto 0);
when x"0006" => tx_data <= udp_txi.hdr.checksum (15 downto 8); -- checksum (set by upstream)
when x"0007" => tx_data <= udp_txi.hdr.checksum (7 downto 0);
when others =>
-- shouldnt get here - handle as error
next_tx_result <= UDPTX_RESULT_ERR;
set_tx_result <= '1';
end case;
end if;
when SEND_USER_DATA =>
udp_tx_data_out_ready <= ip_tx_data_out_ready; -- in this state, we can accept user data if IP TX rdy
if ip_tx_data_out_ready = '1' then
if udp_txi.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
if unsigned(tx_count) = unsigned(udp_txi.hdr.data_length) then
-- TX terminated due to count - end normally
set_last <= '1';
tx_data <= udp_txi.data.data_out;
next_tx_result <= UDPTX_RESULT_SENT;
set_ip_tx_start <= CLR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
elsif udp_txi.data.data_out_last = '1' then
-- terminate tx with error as got last from upstream before exhausting count
set_last <= '1';
tx_data <= udp_txi.data.data_out;
next_tx_result <= UDPTX_RESULT_ERR;
set_ip_tx_start <= CLR;
set_tx_result <= '1';
next_tx_state <= IDLE;
set_tx_state <= '1';
else
-- TX continues
tx_count_mode <= INCR;
tx_data <= udp_txi.data.data_out;
end if;
end if;
end if;
 
end case;
end process;
 
-----------------------------------------------------------------------------
-- sequential process to action control signals and change states and outputs
-----------------------------------------------------------------------------
 
tx_sequential : process (clk,reset,data_out_ready_reg)
begin
if rising_edge(clk) then
data_out_ready_reg <= ip_tx_data_out_ready;
else
data_out_ready_reg <= data_out_ready_reg;
end if;
 
if rising_edge(clk) then
if reset = '1' then
-- reset state variables
udp_tx_state <= IDLE;
tx_count <= x"0000";
tx_result_reg <= IPTX_RESULT_NONE;
ip_tx_start_reg <= '0';
else
-- Next udp_tx_state processing
if set_tx_state = '1' then
udp_tx_state <= next_tx_state;
else
udp_tx_state <= udp_tx_state;
end if;
-- ip_tx_start_reg processing
case set_ip_tx_start is
when SET => ip_tx_start_reg <= '1';
when CLR => ip_tx_start_reg <= '0';
when HOLD => ip_tx_start_reg <= ip_tx_start_reg;
end case;
 
-- tx result processing
if set_tx_result = '1' then
tx_result_reg <= next_tx_result;
else
tx_result_reg <= tx_result_reg;
end if;
-- tx_count processing
case tx_count_mode is
when RST => tx_count <= x"0000";
when SET => tx_count <= tx_count_val;
when INCR => tx_count <= tx_count + 1;
when HOLD => tx_count <= tx_count;
end case;
end if;
end if;
end process;
 
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/ipcores/xilinx/README.txt
0,0 → 1,9
The IP Core XCO files are xilinx core generator configuration files.
They are provided as examples only and you may need to do some tweaking
to the generated code to get it to work.
 
mac_layer_v2_2.xco - is the current core I last tested with.
 
mac_layer_v2_1.xco - is an earlier xilinx core that I originally developed with.
The interface may have changed slightly, so you may need to make some small changes
to the ml605/xv6mac_straight.vhd module to get it to work with this version.
/tags/v2.3/rtl/vhdl/ipcores/xilinx/mac_layer_v2_1.xco
0,0 → 1,92
##############################################################
#
# Xilinx Core Generator version 13.2
# Date: Sat Jul 23 13:38:01 2011
#
##############################################################
#
# This file contains the customisation parameters for a
# Xilinx CORE Generator IP GUI. It is strongly recommended
# that you do not manually alter this file as it may cause
# unexpected and unsupported behavior.
#
##############################################################
#
# Generated from component: xilinx.com:ip:v6_emac:2.1
#
##############################################################
#
# BEGIN Project Options
SET addpads = false
SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false
SET designentry = VHDL
SET device = xc6vlx240t
SET devicefamily = virtex6
SET flowvendor = Other
SET formalverification = false
SET foundationsym = false
SET implementationfiletype = Ngc
SET package = ff1156
SET removerpms = false
SET simulationfiles = Behavioral
SET speedgrade = -1
SET verilogsim = false
SET vhdlsim = true
# END Project Options
# BEGIN Select
SELECT Virtex-6_Embedded_Tri-Mode_Ethernet_MAC_Wrapper family Xilinx,_Inc. 2.1
# END Select
# BEGIN Parameters
CSET address_filter=false
CSET address_filter_enable=false
CSET axi_ipif=true
CSET client_side_data_width=8_bit
CSET clock_enable=true
CSET component_name=emac1
CSET management_interface=false
CSET mdio=false
CSET number_of_address_table_entries=0
CSET phy_an_enable=false
CSET phy_ignore_adzero=false
CSET phy_isolate=false
CSET phy_link_timer_value=13D
CSET phy_loopback_in_gtp=false
CSET phy_loopback_msb=false
CSET phy_powerdown=false
CSET phy_reset=false
CSET phy_unidirection_enable=false
CSET physical_interface=GMII
CSET rx_ctrl_lencheck_disable=false
CSET rx_disable_length=false
CSET rx_enable=true
CSET rx_flow_control_enable=false
CSET rx_half_duplex_enable=false
CSET rx_in_band_fcs_enable=false
CSET rx_jumbo_frame_enable=false
CSET rx_reset=false
CSET rx_vlan_enable=false
CSET serial_mode_switch_enable=false
CSET sgmii_mode=No_clock
CSET speed=1000_Mbps
CSET statistics_counters=false
CSET statistics_reset=true
CSET statistics_width=32bit
CSET tx_enable=true
CSET tx_flow_control_enable=false
CSET tx_half_duplex_enable=false
CSET tx_ifg_adjust_enable=false
CSET tx_in_band_fcs_enable=false
CSET tx_jumbo_frame_enable=false
CSET tx_reset=false
CSET tx_vlan_enable=false
CSET unicast_pause_mac_address_1=AA
CSET unicast_pause_mac_address_2=BB
CSET unicast_pause_mac_address_3=CC
CSET unicast_pause_mac_address_4=DD
CSET unicast_pause_mac_address_5=EE
CSET unicast_pause_mac_address_6=FF
# END Parameters
GENERATE
# CRC: fd590560
/tags/v2.3/rtl/vhdl/ipcores/xilinx/mac_layer_v2_2.xco
0,0 → 1,95
##############################################################
#
# Xilinx Core Generator version 13.4
# Date: Sat Apr 21 12:31:20 2012
#
##############################################################
#
# This file contains the customisation parameters for a
# Xilinx CORE Generator IP GUI. It is strongly recommended
# that you do not manually alter this file as it may cause
# unexpected and unsupported behavior.
#
##############################################################
#
# Generated from component: xilinx.com:ip:v6_emac:2.2
#
##############################################################
#
# BEGIN Project Options
SET addpads = false
SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false
SET designentry = VHDL
SET device = xc6vlx240t
SET devicefamily = virtex6
SET flowvendor = Other
SET formalverification = false
SET foundationsym = false
SET implementationfiletype = Ngc
SET package = ff1156
SET removerpms = false
SET simulationfiles = Structural
SET speedgrade = -1
SET verilogsim = false
SET vhdlsim = true
# END Project Options
# BEGIN Select
SELECT Virtex-6_Embedded_Tri-Mode_Ethernet_MAC_Wrapper family Xilinx,_Inc. 2.2
# END Select
# BEGIN Parameters
CSET address_filter=false
CSET address_filter_enable=false
CSET axi_ipif=true
CSET client_side_data_width=8_bit
CSET clock_enable=true
CSET component_name=mac_layer_v2_2
CSET management_interface=false
CSET mdio=false
CSET number_of_address_table_entries=0
CSET phy_an_enable=false
CSET phy_ignore_adzero=false
CSET phy_isolate=false
CSET phy_link_timer_value=13D
CSET phy_loopback_in_gtp=false
CSET phy_loopback_msb=false
CSET phy_powerdown=false
CSET phy_reset=false
CSET phy_unidirection_enable=false
CSET physical_interface=GMII
CSET rx_ctrl_lencheck_disable=false
CSET rx_disable_length=false
CSET rx_enable=true
CSET rx_flow_control_enable=false
CSET rx_half_duplex_enable=false
CSET rx_in_band_fcs_enable=false
CSET rx_jumbo_frame_enable=false
CSET rx_reset=false
CSET rx_vlan_enable=false
CSET serial_mode_switch_enable=false
CSET sgmii_mode=No_clock
CSET speed=1000_Mbps
CSET statistics_counters=false
CSET statistics_reset=true
CSET statistics_width=32bit
CSET tx_enable=true
CSET tx_flow_control_enable=false
CSET tx_half_duplex_enable=false
CSET tx_ifg_adjust_enable=false
CSET tx_in_band_fcs_enable=false
CSET tx_jumbo_frame_enable=false
CSET tx_reset=false
CSET tx_vlan_enable=false
CSET unicast_pause_mac_address_1=AA
CSET unicast_pause_mac_address_2=BB
CSET unicast_pause_mac_address_3=CC
CSET unicast_pause_mac_address_4=DD
CSET unicast_pause_mac_address_5=EE
CSET unicast_pause_mac_address_6=FF
# END Parameters
# BEGIN Extra information
MISC pkg_timestamp=2012-01-07T15:29:19Z
# END Extra information
GENERATE
# CRC: 107b69dd
/tags/v2.3/rtl/vhdl/arp_types.vhd
0,0 → 1,81
--
-- Package File Template
--
-- Purpose: This package defines supplemental types, subtypes,
-- constants, and functions
--
-- To use any of the example code shown below, uncomment the lines and modify as necessary
--
-- Revision 0.02 - Added type definitions (store and network) for arpv2
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
 
package arp_types is
 
 
-- arp lookup types
type arp_req_req_type is
record
lookup_req : std_logic; -- set high when wanting mac adr for the requested IP
ip : std_logic_vector (31 downto 0);
end record;
 
type arp_req_rslt_type is
record
got_mac : std_logic; -- indicates that we got the mac
mac : std_logic_vector (47 downto 0);
got_err : std_logic; -- indicates that we got an error (prob a timeout)
end record;
 
type arp_entry_t is record
ip : std_logic_vector (31 downto 0);
mac : std_logic_vector (47 downto 0);
end record;
 
type arp_control_type is
record
clear_cache : std_logic;
end record;
-- arp store types
type arp_store_rslt_t is (IDLE,BUSY,SEARCHING,FOUND,NOT_FOUND);
type arp_store_rdrequest_t is
record
req : std_logic; -- request to lookup
ip : std_logic_vector(31 downto 0); -- contains ip to lookup
end record;
 
type arp_store_wrrequest_t is
record
req : std_logic; -- request to store
entry : arp_entry_t; -- ip,mac to store
end record;
type arp_store_result_t is
record
status : arp_store_rslt_t; -- status of the request
entry : arp_entry_t; -- contains ip,mac if found
end record;
 
-- arp network types
 
type arp_nwk_rslt_t is (IDLE,REQUESTING,RECEIVED,ERROR);
type arp_nwk_request_t is
record
req : std_logic; -- request to resolve IP addr
ip : std_logic_vector(31 downto 0); -- IP to request
end record;
 
type arp_nwk_result_t is
record
status : arp_nwk_rslt_t; -- status of request
entry : arp_entry_t; -- the result
end record;
end arp_types;
/tags/v2.3/rtl/vhdl/arp.vhd
0,0 → 1,807
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 12:00:04 05/31/2011
-- Design Name:
-- Module Name: arp - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle simple IP lookup in cache
-- request cache fill through ARP protocol if required
-- cache is simple 1 deep
-- Handle ARP protocol
-- Respond to ARP requests and replies
-- Ignore pkts that are not ARP
-- Ignore pkts that are not addressed to us
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - Added req for mac tx and wait for grant
-- Revision 0.03 - Added data_out_first
-- Revision 0.04 - Added arp response timeout
-- Revision 0.05 - Added arp cache reset control
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.arp_types.all;
 
entity arp is
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 1; -- (added for compatibility with arpv2. this value not used in this impl)
MAX_ARP_ENTRIES : integer := 1 -- (added for compatibility with arpv2. this value not used in this impl)
);
Port (
-- lookup request signals
arp_req_req : in arp_req_req_type;
arp_req_rslt : out arp_req_rslt_type;
-- MAC layer RX signals
data_in_clk : in STD_LOGIC;
reset : in STD_LOGIC;
data_in : in STD_LOGIC_VECTOR (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
data_in_valid : in STD_LOGIC; -- indicates data_in valid on clock
data_in_last : in STD_LOGIC; -- indicates last data in frame
-- 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_granted : in std_logic; -- indicates that access to channel has been granted
data_out_clk : in std_logic;
data_out_ready : in std_logic; -- indicates system ready to consume data
data_out_valid : out std_logic; -- indicates data out is valid
data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame
data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame
data_out : out std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
-- system signals
our_mac_address : in STD_LOGIC_VECTOR (47 downto 0);
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
control : in arp_control_type;
req_count : out STD_LOGIC_VECTOR(7 downto 0) -- count of arp pkts received
);
end arp;
 
architecture Behavioral of arp is
 
type req_state_type is (IDLE,LOOKUP,REQUEST,WAIT_REPLY,PAUSE1,PAUSE2,PAUSE3);
type rx_state_type is (IDLE,PARSE,PROCESS_ARP,WAIT_END);
type rx_event_type is (NO_EVENT,DATA);
type count_mode_type is (RST,INCR,HOLD);
type arp_oper_type is (NOP,REQUEST,REPLY);
type set_clr_type is (SET, CLR, HOLD);
 
type tx_state_type is (IDLE,WAIT_MAC,SEND);
type arp_entry_type is record
ip : std_logic_vector (31 downto 0);
mac : std_logic_vector (47 downto 0);
is_valid : std_logic;
reply_required : std_logic;
end record;
-- state variables
signal req_state : req_state_type;
signal req_ip_addr : std_logic_vector (31 downto 0); -- IP address to lookup
signal mac_addr_found : STD_LOGIC_VECTOR (47 downto 0); -- mac address found
signal mac_addr_valid_reg: std_logic;
signal send_request_needed : std_logic;
signal tx_mac_chn_reqd : std_logic;
signal freq_scaler : unsigned (31 downto 0); -- scales data_in_clk downto 1Hz
signal timer : unsigned (7 downto 0); -- counts seconds timeout
signal timeout_reg : std_logic;
signal rx_state : rx_state_type;
signal rx_count : unsigned (7 downto 0);
signal arp_operation : arp_oper_type;
signal arp_req_count : unsigned (7 downto 0);
signal arp_entry : arp_entry_type; -- arp entry store
signal new_arp_entry : arp_entry_type;
signal tx_state : tx_state_type;
signal tx_count : unsigned (7 downto 0);
 
-- FIXME - remove these debug state signals
signal arp_err_data : std_logic_vector (7 downto 0);
signal set_err_data : std_logic;
attribute keep : string;
attribute keep of arp_err_data : signal is "true";
 
-- requester control signals
signal next_req_state : req_state_type;
signal set_req_state : std_logic;
signal set_req_ip : std_logic;
signal set_mac_addr : std_logic;
signal set_mac_addr_invalid : std_logic;
signal set_send_req : std_logic;
signal clear_send_req : std_logic;
signal set_timer : count_mode_type; -- timer reset, count, hold control
signal timer_enable : std_logic; -- enable the timer counting
signal set_timeout : set_clr_type; -- control the timeout register
-- rx control signals
signal next_rx_state : rx_state_type;
signal set_rx_state : std_logic;
signal rx_event : rx_event_type;
signal rx_count_mode : count_mode_type;
signal set_arp_oper : std_logic;
signal arp_oper_set_val : arp_oper_type;
signal dataval : std_logic_vector (7 downto 0);
signal set_arp_entry_request : std_logic;
signal set_mac5 : std_logic;
signal set_mac4 : std_logic;
signal set_mac3 : std_logic;
signal set_mac2 : std_logic;
signal set_mac1 : std_logic;
signal set_mac0 : std_logic;
signal set_ip3 : std_logic;
signal set_ip2 : std_logic;
signal set_ip1 : std_logic;
signal set_ip0 : std_logic;
 
-- tx control signals
signal next_tx_state : tx_state_type;
signal set_tx_state : std_logic;
signal tx_count_mode : count_mode_type;
signal clear_reply_req : std_logic;
signal set_chn_reqd : set_clr_type;
signal kill_data_out_valid : std_logic;
 
-- function to determine whether the rx pkt is an arp pkt and whether we want to process it
-- Returns 1 if we should discard
-- The following will make us ignore the frame (all values hexadecimal):
-- PDU type /= 0806
-- Protocol Type /= 0800
-- Hardware Type /= 1
-- Hardware Length /= 6
-- Protocol Length /= 4
-- Operation /= 1 or 2
-- Target IP /= our IP (i.er. message is not meant for us)
--
function not_our_arp(data : STD_LOGIC_VECTOR; count : unsigned; our_ip : std_logic_vector) return std_logic is
begin
if
(count = 12 and data /= x"08") or -- PDU type 0806 : ARP
(count = 13 and data /= x"06") or
(count = 14 and data /= x"00") or -- HW type 1 : eth
(count = 15 and data /= x"01") or
(count = 16 and data /= x"08") or -- Protocol 0800 : IP
(count = 17 and data /= x"00") or
(count = 18 and data /= x"06") or -- HW Length 6
(count = 19 and data /= x"04") or -- protocol length 4
(count = 20 and data /= x"00") or -- operation 1 or 2 (req or reply)
(count = 21 and data /= x"01" and data /= x"02") or
(count = 38 and data /= our_ip(31 downto 24)) or -- target IP is ours
(count = 39 and data /= our_ip(23 downto 16)) or
(count = 40 and data /= our_ip(15 downto 8)) or
(count = 41 and data /= our_ip(7 downto 0))
then
return '1';
else
return '0';
end if;
end function not_our_arp;
 
begin
req_combinatorial : process (
-- input signals
arp_req_req,
-- state variables
req_state, req_ip_addr, mac_addr_found, mac_addr_valid_reg, send_request_needed, arp_entry,
freq_scaler, timer, timeout_reg,
-- control signals
next_req_state, set_req_state, set_req_ip, set_mac_addr, control,
set_mac_addr_invalid,set_send_req, clear_send_req, set_timer, timer_enable, set_timeout
)
begin
-- set output followers
if arp_req_req.lookup_req = '1' then
arp_req_rslt.got_err <= '0';
else
arp_req_rslt.got_err <= timeout_reg;
end if;
-- zero time response to lookup request if already in cache
if arp_req_req.lookup_req = '1' and arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
arp_req_rslt.got_mac <= '1';
arp_req_rslt.mac <= arp_entry.mac;
elsif arp_req_req.lookup_req = '1' then
arp_req_rslt.got_mac <= '0'; -- hold off got_mac while req is there as arp_entry will not be correct yet
arp_req_rslt.mac <= arp_entry.mac;
else
arp_req_rslt.got_mac <= mac_addr_valid_reg;
arp_req_rslt.mac <= mac_addr_found;
end if;
-- set signal defaults
next_req_state <= IDLE;
set_req_state <= '0';
set_req_ip <= '0';
set_mac_addr <= '0';
set_mac_addr_invalid <= '0';
set_send_req <= '0';
clear_send_req <= '0';
set_timer <= INCR; -- default is timer running, unless we hold or reset it
set_timeout <= HOLD;
timer_enable <= '0';
-- combinatorial logic
if freq_scaler = x"00000000" then
timer_enable <= '1';
end if;
-- REQ FSM
case req_state is
when IDLE =>
set_timer <= RST;
if arp_req_req.lookup_req = '1' then
-- check if we already have the info in cache
if arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
-- already have this IP
set_mac_addr <= '1';
else
set_timeout <= CLR;
next_req_state <= LOOKUP;
set_req_state <= '1';
set_req_ip <= '1';
set_mac_addr_invalid <= '1';
end if;
end if;
 
when LOOKUP =>
if arp_entry.ip = req_ip_addr and arp_entry.is_valid = '1' then
-- already have this IP
next_req_state <= IDLE;
set_req_state <= '1';
set_mac_addr <= '1';
else
-- need to request mac for this IP
set_send_req <= '1';
set_timer <= RST;
next_req_state <= REQUEST;
set_req_state <= '1';
end if;
when REQUEST =>
clear_send_req <= '1';
next_req_state <= WAIT_REPLY;
set_req_state <= '1';
when WAIT_REPLY =>
if arp_entry.is_valid = '1' then
-- have reply, go back to LOOKUP state to see if it is the right one
next_req_state <= LOOKUP;
set_req_state <= '1';
end if;
if timer >= ARP_TIMEOUT then
set_timeout <= SET;
next_req_state <= PAUSE1;
set_req_state <= '1';
end if;
 
when PAUSE1 =>
next_req_state <= PAUSE2;
set_req_state <= '1';
 
when PAUSE2 =>
next_req_state <= PAUSE3;
set_req_state <= '1';
 
when PAUSE3 =>
next_req_state <= IDLE;
set_req_state <= '1';
 
end case;
end process;
 
req_sequential : process (data_in_clk,reset)
begin
if rising_edge(data_in_clk) then
if reset = '1' then
-- reset state variables
req_state <= IDLE;
req_ip_addr <= (others => '0');
mac_addr_found <= (others => '0');
mac_addr_valid_reg <= '0';
send_request_needed <= '0';
freq_scaler <= to_unsigned(CLOCK_FREQ,32);
timer <= (others => '0');
timeout_reg <= '0';
else
-- Next req_state processing
if set_req_state = '1' then
req_state <= next_req_state;
else
req_state <= req_state;
end if;
 
-- Latch the requested IP address
if set_req_ip = '1' then
req_ip_addr <= arp_req_req.ip;
else
req_ip_addr <= req_ip_addr;
end if;
-- send request to TX&RX FSMs to send an ARP request
if set_send_req = '1' then
send_request_needed <= '1';
elsif clear_send_req = '1' then
send_request_needed <= '0';
else
send_request_needed <= send_request_needed;
end if;
-- Set the found mac address
if set_mac_addr = '1' then
mac_addr_found <= arp_entry.mac;
mac_addr_valid_reg <= '1';
elsif set_mac_addr_invalid = '1' then
mac_addr_found <= (others => '0');
mac_addr_valid_reg <= '0';
else
mac_addr_found <= mac_addr_found;
mac_addr_valid_reg <= mac_addr_valid_reg;
end if;
-- freq scaling and 1-sec timer
if freq_scaler = x"00000000" then
freq_scaler <= to_unsigned(CLOCK_FREQ,32);
else
freq_scaler <= freq_scaler - 1;
end if;
-- timer processing
case set_timer is
when RST =>
timer <= x"00";
when INCR =>
if timer_enable = '1' then
timer <= timer + 1;
else
timer <= timer;
end if;
when HOLD =>
timer <= timer;
end case;
-- timeout latching
case set_timeout is
when CLR => timeout_reg <= '0';
when SET => timeout_reg <= '1';
when HOLD => timeout_reg <= timeout_reg;
end case;
end if;
end if;
end process;
 
 
rx_combinatorial : process (
-- input signals
data_in, data_in_valid, data_in_last, our_ip_address,
-- state variables
rx_state, rx_count, arp_operation, arp_req_count, arp_err_data,
-- control signals
next_rx_state, set_rx_state, rx_event, rx_count_mode, set_arp_oper, arp_oper_set_val,
dataval,set_mac5,set_mac4,set_mac3,set_mac2,set_mac1,set_mac0,set_ip3,set_ip2,set_ip1,set_ip0, set_err_data,
set_arp_entry_request)
begin
-- set output followers
req_count <= STD_LOGIC_VECTOR(arp_req_count);
-- set signal defaults
next_rx_state <= IDLE;
set_rx_state <= '0';
rx_event <= NO_EVENT;
rx_count_mode <= HOLD;
set_arp_oper <= '0';
arp_oper_set_val <= NOP;
dataval <= (others => '0');
set_mac5 <= '0';
set_mac4 <= '0';
set_mac3 <= '0';
set_mac2 <= '0';
set_mac1 <= '0';
set_mac0 <= '0';
set_ip3 <= '0';
set_ip2 <= '0';
set_ip1 <= '0';
set_ip0 <= '0';
set_arp_entry_request <= '0';
set_err_data <= '0';
-- determine event (if any)
if data_in_valid = '1' then
rx_event <= DATA;
end if;
-- RX FSM
case rx_state is
when IDLE =>
rx_count_mode <= RST;
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
next_rx_state <= PARSE;
set_rx_state <= '1';
rx_count_mode <= INCR;
end case;
 
when PARSE =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
rx_count_mode <= INCR;
-- handle early frame termination
if data_in_last = '1' then
next_rx_state <= IDLE;
set_rx_state <= '1';
else
-- check for end of frame. Also, detect and discard if not our frame
if rx_count = 42 then
next_rx_state <= PROCESS_ARP;
set_rx_state <= '1';
elsif not_our_arp(data_in,rx_count,our_ip_address) = '1' then
dataval <= data_in;
set_err_data <= '1';
next_rx_state <= WAIT_END;
set_rx_state <= '1';
elsif rx_count = 21 then
-- capture ARP operation
case data_in is
when x"01" =>
arp_oper_set_val <= REQUEST;
set_arp_oper <= '1';
when x"02" =>
arp_oper_set_val <= REPLY;
set_arp_oper <= '1';
when others => -- ignore other values
end case;
-- capture source mac addr
elsif rx_count = 22 then
set_mac5 <= '1';
dataval <= data_in;
elsif rx_count = 23 then
set_mac4 <= '1';
dataval <= data_in;
elsif rx_count = 24 then
set_mac3 <= '1';
dataval <= data_in;
elsif rx_count = 25 then
set_mac2 <= '1';
dataval <= data_in;
elsif rx_count = 26 then
set_mac1 <= '1';
dataval <= data_in;
elsif rx_count = 27 then
set_mac0 <= '1';
dataval <= data_in;
-- capture source ip addr
elsif rx_count = 28 then
set_ip3 <= '1';
dataval <= data_in;
elsif rx_count = 29 then
set_ip2 <= '1';
dataval <= data_in;
elsif rx_count = 30 then
set_ip1 <= '1';
dataval <= data_in;
elsif rx_count = 31 then
set_ip0 <= '1';
dataval <= data_in;
end if;
end if;
end case;
 
when PROCESS_ARP =>
next_rx_state <= WAIT_END;
set_rx_state <= '1';
case arp_operation is
when NOP => -- (nothing to do)
when REQUEST =>
set_arp_entry_request <= '1';
arp_oper_set_val <= NOP;
set_arp_oper <= '1';
when REPLY =>
set_arp_entry_request <= '1';
arp_oper_set_val <= NOP;
set_arp_oper <= '1';
end case;
 
when WAIT_END =>
case rx_event is
when NO_EVENT => -- (nothing to do)
when DATA =>
if data_in_last = '1' then
next_rx_state <= IDLE;
set_rx_state <= '1';
end if;
end case;
end case;
end process;
 
rx_sequential : process (data_in_clk)
begin
if rising_edge(data_in_clk) then
if reset = '1' then
-- reset state variables
rx_state <= IDLE;
rx_count <= x"00";
arp_operation <= NOP;
arp_req_count <= x"00";
-- reset arp entry store
arp_entry.ip <= x"00000000";
arp_entry.mac <= x"000000000000";
arp_entry.is_valid <= '0';
arp_entry.reply_required <= '0';
arp_err_data <= (others => '0');
else
-- Next rx_state processing
if set_rx_state = '1' then
rx_state <= next_rx_state;
else
rx_state <= rx_state;
end if;
-- rx_count processing
case rx_count_mode is
when RST =>
rx_count <= x"00";
when INCR =>
rx_count <= rx_count + 1;
when HOLD =>
rx_count <= rx_count;
end case;
-- err data
if set_err_data = '1' then
arp_err_data <= data_in;
else
arp_err_data <= arp_err_data;
end if;
-- arp operation processing
if set_arp_oper = '1' then
arp_operation <= arp_oper_set_val;
else
arp_operation <= arp_operation;
end if;
-- source mac capture
if (set_mac5 = '1') then new_arp_entry.mac(47 downto 40) <= dataval; end if;
if (set_mac4 = '1') then new_arp_entry.mac(39 downto 32) <= dataval; end if;
if (set_mac3 = '1') then new_arp_entry.mac(31 downto 24) <= dataval; end if;
if (set_mac2 = '1') then new_arp_entry.mac(23 downto 16) <= dataval; end if;
if (set_mac1 = '1') then new_arp_entry.mac(15 downto 8) <= dataval; end if;
if (set_mac0 = '1') then new_arp_entry.mac(7 downto 0) <= dataval; end if;
 
-- source ip capture
if (set_ip3 = '1') then new_arp_entry.ip(31 downto 24) <= dataval; end if;
if (set_ip2 = '1') then new_arp_entry.ip(23 downto 16) <= dataval; end if;
if (set_ip1 = '1') then new_arp_entry.ip(15 downto 8) <= dataval; end if;
if (set_ip0 = '1') then new_arp_entry.ip(7 downto 0) <= dataval; end if;
-- set arp entry request
if control.clear_cache = '1' then
arp_entry.ip <= x"00000000";
arp_entry.mac <= x"000000000000";
arp_entry.is_valid <= '0';
arp_entry.reply_required <= '0';
elsif set_arp_entry_request = '1' then
-- copy info from new entry to arp_entry and set reply required
arp_entry.mac <= new_arp_entry.mac;
arp_entry.ip <= new_arp_entry.ip;
arp_entry.is_valid <= '1';
if arp_operation = REQUEST then
arp_entry.reply_required <= '1';
else
arp_entry.reply_required <= '0';
end if;
-- count another ARP pkt received
arp_req_count <= arp_req_count + 1;
elsif clear_reply_req = '1' then
-- note: clear_reply_req is set by tx logic, but handled in the clk domain of the rx
-- maintain arp entry state, but reset the reply required flag
arp_entry.mac <= arp_entry.mac;
arp_entry.ip <= arp_entry.ip;
arp_entry.is_valid <= arp_entry.is_valid;
arp_entry.reply_required <= '0';
arp_req_count <= arp_req_count;
elsif send_request_needed = '1' then
-- set up the arp entry to take the request to be transmitted out by the TX FSM
arp_entry.ip <= req_ip_addr;
arp_entry.mac <= (others => '0');
arp_entry.is_valid <= '0';
arp_entry.reply_required <= '0';
else
arp_entry <= arp_entry;
arp_req_count <= arp_req_count;
end if;
end if;
end if;
end process;
 
tx_combinatorial : process (
-- input signals
data_out_ready, send_request_needed, mac_tx_granted, our_mac_address, our_ip_address,
-- state variables
tx_state, tx_count, tx_mac_chn_reqd, arp_entry,
-- control signals
next_rx_state, set_rx_state, tx_count_mode, kill_data_out_valid,
set_chn_reqd, clear_reply_req)
begin
-- set output followers
mac_tx_req <= tx_mac_chn_reqd;
-- set initial values for combinatorial outputs
data_out_first <= '0';
case tx_state is
when SEND =>
if data_out_ready = '1' and kill_data_out_valid = '0' then
data_out_valid <= '1';
else
data_out_valid <= '0';
end if;
when OTHERS => data_out_valid <= '0';
end case;
-- set signal defaults
next_tx_state <= IDLE;
set_tx_state <= '0';
tx_count_mode <= HOLD;
data_out <= x"00";
data_out_last <= '0';
clear_reply_req <= '0';
set_chn_reqd <= HOLD;
kill_data_out_valid <= '0';
-- TX FSM
case tx_state is
when IDLE =>
tx_count_mode <= RST;
if arp_entry.reply_required = '1' then
set_chn_reqd <= SET;
next_tx_state <= WAIT_MAC;
set_tx_state <= '1';
elsif send_request_needed = '1' then
set_chn_reqd <= SET;
next_tx_state <= WAIT_MAC;
set_tx_state <= '1';
else
set_chn_reqd <= CLR;
end if;
 
when WAIT_MAC =>
tx_count_mode <= RST;
if mac_tx_granted = '1' then
next_tx_state <= SEND;
set_tx_state <= '1';
end if;
-- TODO - should handle timeout here
when SEND =>
if data_out_ready = '1' then
tx_count_mode <= INCR;
end if;
case tx_count is
when x"00" =>
data_out_first <= data_out_ready;
data_out <= x"ff"; -- dst = broadcast
when x"01" => data_out <= x"ff";
when x"02" => data_out <= x"ff";
when x"03" => data_out <= x"ff";
when x"04" => data_out <= x"ff";
when x"05" => data_out <= x"ff";
when x"06" => data_out <= our_mac_address (47 downto 40); -- src = our mac
when x"07" => data_out <= our_mac_address (39 downto 32);
when x"08" => data_out <= our_mac_address (31 downto 24);
when x"09" => data_out <= our_mac_address (23 downto 16);
when x"0a" => data_out <= our_mac_address (15 downto 8);
when x"0b" => data_out <= our_mac_address (7 downto 0);
when x"0c" => data_out <= x"08"; -- pkt type = 0806 : ARP
when x"0d" => data_out <= x"06";
when x"0e" => data_out <= x"00"; -- HW type = 0001 : eth
when x"0f" => data_out <= x"01";
when x"10" => data_out <= x"08"; -- protocol = 0800 : ip
when x"11" => data_out <= x"00";
when x"12" => data_out <= x"06"; -- HW size = 06
when x"13" => data_out <= x"04"; -- prot size = 04
when x"14" => data_out <= x"00"; -- opcode =
when x"15" =>
if arp_entry.is_valid = '1' then
data_out <= x"02"; -- 02 : REPLY if arp_entry valid
else
data_out <= x"01"; -- 01 : REQ if arp_entry invalid
end if;
when x"16" => data_out <= our_mac_address (47 downto 40); -- sender mac
when x"17" => data_out <= our_mac_address (39 downto 32);
when x"18" => data_out <= our_mac_address (31 downto 24);
when x"19" => data_out <= our_mac_address (23 downto 16);
when x"1a" => data_out <= our_mac_address (15 downto 8);
when x"1b" => data_out <= our_mac_address (7 downto 0);
when x"1c" => data_out <= our_ip_address (31 downto 24); -- sender ip
when x"1d" => data_out <= our_ip_address (23 downto 16);
when x"1e" => data_out <= our_ip_address (15 downto 8);
when x"1f" => data_out <= our_ip_address (7 downto 0);
when x"20" => data_out <= arp_entry.mac (47 downto 40); -- target mac
when x"21" => data_out <= arp_entry.mac (39 downto 32);
when x"22" => data_out <= arp_entry.mac (31 downto 24);
when x"23" => data_out <= arp_entry.mac (23 downto 16);
when x"24" => data_out <= arp_entry.mac (15 downto 8);
when x"25" => data_out <= arp_entry.mac (7 downto 0);
when x"26" => data_out <= arp_entry.ip (31 downto 24); -- target ip
when x"27" => data_out <= arp_entry.ip (23 downto 16);
when x"28" => data_out <= arp_entry.ip (15 downto 8);
when x"29" =>
data_out <= arp_entry.ip(7 downto 0);
data_out_last <= '1';
when x"2a" =>
clear_reply_req <= '1'; -- reset the reply request (done in the rx clk process domain)
kill_data_out_valid <= '1'; -- data is no longer valid
next_tx_state <= IDLE;
set_tx_state <= '1';
 
when others =>
next_tx_state <= IDLE;
set_tx_state <= '1';
end case;
end case;
end process;
 
tx_sequential : process (data_out_clk,reset)
begin
if rising_edge(data_out_clk) then
if reset = '1' then
-- reset state variables
tx_state <= IDLE;
tx_mac_chn_reqd <= '0';
else
-- Next rx_state processing
if set_tx_state = '1' then
tx_state <= next_tx_state;
else
tx_state <= tx_state;
end if;
-- tx_count processing
case tx_count_mode is
when RST =>
tx_count <= x"00";
when INCR =>
tx_count <= tx_count + 1;
when HOLD =>
tx_count <= tx_count;
end case;
 
-- control access request to mac tx chn
case set_chn_reqd is
when SET => tx_mac_chn_reqd <= '1';
when CLR => tx_mac_chn_reqd <= '0';
when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
end case;
end if;
end if;
end process;
 
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/ml605/IP_complete.vhd
0,0 → 1,272
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 20:25:56 06/03/2011
-- Design Name:
-- Module Name: IP_complete - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description: Implements complete IP stack with ARP and MAC
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
 
entity IP_complete is
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
Port (
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
ip_rx : out ipv4_rx_type;
-- system signals
clk_in_p : in std_logic; -- 200MHz clock input from board
clk_in_n : in std_logic;
clk_out : out std_logic;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in ip_control_type;
-- status signals
arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received
ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- GMII Interface
phy_resetn : out std_logic;
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
gmii_col : in std_logic;
gmii_crs : in std_logic;
mii_tx_clk : in std_logic
);
end IP_complete;
 
architecture structural of IP_complete is
 
------------------------------------------------------------------------------
-- Component Declaration for the IP layer
------------------------------------------------------------------------------
 
COMPONENT IP_complete_nomac
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
Port (
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
ip_rx : out ipv4_rx_type;
-- system signals
rx_clk : in STD_LOGIC;
tx_clk : in STD_LOGIC;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in ip_control_type;
-- status signals
arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received
ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- MAC Transmitter
mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : out std_logic; -- tdata is valid
mac_tx_tready : in std_logic; -- mac is ready to accept data
mac_tx_tfirst : out std_logic; -- indicates first byte of frame
mac_tx_tlast : out std_logic; -- indicates last byte of frame
-- MAC Receiver
mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : in std_logic; -- indicates tdata is valid
mac_rx_tready : out std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : in std_logic -- indicates last byte of the trame
);
END COMPONENT;
 
 
------------------------------------------------------------------------------
-- Component Declaration for the MAC layer
------------------------------------------------------------------------------
component mac_layer_v2_1
port (
-- System controls
------------------
glbl_rst : in std_logic; -- asynchronous reset
mac_reset : in std_logic; -- reset mac layer
clk_in_p : in std_logic; -- 200MHz clock input from board
clk_in_n : in std_logic;
-- MAC Transmitter (AXI-S) Interface
---------------------------------------------
mac_tx_clock : out std_logic; -- data sampled on rising edge
mac_tx_tdata : in std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : in std_logic; -- tdata is valid
mac_tx_tready : out std_logic; -- mac is ready to accept data
mac_tx_tlast : in std_logic; -- indicates last byte of frame
 
-- MAC Receiver (AXI-S) Interface
------------------------------------------
mac_rx_clock : out std_logic; -- data valid on rising edge
mac_rx_tdata : out std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : out std_logic; -- indicates tdata is valid
mac_rx_tready : in std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : out std_logic; -- indicates last byte of the trame
-- GMII Interface
-----------------
phy_resetn : out std_logic;
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
gmii_col : in std_logic;
gmii_crs : in std_logic;
mii_tx_clk : in std_logic
);
end component;
 
---------------------------
-- Signals
---------------------------
-- MAC RX bus
signal mac_rx_clock : std_logic;
signal mac_rx_tdata : std_logic_vector (7 downto 0);
signal mac_rx_tvalid : std_logic;
signal mac_rx_tready : std_logic;
signal mac_rx_tlast : std_logic;
-- MAC TX bus
signal mac_tx_clock : std_logic;
signal mac_tx_tdata : std_logic_vector (7 downto 0);
signal mac_tx_tvalid : std_logic;
signal mac_tx_tready : std_logic;
signal mac_tx_tlast : std_logic;
-- control signals
signal mac_tx_tready_int : std_logic;
signal mac_tx_granted_int : std_logic;
 
begin
 
clk_out <= mac_rx_clock;
 
------------------------------------------------------------------------------
-- Instantiate the IP layer
------------------------------------------------------------------------------
 
IP_layer : IP_complete_nomac
generic map (
CLOCK_FREQ => CLOCK_FREQ,
ARP_TIMEOUT => ARP_TIMEOUT,
ARP_MAX_PKT_TMO => ARP_MAX_PKT_TMO,
MAX_ARP_ENTRIES => MAX_ARP_ENTRIES
)
PORT MAP (
-- IP Layer signals
ip_tx_start => ip_tx_start,
ip_tx => ip_tx,
ip_tx_result => ip_tx_result,
ip_tx_data_out_ready => ip_tx_data_out_ready,
ip_rx_start => ip_rx_start,
ip_rx => ip_rx,
-- system signals
rx_clk => mac_rx_clock,
tx_clk => mac_rx_clock,
reset => reset,
our_ip_address => our_ip_address,
our_mac_address => our_mac_address,
control => control,
-- status signals
arp_pkt_count => arp_pkt_count,
ip_pkt_count => ip_pkt_count,
-- MAC Transmitter
mac_tx_tready => mac_tx_tready_int,
mac_tx_tvalid => mac_tx_tvalid,
mac_tx_tfirst => open,
mac_tx_tlast => mac_tx_tlast,
mac_tx_tdata => mac_tx_tdata,
-- MAC Receiver
mac_rx_tdata => mac_rx_tdata,
mac_rx_tvalid => mac_rx_tvalid,
mac_rx_tready => mac_rx_tready,
mac_rx_tlast => mac_rx_tlast
);
 
------------------------------------------------------------------------------
-- Instantiate the MAC layer
------------------------------------------------------------------------------
mac_block : mac_layer_v2_1
Port map(
-- System controls
------------------
glbl_rst => reset,
mac_reset => '0',
clk_in_p => clk_in_p,
clk_in_n => clk_in_n,
-- MAC Transmitter (AXI-S) Interface
---------------------------------------------
mac_tx_clock => mac_tx_clock,
mac_tx_tdata => mac_tx_tdata,
mac_tx_tvalid => mac_tx_tvalid,
mac_tx_tready => mac_tx_tready_int,
mac_tx_tlast => mac_tx_tlast,
 
-- MAC Receiver (AXI-S) Interface
------------------------------------------
mac_rx_clock => mac_rx_clock,
mac_rx_tdata => mac_rx_tdata,
mac_rx_tvalid => mac_rx_tvalid,
mac_rx_tready => mac_rx_tready,
mac_rx_tlast => mac_rx_tlast,
-- GMII Interface
-----------------
phy_resetn => phy_resetn,
gmii_txd => gmii_txd,
gmii_tx_en => gmii_tx_en,
gmii_tx_er => gmii_tx_er,
gmii_tx_clk => gmii_tx_clk,
gmii_rxd => gmii_rxd,
gmii_rx_dv => gmii_rx_dv,
gmii_rx_er => gmii_rx_er,
gmii_rx_clk => gmii_rx_clk,
gmii_col => gmii_col,
gmii_crs => gmii_crs,
mii_tx_clk => mii_tx_clk
);
 
end structural;
 
/tags/v2.3/rtl/vhdl/ml605/UDP_Complete.vhd
0,0 → 1,296
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:51:18 06/11/2011
-- Design Name:
-- Module Name: UDP_Complete - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - separated RX and TX clocks
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
 
entity UDP_Complete is
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
Port (
-- UDP TX signals
udp_tx_start : in std_logic; -- indicates req to tx UDP
udp_txi : in udp_tx_type; -- UDP tx cxns
udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission)
udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data
-- UDP RX signals
udp_rx_start : out std_logic; -- indicates receipt of udp header
udp_rxo : out udp_rx_type;
-- IP RX signals
ip_rx_hdr : out ipv4_rx_header_type;
-- system signals
clk_in_p : in std_logic; -- 200MHz clock input from board
clk_in_n : in std_logic;
clk_out : out std_logic;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in udp_control_type;
-- status signals
arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received
ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- GMII Interface
phy_resetn : out std_logic;
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
gmii_col : in std_logic;
gmii_crs : in std_logic;
mii_tx_clk : in std_logic
);
end UDP_Complete;
 
 
 
 
architecture structural of UDP_Complete is
 
------------------------------------------------------------------------------
-- Component Declaration for UDP complete no mac
------------------------------------------------------------------------------
 
COMPONENT UDP_Complete_nomac
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
Port (
-- UDP TX signals
udp_tx_start : in std_logic; -- indicates req to tx UDP
udp_txi : in udp_tx_type; -- UDP tx cxns
udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission)
udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data
-- UDP RX signals
udp_rx_start : out std_logic; -- indicates receipt of udp header
udp_rxo : out udp_rx_type;
-- IP RX signals
ip_rx_hdr : out ipv4_rx_header_type;
-- system signals
rx_clk : in STD_LOGIC;
tx_clk : in STD_LOGIC;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in udp_control_type;
-- status signals
arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received
ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- MAC Transmitter
mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : out std_logic; -- tdata is valid
mac_tx_tready : in std_logic; -- mac is ready to accept data
mac_tx_tfirst : out std_logic; -- indicates first byte of frame
mac_tx_tlast : out std_logic; -- indicates last byte of frame
-- MAC Receiver
mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : in std_logic; -- indicates tdata is valid
mac_rx_tready : out std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : in std_logic -- indicates last byte of the trame
);
END COMPONENT;
 
 
------------------------------------------------------------------------------
-- Component Declaration for the MAC layer
------------------------------------------------------------------------------
component mac_v2_2
-- component xv6mac_straight
port (
-- System controls
------------------
glbl_rst : in std_logic; -- asynchronous reset
mac_reset : in std_logic; -- reset mac layer
clk_in_p : in std_logic; -- 200MHz clock input from board
clk_in_n : in std_logic;
-- MAC Transmitter (AXI-S) Interface
---------------------------------------------
mac_tx_clock : out std_logic; -- data sampled on rising edge
mac_tx_tdata : in std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : in std_logic; -- tdata is valid
mac_tx_tready : out std_logic; -- mac is ready to accept data
mac_tx_tlast : in std_logic; -- indicates last byte of frame
 
-- MAC Receiver (AXI-S) Interface
------------------------------------------
mac_rx_clock : out std_logic; -- data valid on rising edge
mac_rx_tdata : out std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : out std_logic; -- indicates tdata is valid
mac_rx_tready : in std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : out std_logic; -- indicates last byte of the trame
-- GMII Interface
-----------------
phy_resetn : out std_logic;
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
gmii_col : in std_logic;
gmii_crs : in std_logic;
mii_tx_clk : in std_logic
);
end component;
 
 
---------------------------
-- Signals
---------------------------
-- MAC RX bus
signal mac_rx_clock : std_logic;
signal mac_rx_tdata : std_logic_vector (7 downto 0);
signal mac_rx_tvalid : std_logic;
signal mac_rx_tready : std_logic;
signal mac_rx_tlast : std_logic;
-- MAC TX bus
signal mac_tx_clock : std_logic;
signal mac_tx_tdata : std_logic_vector (7 downto 0);
signal mac_tx_tvalid : std_logic;
signal mac_tx_tready : std_logic;
signal mac_tx_tlast : std_logic;
-- control signals
signal mac_tx_tready_int : std_logic;
signal mac_tx_granted_int : std_logic;
 
 
begin
 
 
process (mac_tx_clock)
begin
-- output followers
clk_out <= mac_tx_clock;
end process;
 
------------------------------------------------------------------------------
-- Instantiate the UDP layer
------------------------------------------------------------------------------
 
udp_block: UDP_Complete_nomac
generic map (
CLOCK_FREQ => CLOCK_FREQ,
ARP_TIMEOUT => ARP_TIMEOUT,
ARP_MAX_PKT_TMO => ARP_MAX_PKT_TMO,
MAX_ARP_ENTRIES => MAX_ARP_ENTRIES
)
PORT MAP (
-- UDP TX signals
udp_tx_start => udp_tx_start,
udp_txi => udp_txi,
udp_tx_result => udp_tx_result,
udp_tx_data_out_ready => udp_tx_data_out_ready,
-- UDP RX signals
udp_rx_start => udp_rx_start,
udp_rxo => udp_rxo,
-- IP RX signals
ip_rx_hdr => ip_rx_hdr,
-- system signals
rx_clk => mac_rx_clock,
tx_clk => mac_tx_clock,
reset => reset,
our_ip_address => our_ip_address,
our_mac_address => our_mac_address,
-- status signals
arp_pkt_count => arp_pkt_count,
ip_pkt_count => ip_pkt_count,
control => control,
-- MAC Transmitter
mac_tx_tready => mac_tx_tready_int,
mac_tx_tvalid => mac_tx_tvalid,
mac_tx_tfirst => open,
mac_tx_tlast => mac_tx_tlast,
mac_tx_tdata => mac_tx_tdata,
-- MAC Receiver
mac_rx_tdata => mac_rx_tdata,
mac_rx_tvalid => mac_rx_tvalid,
mac_rx_tready => mac_rx_tready,
mac_rx_tlast => mac_rx_tlast
);
 
 
------------------------------------------------------------------------------
-- Instantiate the MAC layer
------------------------------------------------------------------------------
mac_block : mac_v2_2
-- mac_block : xv6mac_straight
Port map(
-- System controls
------------------
glbl_rst => reset,
mac_reset => '0',
clk_in_p => clk_in_p,
clk_in_n => clk_in_n,
-- MAC Transmitter (AXI-S) Interface
---------------------------------------------
mac_tx_clock => mac_tx_clock,
mac_tx_tdata => mac_tx_tdata,
mac_tx_tvalid => mac_tx_tvalid,
mac_tx_tready => mac_tx_tready_int,
mac_tx_tlast => mac_tx_tlast,
 
-- MAC Receiver (AXI-S) Interface
------------------------------------------
mac_rx_clock => mac_rx_clock,
mac_rx_tdata => mac_rx_tdata,
mac_rx_tvalid => mac_rx_tvalid,
mac_rx_tready => mac_rx_tready,
mac_rx_tlast => mac_rx_tlast,
-- GMII Interface
-----------------
phy_resetn => phy_resetn,
gmii_txd => gmii_txd,
gmii_tx_en => gmii_tx_en,
gmii_tx_er => gmii_tx_er,
gmii_tx_clk => gmii_tx_clk,
gmii_rxd => gmii_rxd,
gmii_rx_dv => gmii_rx_dv,
gmii_rx_er => gmii_rx_er,
gmii_rx_clk => gmii_rx_clk,
gmii_col => gmii_col,
gmii_crs => gmii_crs,
mii_tx_clk => mii_tx_clk
);
 
 
end structural;
 
 
/tags/v2.3/rtl/vhdl/ml605/UDP_integration_example.vhd
0,0 → 1,490
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 11:01:00 06/11/2011
-- Design Name:
-- Module Name: UDP_integration_example - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
 
entity UDP_integration_example is
port (
-- System signals
------------------
reset : in std_logic; -- asynchronous reset
clk_in_p : in std_logic; -- 200MHz clock input from board
clk_in_n : in std_logic;
 
-- System controls
------------------
PBTX : in std_logic;
PB_DO_SECOND_TX : in std_logic;
DO_SECOND_TX_LED : out std_logic;
UDP_RX : out std_logic;
UDP_Start : out std_logic;
PBTX_LED : out std_logic;
TX_Started : out std_logic;
TX_Completed : out std_logic;
TX_RSLT_0 : out std_logic;
TX_RSLT_1 : out std_logic;
reset_leds : in std_logic;
display : out std_logic_vector(7 downto 0);
-- GMII Interface
-----------------
phy_resetn : out std_logic;
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
gmii_col : in std_logic;
gmii_crs : in std_logic;
mii_tx_clk : in std_logic
);
end UDP_integration_example;
 
architecture Behavioral of UDP_integration_example is
 
 
------------------------------------------------------------------------------
-- Component Declaration for the complete UDP layer
------------------------------------------------------------------------------
component UDP_Complete
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
Port (
-- UDP TX signals
udp_tx_start : in std_logic; -- indicates req to tx UDP
udp_txi : in udp_tx_type; -- UDP tx cxns
udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission)
udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data
-- UDP RX signals
udp_rx_start : out std_logic; -- indicates receipt of udp header
udp_rxo : out udp_rx_type;
-- IP RX signals
ip_rx_hdr : out ipv4_rx_header_type;
-- system signals
clk_in_p : in std_logic; -- 200MHz clock input from board
clk_in_n : in std_logic;
clk_out : out std_logic;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in udp_control_type;
-- status signals
arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received
ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- GMII Interface
phy_resetn : out std_logic;
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
gmii_col : in std_logic;
gmii_crs : in std_logic;
mii_tx_clk : in std_logic
);
end component;
 
-- for UDP_block : UDP_Complete use configuration work.UDP_Complete.udpc_multi_slot_arp;
 
 
type state_type is (IDLE, WAIT_RX_DONE, DATA_OUT, PAUSE, CHECK_SECOND_TX, SET_SEC_HDR);
type count_mode_type is (RST, INCR, HOLD);
type set_clr_type is (SET, CLR, HOLD);
type sec_tx_ctrl_type is (CLR,PRIME,DO,HOLD);
 
-- system signals
signal clk_int : std_logic;
signal our_mac : STD_LOGIC_VECTOR (47 downto 0);
signal our_ip : STD_LOGIC_VECTOR (31 downto 0);
signal udp_tx_int : udp_tx_type;
signal udp_tx_result_int : std_logic_vector (1 downto 0);
signal udp_tx_data_out_ready_int : std_logic;
signal udp_rx_int : udp_rx_type;
signal udp_tx_start_int : std_logic;
signal udp_rx_start_int : std_logic;
signal arp_pkt_count_int : STD_LOGIC_VECTOR(7 downto 0);
signal ip_pkt_count_int : STD_LOGIC_VECTOR(7 downto 0);
signal ip_rx_hdr_int : ipv4_rx_header_type;
-- state signals
signal state : state_type;
signal count : unsigned (7 downto 0);
signal tx_hdr : udp_tx_header_type;
signal tx_start_reg : std_logic;
signal tx_started_reg : std_logic;
signal tx_fin_reg : std_logic;
signal prime_second_tx : std_logic; -- if want to do a 2nd tx after the first
signal do_second_tx : std_logic; -- if need to do a 2nd tx as next tx
-- control signals
signal next_state : state_type;
signal set_state : std_logic;
signal set_count : count_mode_type;
signal set_hdr : std_logic;
signal set_tx_start : set_clr_type;
signal set_last : std_logic;
signal set_tx_started : set_clr_type;
signal set_tx_fin : set_clr_type;
signal first_byte_rx : STD_LOGIC_VECTOR(7 downto 0);
signal control_int : udp_control_type;
signal set_second_tx : sec_tx_ctrl_type;
 
begin
 
process (
our_ip, our_mac, udp_tx_result_int, udp_rx_int, udp_tx_start_int, udp_rx_start_int, ip_rx_hdr_int,
udp_tx_int, count, clk_int, ip_pkt_count_int, arp_pkt_count_int,
reset, tx_started_reg, tx_fin_reg, tx_start_reg, state, prime_second_tx, do_second_tx, set_second_tx,
PB_DO_SECOND_TX, do_second_tx
)
begin
-- set up our local addresses and default controls
our_ip <= x"c0a80019"; -- 192.168.0.25
our_mac <= x"002320212223";
control_int.ip_controls.arp_controls.clear_cache <= '0';
-- determine RX good and error LEDs
if udp_rx_int.hdr.is_valid = '1' then
UDP_RX <= '1';
else
UDP_RX <= '0';
end if;
UDP_Start <= udp_rx_start_int;
TX_Started <= tx_start_reg; --tx_started_reg;
TX_Completed <= tx_fin_reg;
TX_RSLT_0 <= udp_tx_result_int(0);
TX_RSLT_1 <= udp_tx_result_int(1);
DO_SECOND_TX_LED <= prime_second_tx;
-- set display leds to show IP pkt rx count on 7..4 and arp rx count on 3..0
display (7 downto 4) <= ip_pkt_count_int (3 downto 0);
-- display (3 downto 0) <= arp_pkt_count_int (3 downto 0);
case state is
when IDLE => display (3 downto 0) <= "0001";
when WAIT_RX_DONE => display (3 downto 0) <= "0010";
when DATA_OUT => display (3 downto 0) <= "0011";
when PAUSE => display (3 downto 0) <= "0100";
when CHECK_SECOND_TX => display (3 downto 0) <= "0101";
when SET_SEC_HDR => display (3 downto 0) <= "0110";
end case;
 
end process;
-- AUTO TX process - on receipt of any UDP pkt, send a response. data sent is modified if a broadcast was received.
-- TX response process - COMB
tx_proc_combinatorial: process(
-- inputs
udp_rx_start_int, udp_rx_int, udp_tx_data_out_ready_int, udp_tx_result_int, ip_rx_hdr_int,
udp_tx_int.data.data_out_valid, PBTX, PB_DO_SECOND_TX,
-- state
state, count, tx_hdr, tx_start_reg, tx_started_reg, tx_fin_reg, prime_second_tx, do_second_tx,
-- controls
next_state, set_state, set_count, set_hdr, set_tx_start, set_last,
set_tx_started, set_tx_fin, first_byte_rx, set_second_tx
)
begin
-- set output_followers
udp_tx_int.hdr <= tx_hdr;
udp_tx_int.data.data_out_last <= set_last;
udp_tx_start_int <= tx_start_reg;
 
-- set control signal defaults
next_state <= IDLE;
set_state <= '0';
set_count <= HOLD;
set_hdr <= '0';
set_tx_start <= HOLD;
set_last <= '0';
set_tx_started <= HOLD;
set_tx_fin <= HOLD;
first_byte_rx <= (others => '0');
udp_tx_int.data.data_out <= (others => '0');
udp_tx_int.data.data_out_valid <= '0';
set_second_tx <= HOLD;
if PB_DO_SECOND_TX = '1' then
set_second_tx <= PRIME;
end if;
-- FSM
case state is
when IDLE =>
udp_tx_int.data.data_out_valid <= '0';
if udp_rx_start_int = '1' or PBTX = '1' then
if udp_rx_start_int = '1' then
first_byte_rx <= udp_rx_int.data.data_in;
else
first_byte_rx <= x"00";
end if;
set_tx_fin <= CLR;
set_count <= RST;
set_hdr <= '1';
if udp_rx_int.data.data_in_last = '1' then
set_tx_started <= SET;
set_tx_start <= SET;
next_state <= DATA_OUT;
set_state <= '1';
else
next_state <= WAIT_RX_DONE;
set_state <= '1';
end if;
end if;
when WAIT_RX_DONE =>
-- wait until RX pkt fully received
if udp_rx_int.data.data_in_last = '1' then
set_tx_started <= SET;
set_tx_start <= SET;
next_state <= DATA_OUT;
set_state <= '1';
end if;
when DATA_OUT =>
if udp_tx_result_int = UDPTX_RESULT_ERR then
-- have an error from the IP TX layer, clear down the TX
set_tx_start <= CLR;
set_tx_fin <= SET;
set_tx_started <= CLR;
set_second_tx <= CLR;
next_state <= IDLE;
set_state <= '1';
else
if udp_tx_result_int = UDPTX_RESULT_SENDING then
set_tx_start <= CLR; -- reset out start req as soon as we know we are sending
end if;
if ip_rx_hdr_int.is_broadcast = '1' then
udp_tx_int.data.data_out <= std_logic_vector(count) or x"50";
else
udp_tx_int.data.data_out <= std_logic_vector(count) or x"40";
end if;
udp_tx_int.data.data_out_valid <= udp_tx_data_out_ready_int;
if udp_tx_data_out_ready_int = '1' then
if unsigned(count) = x"03" then
set_last <= '1';
set_tx_fin <= SET;
set_tx_started <= CLR;
next_state <= PAUSE;
set_state <= '1';
else
set_count <= INCR;
end if;
end if;
end if;
 
when PAUSE =>
next_state <= CHECK_SECOND_TX;
set_state <= '1';
 
 
when CHECK_SECOND_TX =>
if prime_second_tx = '1' then
set_second_tx <= DO;
next_state <= SET_SEC_HDR;
set_state <= '1';
else
set_second_tx <= CLR;
next_state <= IDLE;
set_state <= '1';
end if;
when SET_SEC_HDR =>
set_hdr <= '1';
set_tx_started <= SET;
set_tx_start <= SET;
next_state <= DATA_OUT;
set_state <= '1';
end case;
end process;
 
-- TX response process - SEQ
tx_proc_sequential: process(clk_int)
begin
if rising_edge(clk_int) then
if reset = '1' then
-- reset state variables
state <= IDLE;
count <= x"00";
tx_start_reg <= '0';
tx_hdr.dst_ip_addr <= (others => '0');
tx_hdr.dst_port <= (others => '0');
tx_hdr.src_port <= (others => '0');
tx_hdr.data_length <= (others => '0');
tx_hdr.checksum <= (others => '0');
tx_started_reg <= '0';
tx_fin_reg <= '0';
PBTX_LED <= '0';
do_second_tx <= '0';
prime_second_tx <= '0';
else
PBTX_LED <= PBTX;
-- Next rx_state processing
if set_state = '1' then
state <= next_state;
else
state <= state;
end if;
-- count processing
case set_count is
when RST => count <= x"00";
when INCR => count <= count + 1;
when HOLD => count <= count;
end case;
-- set tx hdr
if set_hdr = '1' then
-- select the dst addr of the tx:
-- if do_second_tx, to solaris box
-- otherwise control according to first byte of received data:
-- B = broadcast
-- C = to dummy address to test timeout
-- D to solaris box
-- otherwise, direct to sender
if do_second_tx = '1' then
tx_hdr.dst_ip_addr <= x"c0a80005"; -- set dst to solaris box at 192.168.0.5
elsif first_byte_rx = x"42" then
tx_hdr.dst_ip_addr <= IP_BC_ADDR; -- send to Broadcast addr
elsif first_byte_rx = x"43" then
tx_hdr.dst_ip_addr <= x"c0bbccdd"; -- set dst unknown so get ARP timeout
elsif first_byte_rx = x"44" then
tx_hdr.dst_ip_addr <= x"c0a80005"; -- set dst to solaris box at 192.168.0.5
else
tx_hdr.dst_ip_addr <= udp_rx_int.hdr.src_ip_addr; -- reply to sender
end if;
tx_hdr.dst_port <= udp_rx_int.hdr.src_port;
tx_hdr.src_port <= udp_rx_int.hdr.dst_port;
tx_hdr.data_length <= x"0004";
tx_hdr.checksum <= x"0000";
else
tx_hdr <= tx_hdr;
end if;
-- set tx start signal
case set_tx_start is
when SET => tx_start_reg <= '1';
when CLR => tx_start_reg <= '0';
when HOLD => tx_start_reg <= tx_start_reg;
end case;
 
-- set tx started signal
case set_tx_started is
when SET => tx_started_reg <= '1';
when CLR => tx_started_reg <= '0';
when HOLD => tx_started_reg <= tx_started_reg;
end case;
 
-- set tx finished signal
case set_tx_fin is
when SET => tx_fin_reg <= '1';
when CLR => tx_fin_reg <= '0';
when HOLD => tx_fin_reg <= tx_fin_reg;
end case;
 
-- set do_second_tx
case set_second_tx is
when PRIME =>
prime_second_tx <= '1';
when DO =>
prime_second_tx <= '0';
do_second_tx <= '1';
when CLR =>
prime_second_tx <= '0';
do_second_tx <= '0';
when HOLD =>
prime_second_tx <= prime_second_tx;
do_second_tx <= do_second_tx;
end case;
end if;
end if;
 
end process;
 
------------------------------------------------------------------------------
-- Instantiate the UDP layer
------------------------------------------------------------------------------
UDP_block : UDP_Complete
generic map (
ARP_TIMEOUT => 10 -- timeout in seconds
)
PORT MAP (
-- UDP interface
udp_tx_start => udp_tx_start_int,
udp_txi => udp_tx_int,
udp_tx_result => udp_tx_result_int,
udp_tx_data_out_ready=> udp_tx_data_out_ready_int,
udp_rx_start => udp_rx_start_int,
udp_rxo => udp_rx_int,
-- IP RX signals
ip_rx_hdr => ip_rx_hdr_int,
-- System interface
clk_in_p => clk_in_p,
clk_in_n => clk_in_n,
clk_out => clk_int,
reset => reset,
our_ip_address => our_ip,
our_mac_address => our_mac,
control => control_int,
-- status signals
arp_pkt_count => arp_pkt_count_int,
ip_pkt_count => ip_pkt_count_int,
-- GMII Interface
-----------------
phy_resetn => phy_resetn,
gmii_txd => gmii_txd,
gmii_tx_en => gmii_tx_en,
gmii_tx_er => gmii_tx_er,
gmii_tx_clk => gmii_tx_clk,
gmii_rxd => gmii_rxd,
gmii_rx_dv => gmii_rx_dv,
gmii_rx_er => gmii_rx_er,
gmii_rx_clk => gmii_rx_clk,
gmii_col => gmii_col,
gmii_crs => gmii_crs,
mii_tx_clk => mii_tx_clk
);
 
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/ml605/xv6mac_straight.vhd
0,0 → 1,463
--------------------------------------------------------------------------------
-- Project : low latency UDP
-- File : xv6mac_straight
-- Version : 0.0
-------------------------------------------------------------------------------
--
--
-- Description: This is an adaptation of the Xilinx V6 MAC layer, but without the FIFOs
--
--
--
-- ---------------------------------------------------------------------
-- | EXAMPLE DESIGN WRAPPER |
-- | --------------------------------------------------------|
-- | |FIFO BLOCK WRAPPER |
-- | | |
-- | | |
-- | | -----------------------------------------|
-- | | | BLOCK LEVEL WRAPPER |
-- | | | --------------------- |
-- | | | | V6 EMAC CORE | |
-- | | | | | |
-- | | | | | |
-- | | | | | |
-- | | | | | |
-- | | | | | |
-- | | | | | | | --------- |
-- | | |->|->----------->|--|--->| Tx Tx |--| |--->|
-- | | | | | | AXI-S PHY | | | |
-- | | | | | | I/F I/F | | | |
-- | | | | | | | | PHY | |
-- | | | | | | | | I/F | |
-- | | | | | | | | | |
-- | | | | | | Rx Rx | | | |
-- | | | | | | AX)-S PHY | | | |
-- | | |<-|<-------------|----| I/F I/F |<-| |<---|
-- | | | | | | | --------- |
-- | -------- | | --------------------- |
-- | | | |
-- | | -----------------------------------------|
-- | --------------------------------------------------------|
-- ---------------------------------------------------------------------
--
--------------------------------------------------------------------------------
 
library unisim;
use unisim.vcomponents.all;
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
 
entity xv6mac_straight is
port (
-- System controls
------------------
glbl_rst : in std_logic; -- asynchronous reset
mac_reset : in std_logic; -- reset mac layer
clk_in_p : in std_logic; -- 200MHz clock input from board
clk_in_n : in std_logic;
-- MAC Transmitter (AXI-S) Interface
---------------------------------------------
mac_tx_clock : out std_logic; -- data sampled on rising edge
mac_tx_tdata : in std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : in std_logic; -- tdata is valid
mac_tx_tready : out std_logic; -- mac is ready to accept data
mac_tx_tlast : in std_logic; -- indicates last byte of frame
 
-- MAC Receiver (AXI-S) Interface
------------------------------------------
mac_rx_clock : out std_logic; -- data valid on rising edge
mac_rx_tdata : out std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : out std_logic; -- indicates tdata is valid
mac_rx_tready : in std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : out std_logic; -- indicates last byte of the trame
-- GMII Interface
-----------------
phy_resetn : out std_logic;
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
gmii_col : in std_logic;
gmii_crs : in std_logic;
mii_tx_clk : in std_logic
);
end xv6mac_straight;
 
architecture wrapper of xv6mac_straight is
 
------------------------------------------------------------------------------
-- Component declaration for the internal mac layer
------------------------------------------------------------------------------
component mac_layer_v2_2_block
port(
gtx_clk : in std_logic;
 
-- Receiver Interface
----------------------------
rx_statistics_vector : out std_logic_vector(27 downto 0);
rx_statistics_valid : out std_logic;
 
rx_mac_aclk : out std_logic;
rx_reset : out std_logic;
rx_axis_mac_tdata : out std_logic_vector(7 downto 0);
rx_axis_mac_tvalid : out std_logic;
rx_axis_mac_tlast : out std_logic;
rx_axis_mac_tuser : out std_logic;
 
-- Transmitter Interface
-------------------------------
tx_ifg_delay : in std_logic_vector(7 downto 0);
tx_statistics_vector : out std_logic_vector(31 downto 0);
tx_statistics_valid : out std_logic;
 
tx_reset : out std_logic;
tx_axis_mac_tdata : in std_logic_vector(7 downto 0);
tx_axis_mac_tvalid : in std_logic;
tx_axis_mac_tlast : in std_logic;
tx_axis_mac_tuser : in std_logic;
tx_axis_mac_tready : out std_logic;
tx_collision : out std_logic;
tx_retransmit : out std_logic;
 
-- MAC Control Interface
------------------------
pause_req : in std_logic;
pause_val : in std_logic_vector(15 downto 0);
 
-- Reference clock for IDELAYCTRL's
refclk : in std_logic;
 
-- GMII Interface
-----------------
gmii_txd : out std_logic_vector(7 downto 0);
gmii_tx_en : out std_logic;
gmii_tx_er : out std_logic;
gmii_tx_clk : out std_logic;
gmii_rxd : in std_logic_vector(7 downto 0);
gmii_rx_dv : in std_logic;
gmii_rx_er : in std_logic;
gmii_rx_clk : in std_logic;
 
-- asynchronous reset
-----------------
glbl_rstn : in std_logic;
rx_axi_rstn : in std_logic;
tx_axi_rstn : in std_logic
 
);
end component;
 
 
------------------------------------------------------------------------------
-- Component Declaration for the Clock generator
------------------------------------------------------------------------------
 
component clk_wiz_v2_2
port (
-- Clock in ports
CLK_IN1_P : in std_logic;
CLK_IN1_N : in std_logic;
-- Clock out ports
CLK_OUT1 : out std_logic;
CLK_OUT2 : out std_logic;
CLK_OUT3 : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end component;
 
 
------------------------------------------------------------------------------
-- Component declaration for the reset synchroniser
------------------------------------------------------------------------------
component reset_sync_v2_2
port (
reset_in : in std_logic; -- Active high asynchronous reset
enable : in std_logic;
clk : in std_logic; -- clock to be sync'ed to
reset_out : out std_logic -- "Synchronised" reset signal
);
end component;
 
------------------------------------------------------------------------------
-- Component declaration for the synchroniser
------------------------------------------------------------------------------
component sync_block_v2_2
port (
clk : in std_logic;
data_in : in std_logic;
data_out : out std_logic
);
end component;
 
------------------------------------------------------------------------------
-- Constants used in this top level wrapper.
------------------------------------------------------------------------------
constant BOARD_PHY_ADDR : std_logic_vector(7 downto 0) := "00000111";
 
 
------------------------------------------------------------------------------
-- internal signals used in this top level wrapper.
------------------------------------------------------------------------------
 
-- example design clocks
signal gtx_clk_bufg : std_logic;
signal refclk_bufg : std_logic;
signal rx_mac_aclk : std_logic;
-- tx handshaking
signal mac_tx_tready_int : std_logic;
signal tx_full_reg : std_logic;
signal tx_full_val : std_logic;
signal tx_data_reg : std_logic_vector(7 downto 0);
signal tx_last_reg : std_logic;
signal set_tx_reg : std_logic;
signal phy_resetn_int : std_logic;
 
-- resets (and reset generation)
signal local_chk_reset : std_logic;
signal chk_reset_int : std_logic;
signal chk_pre_resetn : std_logic := '0';
signal chk_resetn : std_logic := '0';
signal dcm_locked : std_logic;
 
signal glbl_rst_int : std_logic;
signal phy_reset_count : unsigned(5 downto 0);
signal glbl_rst_intn : std_logic;
 
-- pipeline register for RX signals
signal rx_data_val : std_logic_vector(7 downto 0);
signal rx_tvalid_val : std_logic;
signal rx_tlast_val : std_logic;
signal rx_data_reg : std_logic_vector(7 downto 0);
signal rx_tvalid_reg : std_logic;
signal rx_tlast_reg : std_logic;
 
attribute keep : string;
attribute keep of gtx_clk_bufg : signal is "true";
attribute keep of refclk_bufg : signal is "true";
attribute keep of mac_tx_tready_int : signal is "true";
attribute keep of tx_full_reg : signal is "true";
 
 
------------------------------------------------------------------------------
-- Begin architecture
------------------------------------------------------------------------------
 
begin
 
combinatorial: process (
rx_data_reg, rx_tvalid_reg, rx_tlast_reg,
mac_tx_tvalid, mac_tx_tready_int, tx_full_reg, tx_full_val, set_tx_reg
)
begin
-- output followers
mac_rx_tdata <= rx_data_reg;
mac_rx_tvalid <= rx_tvalid_reg;
mac_rx_tlast <= rx_tlast_reg;
mac_tx_tready <= not (tx_full_reg and not mac_tx_tready_int); -- if not full, we are ready to accept
 
-- control defaults
tx_full_val <= tx_full_reg;
set_tx_reg <= '0';
-- tx handshaking logic
if mac_tx_tvalid = '1' then
tx_full_val <= '1';
set_tx_reg <= '1';
elsif mac_tx_tready_int = '1' then
tx_full_val <= '0';
end if;
end process;
 
sequential: process(gtx_clk_bufg)
begin
if rising_edge(gtx_clk_bufg) then
if chk_resetn = '0' then
-- reset state variables
rx_data_reg <= (others => '0');
rx_tvalid_reg <= '0';
rx_tlast_reg <= '0';
tx_full_reg <= '0';
tx_data_reg <= (others => '0');
tx_last_reg <= '0';
else
-- register rx data
rx_data_reg <= rx_data_val;
rx_tvalid_reg <= rx_tvalid_val;
rx_tlast_reg <= rx_tlast_val;
-- process tx tvalid and tready
tx_full_reg <= tx_full_val;
if set_tx_reg = '1' then
tx_data_reg <= mac_tx_tdata;
tx_last_reg <= mac_tx_tlast;
else
tx_data_reg <= tx_data_reg;
tx_last_reg <= tx_last_reg;
end if;
end if;
end if;
end process;
 
------------------------------------------------------------------------------
-- Instantiate the Tri-Mode EMAC Block wrapper
------------------------------------------------------------------------------
v6emac_block : mac_layer_v2_2_block
port map(
gtx_clk => gtx_clk_bufg,
 
-- Client Receiver Interface
rx_statistics_vector => open,
rx_statistics_valid => open,
 
rx_mac_aclk => open,
rx_reset => open,
rx_axis_mac_tdata => rx_data_val,
rx_axis_mac_tvalid => rx_tvalid_val,
rx_axis_mac_tlast => rx_tlast_val,
rx_axis_mac_tuser => open,
 
-- Client Transmitter Interface
tx_ifg_delay => x"00",
tx_statistics_vector => open,
tx_statistics_valid => open,
 
tx_reset => open,
tx_axis_mac_tdata => tx_data_reg,
tx_axis_mac_tvalid => tx_full_reg,
tx_axis_mac_tlast => tx_last_reg,
tx_axis_mac_tuser => '0',
tx_axis_mac_tready => mac_tx_tready_int,
tx_collision => open,
tx_retransmit => open,
 
-- Flow Control
pause_req => '0',
pause_val => x"0000",
 
-- Reference clock for IDELAYCTRL's
refclk => refclk_bufg,
 
-- GMII Interface
gmii_txd => gmii_txd,
gmii_tx_en => gmii_tx_en,
gmii_tx_er => gmii_tx_er,
gmii_tx_clk => gmii_tx_clk,
gmii_rxd => gmii_rxd,
gmii_rx_dv => gmii_rx_dv,
gmii_rx_er => gmii_rx_er,
gmii_rx_clk => gmii_rx_clk,
 
-- asynchronous reset
glbl_rstn => chk_resetn,
rx_axi_rstn => '1',
tx_axi_rstn => '1'
);
 
 
 
------------------------------------------------------------------------------
-- Clock logic to generate required clocks from the 200MHz on board
-- if 125MHz is available directly this can be removed
------------------------------------------------------------------------------
clock_generator : clk_wiz_v2_2
port map (
-- Clock in ports
CLK_IN1_P => clk_in_p,
CLK_IN1_N => clk_in_n,
-- Clock out ports
CLK_OUT1 => gtx_clk_bufg,
CLK_OUT2 => open,
CLK_OUT3 => refclk_bufg,
-- Status and control signals
RESET => glbl_rst,
LOCKED => dcm_locked
);
 
-----------------
-- global reset
glbl_reset_gen : reset_sync_v2_2
port map (
clk => gtx_clk_bufg,
enable => dcm_locked,
reset_in => glbl_rst,
reset_out => glbl_rst_int
);
 
glbl_rst_intn <= not glbl_rst_int;
 
-- generate the user side clocks
mac_tx_clock <= gtx_clk_bufg;
mac_rx_clock <= gtx_clk_bufg;
 
------------------------------------------------------------------------------
-- Generate resets
------------------------------------------------------------------------------
-- in each case the async reset is first captured and then synchronised
 
 
local_chk_reset <= glbl_rst or mac_reset;
 
-----------------
-- data check reset
chk_reset_gen : reset_sync_v2_2
port map (
clk => gtx_clk_bufg,
enable => dcm_locked,
reset_in => local_chk_reset,
reset_out => chk_reset_int
);
 
-- Create fully synchronous reset in the gtx clock domain.
gen_chk_reset : process (gtx_clk_bufg)
begin
if gtx_clk_bufg'event and gtx_clk_bufg = '1' then
if chk_reset_int = '1' then
chk_pre_resetn <= '0';
chk_resetn <= '0';
else
chk_pre_resetn <= '1';
chk_resetn <= chk_pre_resetn;
end if;
end if;
end process gen_chk_reset;
 
 
-----------------
-- PHY reset
-- the phy reset output (active low) needs to be held for at least 10x25MHZ cycles
-- this is derived using the 125MHz available and a 6 bit counter
gen_phy_reset : process (gtx_clk_bufg)
begin
if gtx_clk_bufg'event and gtx_clk_bufg = '1' then
if glbl_rst_intn = '0' then
phy_resetn_int <= '0';
phy_reset_count <= (others => '0');
else
if phy_reset_count /= "111111" then
phy_reset_count <= phy_reset_count + "000001";
else
phy_resetn_int <= '1';
end if;
end if;
end if;
end process gen_phy_reset;
 
phy_resetn <= phy_resetn_int;
 
 
end wrapper;
/tags/v2.3/rtl/vhdl/ml605/udp_constraints.ucf
0,0 → 1,83
CONFIG PART = xc6vlx240tff1156-1;
 
 
########## ML605 Board ##########
NET clk_in_p LOC = J9 |IOSTANDARD = LVDS_25 |DIFF_TERM = TRUE;
NET clk_in_n LOC = H9 |IOSTANDARD = LVDS_25 |DIFF_TERM = TRUE;
 
Net reset LOC = H10 |IOSTANDARD = LVCMOS15 |TIG;
 
# downgrade the Place:1153 error in the mapper
NET "reset" CLOCK_DEDICATED_ROUTE = FALSE;
 
#### Module LEDs_8Bit constraints
NET "display[0]" LOC = AC22;
NET "display[1]" LOC = AC24;
NET "display[2]" LOC = AE22;
NET "display[3]" LOC = AE23;
NET "display[4]" LOC = AB23;
NET "display[5]" LOC = AG23;
NET "display[6]" LOC = AE24;
NET "display[7]" LOC = AD24;
 
NET PBTX_LED LOC = AD21;
NET UDP_RX LOC = AH27;
NET DO_SECOND_TX_LED LOC = AH28;
NET TX_RSLT_0 LOC = AE21;
NET TX_RSLT_1 LOC = AP24;
 
 
 
#### Module Push_Buttons_4Bit constraints
NET PBTX LOC = H17;
NET PB_DO_SECOND_TX LOC = A18;
NET reset_leds LOC = G26;
 
#### Module DIP_Switches_4Bit constraints
 
 
Net phy_resetn LOC = AH13 |IOSTANDARD = LVCMOS25 |TIG;
 
Net gmii_rxd<7> LOC = AC13 |IOSTANDARD = LVCMOS25;
Net gmii_rxd<6> LOC = AC12 |IOSTANDARD = LVCMOS25;
Net gmii_rxd<5> LOC = AD11 |IOSTANDARD = LVCMOS25;
Net gmii_rxd<4> LOC = AM12 |IOSTANDARD = LVCMOS25;
Net gmii_rxd<3> LOC = AN12 |IOSTANDARD = LVCMOS25;
Net gmii_rxd<2> LOC = AE14 |IOSTANDARD = LVCMOS25;
Net gmii_rxd<1> LOC = AF14 |IOSTANDARD = LVCMOS25;
Net gmii_rxd<0> LOC = AN13 |IOSTANDARD = LVCMOS25;
 
Net gmii_txd<7> LOC = AF11 |IOSTANDARD = LVCMOS25;
Net gmii_txd<6> LOC = AE11 |IOSTANDARD = LVCMOS25;
Net gmii_txd<5> LOC = AM10 |IOSTANDARD = LVCMOS25;
Net gmii_txd<4> LOC = AL10 |IOSTANDARD = LVCMOS25;
Net gmii_txd<3> LOC = AG11 |IOSTANDARD = LVCMOS25;
Net gmii_txd<2> LOC = AG10 |IOSTANDARD = LVCMOS25;
Net gmii_txd<1> LOC = AL11 |IOSTANDARD = LVCMOS25;
Net gmii_txd<0> LOC = AM11 |IOSTANDARD = LVCMOS25;
 
Net gmii_col LOC = AK13 |IOSTANDARD = LVCMOS25;
Net gmii_crs LOC = AL13 |IOSTANDARD = LVCMOS25;
Net mii_tx_clk LOC = AD12 |IOSTANDARD = LVCMOS25;
 
Net gmii_tx_en LOC = AJ10 |IOSTANDARD = LVCMOS25;
Net gmii_tx_er LOC = AH10 |IOSTANDARD = LVCMOS25;
Net gmii_tx_clk LOC = AH12 |IOSTANDARD = LVCMOS25;
 
Net gmii_rx_dv LOC = AM13 |IOSTANDARD = LVCMOS25;
Net gmii_rx_er LOC = AG12 |IOSTANDARD = LVCMOS25;
# P20 - GCLK7
Net gmii_rx_clk LOC = AP11 |IOSTANDARD = LVCMOS25;
 
 
 
NET "clk_in_p" TNM_NET = "clk_in_p";
TIMESPEC "TS_emac1_clk_in_p" = PERIOD "clk_in_p" 5.000 ns HIGH 50% INPUT_JITTER 50.0ps;
 
 
# Ethernet GTX_CLK high quality 125 MHz reference clock
NET "*mac_block/gtx_clk_bufg" TNM_NET = "ref_gtx_clk";
TIMEGRP "emac1_clk_ref_gtx" = "ref_gtx_clk";
TIMESPEC TS_emac1_clk_ref_gtx = PERIOD "N/A" 8 ns HIGH 50%;
 
 
/tags/v2.3/rtl/vhdl/UDP_Complete_nomac.vhd
0,0 → 1,251
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 09:38:49 06/13/2011
-- Design Name:
-- Module Name: UDP_Complete_nomac - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - separated RX and TX clocks
-- Revision 0.03 - Added mac_tx_tfirst
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
 
entity UDP_Complete_nomac is
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
Port (
-- UDP TX signals
udp_tx_start : in std_logic; -- indicates req to tx UDP
udp_txi : in udp_tx_type; -- UDP tx cxns
udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission)
udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data
-- UDP RX signals
udp_rx_start : out std_logic; -- indicates receipt of udp header
udp_rxo : out udp_rx_type;
-- IP RX signals
ip_rx_hdr : out ipv4_rx_header_type;
-- system signals
rx_clk : in STD_LOGIC;
tx_clk : in STD_LOGIC;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in udp_control_type;
-- status signals
arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received
ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- MAC Transmitter
mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : out std_logic; -- tdata is valid
mac_tx_tready : in std_logic; -- mac is ready to accept data
mac_tx_tfirst : out std_logic; -- indicates first byte of frame
mac_tx_tlast : out std_logic; -- indicates last byte of frame
-- MAC Receiver
mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : in std_logic; -- indicates tdata is valid
mac_rx_tready : out std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : in std_logic -- indicates last byte of the trame
);
end UDP_Complete_nomac;
 
 
 
 
 
architecture structural of UDP_Complete_nomac is
 
------------------------------------------------------------------------------
-- Component Declaration for UDP TX
------------------------------------------------------------------------------
 
COMPONENT UDP_TX
PORT(
-- UDP Layer signals
udp_tx_start : in std_logic; -- indicates req to tx UDP
udp_txi : in udp_tx_type; -- UDP tx cxns
udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission)
udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data
-- system signals
clk : in STD_LOGIC; -- same clock used to clock mac data and ip data
reset : in STD_LOGIC;
-- IP layer TX signals
ip_tx_start : out std_logic;
ip_tx : out ipv4_tx_type; -- IP tx cxns
ip_tx_result : in std_logic_vector (1 downto 0); -- tx status (changes during transmission)
ip_tx_data_out_ready : in std_logic -- indicates IP TX is ready to take data
);
END COMPONENT;
 
------------------------------------------------------------------------------
-- Component Declaration for UDP RX
------------------------------------------------------------------------------
 
COMPONENT UDP_RX
PORT(
-- UDP Layer signals
udp_rx_start : out std_logic; -- indicates receipt of udp header
udp_rxo : out udp_rx_type;
-- system signals
clk : in STD_LOGIC;
reset : in STD_LOGIC;
-- IP layer RX signals
ip_rx_start : in std_logic; -- indicates receipt of ip header
ip_rx : in ipv4_rx_type
);
END COMPONENT;
 
------------------------------------------------------------------------------
-- Component Declaration for the IP layer
------------------------------------------------------------------------------
 
component IP_complete_nomac
generic (
CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr
ARP_TIMEOUT : integer := 60; -- ARP response timeout (s)
ARP_MAX_PKT_TMO : integer := 5; -- # wrong nwk pkts received before set error
MAX_ARP_ENTRIES : integer := 255 -- max entries in the ARP store
);
Port (
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
ip_rx : out ipv4_rx_type;
-- system signals
rx_clk : in STD_LOGIC;
tx_clk : in STD_LOGIC;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
control : in ip_control_type;
-- status signals
arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received
ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- MAC Transmitter
mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx
mac_tx_tvalid : out std_logic; -- tdata is valid
mac_tx_tready : in std_logic; -- mac is ready to accept data
mac_tx_tfirst : out std_logic; -- indicates first byte of frame
mac_tx_tlast : out std_logic; -- indicates last byte of frame
-- MAC Receiver
mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received
mac_rx_tvalid : in std_logic; -- indicates tdata is valid
mac_rx_tready : out std_logic; -- tells mac that we are ready to take data
mac_rx_tlast : in std_logic -- indicates last byte of the trame
);
end component;
 
-- IP TX connectivity
signal ip_tx_int : ipv4_tx_type;
signal ip_tx_start_int : std_logic;
signal ip_tx_result_int : std_logic_vector (1 downto 0);
signal ip_tx_data_out_ready_int : std_logic;
 
-- IP RX connectivity
signal ip_rx_int : ipv4_rx_type;
signal ip_rx_start_int : std_logic := '0';
 
 
begin
 
-- output followers
ip_rx_hdr <= ip_rx_int.hdr;
 
-- Instantiate the UDP TX block
udp_tx_block: UDP_TX
PORT MAP (
-- UDP Layer signals
udp_tx_start => udp_tx_start,
udp_txi => udp_txi,
udp_tx_result => udp_tx_result,
udp_tx_data_out_ready=> udp_tx_data_out_ready,
-- system signals
clk => tx_clk,
reset => reset,
-- IP layer TX signals
ip_tx_start => ip_tx_start_int,
ip_tx => ip_tx_int,
ip_tx_result => ip_tx_result_int,
ip_tx_data_out_ready => ip_tx_data_out_ready_int
);
 
-- Instantiate the UDP RX block
udp_rx_block: UDP_RX PORT MAP (
-- UDP Layer signals
udp_rxo => udp_rxo,
udp_rx_start => udp_rx_start,
-- system signals
clk => rx_clk,
reset => reset,
-- IP layer RX signals
ip_rx_start => ip_rx_start_int,
ip_rx => ip_rx_int
);
 
------------------------------------------------------------------------------
-- Instantiate the IP layer
------------------------------------------------------------------------------
IP_block : IP_complete_nomac
generic map (
CLOCK_FREQ => CLOCK_FREQ,
ARP_TIMEOUT => ARP_TIMEOUT,
ARP_MAX_PKT_TMO => ARP_MAX_PKT_TMO,
MAX_ARP_ENTRIES => MAX_ARP_ENTRIES
)
PORT MAP (
-- IP interface
ip_tx_start => ip_tx_start_int,
ip_tx => ip_tx_int,
ip_tx_result => ip_tx_result_int,
ip_tx_data_out_ready => ip_tx_data_out_ready_int,
ip_rx_start => ip_rx_start_int,
ip_rx => ip_rx_int,
-- System interface
rx_clk => rx_clk,
tx_clk => tx_clk,
reset => reset,
our_ip_address => our_ip_address,
our_mac_address => our_mac_address,
control => control.ip_controls,
-- status signals
arp_pkt_count => arp_pkt_count,
ip_pkt_count => ip_pkt_count,
-- MAC Transmitter
mac_tx_tdata => mac_tx_tdata,
mac_tx_tvalid => mac_tx_tvalid,
mac_tx_tready => mac_tx_tready,
mac_tx_tfirst => mac_tx_tfirst,
mac_tx_tlast => mac_tx_tlast,
-- MAC Receiver
mac_rx_tdata => mac_rx_tdata,
mac_rx_tvalid => mac_rx_tvalid,
mac_rx_tready => mac_rx_tready,
mac_rx_tlast => mac_rx_tlast
);
 
 
end structural;
 
 
/tags/v2.3/rtl/vhdl/ipv4_types.vhd
0,0 → 1,120
--
--
-- Purpose: This package defines types for use in IPv4
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use work.axi.all;
use work.arp_types.all;
 
package ipv4_types is
 
constant IP_BC_ADDR : std_logic_vector (31 downto 0) := x"ffffffff";
constant MAC_BC_ADDR : std_logic_vector (47 downto 0) := x"ffffffffffff";
 
--------------
-- IPv4 TX --
--------------
 
-- coding for result in tx
constant IPTX_RESULT_NONE : std_logic_vector (1 downto 0) := "00";
constant IPTX_RESULT_SENDING : std_logic_vector (1 downto 0) := "01";
constant IPTX_RESULT_ERR : std_logic_vector (1 downto 0) := "10";
constant IPTX_RESULT_SENT : std_logic_vector (1 downto 0) := "11";
 
type ipv4_tx_header_type is record
protocol : std_logic_vector (7 downto 0);
data_length : STD_LOGIC_VECTOR (15 downto 0); -- user data size, bytes
dst_ip_addr : STD_LOGIC_VECTOR (31 downto 0);
end record;
type ipv4_tx_type is record
hdr : ipv4_tx_header_type; -- header to tx
data : axi_out_type; -- tx axi bus
end record;
 
 
--------------
-- IPv4 RX --
--------------
 
-- coding for last_error_code in rx hdr
constant RX_EC_NONE : std_logic_vector (3 downto 0) := x"0";
constant RX_EC_ET_ETH : std_logic_vector (3 downto 0) := x"1"; -- early termination in ETH hdr phase
constant RX_EC_ET_IP : std_logic_vector (3 downto 0) := x"2"; -- early termination in IP hdr phase
constant RX_EC_ET_USER : std_logic_vector (3 downto 0) := x"3"; -- early termination in USER DATA phase
 
type ipv4_rx_header_type is record
is_valid : std_logic;
protocol : std_logic_vector (7 downto 0);
data_length : STD_LOGIC_VECTOR (15 downto 0); -- user data size, bytes
src_ip_addr : STD_LOGIC_VECTOR (31 downto 0);
num_frame_errors : std_logic_vector (7 downto 0);
last_error_code : std_logic_vector (3 downto 0); -- see RX_EC_xxx constants
is_broadcast : std_logic; -- set if the msg received is a broadcast
end record;
 
type ipv4_rx_type is record
hdr : ipv4_rx_header_type; -- header received
data : axi_in_type; -- rx axi bus
end record;
type ip_control_type is record
arp_controls : arp_control_type;
end record;
 
------------
-- UDP TX --
------------
 
-- coding for result in tx
constant UDPTX_RESULT_NONE : std_logic_vector (1 downto 0) := "00";
constant UDPTX_RESULT_SENDING : std_logic_vector (1 downto 0) := "01";
constant UDPTX_RESULT_ERR : std_logic_vector (1 downto 0) := "10";
constant UDPTX_RESULT_SENT : std_logic_vector (1 downto 0) := "11";
 
type udp_tx_header_type is record
dst_ip_addr : STD_LOGIC_VECTOR (31 downto 0);
dst_port : STD_LOGIC_VECTOR (15 downto 0);
src_port : STD_LOGIC_VECTOR (15 downto 0);
data_length : STD_LOGIC_VECTOR (15 downto 0); -- user data size, bytes
checksum : STD_LOGIC_VECTOR (15 downto 0);
end record;
 
 
type udp_tx_type is record
hdr : udp_tx_header_type; -- header received
data : axi_out_type; -- tx axi bus
end record;
------------
-- UDP RX --
------------
 
type udp_rx_header_type is record
is_valid : std_logic;
src_ip_addr : STD_LOGIC_VECTOR (31 downto 0);
src_port : STD_LOGIC_VECTOR (15 downto 0);
dst_port : STD_LOGIC_VECTOR (15 downto 0);
data_length : STD_LOGIC_VECTOR (15 downto 0); -- user data size, bytes
end record;
 
 
type udp_rx_type is record
hdr : udp_rx_header_type; -- header received
data : axi_in_type; -- rx axi bus
end record;
type udp_addr_type is record
ip_addr : STD_LOGIC_VECTOR (31 downto 0);
port_num : STD_LOGIC_VECTOR (15 downto 0);
end record;
type udp_control_type is record
ip_controls : ip_control_type;
end record;
 
end ipv4_types;
/tags/v2.3/rtl/vhdl/IPv4.vhd
0,0 → 1,152
----------------------------------------------------------------------------------
-- Company:
-- Engineer: Peter Fall
--
-- Create Date: 16:20:42 06/01/2011
-- Design Name:
-- Module Name: IPv4 - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
-- handle simple IP RX and TX
-- doesnt handle seg & reass
-- dest MAC addr resolution through ARP layer
-- Handle IPv4 protocol
-- Respond to ARP requests and replies
-- Ignore pkts that are not IP
-- Ignore pkts that are not addressed to us--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - separated RX and TX clocks
-- Revision 0.03 - Added mac_data_out_first
-- Additional Comments:
--
----------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.axi.all;
use work.ipv4_types.all;
use work.arp_types.all;
 
entity IPv4 is
Port (
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
ip_rx : out ipv4_rx_type;
-- system control signals
rx_clk : in STD_LOGIC;
tx_clk : in STD_LOGIC;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
-- system status signals
rx_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- ARP lookup signals
arp_req_req : out arp_req_req_type;
arp_req_rslt : in arp_req_rslt_type;
-- MAC layer RX signals
mac_data_in : in STD_LOGIC_VECTOR (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
mac_data_in_valid : in STD_LOGIC; -- indicates data_in valid on clock
mac_data_in_last : in STD_LOGIC; -- indicates last data in frame
-- 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_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_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 : out std_logic_vector (7 downto 0) -- ethernet frame (from dst mac addr through to last byte of frame)
);
end IPv4;
 
architecture structural of IPv4 is
 
COMPONENT IPv4_TX
PORT(
-- IP Layer signals
ip_tx_start : in std_logic;
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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
 
-- system signals
clk : in STD_LOGIC; -- same clock used to clock mac data and ip data
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
our_mac_address : in std_logic_vector (47 downto 0);
-- ARP lookup signals
arp_req_req : out arp_req_req_type;
arp_req_rslt : in arp_req_rslt_type;
-- 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_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_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 : out std_logic_vector (7 downto 0) -- ethernet frame (from dst mac addr through to last byte of frame)
);
END COMPONENT;
 
COMPONENT IPv4_RX
PORT(
-- IP Layer signals
ip_rx : out ipv4_rx_type;
ip_rx_start : out std_logic; -- indicates receipt of ip frame.
-- system signals
clk : in STD_LOGIC;
reset : in STD_LOGIC;
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
rx_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us
-- MAC layer RX signals
mac_data_in : in STD_LOGIC_VECTOR (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
mac_data_in_valid : in STD_LOGIC; -- indicates data_in valid on clock
mac_data_in_last : in STD_LOGIC -- indicates last data in frame
);
END COMPONENT;
 
begin
 
TX : IPv4_TX PORT MAP (
ip_tx_start => ip_tx_start,
ip_tx => ip_tx,
ip_tx_result => ip_tx_result,
ip_tx_data_out_ready=> ip_tx_data_out_ready,
clk => tx_clk,
reset => reset,
our_ip_address => our_ip_address,
our_mac_address => our_mac_address,
arp_req_req => arp_req_req,
arp_req_rslt => arp_req_rslt,
mac_tx_req => mac_tx_req,
mac_tx_granted => mac_tx_granted,
mac_data_out_ready => mac_data_out_ready,
mac_data_out_valid => mac_data_out_valid,
mac_data_out_first => mac_data_out_first,
mac_data_out_last => mac_data_out_last,
mac_data_out => mac_data_out
);
 
RX : IPv4_RX PORT MAP (
ip_rx => ip_rx,
ip_rx_start => ip_rx_start,
clk => rx_clk,
reset => reset,
our_ip_address => our_ip_address,
rx_pkt_count => rx_pkt_count,
mac_data_in => mac_data_in,
mac_data_in_valid => mac_data_in_valid,
mac_data_in_last => mac_data_in_last
);
 
 
end structural;
 
/tags/v2.3/rtl/vhdl/tx_arbitrator.vhd
0,0 → 1,116
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 08:03:30 06/04/2011
-- Design Name:
-- Module Name: tx_arbitrator - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description: arbitrate between two sources that want to transmit onto a bus
-- handles arbitration and multiplexing
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.02 - Made sticky on port M1 to optimise access on this port and allow immediate grant
-- Revision 0.03 - Added first
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
 
entity tx_arbitrator is
port (
clk : in std_logic;
reset : in std_logic;
req_1 : in std_logic;
grant_1 : out std_logic;
data_1 : in std_logic_vector(7 downto 0); -- data byte to tx
valid_1 : in std_logic; -- tdata is valid
first_1 : in std_logic; -- indicates first byte of frame
last_1 : in std_logic; -- indicates last byte of frame
 
req_2 : in std_logic;
grant_2 : out std_logic;
data_2 : in std_logic_vector(7 downto 0); -- data byte to tx
valid_2 : in std_logic; -- tdata is valid
first_2 : in std_logic; -- indicates first byte of frame
last_2 : in std_logic; -- indicates last byte of frame
data : out std_logic_vector(7 downto 0); -- data byte to tx
valid : out std_logic; -- tdata is valid
first : out std_logic; -- indicates first byte of frame
last : out std_logic -- indicates last byte of frame
);
end tx_arbitrator;
 
architecture Behavioral of tx_arbitrator is
 
type grant_type is (M1,M2);
 
signal grant : grant_type;
begin
combinatorial : process (
grant,
data_1, valid_1, first_1, last_1,
data_2, valid_2, first_2, last_2
)
begin
-- grant outputs
case grant is
when M1 =>
grant_1 <= '1';
grant_2 <= '0';
when M2 =>
grant_1 <= '0';
grant_2 <= '1';
end case;
-- multiplexer
if grant = M1 then
data <= data_1;
valid <= valid_1;
first <= first_1;
last <= last_1;
else
data <= data_2;
valid <= valid_2;
first <= first_2;
last <= last_2;
end if;
end process;
sequential : process (clk, reset, req_1, req_2, grant)
begin
if rising_edge(clk) then
if reset = '1' then
grant <= M1;
else
case grant is
when M1 =>
if req_1 = '1' then
grant <= M1;
elsif req_2 = '1' then
grant <= M2;
end if;
when M2 =>
if req_2 = '1' then
grant <= M2;
else
grant <= M1;
end if;
end case;
end if;
end if;
end process;
 
 
end Behavioral;
 
/tags/v2.3/rtl/vhdl/axi.vhd
0,0 → 1,25
--
-- Package File Template
--
-- Purpose: This package defines data types for AXI transfers
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
 
package axi is
 
type axi_in_type is record
data_in : STD_LOGIC_VECTOR (7 downto 0);
data_in_valid : STD_LOGIC; -- indicates data_in valid on clock
data_in_last : STD_LOGIC; -- indicates last data in frame
end record;
type axi_out_type is record
data_out_valid : std_logic; -- indicates data out is valid
data_out_last : std_logic; -- with data out valid indicates the last byte of a frame
data_out : std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame)
end record;
 
end axi;
/tags/v2.3/doc/release_notes.txt
0,0 → 1,36
V2.1 - Updates contributed by Tim Brooks.
 
- To resolve the mac address of an IP address off the local network, I believe the "Who-has" has to be sent to the IP address of the default gateway (or router). For that to happen ARP has to know the address of the default gateway and the net mask.
In the tar ball I've attached, I modified ARP_req.vhd to provide this functionality. I may be useful to you or someone else who downloads the core... also updated the tb to check this.
- Bugs fixed by Tim Brooks:
-- In IPV4_TX, I've removed signal "mac_data_out_ready_reg". It was causing tx_count to be wrong by 1 at the end of a transfer where mac_data_out_ready when low during the transfer. IP_tx_tb didn't catch it. I use Xilinx Isim and it seems that "wait for clk_period" causes signals to change, in effect, just before the clock. I replaced with wait until clk = '1' thorough that test-bench, which assure that the signal changes as if it where clocked. You may want to check this with your simulator and, if you have similar results, you may want to change "wait for clk_period" to "wait until clk = '1'" throughout your test-benches...
-- In ARP_req.vhd, the statements on lines 192&193 would cause the cache to be updated and "got_mac" signal to go high on the next clock, even if the received IP address resolved was not what was asked for.
-- This was also masked by the fact that the test-bench checks "to early" for the "Got_mac" signal staying low (or going high for that matter). For T7.2, I've moved the Assert statements to the same clock period as the data_in_last signal going low. probably should be done for other tests as well
-- ARP_rx, in my system, from the soft Ethernet core, data_in_last usually occurs when rx_count = 41. this means that rx_state never goes to process_arp. I've modified this so that it is processed on rx_count = 41 and outside of the "else" statement of data_in_last = 1 catch.
-- arp_tx. Replies should not be broadcast. I replaced the hard coded FFs in the destination mac field with target.mac, having it set to all 1s as default.
-- There are 2 places that were causing timing problems for my spartan 6 setup. read_result in ARP_store_br. I just added a pipeline stage and that problem went away.
in ipv4_rx, putting the decision as to whether the packet is for and should be processed in case rx_count = 0013 was a problem. I've spread that decision over 0010 to 0013 as it was before the broadcast address test was added. setting or clearing Set_is_broadcast is still in rx_count= 0013.
---------------------------------------------------------------------
 
 
V1.3 - Added ARP timeout and ability to reset the ARP IP/MAC cache
Migration notes: v1.2 to v1.3 - UDP_complete_nomac and IP_Complete_nomac have generics
to specify clock rate and ARP timeout, and an additional control input.
The generics can be left at their default values, the control input should have clear_cache set to '0'.
---------------------------------------------------------------------
 
 
V1.2 - Added handling for receipt of IP pkts with broadcast address ff.ff.ff.ff. Added is_broadcast flag
to IP RX hdr.
- Added ability to transmit IP pkts to broadcast address.
Migration Notes: V1.1 to V1.2 - IP_RX_HDR has an additional output signal to indicate the IP pkt
was received on the broadcast address.
---------------------------------------------------------------------
 
V1.1 - Added mac_tx_tfirst output to assist coupling to MAC layers that require a start of frame indication.
Migration Notes: V1.0 to V1.1
- The entity declaration for UDP_Complete_nomac and IP_Complete_nomac have changed.
- if you dont need to use the new mac_tx_tfirst output, leave it open.
---------------------------------------------------------------------
 
V1.0 - initial release
/tags/v2.3/doc/src/UDP_IP_Stack.pptx Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/v2.3/doc/src/UDP_IP_Stack.pptx Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/v2.3/doc/src/zero latency receive.jpg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.3/doc/src/zero latency receive.jpg =================================================================== --- tags/v2.3/doc/src/zero latency receive.jpg (nonexistent) +++ tags/v2.3/doc/src/zero latency receive.jpg (revision 25)
tags/v2.3/doc/src/zero latency receive.jpg Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/v2.3/doc/UDP_IP_Stack.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.3/doc/UDP_IP_Stack.pdf =================================================================== --- tags/v2.3/doc/UDP_IP_Stack.pdf (nonexistent) +++ tags/v2.3/doc/UDP_IP_Stack.pdf (revision 25)
tags/v2.3/doc/UDP_IP_Stack.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/v2.3/bench/vhdl/arpv2_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/arpv2_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/arpv2_tb.vhd (revision 25) @@ -0,0 +1,1134 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12:35:50 05/31/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/arp1/arp_tb.vhd +-- Project Name: arp1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: arp +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 0.02 - Added tests for ARP timeout +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.arp_types.all; + +entity arpv2_tb is +end arpv2_tb; + +architecture behavior of arpv2_tb is + + -- Component Declaration for the Unit Under Test (UUT) + + component arpv2 + generic ( + no_default_gateway : boolean := true; + CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr + ARP_TIMEOUT : integer := 60; -- ARP response timeout (s) + MAX_ARP_ENTRIES : integer := 255 -- max entries in the arp store + ); + port ( + -- lookup request signals + arp_req_req : in arp_req_req_type; + arp_req_rslt : out arp_req_rslt_type; + -- MAC layer RX signals + data_in_clk : in std_logic; + reset : in std_logic; + data_in : in std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame) + data_in_valid : in std_logic; -- indicates data_in valid on clock + data_in_last : in std_logic; -- indicates last data in frame + -- 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_granted : in std_logic; -- indicates that access to channel has been granted + data_out_clk : in std_logic; + data_out_ready : in std_logic; -- indicates system ready to consume data + data_out_valid : out std_logic; -- indicates data out is valid + data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame + data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame + data_out : out std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame) + -- system signals + our_mac_address : in std_logic_vector (47 downto 0); + our_ip_address : in std_logic_vector (31 downto 0); + nwk_gateway : in std_logic_vector (31 downto 0); -- IP address of default gateway + nwk_mask : in std_logic_vector (31 downto 0); -- Net mask + control : in arp_control_type; + req_count : out std_logic_vector(7 downto 0) -- count of arp pkts received + ); + end component; + + + --Inputs + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal data_in : std_logic_vector(7 downto 0) := (others => '0'); + signal data_in_valid : std_logic := '0'; + signal data_in_last : std_logic := '0'; + signal our_mac_address : std_logic_vector(47 downto 0) := (others => '0'); + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal nwk_gateway : std_logic_vector(31 downto 0) := (others => '0'); + signal nwk_mask : std_logic_vector(31 downto 0) := (others => '0'); + signal data_out_ready : std_logic; + signal data_out_valid : std_logic; + signal data_out_first : std_logic; + signal data_out_last : std_logic; + signal data_out : std_logic_vector (7 downto 0); + signal req_count : std_logic_vector(7 downto 0); + signal arp_req_req : arp_req_req_type; + signal arp_req_rslt : arp_req_rslt_type; + signal mac_tx_req : std_logic; + signal mac_tx_granted : std_logic; + signal control : arp_control_type; + + constant no_default_gateway : boolean := false; + + -- Clock period definitions + constant clk_period : time := 8 ns; + +begin + + -- Instantiate the Unit Under Test (UUT) + uut : arpv2 + generic map ( + no_default_gateway => no_default_gateway, + CLOCK_FREQ => 10, -- artificially low count to enable pragmatic testing + ARP_TIMEOUT => 20 + ) + port map ( + -- lookup request mappings + arp_req_req => arp_req_req, + arp_req_rslt => arp_req_rslt, + -- rx mappings + data_in_clk => clk, + reset => reset, + data_in => data_in, + data_in_valid => data_in_valid, + data_in_last => data_in_last, + -- tx mappings + mac_tx_req => mac_tx_req, + mac_tx_granted => mac_tx_granted, + data_out_clk => clk, + data_out_ready => data_out_ready, + data_out_valid => data_out_valid, + data_out_first => data_out_first, + data_out_last => data_out_last, + data_out => data_out, + -- system mappings + our_mac_address => our_mac_address, + our_ip_address => our_ip_address, + nwk_gateway => nwk_gateway, + nwk_mask => nwk_mask, + control => control, + req_count => req_count + ); + + -- Clock process definitions + clk_process : process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc : process + begin + -- hold reset state for 100 ns. + wait for 100 ns; + + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + nwk_mask <= x"FFFFFF00"; + nwk_gateway <= x"c0a80501"; -- 192.168.5.9 + our_mac_address <= x"002320212223"; + mac_tx_granted <= '1'; -- FIXME 0 + control.clear_cache <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + assert mac_tx_req = '0' report "mac_tx_req asserted on reset"; + + wait until clk = '1'; + + -- insert stimulus here + arp_req_req.lookup_req <= '0'; + arp_req_req.ip <= (others => '0'); + data_out_ready <= '1'; + + report "T1: Send an ARP request: who has 192.168.5.9? Tell 192.168.5.1"; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Sender MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + + report "T1: Expect that we send an 'I have 192.168.5.9' msg"; + + -- check tx arbitration signals + + report "T1: waiting for tx req"; + wait until mac_tx_req = '1'; + + -- ready to tx + data_out_ready <= '1'; + mac_tx_granted <= '1'; + report "T1: waiting for data_out_valid"; + wait until data_out_valid = '1'; + report "T1: got data_out_valid"; + wait for clk_period*10; + data_out_ready <= '0'; + wait for clk_period*2; + data_out_ready <= '1'; + wait for clk_period*12; + assert data_out = x"02" report "T1: expected opcode = 02 for reply 'I have'"; + -- expect our mac 00 23 20 21 22 23 + wait for clk_period; + assert data_out = x"00" report "T1: incorrect our mac.0"; + wait for clk_period; + assert data_out = x"23" report "T1: incorrect our mac.1"; + wait for clk_period; + assert data_out = x"20" report "T1: incorrect our mac.2"; + wait for clk_period; + assert data_out = x"21" report "T1: incorrect our mac.3"; + wait for clk_period; + assert data_out = x"22" report "T1: incorrect our mac.4"; + wait for clk_period; + assert data_out = x"23" report "T1: incorrect our mac.5"; + -- expect our IP c0 a8 05 05 + wait for clk_period; + assert data_out = x"c0" report "T1: incorrect our IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T1: incorrect our IP.1"; + wait for clk_period; + assert data_out = x"05" report "T1: incorrect our IP.2"; + wait for clk_period; + assert data_out = x"09" report "T1: incorrect our IP.3"; + + -- expect target mac 00 23 18 29 26 7c + wait for clk_period; + assert data_out = x"00" report "T1: incorrect target mac.0"; + wait for clk_period; + assert data_out = x"23" report "T1: incorrect target mac.1"; + wait for clk_period; + assert data_out = x"18" report "T1: incorrect target mac.2"; + wait for clk_period; + assert data_out = x"29" report "T1: incorrect target mac.3"; + wait for clk_period; + assert data_out = x"26" report "T1: incorrect target mac.4"; + wait for clk_period; + assert data_out = x"7c" report "T1: incorrect target mac.5"; + -- expect target IP c0 a8 05 01 + wait for clk_period; + assert data_out = x"c0" report "T1: incorrect target IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T1: incorrect target IP.1"; + wait for clk_period; + assert data_out = x"05" report "T1: incorrect target IP.2"; + assert data_out_last = '0' report "T1: data out last incorrectly set on target IP.2 byte"; + wait for clk_period; + assert data_out = x"01" report "T1: incorrect target IP.3"; + assert data_out_last = '1' report "T1: data out last should be set"; + + wait for clk_period*10; + + report "T2: Send another ARP request: who has 192.168.5.8? Tell 192.168.5.1, holding off transmitter"; + data_out_ready <= '0'; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Sender MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + + -- ready to tx + wait for clk_period*10; + data_out_ready <= '1'; + + wait for clk_period*50; + + report "T3: Send a request for the IP that is already in the store"; + arp_req_req.ip <= x"c0a80501"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + report "T3: wait for reply from store"; + wait until arp_req_rslt.got_mac = '1' or arp_req_rslt.got_err = '1'; + assert arp_req_rslt.got_mac = '1' report "T3: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T3: expected got err = 0"; + assert arp_req_rslt.mac = x"00231829267c" report "T3: wrong mac value"; + wait for clk_period*2; + + -- the entry that was in the store should now be in the cache - check it + report "T4: Send a request for the IP that is already in the cache"; + arp_req_req.ip <= x"c0a80501"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + assert arp_req_rslt.got_mac = '1' report "T4: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T4: expected got err = 0"; + assert arp_req_rslt.mac = x"00231829267c" report "T4: wrong mac value"; + + wait for clk_period*50; + + report "T5 - Send a request for the IP that is not cached or in the store"; + arp_req_req.ip <= x"c0a80503"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + report "T5: waiting for data_out_valid"; + wait until data_out_valid = '1'; + report "T5: got data_out_valid"; + wait for clk_period*10; + data_out_ready <= '0'; + wait for clk_period*2; + data_out_ready <= '1'; + wait for clk_period*12; + assert data_out = x"01" report "T5: expected opcode = 01 for request 'who has'"; + -- expect our mac 00 23 20 21 22 23 + wait for clk_period; + assert data_out = x"00" report "T5: incorrect our mac.0"; + wait for clk_period; + assert data_out = x"23" report "T5: incorrect our mac.1"; + wait for clk_period; + assert data_out = x"20" report "T5: incorrect our mac.2"; + wait for clk_period; + assert data_out = x"21" report "T5: incorrect our mac.3"; + wait for clk_period; + assert data_out = x"22" report "T5: incorrect our mac.4"; + wait for clk_period; + assert data_out = x"23" report "T5: incorrect our mac.5"; + -- expect our IP c0 a8 05 05 + wait for clk_period; + assert data_out = x"c0" report "T5: incorrect our IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T5: incorrect our IP.1"; + wait for clk_period; + assert data_out = x"05" report "T5: incorrect our IP.2"; + wait for clk_period; + assert data_out = x"09" report "T5: incorrect our IP.3"; + + -- expect empty target mac + wait for clk_period; + assert data_out = x"ff" report "T5: incorrect target mac.0"; + wait for clk_period; + assert data_out = x"ff" report "T5: incorrect target mac.1"; + wait for clk_period; + assert data_out = x"ff" report "T5: incorrect target mac.2"; + wait for clk_period; + assert data_out = x"ff" report "T5: incorrect target mac.3"; + wait for clk_period; + assert data_out = x"ff" report "T5: incorrect target mac.4"; + wait for clk_period; + assert data_out = x"ff" report "T5: incorrect target mac.5"; + -- expect target IP c0 a8 05 01 + wait for clk_period; + assert data_out = x"c0" report "T5: incorrect target IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T5: incorrect target IP.1"; + wait for clk_period; + assert data_out = x"05" report "T5: incorrect target IP.2"; + assert data_out_last = '0' report "T5: data out last incorrectly set on target IP.2 byte"; + wait for clk_period; + assert data_out = x"03" report "T5: incorrect target IP.3"; + assert data_out_last = '1' report "T5: data out last should be set"; + + wait for clk_period*10; + + -- Send the reply + data_out_ready <= '1'; + + report "T5.2: Send an ARP reply: 192.168.5.3 has mac 02:12:03:23:04:54"; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T5.2: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T5.2: expected got err = 0"; + assert arp_req_rslt.mac = x"021203230454" report "T5.2: wrong mac value"; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period*4; + + report "T6: check that both these IPs remain in the store"; + arp_req_req.ip <= x"c0a80501"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + wait for clk_period; + report "T6.1: wait for reply from store"; + wait until arp_req_rslt.got_mac = '1' or arp_req_rslt.got_err = '1'; + assert arp_req_rslt.got_mac = '1' report "T6.1: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T6.1: expected got err = 0"; + assert arp_req_rslt.mac = x"00231829267c" report "T6.1: wrong mac value"; + wait for clk_period*2; + + arp_req_req.ip <= x"c0a80503"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + wait for clk_period; + report "T6.2: wait for reply from store"; + wait until arp_req_rslt.got_mac = '1' or arp_req_rslt.got_err = '1'; + assert arp_req_rslt.got_mac = '1' report "T6.2: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T6.2: expected got err = 0"; + assert arp_req_rslt.mac = x"021203230454" report "T6.2: wrong mac value"; + wait for clk_period*2; + + report "T7 - test that receipt of wrong I Have does not satisfy a current req"; + arp_req_req.ip <= x"c0a8050e"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + report "T7: waiting for data_out_valid"; + wait until data_out_valid = '1'; + report "T7: got data_out_valid"; + wait for clk_period*10; + data_out_ready <= '0'; + wait for clk_period*2; + data_out_ready <= '1'; + wait for clk_period*12; + assert data_out = x"01" report "T7: expected opcode = 01 for request 'who has'"; + -- expect our mac 00 23 20 21 22 23 + wait for clk_period; + assert data_out = x"00" report "T7: incorrect our mac.0"; + wait for clk_period; + assert data_out = x"23" report "T7: incorrect our mac.1"; + wait for clk_period; + assert data_out = x"20" report "T7: incorrect our mac.2"; + wait for clk_period; + assert data_out = x"21" report "T7: incorrect our mac.3"; + wait for clk_period; + assert data_out = x"22" report "T7: incorrect our mac.4"; + wait for clk_period; + assert data_out = x"23" report "T7: incorrect our mac.5"; + -- expect our IP c0 a8 05 05 + wait for clk_period; + assert data_out = x"c0" report "T7: incorrect our IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T7: incorrect our IP.1"; + wait for clk_period; + assert data_out = x"05" report "T7: incorrect our IP.2"; + wait for clk_period; + assert data_out = x"09" report "T7: incorrect our IP.3"; + + -- expect empty target mac + wait for clk_period; + assert data_out = x"ff" report "T7: incorrect target mac.0"; + wait for clk_period; + assert data_out = x"ff" report "T7: incorrect target mac.1"; + wait for clk_period; + assert data_out = x"ff" report "T7: incorrect target mac.2"; + wait for clk_period; + assert data_out = x"ff" report "T7: incorrect target mac.3"; + wait for clk_period; + assert data_out = x"ff" report "T7: incorrect target mac.4"; + wait for clk_period; + assert data_out = x"ff" report "T7: incorrect target mac.5"; + -- expect target IP c0 a8 05 0e + wait for clk_period; + assert data_out = x"c0" report "T7: incorrect target IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T7: incorrect target IP.1"; + wait for clk_period; + assert data_out = x"05" report "T7: incorrect target IP.2"; + assert data_out_last = '0' report "T7: data out last incorrectly set on target IP.2 byte"; + wait for clk_period; + assert data_out = x"0e" report "T7: incorrect target IP.3"; + assert data_out_last = '1' report "T7: data out last should be set"; + + wait for clk_period*10; + + -- Send the reply + data_out_ready <= '1'; + + report "T7.2: Send an arbitrary unwanted ARP reply: 192.168.5.143 has mac 57:12:34:19:23:9a"; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"57"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"34"; wait for clk_period; + data_in <= x"19"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"9a"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"57"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"34"; wait for clk_period; + data_in <= x"19"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"9a"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"25"; wait for clk_period; + data_in <= x"93"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + assert arp_req_rslt.got_mac = '0' report "T7.2: expected got mac = 0"; + assert arp_req_rslt.got_err = '0' report "T7.2: expected got err = 0"; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period*4; + + -- Send the reply + data_out_ready <= '1'; + + report "T7.3: Send a wanted ARP reply: 192.168.5.e has mac 76:34:98:55:aa:37"; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"76"; wait for clk_period; + data_in <= x"34"; wait for clk_period; + data_in <= x"98"; wait for clk_period; + data_in <= x"55"; wait for clk_period; + data_in <= x"aa"; wait for clk_period; + data_in <= x"37"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"76"; wait for clk_period; + data_in <= x"34"; wait for clk_period; + data_in <= x"98"; wait for clk_period; + data_in <= x"55"; wait for clk_period; + data_in <= x"aa"; wait for clk_period; + data_in <= x"37"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"0e"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T7.3: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T7.3: expected got err = 0"; + assert arp_req_rslt.mac = x"76349855aa37" report "T7.3: wrong mac value"; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period*4; + + + report "T8: Request 192.168.5.4 (not cached), dont send a reply and wait for timeout"; + arp_req_req.ip <= x"c0a80504"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + assert mac_tx_req = '1' report "T8: should be requesting TX channel"; + wait for clk_period*220; + assert arp_req_rslt.got_mac = '0' report "T8: should not have got mac"; + assert arp_req_rslt.got_err = '1' report "T8: should have got err"; + + report "T9: Request 192.168.5.7 (not cached= and Send an ARP reply: 192.168.5.7 has mac 02:15:03:23:04:54"; + arp_req_req.ip <= x"c0a80507"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + assert arp_req_rslt.got_mac = '0' report "T9: should not yet have mac"; + assert arp_req_rslt.got_err = '0' report "T9: should not have got err"; + + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + assert mac_tx_req = '1' report "T9: should be requesting TX channel"; + wait for clk_period*50; + -- Send the reply + data_out_ready <= '1'; + + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"07"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T9: should have got mac"; + assert arp_req_rslt.mac = x"021503230454" report "T9: incorrect mac"; + assert arp_req_rslt.got_err = '0' report "T9: should not have got err"; + wait for clk_period*10; + + report "T10: Request 192.168.5.7 again an expect it to be in the cache"; + arp_req_req.ip <= x"c0a80507"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T10: should have mac"; + assert arp_req_rslt.got_err = '0' report "T10: should not have got err"; + + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + +-- + wait until clk = '1'; + report "T11 - Send a request for the IP that is not on the local network"; + arp_req_req.ip <= x"0a000003"; --c0a80501 + arp_req_req.lookup_req <= '1'; + wait until clk = '1'; --for clk_period + arp_req_req.lookup_req <= '0'; + report "T11: wait for reply from store"; + wait until arp_req_rslt.got_mac = '1' or arp_req_rslt.got_err = '1'; + assert arp_req_rslt.got_mac = '1' report "T11: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T11: expected got err = 0"; + assert arp_req_rslt.mac = x"00231829267c" report "T11: wrong mac value";-- severity failure; + wait for clk_period*2; +-- + + report "T12: Clear the cache, Request 192.168.5.7 again an expect a 'who has' to be sent"; + control.clear_cache <= '1'; + wait for clk_period; + control.clear_cache <= '0'; + wait for clk_period; + + arp_req_req.ip <= x"c0a80507"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + assert arp_req_rslt.got_mac = '0' report "T12: should not yet have mac"; + assert arp_req_rslt.got_err = '0' report "T12: should not have got err"; + + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + + + assert mac_tx_req = '1' report "T12: should be requesting TX channel"; + wait for clk_period*50; + -- Send the reply + data_out_ready <= '1'; + + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"55"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"07"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T12: should have got mac"; + assert arp_req_rslt.mac = x"021503235554" report "T12: incorrect mac"; + assert arp_req_rslt.got_err = '0' report "T12: should not have got err"; + wait for clk_period*10; + +-- + report "T13 - Send a request for the IP that is not on the local network"; + arp_req_req.ip <= x"0a000003"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + report "T13: waiting for data_out_valid"; + wait until data_out_valid = '1'; + report "T13: got data_out_valid"; + wait for clk_period*10; + data_out_ready <= '0'; + wait for clk_period*2; + data_out_ready <= '1'; + wait for clk_period*12; + assert data_out = x"01" report "T13: expected opcode = 01 for request 'who has'"; + -- expect our mac 00 23 20 21 22 23 + wait for clk_period; + assert data_out = x"00" report "T13: incorrect our mac.0"; + wait for clk_period; + assert data_out = x"23" report "T13: incorrect our mac.1"; + wait for clk_period; + assert data_out = x"20" report "T13: incorrect our mac.2"; + wait for clk_period; + assert data_out = x"21" report "T13: incorrect our mac.3"; + wait for clk_period; + assert data_out = x"22" report "T13: incorrect our mac.4"; + wait for clk_period; + assert data_out = x"23" report "T13: incorrect our mac.5"; + -- expect our IP c0 a8 05 05 + wait for clk_period; + assert data_out = x"c0" report "T13: incorrect our IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T13: incorrect our IP.1"; + wait for clk_period; + assert data_out = x"05" report "T13: incorrect our IP.2"; + wait for clk_period; + assert data_out = x"09" report "T13: incorrect our IP.3"; + + -- expect empty target mac + wait for clk_period; + assert data_out = x"ff" report "T13: incorrect target mac.0"; + wait for clk_period; + assert data_out = x"ff" report "T13: incorrect target mac.1"; + wait for clk_period; + assert data_out = x"ff" report "T13: incorrect target mac.2"; + wait for clk_period; + assert data_out = x"ff" report "T13: incorrect target mac.3"; + wait for clk_period; + assert data_out = x"ff" report "T13: incorrect target mac.4"; + wait for clk_period; + assert data_out = x"ff" report "T13: incorrect target mac.5"; + -- expect target IP c0 a8 05 01 + wait for clk_period; + assert data_out = x"c0" report "T13: incorrect target IP.0"; + wait for clk_period; + assert data_out = x"a8" report "T13: incorrect target IP.1"; + wait for clk_period; + assert data_out = x"05" report "T13: incorrect target IP.2"; + assert data_out_last = '0' report "T13: data out last incorrectly set on target IP.2 byte"; + wait for clk_period; + assert data_out = x"01" report "T13: incorrect target IP.3"; + assert data_out_last = '1' report "T13: data out last should be set"; + + wait for clk_period*10; + + -- Send the reply + data_out_ready <= '1'; + + report "T13.2: Send an ARP reply: 192.168.5.1 has mac 02:12:03:23:04:54"; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T13.2: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T13.2: expected got err = 0"; + assert arp_req_rslt.mac = x"021203230454" report "T13.2: wrong mac value"; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period*4; + + report "T14 - Send a request for an other IP that is not on the local network"; + arp_req_req.ip <= x"0a000204"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + report "T14: reply should be from cache"; +-- wait until arp_req_rslt.got_mac = '1' or arp_req_rslt.got_err = '1'; + assert arp_req_rslt.got_mac = '1' report "T14: expected got mac"; + assert arp_req_rslt.got_err = '0' report "T14: expected got err = 0"; + assert arp_req_rslt.mac = x"021203230454" report "T14: wrong mac value"; + wait for clk_period*2; +-- + + + report "--- end of tests ---"; + wait; + end process; + +end; Index: tags/v2.3/bench/vhdl/IPv4_TX_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/IPv4_TX_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/IPv4_TX_tb.vhd (revision 25) @@ -0,0 +1,363 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 09:35:58 06/03/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/ip1/IPv4_TX_tb.vhd +-- Project Name: ip1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: IPv4_TX +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 0.02 - Added test for IP broadcast tx +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use IEEE.NUMERIC_STD.all; +use work.axi.all; +use work.ipv4_types.all; +use work.arp_types.all; + + +entity IPv4_TX_tb is +end IPv4_TX_tb; + +architecture behavior of IPv4_TX_tb is + + -- Component Declaration for the Unit Under Test (UUT) + + component IPv4_TX + port( + -- IP Layer signals + ip_tx_start : in std_logic; + 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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data + + -- system signals + clk : in std_logic; -- same clock used to clock mac data and ip data + reset : in std_logic; + our_ip_address : in std_logic_vector (31 downto 0); + our_mac_address : in std_logic_vector (47 downto 0); + -- ARP lookup signals + arp_req_req : out arp_req_req_type; + arp_req_rslt : in arp_req_rslt_type; + -- 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_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_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 : out std_logic_vector (7 downto 0) -- ethernet frame (from dst mac addr through to last byte of frame) + ); + end component; + + + --Inputs + signal ip_tx_start : std_logic := '0'; + signal ip_tx : ipv4_tx_type; + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal our_mac_address : std_logic_vector(47 downto 0) := (others => '0'); + signal mac_tx_granted : std_logic := '0'; + signal mac_data_out_ready : std_logic := '0'; + signal arp_req_rslt : arp_req_rslt_type; + + --Outputs + signal ip_tx_result : std_logic_vector (1 downto 0); -- tx status (changes during transmission) + signal ip_tx_data_out_ready : std_logic; -- indicates IP TX is ready to take data + signal mac_tx_req : std_logic; + signal mac_data_out_valid : std_logic; + signal mac_data_out_last : std_logic; + signal mac_data_out_first : std_logic; + signal mac_data_out : std_logic_vector(7 downto 0); + signal arp_req_req : arp_req_req_type; + + -- Clock period definitions + constant clk_period : time := 8 ns; + +begin + + -- Instantiate the Unit Under Test (UUT) + uut : IPv4_TX port map ( + ip_tx_start => ip_tx_start, + ip_tx => ip_tx, + ip_tx_result => ip_tx_result, + ip_tx_data_out_ready => ip_tx_data_out_ready, + clk => clk, + reset => reset, + our_ip_address => our_ip_address, + our_mac_address => our_mac_address, + arp_req_req => arp_req_req, + arp_req_rslt => arp_req_rslt, + mac_tx_req => mac_tx_req, + mac_tx_granted => mac_tx_granted, + mac_data_out_ready => mac_data_out_ready, + mac_data_out_valid => mac_data_out_valid, + mac_data_out_first => mac_data_out_first, + mac_data_out_last => mac_data_out_last, + mac_data_out => mac_data_out + ); + + -- Clock process definitions + clk_process : process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc : process + begin + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + our_mac_address <= x"002320212223"; + ip_tx_start <= '0'; + mac_tx_granted <= '0'; + mac_data_out_ready <= '0'; + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + arp_req_rslt.got_mac <= '0'; + arp_req_rslt.got_err <= '0'; + arp_req_rslt.mac <= (others => '0'); + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait until clk = '1'; + wait for clk_period*5; + wait until clk = '1'; + + -- check reset conditions + assert arp_req_req.lookup_req = '0' report "arp_req_req.lookup_req not initialised correctly on reset"; + assert ip_tx_result = IPTX_RESULT_NONE report "ip_tx_result not initialised correctly on reset"; + assert ip_tx_data_out_ready = '0' report "ip_tx_data_out_ready not initialised correctly on reset"; + assert mac_tx_req = '0' report "mac_tx_req not initialised correctly on reset"; + assert mac_data_out_valid = '0' report "mac_data_out_valid not initialised correctly on reset"; + assert mac_data_out_last = '0' report "mac_data_out_last not initialised correctly on reset"; + + -- insert stimulus here + + ------------ + -- TEST 1 -- basic functional tx test with some delays for arp and chn access + ------------ + + report "T1: basic functional tx test with some delays for arp and chn access"; + + ip_tx.hdr.protocol <= x"35"; + ip_tx.hdr.data_length <= x"0008"; + ip_tx.hdr.dst_ip_addr <= x"c0123478"; + ip_tx_start <= '1'; + wait until clk = '1'; + ip_tx_start <= '0'; + arp_req_rslt.got_mac <= '0'; + arp_req_rslt.got_err <= '0'; + + wait until clk = '1'; + assert arp_req_req.lookup_req = '1' report "T1: lookup_req not set on tx start"; + assert ip_tx_result = IPTX_RESULT_SENDING report "T1: result should be IPTX_RESULT_SENDING"; + + wait for clk_period*10; -- simulate arp lookup time + wait until clk = '1'; + arp_req_rslt.mac <= x"050423271016"; + arp_req_rslt.got_mac <= '1'; + + wait until clk = '1'; + wait until clk = '1'; + assert arp_req_req.lookup_req = '0' report "T1: lookup_req not clear after setting"; + assert mac_tx_req = '1' report "T1: mac_tx_req not set after getting mac"; + + wait for clk_period*10; -- simulate mac chn access time + wait until clk = '1'; + mac_tx_granted <= '1'; + wait until clk = '1'; wait until clk = '1'; mac_data_out_ready <= '1'; + assert mac_data_out_valid = '0' report "T1: mac_data_out_valid asserted too early"; + + wait until clk = '1'; + + assert ip_tx_data_out_ready = '0' report "T1: IP data out ready asserted too early"; + wait until clk = '1'; + assert mac_data_out_valid = '1' report "T1: mac_data_out_valid not asserted"; + + -- wait until in eth hdr + wait for clk_period*3; + wait until clk = '1'; + -- go mac not ready for 2 clocks + mac_data_out_ready <= '0'; + wait until clk = '1'; wait until clk = '1'; wait until clk = '1'; + mac_data_out_ready <= '1'; + + + wait until ip_tx_data_out_ready = '1'; + wait until clk = '1'; + + -- start to tx IP data + ip_tx.data.data_out_valid <= '1'; + ip_tx.data.data_out <= x"56"; wait until clk = '1'; + -- delay data in for 1 clk cycle + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out <= x"57"; wait until clk = '1'; + ip_tx.data.data_out_valid <= '1'; wait until clk = '1'; + ip_tx.data.data_out <= x"58"; wait until clk = '1'; + ip_tx.data.data_out <= x"59"; wait until clk = '1'; +--wait for clk_period; + + -- delay mac ready for 2 clk cycles + mac_data_out_ready <= '0'; + ip_tx.data.data_out <= x"5a"; wait until clk = '1'; +--wait for clk_period; + assert ip_tx_data_out_ready = '0' report "T1: ip_tx_data_out_ready not cleared when mac not ready"; + + ip_tx.data.data_out <= x"5a"; wait until clk = '1'; +--wait for clk_period; + mac_data_out_ready <= '1'; + wait until ip_tx_data_out_ready = '1'; + wait until clk = '1'; +-- wait for clk_period; + assert ip_tx_data_out_ready = '1' report "T1: ip_tx_data_out_ready not set when mac ready"; + ip_tx.data.data_out <= x"5b"; wait until clk = '1'; + ip_tx.data.data_out <= x"5c"; wait until clk = '1'; + + ip_tx.data.data_out <= x"5d"; + ip_tx.data.data_out_last <= '1'; + wait until clk = '1'; + assert mac_data_out_last = '1' report "T1: mac_datda_out_last not set on last byte"; + + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait until clk = '1'; wait until clk = '1'; + assert ip_tx_result = IPTX_RESULT_SENT report "T1: result should be IPTX_RESULT_SENT"; + assert mac_tx_req = '0' report "T1: mac_tx_req held on too long after TX"; + + mac_tx_granted <= '0'; + wait until clk = '1'; wait until clk = '1'; + ------------ + -- TEST 2 -- basic functional tx test with no delays for arp and chn access + ------------ + + report "T2: basic functional tx test with no delays for arp and chn access"; + + ip_tx.hdr.protocol <= x"11"; + ip_tx.hdr.data_length <= x"0006"; + ip_tx.hdr.dst_ip_addr <= x"c0123478"; + ip_tx_start <= '1'; + wait until clk = '1'; + ip_tx_start <= '0'; wait until clk = '1'; + arp_req_rslt.got_mac <= '0'; + + assert arp_req_req.lookup_req = '1' report "T2: lookup_req not set on tx start"; + assert ip_tx_result = IPTX_RESULT_SENDING report "T2: result should be IPTX_RESULT_SENDING"; + + wait until clk = '1'; -- simulate arp lookup time + arp_req_rslt.mac <= x"050423271016"; + arp_req_rslt.got_mac <= '1'; + + wait until clk = '1'; wait until clk = '1'; + assert arp_req_req.lookup_req = '0' report "T2: lookup_req not clear after setting"; + assert mac_tx_req = '1' report "T2: mac_tx_req not set after getting mac"; + + wait until clk = '1'; -- simulate mac chn access time + mac_tx_granted <= '1'; + wait until clk = '1'; wait until clk = '1'; mac_data_out_ready <= '1'; + + assert ip_tx_data_out_ready = '0' report "T2: IP data out ready asserted too early"; + + wait until ip_tx_data_out_ready = '1'; + + -- start to tx IP data + ip_tx.data.data_out_valid <= '1'; + ip_tx.data.data_out <= x"c1"; wait until clk = '1'; + ip_tx.data.data_out <= x"c2"; wait until clk = '1'; + ip_tx.data.data_out <= x"c3"; wait until clk = '1'; + ip_tx.data.data_out <= x"c4"; wait until clk = '1'; + ip_tx.data.data_out <= x"c5"; wait until clk = '1'; + + ip_tx.data.data_out <= x"c6"; + ip_tx.data.data_out_last <= '1'; + wait until clk = '1'; + + assert mac_data_out_last = '1' report "T2: mac_datda_out_last not set on last byte"; + + + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait until clk = '1'; wait until clk = '1'; + assert ip_tx_result = IPTX_RESULT_SENT report "T2: result should be IPTX_RESULT_SENT"; + assert mac_tx_req = '0' report "T2: mac_tx_req held on too long after TX"; + + mac_tx_granted <= '0'; + wait until clk = '1'; wait until clk = '1'; + ------------ + -- TEST 3 -- tx test for IP broadcast, should be no arp req + ------------ + + report "T3: tx test for IP broadcast, should be no arp req"; + + ip_tx.hdr.protocol <= x"11"; + ip_tx.hdr.data_length <= x"0006"; + ip_tx.hdr.dst_ip_addr <= x"ffffffff"; + ip_tx_start <= '1'; + wait until clk = '1'; + ip_tx_start <= '0'; wait until clk = '1'; + arp_req_rslt.got_mac <= '0'; + + assert arp_req_req.lookup_req = '0' report "T3: its trying to do an ARP req tx start"; + assert ip_tx_result = IPTX_RESULT_SENDING report "T3: result should be IPTX_RESULT_SENDING"; + + wait until clk = '1'; -- simulate mac chn access time + mac_tx_granted <= '1'; + wait until clk = '1'; wait until clk = '1'; mac_data_out_ready <= '1'; + + assert ip_tx_data_out_ready = '0' report "T3: IP data out ready asserted too early"; + + wait until ip_tx_data_out_ready = '1'; + + -- start to tx IP data + ip_tx.data.data_out_valid <= '1'; + ip_tx.data.data_out <= x"c1"; wait until clk = '1'; + ip_tx.data.data_out <= x"c2"; wait until clk = '1'; + ip_tx.data.data_out <= x"c3"; wait until clk = '1'; + ip_tx.data.data_out <= x"c4"; wait until clk = '1'; + ip_tx.data.data_out <= x"c5"; wait until clk = '1'; + + ip_tx.data.data_out <= x"c6"; + ip_tx.data.data_out_last <= '1'; + wait until clk = '1'; + + assert mac_data_out_last = '1' report "T3: mac_datda_out_last not set on last byte"; + + + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait until clk = '1'; wait until clk = '1'; + assert ip_tx_result = IPTX_RESULT_SENT report "T3: result should be IPTX_RESULT_SENT"; + assert mac_tx_req = '0' report "T3: mac_tx_req held on too long after TX"; + + mac_tx_granted <= '0'; + wait until clk = '1'; wait until clk = '1'; + + report "--- end of tests ---"; + + wait; + end process; + +end; Index: tags/v2.3/bench/vhdl/UDP_complete_nomac_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/UDP_complete_nomac_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/UDP_complete_nomac_tb.vhd (revision 25) @@ -0,0 +1,1413 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 09:57:01 06/13/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/udp1/UDP_complete_nomac_tb.vhd +-- Project Name: udp1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: UDP_Complete_nomac +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 0.02 - Added test for IP broadcast tx +-- Revision 0.03 - Added tests for ARP timeout +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.axi.all; +use work.ipv4_types.all; +use work.arp_types.all; + +ENTITY UDP_complete_nomac_tb IS +END UDP_complete_nomac_tb; + +ARCHITECTURE behavior OF UDP_complete_nomac_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT UDP_Complete_nomac + generic ( + CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr + ARP_TIMEOUT : integer := 60 -- ARP response timeout (s) + ); + Port ( + -- UDP TX signals + udp_tx_start : in std_logic; -- indicates req to tx UDP + udp_txi : in udp_tx_type; -- UDP tx cxns + udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission) + udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data + -- UDP RX signals + udp_rx_start : out std_logic; -- indicates receipt of udp header + udp_rxo : out udp_rx_type; + -- IP RX signals + ip_rx_hdr : out ipv4_rx_header_type; + -- system signals + rx_clk : in STD_LOGIC; + tx_clk : in STD_LOGIC; + reset : in STD_LOGIC; + our_ip_address : in STD_LOGIC_VECTOR (31 downto 0); + our_mac_address : in std_logic_vector (47 downto 0); + control : in udp_control_type; + -- status signals + arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received + ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us + -- MAC Transmitter + mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx + mac_tx_tvalid : out std_logic; -- tdata is valid + mac_tx_tready : in std_logic; -- mac is ready to accept data + mac_tx_tfirst : out std_logic; -- indicates first byte of frame + mac_tx_tlast : out std_logic; -- indicates last byte of frame + -- MAC Receiver + mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received + mac_rx_tvalid : in std_logic; -- indicates tdata is valid + mac_rx_tready : out std_logic; -- tells mac that we are ready to take data + mac_rx_tlast : in std_logic -- indicates last byte of the trame + ); + END COMPONENT; + + + + type state_type is (IDLE, WAIT_RX_DONE, DATA_OUT); + type count_mode_type is (RST, INCR, HOLD); + type set_clr_type is (SET, CLR, HOLD); + + + --Inputs + signal udp_tx_start_int : std_logic := '0'; + signal udp_tx_int : udp_tx_type; + signal clk_int : std_logic := '0'; + signal reset : std_logic := '0'; + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal our_mac_address : std_logic_vector(47 downto 0) := (others => '0'); + signal mac_tx_tready : std_logic := '0'; + signal mac_rx_tdata : std_logic_vector(7 downto 0) := (others => '0'); + signal mac_rx_tvalid : std_logic := '0'; + signal mac_rx_tlast : std_logic := '0'; + signal control : udp_control_type; + + --Outputs + signal udp_rx_start_int : std_logic; + signal udp_rx_int : udp_rx_type; + signal ip_rx_hdr : ipv4_rx_header_type; + signal udp_tx_result : std_logic_vector (1 downto 0); + signal udp_tx_data_out_ready_int: std_logic; + + signal arp_pkt_count : std_logic_vector(7 downto 0); + signal ip_pkt_count : std_logic_vector(7 downto 0); + signal mac_tx_tdata : std_logic_vector(7 downto 0); + signal mac_tx_tvalid : std_logic; + signal mac_tx_tfirst : std_logic; + signal mac_tx_tlast : std_logic; + signal mac_rx_tready : std_logic; + + signal pbtx_led : std_logic; + signal pbtx : std_logic := '0'; + + -- state signals + signal state : state_type; + signal count : unsigned (7 downto 0); + signal tx_hdr : udp_tx_header_type; + signal tx_start_reg : std_logic; + signal tx_started_reg : std_logic; + signal tx_fin_reg : std_logic; + + + -- control signals + signal next_state : state_type; + signal set_state : std_logic; + signal set_count : count_mode_type; + signal set_hdr : std_logic; + signal set_tx_start : set_clr_type; + signal set_last : std_logic; + signal set_tx_started : set_clr_type; + signal set_tx_fin : set_clr_type; + signal first_byte_rx : STD_LOGIC_VECTOR(7 downto 0); + + + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: UDP_Complete_nomac + generic map ( + CLOCK_FREQ => 10, -- artificially low count to enable pragmatic testing + ARP_TIMEOUT => 20 + ) + PORT MAP ( + udp_tx_start => udp_tx_start_int, + udp_txi => udp_tx_int, + udp_tx_result => udp_tx_result, + udp_tx_data_out_ready => udp_tx_data_out_ready_int, + udp_rx_start => udp_rx_start_int, + udp_rxo => udp_rx_int, + ip_rx_hdr => ip_rx_hdr, + rx_clk => clk_int, + tx_clk => clk_int, + reset => reset, + our_ip_address => our_ip_address, + our_mac_address => our_mac_address, + control => control, + arp_pkt_count => arp_pkt_count, + ip_pkt_count => ip_pkt_count, + mac_tx_tdata => mac_tx_tdata, + mac_tx_tvalid => mac_tx_tvalid, + mac_tx_tready => mac_tx_tready, + mac_tx_tfirst => mac_tx_tfirst, + mac_tx_tlast => mac_tx_tlast, + mac_rx_tdata => mac_rx_tdata, + mac_rx_tvalid => mac_rx_tvalid, + mac_rx_tready => mac_rx_tready, + mac_rx_tlast => mac_rx_tlast + ); + + -- Clock process definitions + clk_process :process + begin + clk_int <= '0'; + wait for clk_period/2; + clk_int <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 100 ns; + + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + our_mac_address <= x"002320212223"; + control.ip_controls.arp_controls.clear_cache <= '0'; + mac_tx_tready <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + -- check reset conditions + assert udp_tx_result = UDPTX_RESULT_NONE report "udp_tx_result not initialised correctly on reset"; + assert udp_tx_data_out_ready_int = '0' report "ip_udp_txitx.data.data_out_ready not initialised correctly on reset"; + assert mac_tx_tvalid = '0' report "mac_tx_tvalid not initialised correctly on reset"; + assert mac_tx_tlast = '0' report "mac_tx_tlast not initialised correctly on reset"; + assert arp_pkt_count = x"00" report "arp_pkt_count not initialised correctly on reset"; + assert ip_pkt_count = x"00" report "ip_pkt_count not initialised correctly on reset"; + assert udp_rx_start_int = '0' report "udp_rx_start not initialised correctly on reset"; + assert udp_rx_int.hdr.is_valid = '0' report "udp_rx_int.hdr.is_valid not initialised correctly on reset"; + assert udp_rx_int.hdr.data_length = x"0000" report "udp_rx_int.hdr.data_length not initialised correctly on reset"; + assert udp_rx_int.hdr.src_ip_addr = x"00000000" report "udp_rx_int.hdr.src_ip_addr not initialised correctly on reset"; + assert udp_rx_int.hdr.src_port = x"0000" report "udp_rx_int.hdr.src_port not initialised correctly on reset"; + assert udp_rx_int.hdr.dst_port = x"0000" report "udp_rx_int.hdr.dst_port not initialised correctly on reset"; + assert udp_rx_int.data.data_in = x"00" report "udp_rx_start.data.data_in not initialised correctly on reset"; + assert udp_rx_int.data.data_in_valid = '0' report "udp_rx_start.data.data_in_valid not initialised correctly on reset"; + assert udp_rx_int.data.data_in_last = '0' report "udp_rx_start.data.data_in_last not initialised correctly on reset"; + assert ip_rx_hdr.is_valid = '0' report "ip_rx_hdr.is_valid not initialised correctly on reset"; + assert ip_rx_hdr.protocol = x"00" report "ip_rx_hdr.protocol not initialised correctly on reset"; + assert ip_rx_hdr.data_length = x"0000" report "ip_rx_hdr.data_length not initialised correctly on reset"; + assert ip_rx_hdr.src_ip_addr = x"00000000" report "ip_rx_hdr.src_ip_addr not initialised correctly on reset"; + assert ip_rx_hdr.num_frame_errors = x"00" report "ip_rx_hdr.num_frame_errors not initialised correctly on reset"; + + + -- insert stimulus here + + ------------ + -- TEST 1 -- send ARP request + ------------ + + report "T1: Send an ARP request: who has 192.168.5.9? Tell 192.168.5.1"; + + mac_tx_tready <= '1'; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"06"; wait for clk_period; + -- HW type + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Protocol type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- HW size + mac_rx_tdata <= x"06"; wait for clk_period; + -- protocol size + mac_rx_tdata <= x"04"; wait for clk_period; + -- Opcode + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Sender MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- Sender IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Target MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- Target IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '1'; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + + -- check we got the ARP pkt + assert arp_pkt_count = x"01" report "T1: arp_pkt_count wrong value"; + assert ip_pkt_count = x"00" report "T1: ip_pkt_count wrong value"; + assert udp_tx_result = UDPTX_RESULT_NONE report "T1: udp_tx_result wrong value"; + assert udp_tx_data_out_ready_int = '0' report "T1: ip_udp_txitx.data.data_out_ready wrong value"; + assert udp_rx_start_int = '0' report "T1: udp_rx_start wrong value"; + assert udp_rx_int.hdr.is_valid = '0' report "T1: udp_rx_int.hdr.is_valid wrong value"; + assert ip_rx_hdr.is_valid = '0' report "T1: ip_rx_hdr.is_valid wrong value"; + + -- check we tx a response + + wait for clk_period*25; + assert mac_tx_tvalid = '1' report "T1: not transmitting a response"; + wait for clk_period*25; + assert mac_tx_tvalid = '0' report "T1: tx held on for too long"; + + ------------ + -- TEST 2 -- send UDP pkt (same as sample from Java program) + ------------ + + report "T2: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T2: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T2: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T2: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T2: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T2: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T2: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T2: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T2: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T2: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T2: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T2: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T2: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T2: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + assert udp_rx_int.data.data_in_valid = '0' report "T2: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T2: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T2: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T2: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T2: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"01" report "T2: ip pkt cnt incorrect"; + + wait for clk_period*20; + + ------------ + -- TEST 3 -- send UDP pkt again (same as sample from Java program) + ------------ + + report "T3: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T3: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T3: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T3: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T3: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T3: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T3: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T3: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T3: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T3: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T3: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T3: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T3: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T3: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + assert udp_rx_int.data.data_in_valid = '0' report "T3: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T3: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T3: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T3: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T3: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"02" report "T3: ip pkt cnt incorrect"; + + wait for clk_period*50; + + ------------ + -- TEST 4 -- send UDP pkt with specific UDP data to force a broadcast tx in reply + ------------ + + report "T4: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"42"; wait for clk_period; -- First byte 'B' triggers a reply to broadcast addr + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T4: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T4: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T4: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T4: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T4: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T4: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T4: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T4: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T4: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T4: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T4: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T4: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T4: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + report "T4: waiting for mac data tx"; + wait until mac_tx_tvalid = '1'; + report "T4: starting mac data tx"; + wait for clk_period; + + -- check the mac data being transmitted + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T4: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T4: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T4: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T4: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T4: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T4: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T4: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"45" report "T4: incorrect ver.hlen"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect srv type"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect len 0"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T4: incorrect len 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T4: incorrect ident 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect ident 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect flag&frag 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect flag&frag 1"; wait for clk_period; + + assert mac_tx_tdata = x"80" report "T4: incorrect TTL"; wait for clk_period; + assert mac_tx_tdata = x"11" report "T4: incorrect protocol"; wait for clk_period; + assert mac_tx_tdata = x"75" report "T4: incorrect hdr.cks 0"; wait for clk_period; + assert mac_tx_tdata = x"1c" report "T4: incorrect hdr.cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T4: incorrect src ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T4: incorrect src ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T4: incorrect src ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T4: incorrect src ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 0"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 1"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 2"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"26" report "T4: incorrect src port 0"; wait for clk_period; + assert mac_tx_tdata = x"94" report "T4: incorrect src port 1"; wait for clk_period; + assert mac_tx_tdata = x"f4" report "T4: incorrect dst port 0"; wait for clk_period; + assert mac_tx_tdata = x"9a" report "T4: incorrect dst port 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T4: incorrect udp len 0"; wait for clk_period; + assert mac_tx_tdata = x"0c" report "T4: incorrect udp len 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect udp cks 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect udp cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"40" report "T4: incorrect udp data 0"; wait for clk_period; + assert mac_tx_tdata = x"41" report "T4: incorrect udp data 1"; wait for clk_period; + + assert mac_tx_tdata = x"42" report "T4: incorrect udp data 2"; + assert mac_tx_tlast = '0' report "T4: tlast asserted too soon"; wait for clk_period; + assert mac_tx_tdata = x"43" report "T4: incorrect udp data 3"; + assert mac_tx_tlast = '1' report "T4: tlast not asserted"; wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENT report "T4: TX did not complete"; + + assert udp_rx_int.data.data_in_valid = '0' report "T4: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T4: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T4: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T4: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T4: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"03" report "T4: ip pkt cnt incorrect"; + + ------------ + -- TEST 5 -- send UDP pkt with dst=bc addr to ensure we can receive broadcast tx + ------------ + + report "T5: Send UDP IP pkt dst ip_address bc, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T5: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T5: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T5: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T5: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T5: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T5: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T5: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T5: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T5: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T5: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T5: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T5: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T5: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + + report "T5: waiting for mac data tx"; + if mac_tx_tvalid = '0' then + wait until mac_tx_tvalid = '1'; + wait for clk_period; + end if; + report "T5: starting mac data tx"; + + -- check the mac data being transmitted + assert mac_tx_tdata = x"00" report "T5: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T5: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"18" report "T5: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"29" report "T5: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"26" report "T5: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"7c" report "T5: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T5: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T5: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T5: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T5: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T5: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T5: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T5: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"45" report "T5: incorrect ver.hlen"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect srv type"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect len 0"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T5: incorrect len 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T5: incorrect ident 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect ident 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect flag&frag 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect flag&frag 1"; wait for clk_period; + + assert mac_tx_tdata = x"80" report "T5: incorrect TTL"; wait for clk_period; + assert mac_tx_tdata = x"11" report "T5: incorrect protocol"; wait for clk_period; + assert mac_tx_tdata = x"af" report "T5: incorrect hdr.cks 0"; wait for clk_period; + assert mac_tx_tdata = x"72" report "T5: incorrect hdr.cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T5: incorrect src ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T5: incorrect src ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T5: incorrect src ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T5: incorrect src ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T5: incorrect dst ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T5: incorrect dst ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T5: incorrect dst ip 2"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T5: incorrect dst ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"26" report "T5: incorrect src port 0"; wait for clk_period; + assert mac_tx_tdata = x"94" report "T5: incorrect src port 1"; wait for clk_period; + assert mac_tx_tdata = x"f4" report "T5: incorrect dst port 0"; wait for clk_period; + assert mac_tx_tdata = x"9a" report "T5: incorrect dst port 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T5: incorrect udp len 0"; wait for clk_period; + assert mac_tx_tdata = x"0c" report "T5: incorrect udp len 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect udp cks 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect udp cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"50" report "T5: incorrect udp data 0"; wait for clk_period; + assert mac_tx_tdata = x"51" report "T5: incorrect udp data 1"; wait for clk_period; + + assert mac_tx_tdata = x"52" report "T5: incorrect udp data 2"; + assert mac_tx_tlast = '0' report "T5: tlast asserted too soon"; wait for clk_period; + assert mac_tx_tdata = x"53" report "T5: incorrect udp data 3"; + assert mac_tx_tlast = '1' report "T5: tlast not asserted"; wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENT report "T5: TX did not complete"; + + assert udp_rx_int.data.data_in_valid = '0' report "T5: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T5: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T5: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T5: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T5: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"04" report "T5: ip pkt cnt incorrect"; + + + ------------ + -- TEST 6 -- send UDP pkt with data to trigger the sending of a pkt to unknown IP addr to force an ARP timeout + ------------ + + report "T6: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694 with data x43 to trig tx to unknown IP"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"43"; wait for clk_period; -- First byte 'C' triggers a reply to unknown addr + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T6: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T6: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T6: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T6: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T6: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T6: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T6: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T6: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T6: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T6: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T6: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T6: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T6: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + report "T6: waiting for mac data tx"; + wait until mac_tx_tvalid = '1'; + report "T6: starting mac data tx"; + wait for clk_period; + + -- check the mac data being transmitted is valid ARP request + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T6: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T6: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T6: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T6: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T6: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"06" report "T6: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T6: incorrect HW type.0"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T6: incorrect HW type.1"; wait for clk_period; + assert mac_tx_tdata = x"08" report "T6: incorrect prot.0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T6: incorrect prot.1"; wait for clk_period; + assert mac_tx_tdata = x"06" report "T6: incorrect HW size"; wait for clk_period; + assert mac_tx_tdata = x"04" report "T6: incorrect prot size"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T6: incorrect opcode.0"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T6: incorrect opcode.1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T6: incorrect sndr mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect sndr mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T6: incorrect sndr mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T6: incorrect sndr mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T6: incorrect sndr mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect sndr mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T6: incorrect sndr ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T6: incorrect sndr ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T6: incorrect sndr ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T6: incorrect sndr ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"ff" report "T6: incorrect trg mac 0"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect trg mac 1"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect trg mac 2"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect trg mac 3"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect trg mac 4"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect trg mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T6: incorrect trg ip 0"; wait for clk_period; + assert mac_tx_tdata = x"bb" report "T6: incorrect trg ip 1"; wait for clk_period; + assert mac_tx_tdata = x"cc" report "T6: incorrect trg ip 2"; + assert mac_tx_tlast = '0' report "T6: tlast asserted too soon"; + wait for clk_period; + + assert mac_tx_tdata = x"dd" report "T6: incorrect trg ip 3"; + assert mac_tx_tlast = '1' report "T6: tlast should be set"; + wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENDING report "T6: TX should still be in sending phase"; + + assert udp_rx_int.data.data_in_valid = '0' report "T6: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T6: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T6: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T6: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T6: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"05" report "T6: ip pkt cnt incorrect"; + + -- check for error on tx as a result of ARP timeout + + wait for clk_period*10*20; + assert udp_tx_result = IPTX_RESULT_ERR report "T6: TX should resulkt in error (arp timeout)"; + + wait for clk_period*10; + + ------------ + -- TEST 7 -- send UDP pkt again to ensure that we can rx a pkt and tx after a timeout + ------------ + + report "T7: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T7: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T7: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T7: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T7: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T7: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T7: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T7: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T7: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T7: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T7: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T7: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T7: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T7: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + -- there should be no ARP exchange as this entry should already be cached. + + report "T7: waiting for mac data tx"; + if mac_tx_tvalid = '0' then + wait until mac_tx_tvalid = '1'; + wait for clk_period; + end if; + report "T7: starting mac data tx"; + + -- check the mac data being transmitted + assert mac_tx_tdata = x"00" report "T7: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T7: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"18" report "T7: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"29" report "T7: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"26" report "T7: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"7c" report "T7: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T7: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T7: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T7: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T7: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T7: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T7: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T7: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"45" report "T7: incorrect ver.hlen"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect srv type"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect len 0"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T7: incorrect len 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T7: incorrect ident 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect ident 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect flag&frag 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect flag&frag 1"; wait for clk_period; + + assert mac_tx_tdata = x"80" report "T7: incorrect TTL"; wait for clk_period; + assert mac_tx_tdata = x"11" report "T7: incorrect protocol"; wait for clk_period; + assert mac_tx_tdata = x"af" report "T7: incorrect hdr.cks 0"; wait for clk_period; + assert mac_tx_tdata = x"72" report "T7: incorrect hdr.cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T7: incorrect src ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T7: incorrect src ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T7: incorrect src ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T7: incorrect src ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T7: incorrect dst ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T7: incorrect dst ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T7: incorrect dst ip 2"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T7: incorrect dst ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"26" report "T7: incorrect src port 0"; wait for clk_period; + assert mac_tx_tdata = x"94" report "T7: incorrect src port 1"; wait for clk_period; + assert mac_tx_tdata = x"f4" report "T7: incorrect dst port 0"; wait for clk_period; + assert mac_tx_tdata = x"9a" report "T7: incorrect dst port 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T7: incorrect udp len 0"; wait for clk_period; + assert mac_tx_tdata = x"0c" report "T7: incorrect udp len 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect udp cks 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect udp cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"40" report "T7: incorrect udp data 0"; wait for clk_period; + assert mac_tx_tdata = x"41" report "T7: incorrect udp data 1"; wait for clk_period; + + assert mac_tx_tdata = x"42" report "T7: incorrect udp data 2"; + assert mac_tx_tlast = '0' report "T7: tlast asserted too soon"; wait for clk_period; + assert mac_tx_tdata = x"43" report "T7: incorrect udp data 3"; + assert mac_tx_tlast = '1' report "T7: tlast not asserted"; wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENT report "T7: TX did not complete"; + + assert udp_rx_int.data.data_in_valid = '0' report "T7: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T7: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T7: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T7: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T7: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"06" report "T7: ip pkt cnt incorrect"; + + + report "--- end of tests ---"; + wait; + end process; + + -- AUTO TX process - on receipt of any UDP pkt, send a response. data sent is modified if a broadcast was received. + + -- TX response process - COMB + tx_proc_combinatorial: process( + -- inputs + udp_rx_start_int, udp_rx_int, udp_tx_data_out_ready_int, udp_tx_result, ip_rx_hdr, + udp_tx_int.data.data_out_valid, PBTX, + -- state + state, count, tx_hdr, tx_start_reg, tx_started_reg, tx_fin_reg, + -- controls + next_state, set_state, set_count, set_hdr, set_tx_start, set_last, + set_tx_started, set_tx_fin, first_byte_rx + ) + begin + -- set output_followers + udp_tx_int.hdr <= tx_hdr; + udp_tx_int.data.data_out_last <= set_last; + udp_tx_start_int <= tx_start_reg; + + -- set control signal defaults + next_state <= IDLE; + set_state <= '0'; + set_count <= HOLD; + set_hdr <= '0'; + set_tx_start <= HOLD; + set_last <= '0'; + set_tx_started <= HOLD; + set_tx_fin <= HOLD; + first_byte_rx <= (others => '0'); + + -- FSM + case state is + + when IDLE => + udp_tx_int.data.data_out <= (others => '0'); + udp_tx_int.data.data_out_valid <= '0'; + if udp_rx_start_int = '1' or PBTX = '1' then + if udp_rx_start_int = '1' then + first_byte_rx <= udp_rx_int.data.data_in; + else + first_byte_rx <= x"00"; + end if; + set_tx_fin <= CLR; + set_count <= RST; + set_hdr <= '1'; + if udp_rx_int.data.data_in_last = '1' then + set_tx_started <= SET; + set_tx_start <= SET; + next_state <= DATA_OUT; + set_state <= '1'; + else + next_state <= WAIT_RX_DONE; + set_state <= '1'; + end if; + end if; + + when WAIT_RX_DONE => + -- wait until RX pkt fully received + if udp_rx_int.data.data_in_last = '1' then + set_tx_started <= SET; + set_tx_start <= SET; + next_state <= DATA_OUT; + set_state <= '1'; + end if; + + when DATA_OUT => + if udp_tx_result = UDPTX_RESULT_ERR then + -- have an error from the IP TX layer, clear down the TX + set_tx_start <= CLR; + set_tx_fin <= SET; + set_tx_started <= CLR; + next_state <= IDLE; + set_state <= '1'; + else + if udp_tx_result = UDPTX_RESULT_SENDING then + set_tx_start <= CLR; -- reset out start req as soon as we know we are sending + end if; + if ip_rx_hdr.is_broadcast = '1' then + udp_tx_int.data.data_out <= std_logic_vector(count) or x"50"; + else + udp_tx_int.data.data_out <= std_logic_vector(count) or x"40"; + end if; + udp_tx_int.data.data_out_valid <= udp_tx_data_out_ready_int; + if udp_tx_data_out_ready_int = '1' then + if unsigned(count) = x"03" then + set_last <= '1'; + set_tx_fin <= SET; + set_tx_started <= CLR; + next_state <= IDLE; + set_state <= '1'; + else + set_count <= INCR; + end if; + end if; + end if; + + end case; + end process; + + + + -- TX response process - SEQ + tx_proc_sequential: process(clk_int) + begin + if rising_edge(clk_int) then + if reset = '1' then + -- reset state variables + state <= IDLE; + count <= x"00"; + tx_start_reg <= '0'; + tx_hdr.dst_ip_addr <= (others => '0'); + tx_hdr.dst_port <= (others => '0'); + tx_hdr.src_port <= (others => '0'); + tx_hdr.data_length <= (others => '0'); + tx_hdr.checksum <= (others => '0'); + tx_started_reg <= '0'; + tx_fin_reg <= '0'; + PBTX_LED <= '0'; + else + PBTX_LED <= PBTX; + + -- Next rx_state processing + if set_state = '1' then + state <= next_state; + else + state <= state; + end if; + + -- count processing + case set_count is + when RST => count <= x"00"; + when INCR => count <= count + 1; + when HOLD => count <= count; + end case; + + -- set tx hdr + if set_hdr = '1' then + -- if the first byte of the rx pkt is 'B' then send to broadcast, otherwise send to reply IP + if first_byte_rx = x"42" then + tx_hdr.dst_ip_addr <= IP_BC_ADDR; -- send to Broadcast addr + elsif first_byte_rx = x"43" then + tx_hdr.dst_ip_addr <= x"c0bbccdd"; -- set dst unknown so get ARP timeout + else + tx_hdr.dst_ip_addr <= udp_rx_int.hdr.src_ip_addr; -- reply to sender + end if; + tx_hdr.dst_port <= udp_rx_int.hdr.src_port; + tx_hdr.src_port <= udp_rx_int.hdr.dst_port; + tx_hdr.data_length <= x"0004"; + tx_hdr.checksum <= x"0000"; + else + tx_hdr <= tx_hdr; + end if; + + -- set tx start signal + case set_tx_start is + when SET => tx_start_reg <= '1'; + when CLR => tx_start_reg <= '0'; + when HOLD => tx_start_reg <= tx_start_reg; + end case; + + -- set tx started signal + case set_tx_started is + when SET => tx_started_reg <= '1'; + when CLR => tx_started_reg <= '0'; + when HOLD => tx_started_reg <= tx_started_reg; + end case; + + -- set tx finished signal + case set_tx_fin is + when SET => tx_fin_reg <= '1'; + when CLR => tx_fin_reg <= '0'; + when HOLD => tx_fin_reg <= tx_fin_reg; + end case; + + + end if; + end if; + + end process; + +END; Index: tags/v2.3/bench/vhdl/arp_STORE_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/arp_STORE_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/arp_STORE_tb.vhd (revision 25) @@ -0,0 +1,384 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 07:38:43 02/13/2012 +-- Design Name: +-- Module Name: arp_STORE_tb.vhd +-- Project Name: udp3 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: arp_STORE_br +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use ieee.std_logic_unsigned.all; +use work.arp_types.all; + +ENTITY arp_STORE_tb IS +END arp_STORE_tb; + +ARCHITECTURE behavior OF arp_STORE_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT arp_STORE_br + generic ( + MAX_ARP_ENTRIES : integer := 256 -- max entries in the store + ); + PORT( + -- read signals + read_req : in arp_store_rdrequest_t; -- requesting a '1' or store + read_result : out arp_store_result_t; -- the result + -- write signals + write_req : in arp_store_wrrequest_t; -- requesting a '1' or store + -- control and status signals + clear_store : in std_logic; -- erase all entries + entry_count : out unsigned(7 downto 0); -- how many entries currently in store + -- system signals + clk : in std_logic; + reset : in STD_LOGIC + ); + END COMPONENT; + + + --Inputs + signal read_req : arp_store_rdrequest_t; + signal write_req : arp_store_wrrequest_t; + signal clear_store : std_logic := '0'; + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + + --Outputs + signal read_result : arp_store_result_t; + signal entry_count : unsigned(7 downto 0); -- how many entries currently in store + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: arp_STORE_br + generic map ( + MAX_ARP_ENTRIES => 4 + ) + PORT MAP ( + read_req => read_req, + read_result => read_result, + write_req => write_req, + clear_store => clear_store, + entry_count => entry_count, + clk => clk, + reset => reset + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + read_req.req <= '0'; + read_req.ip <= (others => '0'); + write_req.req <= '0'; + write_req.entry.ip <= (others => '0'); + write_req.entry.mac <= (others => '0'); + reset <= '1'; + -- hold reset state + wait for clk_period*10; + reset <= '0'; + + -- insert stimulus here + report "T1 - look for something when store is empty"; + read_req.ip <= x"12345678"; + read_req.req <= '1'; + wait for clk_period*4; + assert read_result.status = NOT_FOUND report "T1: expected NOT_FOUND"; + wait for clk_period; + read_req.req <= '0'; + wait for clk_period*2; + assert read_result.status = IDLE report "T1: expected IDLE"; + assert entry_count = x"00" report "T1: wrong entry count"; + + report "T2 - insert first entry into store"; + write_req.entry.ip <= x"12345678"; + write_req.entry.mac <= x"002398127645"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + assert entry_count = x"01" report "T2: wrong entry count"; + + report "T3 - check if can find this single entry"; + read_req.ip <= x"12345678"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T3: expected FOUND"; + assert read_result.entry.ip = x"12345678" report "T3: wrong ip addr"; + assert read_result.entry.mac = x"002398127645" report "T3: wrong mac addr"; + wait for clk_period; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T3: expected IDLE"; + + report "T4 - check unable to find missing entry with one entry in store"; + read_req.ip <= x"12345679"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = NOT_FOUND report "T4: expected NOT_FOUND"; + wait for clk_period; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T4: expected IDLE"; + + report "T5 - insert 2nd entry into store and check can find both entries"; + write_req.entry.ip <= x"12345679"; + write_req.entry.mac <= x"101202303404"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + assert entry_count = x"02" report "T4: wrong entry count"; + read_req.ip <= x"12345678"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T5.1: expected FOUND"; + assert read_result.entry.ip = x"12345678" report "T5.1: wrong ip addr"; + assert read_result.entry.mac = x"002398127645" report "T5.1: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T5.1: expected IDLE"; + read_req.ip <= x"12345679"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T5.2: expected FOUND"; + assert read_result.entry.ip = x"12345679" report "T5.2: wrong ip addr"; + assert read_result.entry.mac = x"101202303404" report "T5.2: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T5.2: expected IDLE"; + + report "T6 - insert 2 more entries so that the store is full. check can find all"; + write_req.entry.ip <= x"1234567a"; + write_req.entry.mac <= x"10120230340a"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + write_req.entry.ip <= x"1234567b"; + write_req.entry.mac <= x"10120230340b"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + assert entry_count = x"04" report "T6: wrong entry count"; + read_req.ip <= x"12345678"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T6.1: expected FOUND"; + assert read_result.entry.ip = x"12345678" report "T6.1: wrong ip addr"; + assert read_result.entry.mac = x"002398127645" report "T6.1: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T6.1: expected IDLE"; + read_req.ip <= x"12345679"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T6.2: expected FOUND"; + assert read_result.entry.ip = x"12345679" report "T6.2: wrong ip addr"; + assert read_result.entry.mac = x"101202303404" report "T6.2: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T6.2: expected IDLE"; + read_req.ip <= x"1234567a"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T6.3: expected FOUND"; + assert read_result.entry.ip = x"1234567a" report "T6.3: wrong ip addr"; + assert read_result.entry.mac = x"10120230340a" report "T6.3: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T6.3: expected IDLE"; + read_req.ip <= x"1234567b"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T6.4: expected FOUND"; + assert read_result.entry.ip = x"1234567b" report "T6.4: wrong ip addr"; + assert read_result.entry.mac = x"10120230340b" report "T6.4: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T6.4: expected IDLE"; + + report "T7 - with store full, check that we dont find missing item"; + read_req.ip <= x"1233367b"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = NOT_FOUND report "T7: expected NOT_FOUND"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T7: expected IDLE"; + + report "T8 - insert additional entry into store - will erase one of the others"; + write_req.entry.ip <= x"12345699"; + write_req.entry.mac <= x"992398127699"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + assert entry_count = x"04" report "T8: wrong entry count"; + read_req.ip <= x"12345699"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T8: expected FOUND"; + assert read_result.entry.ip = x"12345699" report "T8: wrong ip addr"; + assert read_result.entry.mac = x"992398127699" report "T8: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T8: expected IDLE"; + + report "T9 - clear the store and ensure cant find something that was there"; + clear_store <= '1'; + wait for clk_period; + clear_store <= '0'; + wait for clk_period; + assert entry_count = x"00" report "T9: wrong entry count"; + read_req.ip <= x"12345699"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = NOT_FOUND report "T9: expected NOT_FOUND"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T9: expected IDLE"; + + report "T10 - refill the store with three entries"; + write_req.entry.ip <= x"12345675"; + write_req.entry.mac <= x"10120230340a"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + write_req.entry.ip <= x"12345676"; + write_req.entry.mac <= x"10120230340b"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + write_req.entry.ip <= x"12345677"; + write_req.entry.mac <= x"10120230340c"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + assert entry_count = x"03" report "T10: wrong entry count"; + + report "T11 - check middle entry, then change it and check again"; + read_req.ip <= x"12345676"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T11.1: expected FOUND"; + assert read_result.entry.ip = x"12345676" report "T11.1: wrong ip addr"; + assert read_result.entry.mac = x"10120230340b" report "T11.1: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T11.1: expected IDLE"; + write_req.entry.ip <= x"12345676"; + write_req.entry.mac <= x"10120990340b"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait for clk_period; + assert entry_count = x"03" report "T11: wrong entry count"; + read_req.ip <= x"12345676"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T11.2: expected FOUND"; + assert read_result.entry.ip = x"12345676" report "T11.2: wrong ip addr"; + assert read_result.entry.mac = x"10120990340b" report "T11.2: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T11.2: expected IDLE"; + + report "T12 - check 2nd write at beginning"; + -- clear store, write 1st entry, overwrite the entry, and check + clear_store <= '1'; + wait for clk_period; + clear_store <= '0'; + wait for clk_period; + assert entry_count = x"00" report "T12.1: wrong entry count"; + write_req.entry.ip <= x"12345678"; + write_req.entry.mac <= x"002398127645"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + assert entry_count = x"01" report "T12.2: wrong entry count"; + write_req.entry.ip <= x"12345678"; + write_req.entry.mac <= x"002398127647"; + write_req.req <= '1'; + wait for clk_period; + write_req.req <= '0'; + wait until read_result.status = IDLE; + wait for clk_period; + assert entry_count = x"01" report "T12.3: wrong entry count"; + read_req.ip <= x"12345678"; + read_req.req <= '1'; + wait until read_result.status = FOUND or read_result.status = NOT_FOUND; + wait for clk_period; + assert read_result.status = FOUND report "T12.4: expected FOUND"; + assert read_result.entry.ip = x"12345678" report "T12.4: wrong ip addr"; + assert read_result.entry.mac = x"002398127647" report "T12.4: wrong mac addr"; + read_req.req <= '0'; + wait for clk_period*3; + assert read_result.status = IDLE report "T12.5: expected IDLE"; + + report "--- end of tests ---"; + wait; + end process; + +END; Index: tags/v2.3/bench/vhdl/UDP_av2_complete_nomac_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/UDP_av2_complete_nomac_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/UDP_av2_complete_nomac_tb.vhd (revision 25) @@ -0,0 +1,1415 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 09:57:01 06/13/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/udp1/UDP_complete_nomac_tb.vhd +-- Project Name: udp1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: UDP_Complete_nomac +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 0.02 - Added test for IP broadcast tx +-- Revision 0.03 - Added tests for ARP timeout +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.axi.all; +use work.ipv4_types.all; +use work.arp_types.all; + +ENTITY UDP_av2_complete_nomac_tb IS +END UDP_av2_complete_nomac_tb; + +ARCHITECTURE behavior OF UDP_av2_complete_nomac_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT UDP_Complete_nomac + generic ( + CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr + ARP_TIMEOUT : integer := 60 -- ARP response timeout (s) + ); + Port ( + -- UDP TX signals + udp_tx_start : in std_logic; -- indicates req to tx UDP + udp_txi : in udp_tx_type; -- UDP tx cxns + udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission) + udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data + -- UDP RX signals + udp_rx_start : out std_logic; -- indicates receipt of udp header + udp_rxo : out udp_rx_type; + -- IP RX signals + ip_rx_hdr : out ipv4_rx_header_type; + -- system signals + rx_clk : in STD_LOGIC; + tx_clk : in STD_LOGIC; + reset : in STD_LOGIC; + our_ip_address : in STD_LOGIC_VECTOR (31 downto 0); + our_mac_address : in std_logic_vector (47 downto 0); + control : in udp_control_type; + -- status signals + arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received + ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us + -- MAC Transmitter + mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx + mac_tx_tvalid : out std_logic; -- tdata is valid + mac_tx_tready : in std_logic; -- mac is ready to accept data + mac_tx_tfirst : out std_logic; -- indicates first byte of frame + mac_tx_tlast : out std_logic; -- indicates last byte of frame + -- MAC Receiver + mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received + mac_rx_tvalid : in std_logic; -- indicates tdata is valid + mac_rx_tready : out std_logic; -- tells mac that we are ready to take data + mac_rx_tlast : in std_logic -- indicates last byte of the trame + ); + END COMPONENT; + + + + type state_type is (IDLE, WAIT_RX_DONE, DATA_OUT); + type count_mode_type is (RST, INCR, HOLD); + type set_clr_type is (SET, CLR, HOLD); + + + --Inputs + signal udp_tx_start_int : std_logic := '0'; + signal udp_tx_int : udp_tx_type; + signal clk_int : std_logic := '0'; + signal reset : std_logic := '0'; + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal our_mac_address : std_logic_vector(47 downto 0) := (others => '0'); + signal mac_tx_tready : std_logic := '0'; + signal mac_rx_tdata : std_logic_vector(7 downto 0) := (others => '0'); + signal mac_rx_tvalid : std_logic := '0'; + signal mac_rx_tlast : std_logic := '0'; + signal control : udp_control_type; + + --Outputs + signal udp_rx_start_int : std_logic; + signal udp_rx_int : udp_rx_type; + signal ip_rx_hdr : ipv4_rx_header_type; + signal udp_tx_result : std_logic_vector (1 downto 0); + signal udp_tx_data_out_ready_int: std_logic; + + signal arp_pkt_count : std_logic_vector(7 downto 0); + signal ip_pkt_count : std_logic_vector(7 downto 0); + signal mac_tx_tdata : std_logic_vector(7 downto 0); + signal mac_tx_tvalid : std_logic; + signal mac_tx_tfirst : std_logic; + signal mac_tx_tlast : std_logic; + signal mac_rx_tready : std_logic; + + signal pbtx_led : std_logic; + signal pbtx : std_logic := '0'; + + -- state signals + signal state : state_type; + signal count : unsigned (7 downto 0); + signal tx_hdr : udp_tx_header_type; + signal tx_start_reg : std_logic; + signal tx_started_reg : std_logic; + signal tx_fin_reg : std_logic; + + + -- control signals + signal next_state : state_type; + signal set_state : std_logic; + signal set_count : count_mode_type; + signal set_hdr : std_logic; + signal set_tx_start : set_clr_type; + signal set_last : std_logic; + signal set_tx_started : set_clr_type; + signal set_tx_fin : set_clr_type; + signal first_byte_rx : STD_LOGIC_VECTOR(7 downto 0); + + + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: UDP_Complete_nomac + generic map ( + CLOCK_FREQ => 10, -- artificially low count to enable pragmatic testing + ARP_TIMEOUT => 20 + ) + PORT MAP ( + udp_tx_start => udp_tx_start_int, + udp_txi => udp_tx_int, + udp_tx_result => udp_tx_result, + udp_tx_data_out_ready => udp_tx_data_out_ready_int, + udp_rx_start => udp_rx_start_int, + udp_rxo => udp_rx_int, + ip_rx_hdr => ip_rx_hdr, + rx_clk => clk_int, + tx_clk => clk_int, + reset => reset, + our_ip_address => our_ip_address, + our_mac_address => our_mac_address, + control => control, + arp_pkt_count => arp_pkt_count, + ip_pkt_count => ip_pkt_count, + mac_tx_tdata => mac_tx_tdata, + mac_tx_tvalid => mac_tx_tvalid, + mac_tx_tready => mac_tx_tready, + mac_tx_tfirst => mac_tx_tfirst, + mac_tx_tlast => mac_tx_tlast, + mac_rx_tdata => mac_rx_tdata, + mac_rx_tvalid => mac_rx_tvalid, + mac_rx_tready => mac_rx_tready, + mac_rx_tlast => mac_rx_tlast + ); + + -- Clock process definitions + clk_process :process + begin + clk_int <= '0'; + wait for clk_period/2; + clk_int <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 100 ns; + + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + our_mac_address <= x"002320212223"; + control.ip_controls.arp_controls.clear_cache <= '0'; + mac_tx_tready <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + -- check reset conditions + assert udp_tx_result = UDPTX_RESULT_NONE report "udp_tx_result not initialised correctly on reset"; + assert udp_tx_data_out_ready_int = '0' report "ip_udp_txitx.data.data_out_ready not initialised correctly on reset"; + assert mac_tx_tvalid = '0' report "mac_tx_tvalid not initialised correctly on reset"; + assert mac_tx_tlast = '0' report "mac_tx_tlast not initialised correctly on reset"; + assert arp_pkt_count = x"00" report "arp_pkt_count not initialised correctly on reset"; + assert ip_pkt_count = x"00" report "ip_pkt_count not initialised correctly on reset"; + assert udp_rx_start_int = '0' report "udp_rx_start not initialised correctly on reset"; + assert udp_rx_int.hdr.is_valid = '0' report "udp_rx_int.hdr.is_valid not initialised correctly on reset"; + assert udp_rx_int.hdr.data_length = x"0000" report "udp_rx_int.hdr.data_length not initialised correctly on reset"; + assert udp_rx_int.hdr.src_ip_addr = x"00000000" report "udp_rx_int.hdr.src_ip_addr not initialised correctly on reset"; + assert udp_rx_int.hdr.src_port = x"0000" report "udp_rx_int.hdr.src_port not initialised correctly on reset"; + assert udp_rx_int.hdr.dst_port = x"0000" report "udp_rx_int.hdr.dst_port not initialised correctly on reset"; + assert udp_rx_int.data.data_in = x"00" report "udp_rx_start.data.data_in not initialised correctly on reset"; + assert udp_rx_int.data.data_in_valid = '0' report "udp_rx_start.data.data_in_valid not initialised correctly on reset"; + assert udp_rx_int.data.data_in_last = '0' report "udp_rx_start.data.data_in_last not initialised correctly on reset"; + assert ip_rx_hdr.is_valid = '0' report "ip_rx_hdr.is_valid not initialised correctly on reset"; + assert ip_rx_hdr.protocol = x"00" report "ip_rx_hdr.protocol not initialised correctly on reset"; + assert ip_rx_hdr.data_length = x"0000" report "ip_rx_hdr.data_length not initialised correctly on reset"; + assert ip_rx_hdr.src_ip_addr = x"00000000" report "ip_rx_hdr.src_ip_addr not initialised correctly on reset"; + assert ip_rx_hdr.num_frame_errors = x"00" report "ip_rx_hdr.num_frame_errors not initialised correctly on reset"; + + + -- insert stimulus here + + ------------ + -- TEST 1 -- send ARP request + ------------ + + report "T1: Send an ARP request: who has 192.168.5.9? Tell 192.168.5.1"; + + mac_tx_tready <= '1'; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"06"; wait for clk_period; + -- HW type + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Protocol type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- HW size + mac_rx_tdata <= x"06"; wait for clk_period; + -- protocol size + mac_rx_tdata <= x"04"; wait for clk_period; + -- Opcode + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Sender MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- Sender IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Target MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- Target IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '1'; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + + -- check we got the ARP pkt + assert arp_pkt_count = x"01" report "T1: arp_pkt_count wrong value"; + assert ip_pkt_count = x"00" report "T1: ip_pkt_count wrong value"; + assert udp_tx_result = UDPTX_RESULT_NONE report "T1: udp_tx_result wrong value"; + assert udp_tx_data_out_ready_int = '0' report "T1: ip_udp_txitx.data.data_out_ready wrong value"; + assert udp_rx_start_int = '0' report "T1: udp_rx_start wrong value"; + assert udp_rx_int.hdr.is_valid = '0' report "T1: udp_rx_int.hdr.is_valid wrong value"; + assert ip_rx_hdr.is_valid = '0' report "T1: ip_rx_hdr.is_valid wrong value"; + + -- check we tx a response + + wait for clk_period*25; + assert mac_tx_tvalid = '1' report "T1: not transmitting a response"; + wait for clk_period*25; + assert mac_tx_tvalid = '0' report "T1: tx held on for too long"; + + ------------ + -- TEST 2 -- send UDP pkt (same as sample from Java program) + ------------ + + report "T2: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T2: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T2: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T2: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T2: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T2: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T2: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T2: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T2: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T2: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T2: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T2: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T2: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T2: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + assert udp_rx_int.data.data_in_valid = '0' report "T2: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T2: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T2: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T2: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T2: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"01" report "T2: ip pkt cnt incorrect"; + + wait for clk_period*20; + + ------------ + -- TEST 3 -- send UDP pkt again (same as sample from Java program) + ------------ + + report "T3: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T3: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T3: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T3: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T3: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T3: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T3: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T3: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T3: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T3: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T3: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T3: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T3: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T3: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + assert udp_rx_int.data.data_in_valid = '0' report "T3: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T3: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T3: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T3: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T3: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"02" report "T3: ip pkt cnt incorrect"; + + wait for clk_period*50; + + ------------ + -- TEST 4 -- send UDP pkt with specific UDP data to force a broadcast tx in reply + ------------ + + report "T4: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"42"; wait for clk_period; -- First byte 'B' triggers a reply to broadcast addr + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T4: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T4: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T4: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T4: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T4: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T4: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T4: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T4: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T4: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T4: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T4: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T4: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T4: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + report "T4: waiting for mac data tx"; + wait until mac_tx_tvalid = '1'; + report "T4: starting mac data tx"; + wait for clk_period; + + -- check the mac data being transmitted + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T4: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T4: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T4: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T4: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T4: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T4: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T4: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"45" report "T4: incorrect ver.hlen"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect srv type"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect len 0"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T4: incorrect len 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T4: incorrect ident 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect ident 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect flag&frag 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect flag&frag 1"; wait for clk_period; + + assert mac_tx_tdata = x"80" report "T4: incorrect TTL"; wait for clk_period; + assert mac_tx_tdata = x"11" report "T4: incorrect protocol"; wait for clk_period; + assert mac_tx_tdata = x"75" report "T4: incorrect hdr.cks 0"; wait for clk_period; + assert mac_tx_tdata = x"1c" report "T4: incorrect hdr.cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T4: incorrect src ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T4: incorrect src ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T4: incorrect src ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T4: incorrect src ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 0"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 1"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 2"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T4: incorrect dst ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"26" report "T4: incorrect src port 0"; wait for clk_period; + assert mac_tx_tdata = x"94" report "T4: incorrect src port 1"; wait for clk_period; + assert mac_tx_tdata = x"f4" report "T4: incorrect dst port 0"; wait for clk_period; + assert mac_tx_tdata = x"9a" report "T4: incorrect dst port 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T4: incorrect udp len 0"; wait for clk_period; + assert mac_tx_tdata = x"0c" report "T4: incorrect udp len 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect udp cks 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T4: incorrect udp cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"40" report "T4: incorrect udp data 0"; wait for clk_period; + assert mac_tx_tdata = x"41" report "T4: incorrect udp data 1"; wait for clk_period; + + assert mac_tx_tdata = x"42" report "T4: incorrect udp data 2"; + assert mac_tx_tlast = '0' report "T4: tlast asserted too soon"; wait for clk_period; + assert mac_tx_tdata = x"43" report "T4: incorrect udp data 3"; + assert mac_tx_tlast = '1' report "T4: tlast not asserted"; wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENT report "T4: TX did not complete"; + + assert udp_rx_int.data.data_in_valid = '0' report "T4: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T4: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T4: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T4: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T4: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"03" report "T4: ip pkt cnt incorrect"; + + ------------ + -- TEST 5 -- send UDP pkt with dst=bc addr to ensure we can receive broadcast tx + ------------ + + report "T5: Send UDP IP pkt dst ip_address bc, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T5: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T5: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T5: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T5: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T5: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T5: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T5: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T5: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T5: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T5: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T5: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T5: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T5: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + + report "T5: waiting for mac data tx"; + if mac_tx_tvalid = '0' then + wait until mac_tx_tvalid = '1'; + wait for clk_period; + end if; + report "T5: starting mac data tx"; + + -- check the mac data being transmitted + assert mac_tx_tdata = x"00" report "T5: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T5: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"18" report "T5: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"29" report "T5: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"26" report "T5: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"7c" report "T5: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T5: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T5: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T5: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T5: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T5: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T5: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T5: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"45" report "T5: incorrect ver.hlen"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect srv type"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect len 0"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T5: incorrect len 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T5: incorrect ident 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect ident 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect flag&frag 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect flag&frag 1"; wait for clk_period; + + assert mac_tx_tdata = x"80" report "T5: incorrect TTL"; wait for clk_period; + assert mac_tx_tdata = x"11" report "T5: incorrect protocol"; wait for clk_period; + assert mac_tx_tdata = x"af" report "T5: incorrect hdr.cks 0"; wait for clk_period; + assert mac_tx_tdata = x"72" report "T5: incorrect hdr.cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T5: incorrect src ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T5: incorrect src ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T5: incorrect src ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T5: incorrect src ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T5: incorrect dst ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T5: incorrect dst ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T5: incorrect dst ip 2"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T5: incorrect dst ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"26" report "T5: incorrect src port 0"; wait for clk_period; + assert mac_tx_tdata = x"94" report "T5: incorrect src port 1"; wait for clk_period; + assert mac_tx_tdata = x"f4" report "T5: incorrect dst port 0"; wait for clk_period; + assert mac_tx_tdata = x"9a" report "T5: incorrect dst port 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T5: incorrect udp len 0"; wait for clk_period; + assert mac_tx_tdata = x"0c" report "T5: incorrect udp len 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect udp cks 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T5: incorrect udp cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"50" report "T5: incorrect udp data 0"; wait for clk_period; + assert mac_tx_tdata = x"51" report "T5: incorrect udp data 1"; wait for clk_period; + + assert mac_tx_tdata = x"52" report "T5: incorrect udp data 2"; + assert mac_tx_tlast = '0' report "T5: tlast asserted too soon"; wait for clk_period; + assert mac_tx_tdata = x"53" report "T5: incorrect udp data 3"; + assert mac_tx_tlast = '1' report "T5: tlast not asserted"; wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENT report "T5: TX did not complete"; + + assert udp_rx_int.data.data_in_valid = '0' report "T5: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T5: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T5: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T5: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T5: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"04" report "T5: ip pkt cnt incorrect"; + + + ------------ + -- TEST 6 -- send UDP pkt with data to trigger the sending of a pkt to unknown IP addr to force an ARP timeout + ------------ + + report "T6: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694 with data x43 to trig tx to unknown IP"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"43"; wait for clk_period; -- First byte 'C' triggers a reply to unknown addr + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T6: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T6: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T6: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T6: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T6: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T6: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T6: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T6: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T6: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T6: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T6: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T6: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T6: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + report "T6: waiting for mac data tx"; + wait until mac_tx_tvalid = '1'; + report "T6: starting mac data tx"; + wait for clk_period; + + -- check the mac data being transmitted is valid ARP request + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"ff" report "T6: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T6: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T6: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T6: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T6: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T6: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"06" report "T6: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T6: incorrect HW type.0"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T6: incorrect HW type.1"; wait for clk_period; + assert mac_tx_tdata = x"08" report "T6: incorrect prot.0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T6: incorrect prot.1"; wait for clk_period; + assert mac_tx_tdata = x"06" report "T6: incorrect HW size"; wait for clk_period; + assert mac_tx_tdata = x"04" report "T6: incorrect prot size"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T6: incorrect opcode.0"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T6: incorrect opcode.1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T6: incorrect sndr mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect sndr mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T6: incorrect sndr mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T6: incorrect sndr mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T6: incorrect sndr mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T6: incorrect sndr mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T6: incorrect sndr ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T6: incorrect sndr ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T6: incorrect sndr ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T6: incorrect sndr ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"FF" report "T6: incorrect trg mac 0"; wait for clk_period; + assert mac_tx_tdata = x"FF" report "T6: incorrect trg mac 1"; wait for clk_period; + assert mac_tx_tdata = x"FF" report "T6: incorrect trg mac 2"; wait for clk_period; + assert mac_tx_tdata = x"FF" report "T6: incorrect trg mac 3"; wait for clk_period; + assert mac_tx_tdata = x"FF" report "T6: incorrect trg mac 4"; wait for clk_period; + assert mac_tx_tdata = x"FF" report "T6: incorrect trg mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T6: incorrect trg ip 0"; wait for clk_period; + assert mac_tx_tdata = x"bb" report "T6: incorrect trg ip 1"; wait for clk_period; + assert mac_tx_tdata = x"cc" report "T6: incorrect trg ip 2"; + assert mac_tx_tlast = '0' report "T6: tlast asserted too soon"; + wait for clk_period; + + assert mac_tx_tdata = x"dd" report "T6: incorrect trg ip 3"; + assert mac_tx_tlast = '1' report "T6: tlast should be set"; + wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENDING report "T6: TX should still be in sending phase"; + + assert udp_rx_int.data.data_in_valid = '0' report "T6: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T6: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T6: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T6: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T6: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"05" report "T6: ip pkt cnt incorrect"; + + -- check for error on tx as a result of ARP timeout + + wait for clk_period*10*20; + assert udp_tx_result = IPTX_RESULT_ERR report "T6: TX should resulkt in error (arp timeout)"; + + wait for clk_period*10; + + ------------ + -- TEST 7 -- send UDP pkt again to ensure that we can rx a pkt and tx after a timeout + ------------ + + report "T7: Send UDP IP pkt dst ip_address c0a80509, from port f49a to port 2694"; + + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"7a"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"80"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + -- SRC port + mac_rx_tdata <= x"f4"; wait for clk_period; + mac_rx_tdata <= x"9a"; wait for clk_period; + -- DST port + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"94"; wait for clk_period; + -- length + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"0d"; wait for clk_period; + -- cks + mac_rx_tdata <= x"8b"; wait for clk_period; + mac_rx_tdata <= x"79"; wait for clk_period; + -- user data + mac_rx_tdata <= x"68"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert udp_rx_int.hdr.is_valid = '1' report "T7: udp_rx_int.hdr.is_valid not set"; + assert udp_rx_int.hdr.data_length = x"0005" report "T7: udp_rx_int.hdr.data_length not set correctly"; + assert udp_rx_int.hdr.src_ip_addr = x"c0a80501" report "T7: udp_rx_int.hdr.src_ip_addr not set correctly"; + assert udp_rx_int.hdr.src_port = x"f49a" report "T7: udp_rx_int.hdr.src_port not set correctly"; + assert udp_rx_int.hdr.dst_port = x"2694" report "T7: udp_rx_int.hdr.dst_port not set correctly"; + + assert udp_rx_start_int = '1' report "T7: udp_rx_start not set"; + assert udp_rx_int.data.data_in_valid = '1' report "T7: udp_rx_int.data.data_in_valid not set"; + + assert ip_rx_hdr.is_valid = '1' report "T7: ip_rx_hdr.is_valid not set"; + assert ip_rx_hdr.protocol = x"11" report "T7: ip_rx_hdr.protocol not set correctly"; + assert ip_rx_hdr.src_ip_addr = x"c0a80501" report "T7: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T7: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx_hdr.last_error_code = x"0" report "T7: ip_rx.hdr.last_error_code not set correctly"; + + -- put the rest of the user data + mac_rx_tdata <= x"65"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6c"; wait for clk_period; + mac_rx_tdata <= x"6f"; mac_rx_tlast <= '1'; wait for clk_period; + + assert udp_rx_int.data.data_in_last = '1' report "T7: udp_rx_int.data.data_in_last not set"; + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period*2; + + -- the mac address will be cached, so udp tx should occur straight away + assert udp_tx_result = IPTX_RESULT_SENDING report "T7: TX should be sending"; + + report "T7: waiting for mac data tx"; + if mac_tx_tvalid = '0' then + wait until mac_tx_tvalid = '1'; + wait for clk_period; + end if; + report "T7: starting mac data tx"; + + -- check the mac data being transmitted + assert mac_tx_tdata = x"00" report "T7: incorrect dst mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T7: incorrect dst mac 1"; wait for clk_period; + assert mac_tx_tdata = x"18" report "T7: incorrect dst mac 2"; wait for clk_period; + assert mac_tx_tdata = x"29" report "T7: incorrect dst mac 3"; wait for clk_period; + assert mac_tx_tdata = x"26" report "T7: incorrect dst mac 4"; wait for clk_period; + assert mac_tx_tdata = x"7c" report "T7: incorrect dst mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T7: incorrect src mac 0"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T7: incorrect src mac 1"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T7: incorrect src mac 2"; wait for clk_period; + assert mac_tx_tdata = x"21" report "T7: incorrect src mac 3"; wait for clk_period; + assert mac_tx_tdata = x"22" report "T7: incorrect src mac 4"; wait for clk_period; + assert mac_tx_tdata = x"23" report "T7: incorrect src mac 5"; wait for clk_period; + + assert mac_tx_tdata = x"08" report "T7: incorrect pkt_type 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect pkt type 1"; wait for clk_period; + + assert mac_tx_tdata = x"45" report "T7: incorrect ver.hlen"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect srv type"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect len 0"; wait for clk_period; + assert mac_tx_tdata = x"20" report "T7: incorrect len 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T7: incorrect ident 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect ident 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect flag&frag 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect flag&frag 1"; wait for clk_period; + + assert mac_tx_tdata = x"80" report "T7: incorrect TTL"; wait for clk_period; + assert mac_tx_tdata = x"11" report "T7: incorrect protocol"; wait for clk_period; + assert mac_tx_tdata = x"af" report "T7: incorrect hdr.cks 0"; wait for clk_period; + assert mac_tx_tdata = x"72" report "T7: incorrect hdr.cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T7: incorrect src ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T7: incorrect src ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T7: incorrect src ip 2"; wait for clk_period; + assert mac_tx_tdata = x"09" report "T7: incorrect src ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"c0" report "T7: incorrect dst ip 0"; wait for clk_period; + assert mac_tx_tdata = x"a8" report "T7: incorrect dst ip 1"; wait for clk_period; + assert mac_tx_tdata = x"05" report "T7: incorrect dst ip 2"; wait for clk_period; + assert mac_tx_tdata = x"01" report "T7: incorrect dst ip 3"; wait for clk_period; + + assert mac_tx_tdata = x"26" report "T7: incorrect src port 0"; wait for clk_period; + assert mac_tx_tdata = x"94" report "T7: incorrect src port 1"; wait for clk_period; + assert mac_tx_tdata = x"f4" report "T7: incorrect dst port 0"; wait for clk_period; + assert mac_tx_tdata = x"9a" report "T7: incorrect dst port 1"; wait for clk_period; + + assert mac_tx_tdata = x"00" report "T7: incorrect udp len 0"; wait for clk_period; + assert mac_tx_tdata = x"0c" report "T7: incorrect udp len 1"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect udp cks 0"; wait for clk_period; + assert mac_tx_tdata = x"00" report "T7: incorrect udp cks 1"; wait for clk_period; + + assert mac_tx_tdata = x"40" report "T7: incorrect udp data 0"; wait for clk_period; + assert mac_tx_tdata = x"41" report "T7: incorrect udp data 1"; wait for clk_period; + + assert mac_tx_tdata = x"42" report "T7: incorrect udp data 2"; + assert mac_tx_tlast = '0' report "T7: tlast asserted too soon"; wait for clk_period; + assert mac_tx_tdata = x"43" report "T7: incorrect udp data 3"; + assert mac_tx_tlast = '1' report "T7: tlast not asserted"; wait for clk_period; + + assert udp_tx_result = IPTX_RESULT_SENT report "T7: TX did not complete"; + + assert udp_rx_int.data.data_in_valid = '0' report "T7: udp_rx_int.data.data_in_valid not cleared"; + assert udp_rx_int.data.data_in_last = '0' report "T7: udp_rx_int.data.data_in_last not cleared"; + assert udp_rx_start_int = '0' report "T7: udp_rx_start not cleared"; + assert ip_rx_hdr.num_frame_errors = x"00" report "T7: ip_rx_hdr.num_frame_errors non zero at end of test"; + assert ip_rx_hdr.last_error_code = x"0" report "T7: ip_rx_hdr.last_error_code indicates error at end of test"; + assert ip_pkt_count = x"06" report "T7: ip pkt cnt incorrect"; + + + + report "--- end of tests ---"; + wait; + end process; + + -- AUTO TX process - on receipt of any UDP pkt, send a response. data sent is modified if a broadcast was received. + + -- TX response process - COMB + tx_proc_combinatorial: process( + -- inputs + udp_rx_start_int, udp_rx_int, udp_tx_data_out_ready_int, udp_tx_result, ip_rx_hdr, + udp_tx_int.data.data_out_valid, PBTX, + -- state + state, count, tx_hdr, tx_start_reg, tx_started_reg, tx_fin_reg, + -- controls + next_state, set_state, set_count, set_hdr, set_tx_start, set_last, + set_tx_started, set_tx_fin, first_byte_rx + ) + begin + -- set output_followers + udp_tx_int.hdr <= tx_hdr; + udp_tx_int.data.data_out_last <= set_last; + udp_tx_start_int <= tx_start_reg; + + -- set control signal defaults + next_state <= IDLE; + set_state <= '0'; + set_count <= HOLD; + set_hdr <= '0'; + set_tx_start <= HOLD; + set_last <= '0'; + set_tx_started <= HOLD; + set_tx_fin <= HOLD; + first_byte_rx <= (others => '0'); + + -- FSM + case state is + + when IDLE => + udp_tx_int.data.data_out <= (others => '0'); + udp_tx_int.data.data_out_valid <= '0'; + if udp_rx_start_int = '1' or PBTX = '1' then + if udp_rx_start_int = '1' then + first_byte_rx <= udp_rx_int.data.data_in; + else + first_byte_rx <= x"00"; + end if; + set_tx_fin <= CLR; + set_count <= RST; + set_hdr <= '1'; + if udp_rx_int.data.data_in_last = '1' then + set_tx_started <= SET; + set_tx_start <= SET; + next_state <= DATA_OUT; + set_state <= '1'; + else + next_state <= WAIT_RX_DONE; + set_state <= '1'; + end if; + end if; + + when WAIT_RX_DONE => + -- wait until RX pkt fully received + if udp_rx_int.data.data_in_last = '1' then + set_tx_started <= SET; + set_tx_start <= SET; + next_state <= DATA_OUT; + set_state <= '1'; + end if; + + when DATA_OUT => + if udp_tx_result = UDPTX_RESULT_ERR then + -- have an error from the IP TX layer, clear down the TX + set_tx_start <= CLR; + set_tx_fin <= SET; + set_tx_started <= CLR; + next_state <= IDLE; + set_state <= '1'; + else + if udp_tx_result = UDPTX_RESULT_SENDING then + set_tx_start <= CLR; -- reset out start req as soon as we know we are sending + end if; + if ip_rx_hdr.is_broadcast = '1' then + udp_tx_int.data.data_out <= std_logic_vector(count) or x"50"; + else + udp_tx_int.data.data_out <= std_logic_vector(count) or x"40"; + end if; + udp_tx_int.data.data_out_valid <= udp_tx_data_out_ready_int; + if udp_tx_data_out_ready_int = '1' then + if unsigned(count) = x"03" then + set_last <= '1'; + set_tx_fin <= SET; + set_tx_started <= CLR; + next_state <= IDLE; + set_state <= '1'; + else + set_count <= INCR; + end if; + end if; + end if; + + end case; + end process; + + + + -- TX response process - SEQ + tx_proc_sequential: process(clk_int) + begin + if rising_edge(clk_int) then + if reset = '1' then + -- reset state variables + state <= IDLE; + count <= x"00"; + tx_start_reg <= '0'; + tx_hdr.dst_ip_addr <= (others => '0'); + tx_hdr.dst_port <= (others => '0'); + tx_hdr.src_port <= (others => '0'); + tx_hdr.data_length <= (others => '0'); + tx_hdr.checksum <= (others => '0'); + tx_started_reg <= '0'; + tx_fin_reg <= '0'; + PBTX_LED <= '0'; + else + PBTX_LED <= PBTX; + + -- Next rx_state processing + if set_state = '1' then + state <= next_state; + else + state <= state; + end if; + + -- count processing + case set_count is + when RST => count <= x"00"; + when INCR => count <= count + 1; + when HOLD => count <= count; + end case; + + -- set tx hdr + if set_hdr = '1' then + -- if the first byte of the rx pkt is 'B' then send to broadcast, otherwise send to reply IP + if first_byte_rx = x"42" then + tx_hdr.dst_ip_addr <= IP_BC_ADDR; -- send to Broadcast addr + elsif first_byte_rx = x"43" then + tx_hdr.dst_ip_addr <= x"c0bbccdd"; -- set dst unknown so get ARP timeout + else + tx_hdr.dst_ip_addr <= udp_rx_int.hdr.src_ip_addr; -- reply to sender + end if; + tx_hdr.dst_port <= udp_rx_int.hdr.src_port; + tx_hdr.src_port <= udp_rx_int.hdr.dst_port; + tx_hdr.data_length <= x"0004"; + tx_hdr.checksum <= x"0000"; + else + tx_hdr <= tx_hdr; + end if; + + -- set tx start signal + case set_tx_start is + when SET => tx_start_reg <= '1'; + when CLR => tx_start_reg <= '0'; + when HOLD => tx_start_reg <= tx_start_reg; + end case; + + -- set tx started signal + case set_tx_started is + when SET => tx_started_reg <= '1'; + when CLR => tx_started_reg <= '0'; + when HOLD => tx_started_reg <= tx_started_reg; + end case; + + -- set tx finished signal + case set_tx_fin is + when SET => tx_fin_reg <= '1'; + when CLR => tx_fin_reg <= '0'; + when HOLD => tx_fin_reg <= tx_fin_reg; + end case; + + + end if; + end if; + + end process; + +END; Index: tags/v2.3/bench/vhdl/IP_av2_complete_nomac_tb .vhd =================================================================== --- tags/v2.3/bench/vhdl/IP_av2_complete_nomac_tb .vhd (nonexistent) +++ tags/v2.3/bench/vhdl/IP_av2_complete_nomac_tb .vhd (revision 25) @@ -0,0 +1,451 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 13:54:32 06/04/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/ip1/IP_complete_nomac_tb.vhd +-- Project Name: ip1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: IP_complete_nomac +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.axi.all; +use work.ipv4_types.all; +use work.arp_types.all; +use work.arp; +use work.arpv2; + + +ENTITY IP_av2_complete_nomac_tb IS +END IP_av2_complete_nomac_tb; + + + +--configuration main of IP_av2_complete_nomac_tb is +-- for behavior +-- for uut : IP_complete_nomac +-- use configuration work.IP_complete_nomac.multi_slot_arp; +-- end for; +-- end for; +--end main; + +ARCHITECTURE behavior OF IP_av2_complete_nomac_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT IP_complete_nomac + generic ( + CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr + ARP_TIMEOUT : integer := 60 -- ARP response timeout (s) + ); + Port ( + -- IP Layer signals + ip_tx_start : in std_logic; + 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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data + ip_rx_start : out std_logic; -- indicates receipt of ip frame. + ip_rx : out ipv4_rx_type; + -- system signals + rx_clk : in STD_LOGIC; + tx_clk : in STD_LOGIC; + reset : in STD_LOGIC; + our_ip_address : in STD_LOGIC_VECTOR (31 downto 0); + our_mac_address : in std_logic_vector (47 downto 0); + control : in ip_control_type; + -- status signals + arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received + ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us + -- MAC Transmitter + mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx + mac_tx_tvalid : out std_logic; -- tdata is valid + mac_tx_tready : in std_logic; -- mac is ready to accept data + mac_tx_tfirst : out std_logic; -- indicates first byte of frame + mac_tx_tlast : out std_logic; -- indicates last byte of frame + -- MAC Receiver + mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received + mac_rx_tvalid : in std_logic; -- indicates tdata is valid + mac_rx_tready : out std_logic; -- tells mac that we are ready to take data + mac_rx_tlast : in std_logic -- indicates last byte of the trame + ); + END COMPONENT; + + + --Inputs + signal ip_tx_start : std_logic := '0'; + signal ip_tx : ipv4_tx_type; + + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal our_mac_address : std_logic_vector(47 downto 0) := (others => '0'); + signal mac_tx_tready : std_logic := '0'; + signal mac_rx_tdata : std_logic_vector(7 downto 0) := (others => '0'); + signal mac_rx_tvalid : std_logic := '0'; + signal mac_rx_tlast : std_logic := '0'; + signal control : ip_control_type; + + --Outputs + signal ip_tx_result : std_logic_vector (1 downto 0); -- tx status (changes during transmission) + signal ip_tx_data_out_ready : std_logic; -- indicates IP TX is ready to take data + signal ip_rx_start : std_logic; + signal ip_rx : ipv4_rx_type; + signal arp_pkt_count : std_logic_vector(7 downto 0); + signal mac_tx_tdata : std_logic_vector(7 downto 0); + signal mac_tx_tvalid : std_logic; + signal mac_tx_tfirst : std_logic; + signal mac_tx_tlast : std_logic; + signal mac_rx_tready : std_logic; + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: IP_complete_nomac PORT MAP ( + ip_tx_start => ip_tx_start, + ip_tx => ip_tx, + ip_tx_result => ip_tx_result, + ip_tx_data_out_ready => ip_tx_data_out_ready, + ip_rx_start => ip_rx_start, + ip_rx => ip_rx, + rx_clk => clk, + tx_clk => clk, + reset => reset, + our_ip_address => our_ip_address, + our_mac_address => our_mac_address, + control => control, + arp_pkt_count => arp_pkt_count, + mac_tx_tdata => mac_tx_tdata, + mac_tx_tvalid => mac_tx_tvalid, + mac_tx_tready => mac_tx_tready, + mac_tx_tfirst => mac_tx_tfirst, + mac_tx_tlast => mac_tx_tlast, + mac_rx_tdata => mac_rx_tdata, + mac_rx_tvalid => mac_rx_tvalid, + mac_rx_tready => mac_rx_tready, + mac_rx_tlast => mac_rx_tlast + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '1'; + wait for clk_period/2; + clk <= '0'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 80 ns; + + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + our_mac_address <= x"002320212223"; + control.arp_controls.clear_cache <= '0'; + ip_tx_start <= '0'; + mac_tx_tready <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + -- check reset conditions + assert ip_tx_result = IPTX_RESULT_NONE report "ip_tx_result not initialised correctly on reset"; + assert ip_tx_data_out_ready = '0' report "ip_tx_data_out_ready not initialised correctly on reset"; + assert mac_tx_tvalid = '0' report "mac_tx_tvalid not initialised correctly on reset"; + assert mac_tx_tlast = '0' report " mac_tx_tlast not initialised correctly on reset"; + assert arp_pkt_count = x"00" report " arp_pkt_count not initialised correctly on reset"; + assert ip_rx_start = '0' report "ip_rx_start not initialised correctly on reset"; + assert ip_rx.hdr.is_valid = '0' report "ip_rx.hdr.is_valid not initialised correctly on reset"; + assert ip_rx.hdr.protocol = x"00" report "ip_rx.hdr.protocol not initialised correctly on reset"; + assert ip_rx.hdr.data_length = x"0000" report "ip_rx.hdr.data_length not initialised correctly on reset"; + assert ip_rx.hdr.src_ip_addr = x"00000000" report "ip_rx.hdr.src_ip_addr not initialised correctly on reset"; + assert ip_rx.hdr.num_frame_errors = x"00" report "ip_rx.hdr.num_frame_errors not initialised correctly on reset"; + assert ip_rx.data.data_in = x"00" report "ip_rx.data.data_in not initialised correctly on reset"; + assert ip_rx.data.data_in_valid = '0' report "ip_rx.data.data_in_valid not initialised correctly on reset"; + assert ip_rx.data.data_in_last = '0' report "ip_rx.data.data_in_last not initialised correctly on reset"; + + -- insert stimulus here + + ------------ + -- TEST 1 -- basic functional rx test with received ip pkt + ------------ + + report "T1: Send an eth frame with IP pkt dst ip_address c0a80509, dst mac 002320212223"; + + mac_tx_tready <= '1'; + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"00"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + + -- user data + mac_rx_tdata <= x"24"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert ip_rx.hdr.is_valid = '1' report "T1: ip_rx.hdr.is_valid not set"; + assert ip_rx.hdr.protocol = x"11" report "T1: ip_rx.hdr.protocol not set correctly"; + assert ip_rx.hdr.data_length = x"0004" report "T1: ip_rx.hdr.data_length not set correctly"; + assert ip_rx.hdr.src_ip_addr = x"c0a80501" report "T1: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T1: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx.hdr.last_error_code = x"0" report "T1: ip_rx.hdr.last_error_code not set correctly"; + assert ip_rx_start = '1' report "T1: ip_rx_start not set"; + assert ip_rx.data.data_in_valid = '1' report "T1: ip_rx.data.data_in_valid not set"; + + mac_rx_tdata <= x"25"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"27"; mac_rx_tlast <= '1'; wait for clk_period; + + assert ip_rx.data.data_in_last = '1' report "T1: ip_rx.data.data_in_last not set"; + + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + assert ip_rx.data.data_in_valid = '0' report "T1: ip_rx.data.data_in_valid not cleared"; + assert ip_rx.data.data_in_last = '0' report "T1: ip_rx.data.data_in_last not cleared"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T1: ip_rx.hdr.num_frame_errors non zero at end of test"; + assert ip_rx.hdr.last_error_code = x"0" report "T1: ip_rx.hdr.last_error_code indicates error at end of test"; + assert ip_rx_start = '0' report "T1: ip_rx_start not cleared"; + + ------------ + -- TEST 2 -- respond with IP TX + ------------ + + report "T2: respond with IP TX"; + + ip_tx.hdr.protocol <= x"35"; + ip_tx.hdr.data_length <= x"0006"; + ip_tx.hdr.dst_ip_addr <= x"c0123478"; + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period; + + ip_tx_start <= '1'; wait for clk_period; + + ip_tx_start <= '0'; wait for clk_period; + + assert ip_tx_result = IPTX_RESULT_SENDING report "T2: result should be IPTX_RESULT_SENDING"; + + wait for clk_period*2; + + assert ip_tx_data_out_ready = '0' report "T2: IP data out ready asserted too early"; + + -- need to wait for ARP tx to complete + + wait for clk_period*50; + + assert mac_tx_tvalid = '0' report "T2: mac_tx_tvalid not cleared after ARP tx"; + assert mac_tx_tlast = '0' report "T2: mac_tx_tlast not cleared after ARP tx"; + + -- now create the ARP response (rx) + + -- Send the reply + -- Send an ARP reply: x"c0123478" has mac 02:12:03:23:04:54 + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"02"; wait for clk_period; + mac_rx_tdata <= x"12"; wait for clk_period; + mac_rx_tdata <= x"03"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"04"; wait for clk_period; + mac_rx_tdata <= x"54"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"06"; wait for clk_period; + -- HW type + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Protocol type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- HW size + mac_rx_tdata <= x"06"; wait for clk_period; + -- protocol size + mac_rx_tdata <= x"04"; wait for clk_period; + -- Opcode + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"02"; wait for clk_period; + -- Sender MAC + mac_rx_tdata <= x"02"; wait for clk_period; + mac_rx_tdata <= x"12"; wait for clk_period; + mac_rx_tdata <= x"03"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"04"; wait for clk_period; + mac_rx_tdata <= x"54"; wait for clk_period; + -- Sender IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"12"; wait for clk_period; + mac_rx_tdata <= x"34"; wait for clk_period; + mac_rx_tdata <= x"78"; wait for clk_period; + -- Target MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- Target IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '1'; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + + wait until ip_tx_data_out_ready = '1'; + + -- start to tx IP data + ip_tx.data.data_out_valid <= '1'; + ip_tx.data.data_out <= x"56"; wait for clk_period; + ip_tx.data.data_out <= x"57"; wait for clk_period; + ip_tx.data.data_out <= x"58"; wait for clk_period; + ip_tx.data.data_out <= x"59"; wait for clk_period; + ip_tx.data.data_out <= x"5a"; wait for clk_period; + + ip_tx.data.data_out <= x"5b"; + ip_tx.data.data_out_last <= '1'; + wait for clk_period; + + assert mac_tx_tlast = '1' report "T2: mac_tx_tlast not set on last byte"; + + wait for clk_period; + + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period*2; + + assert ip_tx_result = IPTX_RESULT_SENT report "T2: result should be SENT"; + wait for clk_period*10; + + ------------ + -- TEST 3 -- Check that sending to the same IP addr doesnt cause an ARP req as the addr is cached + ------------ + + report "T3: Send 2nd IP TX to same IP addr - should not need to do ARP tx/rx"; + ip_tx.hdr.protocol <= x"35"; + ip_tx.hdr.data_length <= x"0006"; + ip_tx.hdr.dst_ip_addr <= x"c0123478"; + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period; + ip_tx_start <= '1'; wait for clk_period; + ip_tx_start <= '0'; wait for clk_period; + assert ip_tx_result = IPTX_RESULT_SENDING report "T3: result should be IPTX_RESULT_SENDING"; + wait for clk_period*2; + assert ip_tx_data_out_ready = '0' report "T3: IP data out ready asserted too early"; + wait until ip_tx_data_out_ready = '1'; + + -- start to tx IP data + ip_tx.data.data_out_valid <= '1'; + ip_tx.data.data_out <= x"81"; wait for clk_period; + ip_tx.data.data_out <= x"83"; wait for clk_period; + ip_tx.data.data_out <= x"85"; wait for clk_period; + ip_tx.data.data_out <= x"87"; wait for clk_period; + ip_tx.data.data_out <= x"89"; wait for clk_period; + + ip_tx.data.data_out <= x"8b"; + ip_tx.data.data_out_last <= '1'; + wait for clk_period; + + assert mac_tx_tlast = '1' report "T3: mac_tx_tlast not set on last byte"; + + wait for clk_period; + + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period*2; + + assert ip_tx_result = IPTX_RESULT_SENT report "T3: result should be SENT"; + wait for clk_period*2; + + + + report "-- end of tests --"; + + wait; + end process; + +END; Index: tags/v2.3/bench/vhdl/IP_complete_nomac_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/IP_complete_nomac_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/IP_complete_nomac_tb.vhd (revision 25) @@ -0,0 +1,438 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 13:54:32 06/04/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/ip1/IP_complete_nomac_tb.vhd +-- Project Name: ip1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: IP_complete_nomac +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.axi.all; +use work.ipv4_types.all; +use work.arp_types.all; + +ENTITY IP_complete_nomac_tb IS +END IP_complete_nomac_tb; + +ARCHITECTURE behavior OF IP_complete_nomac_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT IP_complete_nomac + generic ( + CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr + ARP_TIMEOUT : integer := 60 -- ARP response timeout (s) + ); + Port ( + -- IP Layer signals + ip_tx_start : in std_logic; + 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_data_out_ready : out std_logic; -- indicates IP TX is ready to take data + ip_rx_start : out std_logic; -- indicates receipt of ip frame. + ip_rx : out ipv4_rx_type; + -- system signals + rx_clk : in STD_LOGIC; + tx_clk : in STD_LOGIC; + reset : in STD_LOGIC; + our_ip_address : in STD_LOGIC_VECTOR (31 downto 0); + our_mac_address : in std_logic_vector (47 downto 0); + control : in ip_control_type; + -- status signals + arp_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- count of arp pkts received + ip_pkt_count : out STD_LOGIC_VECTOR(7 downto 0); -- number of IP pkts received for us + -- MAC Transmitter + mac_tx_tdata : out std_logic_vector(7 downto 0); -- data byte to tx + mac_tx_tvalid : out std_logic; -- tdata is valid + mac_tx_tready : in std_logic; -- mac is ready to accept data + mac_tx_tfirst : out std_logic; -- indicates first byte of frame + mac_tx_tlast : out std_logic; -- indicates last byte of frame + -- MAC Receiver + mac_rx_tdata : in std_logic_vector(7 downto 0); -- data byte received + mac_rx_tvalid : in std_logic; -- indicates tdata is valid + mac_rx_tready : out std_logic; -- tells mac that we are ready to take data + mac_rx_tlast : in std_logic -- indicates last byte of the trame + ); + END COMPONENT; + + + --Inputs + signal ip_tx_start : std_logic := '0'; + signal ip_tx : ipv4_tx_type; + + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal our_mac_address : std_logic_vector(47 downto 0) := (others => '0'); + signal mac_tx_tready : std_logic := '0'; + signal mac_rx_tdata : std_logic_vector(7 downto 0) := (others => '0'); + signal mac_rx_tvalid : std_logic := '0'; + signal mac_rx_tlast : std_logic := '0'; + signal control : ip_control_type; + + --Outputs + signal ip_tx_result : std_logic_vector (1 downto 0); -- tx status (changes during transmission) + signal ip_tx_data_out_ready : std_logic; -- indicates IP TX is ready to take data + signal ip_rx_start : std_logic; + signal ip_rx : ipv4_rx_type; + signal arp_pkt_count : std_logic_vector(7 downto 0); + signal mac_tx_tdata : std_logic_vector(7 downto 0); + signal mac_tx_tvalid : std_logic; + signal mac_tx_tfirst : std_logic; + signal mac_tx_tlast : std_logic; + signal mac_rx_tready : std_logic; + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: IP_complete_nomac PORT MAP ( + ip_tx_start => ip_tx_start, + ip_tx => ip_tx, + ip_tx_result => ip_tx_result, + ip_tx_data_out_ready => ip_tx_data_out_ready, + ip_rx_start => ip_rx_start, + ip_rx => ip_rx, + rx_clk => clk, + tx_clk => clk, + reset => reset, + our_ip_address => our_ip_address, + our_mac_address => our_mac_address, + control => control, + arp_pkt_count => arp_pkt_count, + mac_tx_tdata => mac_tx_tdata, + mac_tx_tvalid => mac_tx_tvalid, + mac_tx_tready => mac_tx_tready, + mac_tx_tfirst => mac_tx_tfirst, + mac_tx_tlast => mac_tx_tlast, + mac_rx_tdata => mac_rx_tdata, + mac_rx_tvalid => mac_rx_tvalid, + mac_rx_tready => mac_rx_tready, + mac_rx_tlast => mac_rx_tlast + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '1'; + wait for clk_period/2; + clk <= '0'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 80 ns; + + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + our_mac_address <= x"002320212223"; + control.arp_controls.clear_cache <= '0'; + ip_tx_start <= '0'; + mac_tx_tready <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + -- check reset conditions + assert ip_tx_result = IPTX_RESULT_NONE report "ip_tx_result not initialised correctly on reset"; + assert ip_tx_data_out_ready = '0' report "ip_tx_data_out_ready not initialised correctly on reset"; + assert mac_tx_tvalid = '0' report "mac_tx_tvalid not initialised correctly on reset"; + assert mac_tx_tlast = '0' report " mac_tx_tlast not initialised correctly on reset"; + assert arp_pkt_count = x"00" report " arp_pkt_count not initialised correctly on reset"; + assert ip_rx_start = '0' report "ip_rx_start not initialised correctly on reset"; + assert ip_rx.hdr.is_valid = '0' report "ip_rx.hdr.is_valid not initialised correctly on reset"; + assert ip_rx.hdr.protocol = x"00" report "ip_rx.hdr.protocol not initialised correctly on reset"; + assert ip_rx.hdr.data_length = x"0000" report "ip_rx.hdr.data_length not initialised correctly on reset"; + assert ip_rx.hdr.src_ip_addr = x"00000000" report "ip_rx.hdr.src_ip_addr not initialised correctly on reset"; + assert ip_rx.hdr.num_frame_errors = x"00" report "ip_rx.hdr.num_frame_errors not initialised correctly on reset"; + assert ip_rx.data.data_in = x"00" report "ip_rx.data.data_in not initialised correctly on reset"; + assert ip_rx.data.data_in_valid = '0' report "ip_rx.data.data_in_valid not initialised correctly on reset"; + assert ip_rx.data.data_in_last = '0' report "ip_rx.data.data_in_last not initialised correctly on reset"; + + -- insert stimulus here + + ------------ + -- TEST 1 -- basic functional rx test with received ip pkt + ------------ + + report "T1: Send an eth frame with IP pkt dst ip_address c0a80509, dst mac 002320212223"; + + mac_tx_tready <= '1'; + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + mac_rx_tdata <= x"29"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"7c"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; -- IP pkt + mac_rx_tdata <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_rx_tdata <= x"45"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- total len + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"18"; wait for clk_period; + -- ID + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- flags & frag + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- TTL + mac_rx_tdata <= x"00"; wait for clk_period; + -- Protocol + mac_rx_tdata <= x"11"; wait for clk_period; + -- Header CKS + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- SRC IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- DST IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + + -- user data + mac_rx_tdata <= x"24"; wait for clk_period; + + -- since we are up to the user data stage, the header should be valid and the data_in_valid should be set + assert ip_rx.hdr.is_valid = '1' report "T1: ip_rx.hdr.is_valid not set"; + assert ip_rx.hdr.protocol = x"11" report "T1: ip_rx.hdr.protocol not set correctly"; + assert ip_rx.hdr.data_length = x"0004" report "T1: ip_rx.hdr.data_length not set correctly"; + assert ip_rx.hdr.src_ip_addr = x"c0a80501" report "T1: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T1: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx.hdr.last_error_code = x"0" report "T1: ip_rx.hdr.last_error_code not set correctly"; + assert ip_rx_start = '1' report "T1: ip_rx_start not set"; + assert ip_rx.data.data_in_valid = '1' report "T1: ip_rx.data.data_in_valid not set"; + + mac_rx_tdata <= x"25"; wait for clk_period; + mac_rx_tdata <= x"26"; wait for clk_period; + mac_rx_tdata <= x"27"; mac_rx_tlast <= '1'; wait for clk_period; + + assert ip_rx.data.data_in_last = '1' report "T1: ip_rx.data.data_in_last not set"; + + + mac_rx_tdata <= x"00"; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + wait for clk_period; + + assert ip_rx.data.data_in_valid = '0' report "T1: ip_rx.data.data_in_valid not cleared"; + assert ip_rx.data.data_in_last = '0' report "T1: ip_rx.data.data_in_last not cleared"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T1: ip_rx.hdr.num_frame_errors non zero at end of test"; + assert ip_rx.hdr.last_error_code = x"0" report "T1: ip_rx.hdr.last_error_code indicates error at end of test"; + assert ip_rx_start = '0' report "T1: ip_rx_start not cleared"; + + ------------ + -- TEST 2 -- respond with IP TX + ------------ + + report "T2: respond with IP TX"; + + ip_tx.hdr.protocol <= x"35"; + ip_tx.hdr.data_length <= x"0006"; + ip_tx.hdr.dst_ip_addr <= x"c0123478"; + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period; + + ip_tx_start <= '1'; wait for clk_period; + + ip_tx_start <= '0'; wait for clk_period; + + assert ip_tx_result = IPTX_RESULT_SENDING report "T2: result should be IPTX_RESULT_SENDING"; + + wait for clk_period*2; + + assert ip_tx_data_out_ready = '0' report "T2: IP data out ready asserted too early"; + + -- need to wait for ARP tx to complete + + wait for clk_period*50; + + assert mac_tx_tvalid = '0' report "T2: mac_tx_tvalid not cleared after ARP tx"; + assert mac_tx_tlast = '0' report "T2: mac_tx_tlast not cleared after ARP tx"; + + -- now create the ARP response (rx) + + -- Send the reply + -- Send an ARP reply: x"c0123478" has mac 02:12:03:23:04:54 + mac_rx_tvalid <= '1'; + -- dst MAC (bc) + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + mac_rx_tdata <= x"ff"; wait for clk_period; + -- src MAC + mac_rx_tdata <= x"02"; wait for clk_period; + mac_rx_tdata <= x"12"; wait for clk_period; + mac_rx_tdata <= x"03"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"04"; wait for clk_period; + mac_rx_tdata <= x"54"; wait for clk_period; + -- type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"06"; wait for clk_period; + -- HW type + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"01"; wait for clk_period; + -- Protocol type + mac_rx_tdata <= x"08"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + -- HW size + mac_rx_tdata <= x"06"; wait for clk_period; + -- protocol size + mac_rx_tdata <= x"04"; wait for clk_period; + -- Opcode + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"02"; wait for clk_period; + -- Sender MAC + mac_rx_tdata <= x"02"; wait for clk_period; + mac_rx_tdata <= x"12"; wait for clk_period; + mac_rx_tdata <= x"03"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"04"; wait for clk_period; + mac_rx_tdata <= x"54"; wait for clk_period; + -- Sender IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"12"; wait for clk_period; + mac_rx_tdata <= x"34"; wait for clk_period; + mac_rx_tdata <= x"78"; wait for clk_period; + -- Target MAC + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + mac_rx_tdata <= x"20"; wait for clk_period; + mac_rx_tdata <= x"21"; wait for clk_period; + mac_rx_tdata <= x"22"; wait for clk_period; + mac_rx_tdata <= x"23"; wait for clk_period; + -- Target IP + mac_rx_tdata <= x"c0"; wait for clk_period; + mac_rx_tdata <= x"a8"; wait for clk_period; + mac_rx_tdata <= x"05"; wait for clk_period; + mac_rx_tdata <= x"09"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '1'; + mac_rx_tdata <= x"00"; wait for clk_period; + mac_rx_tlast <= '0'; + mac_rx_tvalid <= '0'; + + wait until ip_tx_data_out_ready = '1'; + + -- start to tx IP data + ip_tx.data.data_out_valid <= '1'; + ip_tx.data.data_out <= x"56"; wait for clk_period; + ip_tx.data.data_out <= x"57"; wait for clk_period; + ip_tx.data.data_out <= x"58"; wait for clk_period; + ip_tx.data.data_out <= x"59"; wait for clk_period; + ip_tx.data.data_out <= x"5a"; wait for clk_period; + + ip_tx.data.data_out <= x"5b"; + ip_tx.data.data_out_last <= '1'; + wait for clk_period; + + assert mac_tx_tlast = '1' report "T2: mac_tx_tlast not set on last byte"; + + wait for clk_period; + + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period*2; + + assert ip_tx_result = IPTX_RESULT_SENT report "T2: result should be SENT"; + wait for clk_period*10; + + ------------ + -- TEST 3 -- Check that sending to the same IP addr doesnt cause an ARP req as the addr is cached + ------------ + + report "T3: Send 2nd IP TX to same IP addr - should not need to do ARP tx/rx"; + ip_tx.hdr.protocol <= x"35"; + ip_tx.hdr.data_length <= x"0006"; + ip_tx.hdr.dst_ip_addr <= x"c0123478"; + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period; + ip_tx_start <= '1'; wait for clk_period; + ip_tx_start <= '0'; wait for clk_period; + assert ip_tx_result = IPTX_RESULT_SENDING report "T3: result should be IPTX_RESULT_SENDING"; + wait for clk_period*2; + assert ip_tx_data_out_ready = '0' report "T3: IP data out ready asserted too early"; + wait until ip_tx_data_out_ready = '1'; + + -- start to tx IP data + ip_tx.data.data_out_valid <= '1'; + ip_tx.data.data_out <= x"81"; wait for clk_period; + ip_tx.data.data_out <= x"83"; wait for clk_period; + ip_tx.data.data_out <= x"85"; wait for clk_period; + ip_tx.data.data_out <= x"87"; wait for clk_period; + ip_tx.data.data_out <= x"89"; wait for clk_period; + + ip_tx.data.data_out <= x"8b"; + ip_tx.data.data_out_last <= '1'; + wait for clk_period; + + assert mac_tx_tlast = '1' report "T3: mac_tx_tlast not set on last byte"; + + wait for clk_period; + + ip_tx.data.data_out_valid <= '0'; + ip_tx.data.data_out_last <= '0'; + wait for clk_period*2; + + assert ip_tx_result = IPTX_RESULT_SENT report "T3: result should be SENT"; + wait for clk_period*2; + + + + report "-- end of tests --"; + + wait; + end process; + +END; Index: tags/v2.3/bench/vhdl/arp_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/arp_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/arp_tb.vhd (revision 25) @@ -0,0 +1,601 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12:35:50 05/31/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/arp1/arp_tb.vhd +-- Project Name: arp1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: arp +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Revision 0.02 - Added tests for ARP timeout +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; +use work.arp_types.all; + +ENTITY arp_tb IS +END arp_tb; + +ARCHITECTURE behavior OF arp_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT arp + generic ( + CLOCK_FREQ : integer := 125000000; -- freq of data_in_clk -- needed to timout cntr + ARP_TIMEOUT : integer := 60 -- ARP response timeout (s) + ); + Port ( + -- lookup request signals + arp_req_req : in arp_req_req_type; + arp_req_rslt : out arp_req_rslt_type; + -- MAC layer RX signals + data_in_clk : in STD_LOGIC; + reset : in STD_LOGIC; + data_in : in STD_LOGIC_VECTOR (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame) + data_in_valid : in STD_LOGIC; -- indicates data_in valid on clock + data_in_last : in STD_LOGIC; -- indicates last data in frame + -- 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_granted : in std_logic; -- indicates that access to channel has been granted + data_out_clk : in std_logic; + data_out_ready : in std_logic; -- indicates system ready to consume data + data_out_valid : out std_logic; -- indicates data out is valid + data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame + data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame + data_out : out std_logic_vector (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame) + -- system signals + our_mac_address : in STD_LOGIC_VECTOR (47 downto 0); + our_ip_address : in STD_LOGIC_VECTOR (31 downto 0); + control : in arp_control_type; + req_count : out STD_LOGIC_VECTOR(7 downto 0) -- count of arp pkts received + ); + END COMPONENT; + + + --Inputs + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal data_in : std_logic_vector(7 downto 0) := (others => '0'); + signal data_in_valid : std_logic := '0'; + signal data_in_last : std_logic := '0'; + signal our_mac_address : std_logic_vector(47 downto 0) := (others => '0'); + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal data_out_ready : std_logic; + signal data_out_valid : std_logic; + signal data_out_first : std_logic; + signal data_out_last : std_logic; + signal data_out : std_logic_vector (7 downto 0); + signal req_count : STD_LOGIC_VECTOR(7 downto 0); + signal arp_req_req : arp_req_req_type; + signal arp_req_rslt : arp_req_rslt_type; + signal mac_tx_req : std_logic; + signal mac_tx_granted : std_logic; + signal control : arp_control_type; + + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: arp generic map ( + CLOCK_FREQ => 10, -- artificially low count to enable pragmatic testing + ARP_TIMEOUT => 20 + ) + PORT MAP ( + -- lookup request mappings + arp_req_req => arp_req_req, + arp_req_rslt => arp_req_rslt, + -- rx mappings + data_in_clk => clk, + reset => reset, + data_in => data_in, + data_in_valid => data_in_valid, + data_in_last => data_in_last, + -- tx mappings + mac_tx_req => mac_tx_req, + mac_tx_granted => mac_tx_granted, + data_out_clk => clk, + data_out_ready => data_out_ready, + data_out_valid => data_out_valid, + data_out_first => data_out_first, + data_out_last => data_out_last, + data_out => data_out, + -- system mappings + our_mac_address => our_mac_address, + our_ip_address => our_ip_address, + control => control, + req_count => req_count + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 100 ns; + + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + our_mac_address <= x"002320212223"; + mac_tx_granted <= '1'; -- FIXME 0 + control.clear_cache <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + assert mac_tx_req = '0' report "mac_tx_req asserted on reset"; + + -- insert stimulus here + arp_req_req.lookup_req <= '0'; + arp_req_req.ip <= (others => '0'); + data_out_ready <= '1'; + + report "T1: Send an ARP request: who has 192.168.5.9? Tell 192.168.5.1"; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Sender MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + + -- check tx arbitration signals + + assert mac_tx_req = '1' report "T1: mac_tx_req not set"; + + -- ready to tx + data_out_ready <= '1'; + mac_tx_granted <= '1'; + wait for clk_period*10; + data_out_ready <= '0'; + wait for clk_period*2; + data_out_ready <= '1'; + wait for clk_period*50; + + report "T2: Send another ARP request: who has 192.168.5.9? Tell 192.168.5.1, holding off transmitter"; + data_out_ready <= '0'; + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Sender MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"18"; wait for clk_period; + data_in <= x"29"; wait for clk_period; + data_in <= x"26"; wait for clk_period; + data_in <= x"7c"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + + -- ready to tx + wait for clk_period*10; + data_out_ready <= '1'; + + wait for clk_period*50; + + report "T3 Send a request for the IP that is already cached"; + arp_req_req.ip <= x"c0a80501"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T3: should have got mac"; + assert arp_req_rslt.mac = x"00231829267c" report "T3: incorrect mac"; + assert arp_req_rslt.got_err = '0' report "T3: should not have got err"; + arp_req_req.lookup_req <= '0'; + wait for clk_period; + wait for clk_period*10; + + wait for clk_period*20; + assert mac_tx_req = '0' report "T3: should not be requesting TX channel"; + + report "T4: Request 192.168.5.3 (not cached= and Send an ARP reply: 192.168.5.3 has mac 02:12:03:23:04:54"; + arp_req_req.ip <= x"c0a80503"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + assert mac_tx_req = '1' report "T4: should be requesting TX channel"; + wait for clk_period*50; + -- Send the reply + data_out_ready <= '1'; + + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"12"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T4: should have got mac"; + assert arp_req_rslt.mac = x"021203230454" report "T4: incorrect mac"; + assert arp_req_rslt.got_err = '0' report "T4: should not have got err"; + wait for clk_period*10; + + report "T5: Request 192.168.5.4 (not cached), dont send a reply and wait for timeout"; + arp_req_req.ip <= x"c0a80504"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + assert mac_tx_req = '1' report "T5: should be requesting TX channel"; + wait for clk_period*200; + assert arp_req_rslt.got_mac = '0' report "T5: should not have got mac"; + assert arp_req_rslt.got_err = '1' report "T5: should have got err"; + + report "T6: Request 192.168.5.7 (not cached= and Send an ARP reply: 192.168.5.7 has mac 02:15:03:23:04:54"; + arp_req_req.ip <= x"c0a80507"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + assert arp_req_rslt.got_mac = '0' report "T6: should not yet have mac"; + assert arp_req_rslt.got_err = '0' report "T6: should not have got err"; + + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + assert mac_tx_req = '1' report "T6: should be requesting TX channel"; + wait for clk_period*50; + -- Send the reply + data_out_ready <= '1'; + + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"07"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T6: should have got mac"; + assert arp_req_rslt.mac = x"021503230454" report "T6: incorrect mac"; + assert arp_req_rslt.got_err = '0' report "T6: should not have got err"; + wait for clk_period*10; + + report "T7: Request 192.168.5.7 again an expect it to be in the cache"; + arp_req_req.ip <= x"c0a80507"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T7: should have mac"; + assert arp_req_rslt.got_err = '0' report "T7: should not have got err"; + + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + + report "T8: Clear the cache, Request 192.168.5.7 again an expect a 'who has' to be sent"; + control.clear_cache <= '1'; + wait for clk_period; + control.clear_cache <= '0'; + wait for clk_period; + + arp_req_req.ip <= x"c0a80507"; + arp_req_req.lookup_req <= '1'; + wait for clk_period; + assert arp_req_rslt.got_mac = '0' report "T8: should not yet have mac"; + assert arp_req_rslt.got_err = '0' report "T8: should not have got err"; + + arp_req_req.lookup_req <= '0'; + wait for clk_period*20; + + + assert mac_tx_req = '1' report "T8: should be requesting TX channel"; + wait for clk_period*50; + -- Send the reply + data_out_ready <= '1'; + + data_in_valid <= '1'; + -- dst MAC (bc) + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + data_in <= x"ff"; wait for clk_period; + -- src MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"04"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- type + data_in <= x"08"; wait for clk_period; + data_in <= x"06"; wait for clk_period; + -- HW type + data_in <= x"00"; wait for clk_period; + data_in <= x"01"; wait for clk_period; + -- Protocol type + data_in <= x"08"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + -- HW size + data_in <= x"06"; wait for clk_period; + -- protocol size + data_in <= x"04"; wait for clk_period; + -- Opcode + data_in <= x"00"; wait for clk_period; + data_in <= x"02"; wait for clk_period; + -- Sender MAC + data_in <= x"02"; wait for clk_period; + data_in <= x"15"; wait for clk_period; + data_in <= x"03"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"55"; wait for clk_period; + data_in <= x"54"; wait for clk_period; + -- Sender IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"07"; wait for clk_period; + -- Target MAC + data_in <= x"00"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + data_in <= x"20"; wait for clk_period; + data_in <= x"21"; wait for clk_period; + data_in <= x"22"; wait for clk_period; + data_in <= x"23"; wait for clk_period; + -- Target IP + data_in <= x"c0"; wait for clk_period; + data_in <= x"a8"; wait for clk_period; + data_in <= x"05"; wait for clk_period; + data_in <= x"09"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in <= x"00"; wait for clk_period; + data_in_last <= '1'; + data_in <= x"00"; wait for clk_period; + data_in_last <= '0'; + data_in_valid <= '0'; + wait for clk_period; + assert arp_req_rslt.got_mac = '1' report "T8: should have got mac"; + assert arp_req_rslt.mac = x"021503235554" report "T8: incorrect mac"; + assert arp_req_rslt.got_err = '0' report "T8: should not have got err"; + wait for clk_period*10; + + report "--- end of tests ---"; + wait; + end process; + +END; Index: tags/v2.3/bench/vhdl/IPv4_RX_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/IPv4_RX_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/IPv4_RX_tb.vhd (revision 25) @@ -0,0 +1,391 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:32:02 06/03/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/ip1/IPv4_RX_tb.vhd +-- Project Name: ip1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: IPv4_RX +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.axi.all; +use work.ipv4_types.all; +use work.arp_types.all; + + +ENTITY IPv4_RX_tb IS +END IPv4_RX_tb; + +ARCHITECTURE behavior OF IPv4_RX_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT IPv4_RX + PORT( + -- IP Layer signals + ip_rx : out ipv4_rx_type; + ip_rx_start : out std_logic; -- indicates receipt of ip frame. + -- system signals + clk : in STD_LOGIC; -- same clock used to clock mac data and ip data + reset : in STD_LOGIC; + our_ip_address : in STD_LOGIC_VECTOR (31 downto 0); + -- MAC layer RX signals + mac_data_in : in STD_LOGIC_VECTOR (7 downto 0); -- ethernet frame (from dst mac addr through to last byte of frame) + mac_data_in_valid : in STD_LOGIC; -- indicates data_in valid on clock + mac_data_in_last : in STD_LOGIC -- indicates last data in frame + ); + END COMPONENT; + + + --Inputs + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal our_ip_address : std_logic_vector(31 downto 0) := (others => '0'); + signal mac_data_in : std_logic_vector(7 downto 0) := (others => '0'); + signal mac_data_in_valid : std_logic := '0'; + signal mac_data_in_last : std_logic := '0'; + + --Outputs + signal ip_rx_start : std_logic; + signal ip_rx : ipv4_rx_type; + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: IPv4_RX PORT MAP ( + ip_rx => ip_rx, + ip_rx_start => ip_rx_start, + clk => clk, + reset => reset, + our_ip_address => our_ip_address, + mac_data_in => mac_data_in, + mac_data_in_valid => mac_data_in_valid, + mac_data_in_last => mac_data_in_last + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 100 ns; + + our_ip_address <= x"c0a80509"; -- 192.168.5.9 + mac_data_in_valid <= '0'; + mac_data_in_last <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + -- check reset conditions + assert ip_rx_start = '0' report "ip_rx_start not initialised correctly on reset"; + assert ip_rx.hdr.is_valid = '0' report "ip_rx.hdr.is_valid not initialised correctly on reset"; + assert ip_rx.hdr.protocol = x"00" report "ip_rx.hdr.protocol not initialised correctly on reset"; + assert ip_rx.hdr.data_length = x"0000" report "ip_rx.hdr.data_length not initialised correctly on reset"; + assert ip_rx.hdr.src_ip_addr = x"00000000" report "ip_rx.hdr.src_ip_addr not initialised correctly on reset"; + assert ip_rx.hdr.num_frame_errors = x"00" report "ip_rx.hdr.num_frame_errors not initialised correctly on reset"; + assert ip_rx.data.data_in = x"00" report "ip_rx.data.data_in not initialised correctly on reset"; + assert ip_rx.data.data_in_valid = '0' report "ip_rx.data.data_in_valid not initialised correctly on reset"; + assert ip_rx.data.data_in_last = '0' report "ip_rx.data.data_in_last not initialised correctly on reset"; + + -- insert stimulus here + + ------------ + -- TEST 1 -- basic functional rx test with received ip pkt + ------------ + + report "T1: Send an eth frame with IP pkt dst ip_address c0a80509, dst mac 002320212223"; + + mac_data_in_valid <= '1'; + -- dst MAC (bc) + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"23"; wait for clk_period; + mac_data_in <= x"20"; wait for clk_period; + mac_data_in <= x"21"; wait for clk_period; + mac_data_in <= x"22"; wait for clk_period; + mac_data_in <= x"23"; wait for clk_period; + -- src MAC + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"23"; wait for clk_period; + mac_data_in <= x"18"; wait for clk_period; + mac_data_in <= x"29"; wait for clk_period; + mac_data_in <= x"26"; wait for clk_period; + mac_data_in <= x"7c"; wait for clk_period; + -- type + mac_data_in <= x"08"; wait for clk_period; -- IP pkt + mac_data_in <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_data_in <= x"45"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- total len + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"18"; wait for clk_period; + -- ID + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- flags & frag + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- TTL + mac_data_in <= x"00"; wait for clk_period; + -- Protocol + mac_data_in <= x"11"; wait for clk_period; + -- Header CKS + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- SRC IP + mac_data_in <= x"c0"; wait for clk_period; + mac_data_in <= x"a8"; wait for clk_period; + mac_data_in <= x"05"; wait for clk_period; + mac_data_in <= x"01"; wait for clk_period; + -- DST IP + mac_data_in <= x"c0"; wait for clk_period; + mac_data_in <= x"a8"; wait for clk_period; + mac_data_in <= x"05"; wait for clk_period; + mac_data_in <= x"09"; wait for clk_period; + + -- user data + mac_data_in <= x"24"; wait for clk_period; + + assert ip_rx.hdr.is_valid = '1' report "T1: ip_rx.hdr.is_valid not set"; + assert ip_rx.hdr.protocol = x"11" report "T1: ip_rx.hdr.protocol not set correctly"; + assert ip_rx.hdr.data_length = x"0004" report "T1: ip_rx.hdr.data_length not set correctly"; + assert ip_rx.hdr.src_ip_addr = x"c0a80501" report "T1: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T1: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx.hdr.last_error_code = x"0" report "T1: ip_rx.hdr.last_error_code not set correctly"; + assert ip_rx.hdr.is_broadcast = '0' report "T1: ip_rx.hdr.is_broadcast should not be set"; + assert ip_rx_start = '1' report "T1: ip_rx_start not set"; + assert ip_rx.data.data_in_valid = '1' report "T1: ip_rx.data.data_in_valid not set"; + + mac_data_in <= x"25"; wait for clk_period; + mac_data_in <= x"26"; wait for clk_period; + mac_data_in <= x"27"; mac_data_in_last <= '1';wait for clk_period; + + assert ip_rx.data.data_in_last = '1' report "T1: ip_rx.data.data_in_last not set"; + + mac_data_in <= x"00"; + mac_data_in_last <= '0'; + mac_data_in_valid <= '0'; + wait for clk_period; + + assert ip_rx.data.data_in_valid = '0' report "T1: ip_rx.data.data_in_valid not cleared"; + assert ip_rx.data.data_in_last = '0' report "T1: ip_rx.data.data_in_last not cleared"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T1: ip_rx.hdr.num_frame_errors non zero at end of test"; + assert ip_rx.hdr.last_error_code = x"0" report "T1: ip_rx.hdr.last_error_code indicates error at end of test"; + assert ip_rx_start = '0' report "T1: ip_rx_start not cleared"; + + ------------ + -- TEST 2 -- basic functional rx test with received ip pkt that is not for us + ------------ + + report "T2: Send an eth frame with IP pkt dst ip_address c0a80507, dst mac 002320212223"; + + mac_data_in_valid <= '1'; + -- dst MAC (bc) + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"23"; wait for clk_period; + mac_data_in <= x"20"; wait for clk_period; + mac_data_in <= x"21"; wait for clk_period; + mac_data_in <= x"22"; wait for clk_period; + mac_data_in <= x"23"; wait for clk_period; + + assert ip_rx.hdr.is_valid = '0' report "T2: ip_rx.hdr.is_valid remains set"; + + -- src MAC + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"23"; wait for clk_period; + mac_data_in <= x"18"; wait for clk_period; + mac_data_in <= x"29"; wait for clk_period; + mac_data_in <= x"26"; wait for clk_period; + mac_data_in <= x"7c"; wait for clk_period; + -- type + mac_data_in <= x"08"; wait for clk_period; -- IP pkt + mac_data_in <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_data_in <= x"45"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- total len + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"18"; wait for clk_period; + -- ID + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- flags & frag + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- TTL + mac_data_in <= x"00"; wait for clk_period; + -- Protocol + mac_data_in <= x"11"; wait for clk_period; + -- Header CKS + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- SRC IP + mac_data_in <= x"c0"; wait for clk_period; + mac_data_in <= x"a8"; wait for clk_period; + mac_data_in <= x"05"; wait for clk_period; + mac_data_in <= x"02"; wait for clk_period; + -- DST IP + mac_data_in <= x"c0"; wait for clk_period; + mac_data_in <= x"a8"; wait for clk_period; + mac_data_in <= x"05"; wait for clk_period; + mac_data_in <= x"07"; wait for clk_period; + + -- user data + mac_data_in <= x"24"; wait for clk_period; + + assert ip_rx.hdr.is_valid = '1' report "T2: ip_rx.hdr.is_valid not set"; + assert ip_rx.hdr.protocol = x"11" report "T2: ip_rx.hdr.protocol not set correctly"; + assert ip_rx.hdr.data_length = x"0004" report "T2: ip_rx.hdr.data_length not set correctly"; + assert ip_rx.hdr.src_ip_addr = x"c0a80502" report "T2: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T2: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx.hdr.is_broadcast = '0' report "T2: ip_rx.hdr.is_broadcast should not be set"; + assert ip_rx.hdr.last_error_code = x"0" report "T2: ip_rx.hdr.last_error_code not set correctly"; + assert ip_rx_start = '0' report "T2: ip_rx_start set when pkt not for us"; + assert ip_rx.data.data_in_valid = '0' report "T2: ip_rx.data.data_in_valid set when pkt not for us"; + + mac_data_in <= x"25"; wait for clk_period; + mac_data_in <= x"26"; wait for clk_period; + mac_data_in <= x"27"; mac_data_in_last <= '1';wait for clk_period; + + assert ip_rx.data.data_in_last = '0' report "T2: ip_rx.data.data_in_last set"; + + mac_data_in <= x"00"; + mac_data_in_last <= '0'; + mac_data_in_valid <= '0'; + wait for clk_period; + + assert ip_rx.data.data_in_valid = '0' report "T2: ip_rx.data.data_in_valid not cleared"; + assert ip_rx.data.data_in_last = '0' report "T2: ip_rx.data.data_in_last not cleared"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T2: ip_rx.hdr.num_frame_errors non zero at end of test"; + assert ip_rx.hdr.last_error_code = x"0" report "T2: ip_rx.hdr.last_error_code indicates error at end of test"; + assert ip_rx_start = '0' report "T2: ip_rx_start not cleared"; + + wait for clk_period*20; + + + ------------ + -- TEST 3 -- RX Broadcast pkt + ------------ + + report "T3: Send an eth frame with IP pkt dst ip_address = BC, dst mac = BC"; + + mac_data_in_valid <= '1'; + -- dst MAC (bc) + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + -- src MAC + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"23"; wait for clk_period; + mac_data_in <= x"18"; wait for clk_period; + mac_data_in <= x"29"; wait for clk_period; + mac_data_in <= x"26"; wait for clk_period; + mac_data_in <= x"7c"; wait for clk_period; + -- type + mac_data_in <= x"08"; wait for clk_period; -- IP pkt + mac_data_in <= x"00"; wait for clk_period; + -- ver & HL / service type + mac_data_in <= x"45"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- total len + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"18"; wait for clk_period; + -- ID + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- flags & frag + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- TTL + mac_data_in <= x"00"; wait for clk_period; + -- Protocol + mac_data_in <= x"11"; wait for clk_period; + -- Header CKS + mac_data_in <= x"00"; wait for clk_period; + mac_data_in <= x"00"; wait for clk_period; + -- SRC IP + mac_data_in <= x"c0"; wait for clk_period; + mac_data_in <= x"a8"; wait for clk_period; + mac_data_in <= x"05"; wait for clk_period; + mac_data_in <= x"01"; wait for clk_period; + -- DST IP + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + mac_data_in <= x"ff"; wait for clk_period; + + -- user data + mac_data_in <= x"24"; wait for clk_period; + + assert ip_rx.hdr.is_valid = '1' report "T3: ip_rx.hdr.is_valid not set"; + assert ip_rx.hdr.protocol = x"11" report "T3: ip_rx.hdr.protocol not set correctly"; + assert ip_rx.hdr.data_length = x"0004" report "T3: ip_rx.hdr.data_length not set correctly"; + assert ip_rx.hdr.src_ip_addr = x"c0a80501" report "T3: ip_rx.hdr.src_ip_addr not set correctly"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T3: ip_rx.hdr.num_frame_errors not set correctly"; + assert ip_rx.hdr.is_broadcast = '1' report "T3: ip_rx.hdr.is_broadcast not set"; + assert ip_rx.hdr.last_error_code = x"0" report "T3: ip_rx.hdr.last_error_code not set correctly"; + assert ip_rx_start = '1' report "T3: ip_rx_start not set"; + assert ip_rx.data.data_in_valid = '1' report "T3: ip_rx.data.data_in_valid not set"; + + mac_data_in <= x"25"; wait for clk_period; + mac_data_in <= x"26"; wait for clk_period; + mac_data_in <= x"27"; mac_data_in_last <= '1';wait for clk_period; + + assert ip_rx.data.data_in_last = '1' report "T3: ip_rx.data.data_in_last not set"; + + mac_data_in <= x"00"; + mac_data_in_last <= '0'; + mac_data_in_valid <= '0'; + wait for clk_period; + + assert ip_rx.data.data_in_valid = '0' report "T3: ip_rx.data.data_in_valid not cleared"; + assert ip_rx.data.data_in_last = '0' report "T3: ip_rx.data.data_in_last not cleared"; + assert ip_rx.hdr.num_frame_errors = x"00" report "T3: ip_rx.hdr.num_frame_errors non zero at end of test"; + assert ip_rx.hdr.last_error_code = x"0" report "T3: ip_rx.hdr.last_error_code indicates error at end of test"; + assert ip_rx_start = '0' report "T3: ip_rx_start not cleared"; + + + report "--- end of tests ---"; + + wait; + end process; + +END; Index: tags/v2.3/bench/vhdl/UDP_RX_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/UDP_RX_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/UDP_RX_tb.vhd (revision 25) @@ -0,0 +1,325 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 16:53:03 06/10/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/ip1/UDP_RX_tb.vhd +-- Project Name: ip1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: UDP_RX +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.axi.all; +use work.ipv4_types.all; + +ENTITY UDP_RX_tb IS +END UDP_RX_tb; + +ARCHITECTURE behavior OF UDP_RX_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT UDP_RX + PORT( + -- UDP Layer signals + udp_rxo : inout udp_rx_type; + udp_rx_start : out std_logic; -- indicates receipt of udp header + -- system signals + clk : in STD_LOGIC; + reset : in STD_LOGIC; + -- IP layer RX signals + ip_rx_start : in std_logic; -- indicates receipt of ip header + ip_rx : inout ipv4_rx_type + ); + END COMPONENT; + + + --Inputs + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal ip_rx_start : std_logic := '0'; + + --BiDirs + signal udp_rxo : udp_rx_type; + signal ip_rx : ipv4_rx_type; + + --Outputs + signal udp_rx_start : std_logic; + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: UDP_RX PORT MAP ( + udp_rxo => udp_rxo, + udp_rx_start => udp_rx_start, + clk => clk, + reset => reset, + ip_rx_start => ip_rx_start, + ip_rx => ip_rx + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 100 ns; + ip_rx_start <= '0'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '0'; + ip_rx.hdr.protocol <= (others => '0'); + ip_rx.hdr.num_frame_errors <= (others => '0'); + ip_rx.hdr.last_error_code <= (others => '0'); + ip_rx.hdr.is_broadcast <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + reset <= '0'; + + -- check reset conditions + assert udp_rx_start = '0' report "udp_rx_start not initialised correctly on reset"; + assert udp_rxo.hdr.is_valid = '0' report "udp_rxo.hdr.is_valid not initialised correctly on reset"; + assert udp_rxo.data.data_in = x"00" report "udp_rxo.data.data_in not initialised correctly on reset"; + assert udp_rxo.data.data_in_valid = '0' report "udp_rxo.data.data_in_valid not initialised correctly on reset"; + assert udp_rxo.data.data_in_last = '0' report "udp_rxo.data.data_in_last not initialised correctly on reset"; + + -- insert stimulus here + + ------------ + -- TEST 1 -- basic functional rx test with received ip pkt + ------------ + + report "T1: Send an ip frame with IP src ip_address c0a80501, udp protocol from port x1498 to port x8724 and 3 bytes data"; + + ip_rx_start <= '1'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '1'; + ip_rx.hdr.protocol <= x"11"; -- UDP + ip_rx.hdr.data_length <= x"000b"; + ip_rx.hdr.src_ip_addr<= x"c0a80501"; + wait for clk_period*3; + -- now send the data + ip_rx.data.data_in_valid <= '1'; + ip_rx.data.data_in <= x"14"; wait for clk_period; -- src port + ip_rx.data.data_in <= x"98"; wait for clk_period; + ip_rx.data.data_in <= x"87"; wait for clk_period; -- dst port + ip_rx.data.data_in <= x"24"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- len (hdr + data) + ip_rx.data.data_in <= x"0b"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- mty cks + ip_rx.data.data_in <= x"00"; wait for clk_period; + -- udp hdr should be valid + assert udp_rxo.hdr.is_valid = '1' report "T1: udp_rxo.hdr.is_valid not set"; + + ip_rx.data.data_in <= x"41"; wait for clk_period; -- data + + assert udp_rxo.hdr.src_ip_addr = x"c0a80501" report "T1: udp_rxo.hdr.src_ip_addr not set correctly"; + assert udp_rxo.hdr.src_port = x"1498" report "T1: udp_rxo.hdr.src_port not set correctly"; + assert udp_rxo.hdr.dst_port = x"8724" report "T1: udp_rxo.hdr.dst_port not set correctly"; + assert udp_rxo.hdr.data_length = x"0003" report "T1: udp_rxo.hdr.data_length not set correctly"; + assert udp_rx_start = '1' report "T1: udp_rx_start not set"; + assert udp_rxo.data.data_in_valid = '1' report "T1: udp_rxo.data.data_in_valid not set"; + + ip_rx.data.data_in <= x"45"; wait for clk_period; -- data + ip_rx.data.data_in <= x"49"; ip_rx.data.data_in_last <= '1'; wait for clk_period; + assert udp_rxo.data.data_in_last = '1' report "T1: udp_rxo.data.data_in_last not set"; + ip_rx_start <= '0'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '0'; + wait for clk_period; + assert udp_rxo.data.data_in = x"00" report "T1: udp_rxo.data.data_in not cleared"; + assert udp_rxo.data.data_in_valid = '0' report "T1: udp_rxo.data.data_in_valid not cleared"; + assert udp_rxo.data.data_in_last = '0' report "T1: udp_rxo.data.data_in_last not cleared"; + + wait for clk_period; + + ------------ + -- TEST 2 -- ability to receive 2nd ip pkt + ------------ + + report "T2: Send an ip frame with IP src ip_address c0a80501, udp protocol from port x7623 to port x0365 and 5 bytes data"; + + ip_rx_start <= '1'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '1'; + ip_rx.hdr.protocol <= x"11"; -- UDP + ip_rx.hdr.data_length <= x"000b"; + ip_rx.hdr.src_ip_addr<= x"c0a80501"; + wait for clk_period*3; + -- now send the data + ip_rx.data.data_in_valid <= '1'; + ip_rx.data.data_in <= x"76"; wait for clk_period; -- src port + ip_rx.data.data_in <= x"23"; wait for clk_period; + ip_rx.data.data_in <= x"03"; wait for clk_period; -- dst port + ip_rx.data.data_in <= x"65"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- len (hdr + data) + ip_rx.data.data_in <= x"0d"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- mty cks + ip_rx.data.data_in <= x"00"; wait for clk_period; + -- udp hdr should be valid + assert udp_rxo.hdr.is_valid = '1' report "T2: udp_rxo.hdr.is_valid not set"; + + ip_rx.data.data_in <= x"17"; wait for clk_period; -- data + + assert udp_rxo.hdr.src_ip_addr = x"c0a80501" report "T2: udp_rxo.hdr.src_ip_addr not set correctly"; + assert udp_rxo.hdr.src_port = x"7623" report "T2: udp_rxo.hdr.src_port not set correctly"; + assert udp_rxo.hdr.dst_port = x"0365" report "T2: udp_rxo.hdr.dst_port not set correctly"; + assert udp_rxo.hdr.data_length = x"0005" report "T2: udp_rxo.hdr.data_length not set correctly"; + assert udp_rx_start = '1' report "T2: udp_rx_start not set"; + assert udp_rxo.data.data_in_valid = '1' report "T2: udp_rxo.data.data_in_valid not set"; + + ip_rx.data.data_in <= x"37"; wait for clk_period; -- data + ip_rx.data.data_in <= x"57"; wait for clk_period; -- data + ip_rx.data.data_in <= x"73"; wait for clk_period; -- data + ip_rx.data.data_in <= x"f9"; ip_rx.data.data_in_last <= '1'; wait for clk_period; + assert udp_rxo.data.data_in_last = '1' report "T2: udp_rxo.data.data_in_last not set"; + ip_rx_start <= '0'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '0'; + wait for clk_period; + assert udp_rxo.data.data_in = x"00" report "T2: udp_rxo.data.data_in not cleared"; + assert udp_rxo.data.data_in_valid = '0' report "T2: udp_rxo.data.data_in_valid not cleared"; + assert udp_rxo.data.data_in_last = '0' report "T2: udp_rxo.data.data_in_last not cleared"; + + ------------ + -- TEST 3 -- ability to reject non-udp protocols + ------------ + + report "T3: Send an ip frame with IP src ip_address c0a80501, protocol x12 from port x7623 to port x0365 and 5 bytes data"; + + ip_rx_start <= '1'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '1'; + ip_rx.hdr.protocol <= x"12"; -- non-UDP + ip_rx.hdr.data_length <= x"000b"; + ip_rx.hdr.src_ip_addr<= x"c0a80501"; + wait for clk_period*3; + -- now send the data + ip_rx.data.data_in_valid <= '1'; + ip_rx.data.data_in <= x"76"; wait for clk_period; -- src port + ip_rx.data.data_in <= x"23"; wait for clk_period; + ip_rx.data.data_in <= x"03"; wait for clk_period; -- dst port + ip_rx.data.data_in <= x"65"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- len (hdr + data) + ip_rx.data.data_in <= x"0d"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- mty cks + ip_rx.data.data_in <= x"00"; wait for clk_period; + -- udp hdr should be valid + assert udp_rxo.hdr.is_valid = '0' report "T3: udp_rxo.hdr.is_valid incorrectly set"; + + ip_rx.data.data_in <= x"17"; wait for clk_period; -- data + + assert udp_rx_start = '0' report "T3: udp_rx_start incorrectly set"; + assert udp_rxo.data.data_in_valid = '0' report "T3: udp_rxo.data.data_in_valid not set"; + + ip_rx.data.data_in <= x"37"; wait for clk_period; -- data + ip_rx.data.data_in <= x"57"; wait for clk_period; -- data + ip_rx.data.data_in <= x"73"; wait for clk_period; -- data + ip_rx.data.data_in <= x"f9"; ip_rx.data.data_in_last <= '1'; wait for clk_period; + assert udp_rxo.data.data_in_last = '0' report "T3: udp_rxo.data.data_in_last incorrectly set"; + ip_rx_start <= '0'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '0'; + wait for clk_period; + assert udp_rxo.data.data_in = x"00" report "T3: udp_rxo.data.data_in not cleared"; + assert udp_rxo.data.data_in_valid = '0' report "T3: udp_rxo.data.data_in_valid not cleared"; + assert udp_rxo.data.data_in_last = '0' report "T3: udp_rxo.data.data_in_last not cleared"; + + wait for clk_period; + + ------------ + -- TEST 4 -- Ability to receive UDP pkt after non-UDP pkt + ------------ + + report "T4: Send an ip frame with IP src ip_address c0a80501, udp protocol from port x1498 to port x8724 and 3 bytes data"; + + ip_rx_start <= '1'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '1'; + ip_rx.hdr.protocol <= x"11"; -- UDP + ip_rx.hdr.data_length <= x"000b"; + ip_rx.hdr.src_ip_addr<= x"c0a80501"; + wait for clk_period*3; + -- now send the data + ip_rx.data.data_in_valid <= '1'; + ip_rx.data.data_in <= x"14"; wait for clk_period; -- src port + ip_rx.data.data_in <= x"98"; wait for clk_period; + ip_rx.data.data_in <= x"87"; wait for clk_period; -- dst port + ip_rx.data.data_in <= x"24"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- len (hdr + data) + ip_rx.data.data_in <= x"0b"; wait for clk_period; + ip_rx.data.data_in <= x"00"; wait for clk_period; -- mty cks + ip_rx.data.data_in <= x"00"; wait for clk_period; + -- udp hdr should be valid + assert udp_rxo.hdr.is_valid = '1' report "T4: udp_rxo.hdr.is_valid not set"; + + ip_rx.data.data_in <= x"41"; wait for clk_period; -- data + + assert udp_rxo.hdr.src_ip_addr = x"c0a80501" report "T4: udp_rxo.hdr.src_ip_addr not set correctly"; + assert udp_rxo.hdr.src_port = x"1498" report "T4: udp_rxo.hdr.src_port not set correctly"; + assert udp_rxo.hdr.dst_port = x"8724" report "T4: udp_rxo.hdr.dst_port not set correctly"; + assert udp_rxo.hdr.data_length = x"0003" report "T4: udp_rxo.hdr.data_length not set correctly"; + assert udp_rx_start = '1' report "T4: udp_rx_start not set"; + assert udp_rxo.data.data_in_valid = '1' report "T4: udp_rxo.data.data_in_valid not set"; + + ip_rx.data.data_in <= x"45"; wait for clk_period; -- data + ip_rx.data.data_in <= x"49"; ip_rx.data.data_in_last <= '1'; wait for clk_period; + assert udp_rxo.data.data_in_last = '1' report "T4: udp_rxo.data.data_in_last not set"; + ip_rx_start <= '0'; + ip_rx.data.data_in_valid <= '0'; + ip_rx.data.data_in_last <= '0'; + ip_rx.hdr.is_valid <= '0'; + wait for clk_period; + assert udp_rxo.data.data_in = x"00" report "T4: udp_rxo.data.data_in not cleared"; + assert udp_rxo.data.data_in_valid = '0' report "T4: udp_rxo.data.data_in_valid not cleared"; + assert udp_rxo.data.data_in_last = '0' report "T4: udp_rxo.data.data_in_last not cleared"; + + wait for clk_period; + + report "--- end of tests ---"; + + wait; + end process; + +END; Index: tags/v2.3/bench/vhdl/UDP_TX_tb.vhd =================================================================== --- tags/v2.3/bench/vhdl/UDP_TX_tb.vhd (nonexistent) +++ tags/v2.3/bench/vhdl/UDP_TX_tb.vhd (revision 25) @@ -0,0 +1,219 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 18:43:49 06/10/2011 +-- Design Name: +-- Module Name: C:/Users/pjf/Documents/projects/fpga/xilinx/Network/ip1/UDP_TX_tb.vhd +-- Project Name: ip1 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: UDP_TX +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.axi.all; +use work.ipv4_types.all; + +ENTITY UDP_TX_tb IS +END UDP_TX_tb; + +ARCHITECTURE behavior OF UDP_TX_tb IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT UDP_TX + PORT( + -- UDP Layer signals + udp_tx_start : in std_logic; -- indicates req to tx UDP + udp_txi : in udp_tx_type; -- UDP tx cxns + udp_tx_result : out std_logic_vector (1 downto 0);-- tx status (changes during transmission) + udp_tx_data_out_ready: out std_logic; -- indicates udp_tx is ready to take data + -- system signals + clk : in STD_LOGIC; -- same clock used to clock mac data and ip data + reset : in STD_LOGIC; + -- IP layer TX signals + ip_tx_start : out std_logic; + ip_tx : out ipv4_tx_type; -- IP tx cxns + ip_tx_result : in std_logic_vector (1 downto 0); -- tx status (changes during transmission) + ip_tx_data_out_ready : in std_logic -- indicates IP TX is ready to take data + ); + END COMPONENT; + + + --Inputs + signal udp_tx_start : std_logic := '0'; + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal udp_txi : udp_tx_type; + signal ip_tx_result : std_logic_vector (1 downto 0); -- tx status (changes during transmission) + signal ip_tx_data_out_ready : std_logic; -- indicates IP TX is ready to take data + + --Outputs + signal ip_tx_start : std_logic := '0'; + signal ip_tx : ipv4_tx_type; + signal udp_tx_result : std_logic_vector (1 downto 0); + signal udp_tx_data_out_ready : std_logic; + + -- Clock period definitions + constant clk_period : time := 8 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: UDP_TX PORT MAP ( + udp_tx_start => udp_tx_start, + udp_txi => udp_txi, + udp_tx_result => udp_tx_result, + udp_tx_data_out_ready => udp_tx_data_out_ready, + clk => clk, + reset => reset, + ip_tx_start => ip_tx_start, + ip_tx => ip_tx, + ip_tx_result => ip_tx_result, + ip_tx_data_out_ready => ip_tx_data_out_ready + ); + + + -- Clock process definitions + clk_process :process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + -- hold reset state for 100 ns. + wait for 100 ns; + + udp_tx_start <= '0'; + + udp_txi.hdr.dst_ip_addr <= (others => '0'); + udp_txi.hdr.dst_port <= (others => '0'); + udp_txi.hdr.src_port <= (others => '0'); + udp_txi.hdr.data_length <= (others => '0'); + udp_txi.hdr.checksum <= (others => '0'); + udp_txi.data.data_out_last <= '0'; + + reset <= '1'; + wait for clk_period*10; + reset <= '0'; + wait for clk_period*5; + + -- check reset conditions + + assert ip_tx_start = '0' report "ip_tx_start not initialised correctly on reset"; + assert ip_tx.data.data_out_valid = '0' report "ip_tx.data.data_out_valid not initialised correctly on reset"; + assert ip_tx.data.data_out_last = '0' report "ip_tx.data.data_out_last not initialised correctly on reset"; + assert udp_tx_result = UDPTX_RESULT_NONE report "udp_tx_result not initialised correctly on reset"; + + -- insert stimulus here + + wait for clk_period*5; + + ------------ + -- TEST 1 -- basic functional tx test + ------------ + + report "T1: basic functional tx test - send 56, 57, 58 to port 8532"; + + udp_txi.hdr.dst_ip_addr <= x"c0123478"; + udp_txi.hdr.dst_port <= x"1467"; + udp_txi.hdr.src_port <= x"8532"; + udp_txi.hdr.data_length <= x"0003"; + + udp_tx_start <= '1'; + ip_tx_data_out_ready <= '1'; -- IP layer can accept data + wait for clk_period; + udp_tx_start <= '0'; wait for clk_period; + ip_tx_result <= IPTX_RESULT_NONE; + + assert udp_tx_result = UDPTX_RESULT_SENDING report "T1: result should be UDPTX_RESULT_SENDING"; + + wait until udp_tx_data_out_ready = '1'; + + -- start to tx IP data + udp_txi.data.data_out_valid <= '1'; + udp_txi.data.data_out <= x"56"; wait for clk_period; + udp_txi.data.data_out <= x"57"; wait for clk_period; + + udp_txi.data.data_out <= x"58"; + udp_txi.data.data_out_last <= '1'; + wait for clk_period; + + assert ip_tx.data.data_out_last = '1' report "T1: ip_tx.datda_out_last not set on last byte"; + + udp_txi.data.data_out_valid <= '0'; + udp_txi.data.data_out_last <= '0'; + wait for clk_period*2; + ip_tx_result <= IPTX_RESULT_SENT; + + assert udp_tx_result = UDPTX_RESULT_SENT report "T1: result should be UDPTX_RESULT_SENT"; + wait for clk_period*2; + + ------------ + -- TEST 2 -- 2nd pkt + ------------ + + report "T2: send a second pkt - 56,57,58,59 to port 8532"; + + udp_txi.hdr.dst_ip_addr <= x"c0123475"; + udp_txi.hdr.dst_port <= x"1467"; + udp_txi.hdr.src_port <= x"8532"; + udp_txi.hdr.data_length <= x"0005"; + + udp_tx_start <= '1'; + ip_tx_data_out_ready <= '1'; -- IP layer can accept data + wait for clk_period; + udp_tx_start <= '0'; wait for clk_period; + + assert udp_tx_result = UDPTX_RESULT_SENDING report "T1: result should be UDPTX_RESULT_SENDING"; + + wait until udp_tx_data_out_ready = '1'; + + -- start to tx IP data + udp_txi.data.data_out_valid <= '1'; + udp_txi.data.data_out <= x"56"; wait for clk_period; + udp_txi.data.data_out <= x"57"; wait for clk_period; + udp_txi.data.data_out <= x"58"; wait for clk_period; + udp_txi.data.data_out <= x"59"; wait for clk_period; + + udp_txi.data.data_out <= x"5a"; + udp_txi.data.data_out_last <= '1'; + wait for clk_period; + assert ip_tx.data.data_out_last = '1' report "T1: ip_tx.datda_out_last not set on last byte"; + + udp_txi.data.data_out_valid <= '0'; + udp_txi.data.data_out_last <= '0'; + wait for clk_period*2; + + assert udp_tx_result = UDPTX_RESULT_SENT report "T1: result should be UDPTX_RESULT_SENT"; + wait for clk_period*2; + + report "--- end of tests ---"; + + wait; + end process; + +END; Index: tags/v2.3/sw/test_results/UDPTestStream_console.txt =================================================================== --- tags/v2.3/sw/test_results/UDPTestStream_console.txt (nonexistent) +++ tags/v2.3/sw/test_results/UDPTestStream_console.txt (revision 25) @@ -0,0 +1,152 @@ +Sending price tick 225 +Sending price tick 224 +Sending price tick 223 +Sending price tick 222 +Sending price tick 221 +Sending price tick 220 +Sending price tick 219 +Sending price tick 218 +Sending price tick 217 +Sending price tick 216 +Sending price tick 215 +Sending price tick 214 +Sending price tick 213 +Sending price tick 212 +Sending price tick 211 +Sending price tick 210 +Sending price tick 209 +Sending price tick 208 +Sending price tick 207 +Sending price tick 206 +Sending price tick 205 +Sending price tick 204 +Sending price tick 203 +Sending price tick 202 +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Sending price tick 201 +Sending price tick 200 +Sending price tick 199 +Got [@ABC] +Sending price tick 198 +Sending price tick 197 +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Sending price tick 196 +Sending price tick 195 +Got [@ABC] +Sending price tick 194 +Sending price tick 193 +Got [@ABC] +Sending price tick 192 +Sending price tick 191 +Got [@ABC] +Sending price tick 190 +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Sending price tick 189 +Sending price tick 188 +Sending price tick 187 +Got [@ABC] +Got [@ABC] +Sending price tick 186 +Got [@ABC] +Sending price tick 185 +Sending price tick 184 +Got [@ABC] +Sending price tick 183 +Got [@ABC] +Got [@ABC] +Got [@ABC] +Sending price tick 182 +Sending price tick 181 +Got [@ABC] +Sending price tick 180 +Got [@ABC] +Sending price tick 179 +Got [@ABC] +Sending price tick 178 +Sending price tick 177 +Got [@ABC] +Sending price tick 176 +Got [@ABC] +Sending price tick 175 +Got [@ABC] +Got [@ABC] +Sending price tick 174 +Sending price tick 173 +Got [@ABC] +Sending price tick 172 +Got [@ABC] +Got [@ABC] +Got [@ABC] +Sending price tick 171 +Sending price tick 170 +Got [@ABC] +Sending price tick 169 +Sending price tick 168 +Got [@ABC] +Sending price tick 167 +Sending price tick 166 +Got [@ABC] +Sending price tick 165 +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Sending price tick 164 +Got [@ABC] +Sending price tick 163 +Sending price tick 162 +Got [@ABC] +Sending price tick 161 +Got [@ABC] +Sending price tick 160 +Got [@ABC] +Sending price tick 159 +Sending price tick 158 +Got [@ABC] +Sending price tick 157 +Sending price tick 156 +Got [@ABC] +Sending price tick 155 +Got [@ABC] +Sending price tick 154 +Got [@ABC] +Sending price tick 153 +Got [@ABC] +Sending price tick 152 +Got [@ABC] +Got [@ABC] +Got [@ABC] +Got [@ABC] +Sending price tick 151 +Sending price tick 150 +Got [@ABC] +Got [@ABC] Index: tags/v2.3/sw/test_results/UDPTestStream_wireshark.pcap =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.3/sw/test_results/UDPTestStream_wireshark.pcap =================================================================== --- tags/v2.3/sw/test_results/UDPTestStream_wireshark.pcap (nonexistent) +++ tags/v2.3/sw/test_results/UDPTestStream_wireshark.pcap (revision 25)
tags/v2.3/sw/test_results/UDPTestStream_wireshark.pcap Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/v2.3/sw/test_results/UDPTest_console.txt =================================================================== --- tags/v2.3/sw/test_results/UDPTest_console.txt (nonexistent) +++ tags/v2.3/sw/test_results/UDPTest_console.txt (revision 25) @@ -0,0 +1,2 @@ +Sending packet: 1=45~34=201~18=23~ on port 2000 +Got [@ABC] Index: tags/v2.3/sw/test_results/UDPTest_wireshark.pcap =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.3/sw/test_results/UDPTest_wireshark.pcap =================================================================== --- tags/v2.3/sw/test_results/UDPTest_wireshark.pcap (nonexistent) +++ tags/v2.3/sw/test_results/UDPTest_wireshark.pcap (revision 25)
tags/v2.3/sw/test_results/UDPTest_wireshark.pcap Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/v2.3/sw/UDPCxn.java =================================================================== --- tags/v2.3/sw/UDPCxn.java (nonexistent) +++ tags/v2.3/sw/UDPCxn.java (revision 25) @@ -0,0 +1,72 @@ +package com.pjf; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + + +public class UDPCxn { + private DatagramSocket skt; + private InetAddress dstIP; + + public UDPCxn(long dstIPadr) throws SocketException, UnknownHostException { + skt = new DatagramSocket(); + byte[] target = new byte[4]; + target[0] = (byte) ((dstIPadr >> 24) & 0xff); + target[1] = (byte) ((dstIPadr >> 16) & 0xff); + target[2] = (byte) ((dstIPadr >> 8) & 0xff); + target[3] = (byte) (dstIPadr & 0xff); + dstIP = InetAddress.getByAddress(target); + } + + public UDPCxn(String dstIPadr) throws SocketException, UnknownHostException { + skt = new DatagramSocket(); + String[] parts = dstIPadr.split("[.]"); + if (parts.length != 4) { + throw new UnknownHostException("ip addr must have 4 parts"); + } + byte[] target = new byte[4]; + for (int i = 0; i<4; i++) { + target[i] = (byte) Integer.parseInt(parts[i]); + } + dstIP = InetAddress.getByAddress(target); + } + + public void send(byte[] data, int port) throws IOException { + DatagramPacket pkt = new DatagramPacket(data, data.length, dstIP, port); + System.out.println("Sending packet"); + skt.send(pkt); + } + + public void fixSend(String str, int port, boolean print) throws IOException { + String s1 = str.replace('~','\001'); + byte[] data = s1.getBytes(); + DatagramPacket pkt = new DatagramPacket(data, data.length, dstIP, port); + if (print) { + System.out.println("Sending packet: " + str + " on port " + port); + } + skt.send(pkt); + } + + + public byte[] rcv() throws IOException { + byte[] buf = new byte[1024]; + DatagramPacket pkt = new DatagramPacket(buf, buf.length); +// System.out.println("waiting to receive ..."); + skt.receive(pkt); + int len = pkt.getLength(); + byte[] rd = pkt.getData(); + byte[] data = new byte[len]; + for (int i=0; i=150; price--) { + StringBuffer fixmsg = new StringBuffer(fix1); + fixmsg.append(Integer.toString(price)); + fixmsg.append(fix2); + System.out.println("Sending price tick " + price); + cxn.fixSend(fixmsg.toString(), 2000, false); + } + Thread.sleep(2000); + } + + + public static void main(String[] args) { + UDPTestStream ut; + try { + ut = new UDPTestStream(); + ut.go(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + +} Index: tags/v2.3/sw/UDPTest.java =================================================================== --- tags/v2.3/sw/UDPTest.java (nonexistent) +++ tags/v2.3/sw/UDPTest.java (revision 25) @@ -0,0 +1,34 @@ +package com.pjf; + +import java.io.IOException; +import java.net.SocketException; +import java.net.UnknownHostException; + +public class UDPTest { + private UDPCxn cxn; + + public UDPTest() throws SocketException, UnknownHostException { + cxn = new UDPCxn("192.168.5.9"); + } + + public void go() throws IOException { + String fix1 = "1=45~34=201~18=23~"; + cxn.fixSend(fix1, 2000, true); + byte[] rep = cxn.rcv(); + String reply = new String(rep); + System.out.println("Got [" + reply + "]"); + } + + + public static void main(String[] args) { + UDPTest ut; + try { + ut = new UDPTest(); + ut.go(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + +}

powered by: WebSVN 2.1.0

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