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 20 to Rev 21
    Reverse comparison

Rev 20 → Rev 21

/tags/v2.1/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.1/doc/src/UDP_IP_Stack.pptx Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/v2.1/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.1/doc/src/zero latency receive.jpg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.1/doc/src/zero latency receive.jpg =================================================================== --- tags/v2.1/doc/src/zero latency receive.jpg (nonexistent) +++ tags/v2.1/doc/src/zero latency receive.jpg (revision 21)
tags/v2.1/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.1/doc/UDP_IP_Stack.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.1/doc/UDP_IP_Stack.pdf =================================================================== --- tags/v2.1/doc/UDP_IP_Stack.pdf (nonexistent) +++ tags/v2.1/doc/UDP_IP_Stack.pdf (revision 21)
tags/v2.1/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.1/bench/vhdl/arpv2_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/arpv2_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/arpv2_tb.vhd (revision 21) @@ -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.1/bench/vhdl/IPv4_TX_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/IPv4_TX_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/IPv4_TX_tb.vhd (revision 21) @@ -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.1/bench/vhdl/UDP_complete_nomac_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/UDP_complete_nomac_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/UDP_complete_nomac_tb.vhd (revision 21) @@ -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.1/bench/vhdl/arp_STORE_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/arp_STORE_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/arp_STORE_tb.vhd (revision 21) @@ -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.1/bench/vhdl/UDP_av2_complete_nomac_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/UDP_av2_complete_nomac_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/UDP_av2_complete_nomac_tb.vhd (revision 21) @@ -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.1/bench/vhdl/IP_av2_complete_nomac_tb .vhd =================================================================== --- tags/v2.1/bench/vhdl/IP_av2_complete_nomac_tb .vhd (nonexistent) +++ tags/v2.1/bench/vhdl/IP_av2_complete_nomac_tb .vhd (revision 21) @@ -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.1/bench/vhdl/IP_complete_nomac_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/IP_complete_nomac_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/IP_complete_nomac_tb.vhd (revision 21) @@ -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.1/bench/vhdl/arp_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/arp_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/arp_tb.vhd (revision 21) @@ -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.1/bench/vhdl/IPv4_RX_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/IPv4_RX_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/IPv4_RX_tb.vhd (revision 21) @@ -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.1/bench/vhdl/UDP_RX_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/UDP_RX_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/UDP_RX_tb.vhd (revision 21) @@ -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.1/bench/vhdl/UDP_TX_tb.vhd =================================================================== --- tags/v2.1/bench/vhdl/UDP_TX_tb.vhd (nonexistent) +++ tags/v2.1/bench/vhdl/UDP_TX_tb.vhd (revision 21) @@ -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.1/rtl/vhdl/UDP_RX.vhd =================================================================== --- tags/v2.1/rtl/vhdl/UDP_RX.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/UDP_RX.vhd (revision 21) @@ -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 <= ERR; + 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; + Index: tags/v2.1/rtl/vhdl/IP_complete_nomac.vhd =================================================================== --- tags/v2.1/rtl/vhdl/IP_complete_nomac.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/IP_complete_nomac.vhd (revision 21) @@ -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; + + + Index: tags/v2.1/rtl/vhdl/arp_SYNC.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arp_SYNC.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arp_SYNC.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/arp_STORE_br.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arp_STORE_br.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arp_STORE_br.vhd (revision 21) @@ -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; Index: tags/v2.1/rtl/vhdl/arp_REQ.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arp_REQ.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arp_REQ.vhd (revision 21) @@ -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; Index: tags/v2.1/rtl/vhdl/arpv2.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arpv2.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arpv2.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/arp_RX.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arp_RX.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arp_RX.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/IPv4_RX.vhd =================================================================== --- tags/v2.1/rtl/vhdl/IPv4_RX.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/IPv4_RX.vhd (revision 21) @@ -0,0 +1,533 @@ +---------------------------------------------------------------------------------- +-- 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; + 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; + 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; + 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; + 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; + 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; + 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; + Index: tags/v2.1/rtl/vhdl/arp_TX.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arp_TX.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arp_TX.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/IPv4_TX.vhd =================================================================== --- tags/v2.1/rtl/vhdl/IPv4_TX.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/IPv4_TX.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/UDP_TX.vhd =================================================================== --- tags/v2.1/rtl/vhdl/UDP_TX.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/UDP_TX.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/ipcores/xilinx/README.txt =================================================================== --- tags/v2.1/rtl/vhdl/ipcores/xilinx/README.txt (nonexistent) +++ tags/v2.1/rtl/vhdl/ipcores/xilinx/README.txt (revision 21) @@ -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. Index: tags/v2.1/rtl/vhdl/ipcores/xilinx/mac_layer_v2_1.xco =================================================================== --- tags/v2.1/rtl/vhdl/ipcores/xilinx/mac_layer_v2_1.xco (nonexistent) +++ tags/v2.1/rtl/vhdl/ipcores/xilinx/mac_layer_v2_1.xco (revision 21) @@ -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 Index: tags/v2.1/rtl/vhdl/ipcores/xilinx/mac_layer_v2_2.xco =================================================================== --- tags/v2.1/rtl/vhdl/ipcores/xilinx/mac_layer_v2_2.xco (nonexistent) +++ tags/v2.1/rtl/vhdl/ipcores/xilinx/mac_layer_v2_2.xco (revision 21) @@ -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 Index: tags/v2.1/rtl/vhdl/arp_types.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arp_types.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arp_types.vhd (revision 21) @@ -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; Index: tags/v2.1/rtl/vhdl/arp.vhd =================================================================== --- tags/v2.1/rtl/vhdl/arp.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/arp.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/ml605/IP_complete.vhd =================================================================== --- tags/v2.1/rtl/vhdl/ml605/IP_complete.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/ml605/IP_complete.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/ml605/UDP_Complete.vhd =================================================================== --- tags/v2.1/rtl/vhdl/ml605/UDP_Complete.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/ml605/UDP_Complete.vhd (revision 21) @@ -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; + + Index: tags/v2.1/rtl/vhdl/ml605/UDP_integration_example.vhd =================================================================== --- tags/v2.1/rtl/vhdl/ml605/UDP_integration_example.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/ml605/UDP_integration_example.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/ml605/xv6mac_straight.vhd =================================================================== --- tags/v2.1/rtl/vhdl/ml605/xv6mac_straight.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/ml605/xv6mac_straight.vhd (revision 21) @@ -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; Index: tags/v2.1/rtl/vhdl/ml605/udp_constraints.ucf =================================================================== --- tags/v2.1/rtl/vhdl/ml605/udp_constraints.ucf (nonexistent) +++ tags/v2.1/rtl/vhdl/ml605/udp_constraints.ucf (revision 21) @@ -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%; + + Index: tags/v2.1/rtl/vhdl/UDP_Complete_nomac.vhd =================================================================== --- tags/v2.1/rtl/vhdl/UDP_Complete_nomac.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/UDP_Complete_nomac.vhd (revision 21) @@ -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; + + Index: tags/v2.1/rtl/vhdl/ipv4_types.vhd =================================================================== --- tags/v2.1/rtl/vhdl/ipv4_types.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/ipv4_types.vhd (revision 21) @@ -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; Index: tags/v2.1/rtl/vhdl/IPv4.vhd =================================================================== --- tags/v2.1/rtl/vhdl/IPv4.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/IPv4.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/tx_arbitrator.vhd =================================================================== --- tags/v2.1/rtl/vhdl/tx_arbitrator.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/tx_arbitrator.vhd (revision 21) @@ -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; + Index: tags/v2.1/rtl/vhdl/axi.vhd =================================================================== --- tags/v2.1/rtl/vhdl/axi.vhd (nonexistent) +++ tags/v2.1/rtl/vhdl/axi.vhd (revision 21) @@ -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; Index: tags/v2.1/sw/test_results/UDPTestStream_console.txt =================================================================== --- tags/v2.1/sw/test_results/UDPTestStream_console.txt (nonexistent) +++ tags/v2.1/sw/test_results/UDPTestStream_console.txt (revision 21) @@ -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.1/sw/test_results/UDPTestStream_wireshark.pcap =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.1/sw/test_results/UDPTestStream_wireshark.pcap =================================================================== --- tags/v2.1/sw/test_results/UDPTestStream_wireshark.pcap (nonexistent) +++ tags/v2.1/sw/test_results/UDPTestStream_wireshark.pcap (revision 21)
tags/v2.1/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.1/sw/test_results/UDPTest_console.txt =================================================================== --- tags/v2.1/sw/test_results/UDPTest_console.txt (nonexistent) +++ tags/v2.1/sw/test_results/UDPTest_console.txt (revision 21) @@ -0,0 +1,2 @@ +Sending packet: 1=45~34=201~18=23~ on port 2000 +Got [@ABC] Index: tags/v2.1/sw/test_results/UDPTest_wireshark.pcap =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/v2.1/sw/test_results/UDPTest_wireshark.pcap =================================================================== --- tags/v2.1/sw/test_results/UDPTest_wireshark.pcap (nonexistent) +++ tags/v2.1/sw/test_results/UDPTest_wireshark.pcap (revision 21)
tags/v2.1/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.1/sw/UDPCxn.java =================================================================== --- tags/v2.1/sw/UDPCxn.java (nonexistent) +++ tags/v2.1/sw/UDPCxn.java (revision 21) @@ -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.1/sw/UDPTest.java =================================================================== --- tags/v2.1/sw/UDPTest.java (nonexistent) +++ tags/v2.1/sw/UDPTest.java (revision 21) @@ -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.