Line 24... |
Line 24... |
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
|
-- 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
|
-- 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
|
-- to guarantee that the testbench will bind correctly to the post-implementation
|
-- simulation model.
|
-- simulation model.
|
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
LIBRARY ieee;
|
library ieee;
|
USE ieee.std_logic_1164.ALL;
|
use ieee.std_logic_1164.all;
|
use IEEE.NUMERIC_STD.ALL;
|
use IEEE.NUMERIC_STD.all;
|
use work.axi.all;
|
use work.axi.all;
|
use work.ipv4_types.all;
|
use work.ipv4_types.all;
|
use work.arp_types.all;
|
use work.arp_types.all;
|
|
|
|
|
ENTITY IPv4_TX_tb IS
|
entity IPv4_TX_tb is
|
END IPv4_TX_tb;
|
end IPv4_TX_tb;
|
|
|
ARCHITECTURE behavior OF IPv4_TX_tb IS
|
architecture behavior of IPv4_TX_tb is
|
|
|
-- Component Declaration for the Unit Under Test (UUT)
|
-- Component Declaration for the Unit Under Test (UUT)
|
|
|
COMPONENT IPv4_TX
|
component IPv4_TX
|
PORT(
|
port(
|
-- IP Layer signals
|
-- IP Layer signals
|
ip_tx_start : in std_logic;
|
ip_tx_start : in std_logic;
|
ip_tx : in ipv4_tx_type; -- IP tx cxns
|
ip_tx : in ipv4_tx_type; -- IP tx cxns
|
ip_tx_result : out std_logic_vector (1 downto 0); -- tx status (changes during transmission)
|
ip_tx_result : out std_logic_vector (1 downto 0); -- tx status (changes during transmission)
|
ip_tx_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
|
ip_tx_data_out_ready : out std_logic; -- indicates IP TX is ready to take data
|
|
|
-- system signals
|
-- system signals
|
clk : in STD_LOGIC; -- same clock used to clock mac data and ip data
|
clk : in std_logic; -- same clock used to clock mac data and ip data
|
reset : in STD_LOGIC;
|
reset : in std_logic;
|
our_ip_address : in STD_LOGIC_VECTOR (31 downto 0);
|
our_ip_address : in std_logic_vector (31 downto 0);
|
our_mac_address : in std_logic_vector (47 downto 0);
|
our_mac_address : in std_logic_vector (47 downto 0);
|
-- ARP lookup signals
|
-- ARP lookup signals
|
arp_req_req : out arp_req_req_type;
|
arp_req_req : out arp_req_req_type;
|
arp_req_rslt : in arp_req_rslt_type;
|
arp_req_rslt : in arp_req_rslt_type;
|
-- MAC layer TX signals
|
-- MAC layer TX signals
|
Line 64... |
Line 64... |
mac_data_out_valid : out std_logic; -- indicates data out is valid
|
mac_data_out_valid : out std_logic; -- indicates data out is valid
|
mac_data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame
|
mac_data_out_first : out std_logic; -- with data out valid indicates the first byte of a frame
|
mac_data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame
|
mac_data_out_last : out std_logic; -- with data out valid indicates the last byte of a frame
|
mac_data_out : out std_logic_vector (7 downto 0) -- ethernet frame (from dst mac addr through to last byte of frame)
|
mac_data_out : out std_logic_vector (7 downto 0) -- ethernet frame (from dst mac addr through to last byte of frame)
|
);
|
);
|
END COMPONENT;
|
end component;
|
|
|
|
|
--Inputs
|
--Inputs
|
signal ip_tx_start : std_logic := '0';
|
signal ip_tx_start : std_logic := '0';
|
signal ip_tx : ipv4_tx_type;
|
signal ip_tx : ipv4_tx_type;
|
Line 91... |
Line 91... |
signal arp_req_req : arp_req_req_type;
|
signal arp_req_req : arp_req_req_type;
|
|
|
-- Clock period definitions
|
-- Clock period definitions
|
constant clk_period : time := 8 ns;
|
constant clk_period : time := 8 ns;
|
|
|
BEGIN
|
begin
|
|
|
-- Instantiate the Unit Under Test (UUT)
|
-- Instantiate the Unit Under Test (UUT)
|
uut: IPv4_TX PORT MAP (
|
uut : IPv4_TX port map (
|
ip_tx_start => ip_tx_start,
|
ip_tx_start => ip_tx_start,
|
ip_tx => ip_tx,
|
ip_tx => ip_tx,
|
ip_tx_result => ip_tx_result,
|
ip_tx_result => ip_tx_result,
|
ip_tx_data_out_ready => ip_tx_data_out_ready,
|
ip_tx_data_out_ready => ip_tx_data_out_ready,
|
clk => clk,
|
clk => clk,
|
Line 141... |
Line 141... |
arp_req_rslt.mac <= (others => '0');
|
arp_req_rslt.mac <= (others => '0');
|
|
|
reset <= '1';
|
reset <= '1';
|
wait for clk_period*10;
|
wait for clk_period*10;
|
reset <= '0';
|
reset <= '0';
|
|
wait until clk = '1';
|
wait for clk_period*5;
|
wait for clk_period*5;
|
|
wait until clk = '1';
|
|
|
-- check reset conditions
|
-- check reset conditions
|
assert arp_req_req.lookup_req = '0' report "arp_req_req.lookup_req not initialised correctly on reset";
|
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_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 ip_tx_data_out_ready = '0' report "ip_tx_data_out_ready not initialised correctly on reset";
|
Line 163... |
Line 165... |
|
|
ip_tx.hdr.protocol <= x"35";
|
ip_tx.hdr.protocol <= x"35";
|
ip_tx.hdr.data_length <= x"0008";
|
ip_tx.hdr.data_length <= x"0008";
|
ip_tx.hdr.dst_ip_addr <= x"c0123478";
|
ip_tx.hdr.dst_ip_addr <= x"c0123478";
|
ip_tx_start <= '1';
|
ip_tx_start <= '1';
|
wait for clk_period;
|
wait until clk = '1';
|
ip_tx_start <= '0';
|
ip_tx_start <= '0';
|
arp_req_rslt.got_mac <= '0';
|
arp_req_rslt.got_mac <= '0';
|
arp_req_rslt.got_err <= '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 arp_req_req.lookup_req = '1' report "T1: lookup_req not set on tx start";
|
wait for clk_period;
|
|
assert ip_tx_result = IPTX_RESULT_SENDING report "T1: result should be IPTX_RESULT_SENDING";
|
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 for clk_period*10; -- simulate arp lookup time
|
|
wait until clk = '1';
|
arp_req_rslt.mac <= x"050423271016";
|
arp_req_rslt.mac <= x"050423271016";
|
arp_req_rslt.got_mac <= '1';
|
arp_req_rslt.got_mac <= '1';
|
|
|
wait for clk_period*2;
|
wait until clk = '1';
|
|
wait until clk = '1';
|
assert arp_req_req.lookup_req = '0' report "T1: lookup_req not clear after setting";
|
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";
|
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 for clk_period*10; -- simulate mac chn access time
|
|
wait until clk = '1';
|
mac_tx_granted <= '1';
|
mac_tx_granted <= '1';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1'; mac_data_out_ready <= '1';
|
mac_data_out_ready <= '1';
|
|
assert mac_data_out_valid = '0' report "T1: mac_data_out_valid asserted too early";
|
assert mac_data_out_valid = '0' report "T1: mac_data_out_valid asserted too early";
|
|
|
wait for clk_period;
|
wait until clk = '1';
|
|
|
assert ip_tx_data_out_ready = '0' report "T1: IP data out ready asserted too early";
|
assert ip_tx_data_out_ready = '0' report "T1: IP data out ready asserted too early";
|
wait for clk_period;
|
wait until clk = '1';
|
assert mac_data_out_valid = '1' report "T1: mac_data_out_valid not asserted";
|
assert mac_data_out_valid = '1' report "T1: mac_data_out_valid not asserted";
|
|
|
-- wait until in eth hdr
|
-- wait until in eth hdr
|
wait for clk_period*3;
|
wait for clk_period*3;
|
|
wait until clk = '1';
|
-- go mac not ready for 2 clocks
|
-- go mac not ready for 2 clocks
|
mac_data_out_ready <= '0';
|
mac_data_out_ready <= '0';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1'; wait until clk = '1';
|
mac_data_out_ready <= '1';
|
mac_data_out_ready <= '1';
|
|
|
|
|
wait until ip_tx_data_out_ready = '1';
|
wait until ip_tx_data_out_ready = '1';
|
|
wait until clk = '1';
|
|
|
-- start to tx IP data
|
-- start to tx IP data
|
ip_tx.data.data_out_valid <= '1';
|
ip_tx.data.data_out_valid <= '1';
|
ip_tx.data.data_out <= x"56"; wait for clk_period;
|
ip_tx.data.data_out <= x"56"; wait until clk = '1';
|
-- delay data in for 1 clk cycle
|
-- delay data in for 1 clk cycle
|
ip_tx.data.data_out_valid <= '0';
|
ip_tx.data.data_out_valid <= '0';
|
ip_tx.data.data_out <= x"57"; wait for clk_period;
|
ip_tx.data.data_out <= x"57"; wait until clk = '1';
|
ip_tx.data.data_out_valid <= '1'; wait for clk_period;
|
ip_tx.data.data_out_valid <= '1'; wait until clk = '1';
|
ip_tx.data.data_out <= x"58"; wait for clk_period;
|
ip_tx.data.data_out <= x"58"; wait until clk = '1';
|
ip_tx.data.data_out <= x"59"; wait for clk_period;
|
ip_tx.data.data_out <= x"59"; wait until clk = '1';
|
|
--wait for clk_period;
|
|
|
-- delay mac ready for 2 clk cycles
|
-- delay mac ready for 2 clk cycles
|
mac_data_out_ready <= '0';
|
mac_data_out_ready <= '0';
|
ip_tx.data.data_out <= x"5a"; wait for clk_period;
|
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";
|
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 for clk_period;
|
ip_tx.data.data_out <= x"5a"; wait until clk = '1';
|
|
--wait for clk_period;
|
mac_data_out_ready <= '1';
|
mac_data_out_ready <= '1';
|
wait until ip_tx_data_out_ready = '1';
|
wait until ip_tx_data_out_ready = '1';
|
wait for clk_period;
|
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";
|
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 for clk_period;
|
ip_tx.data.data_out <= x"5b"; wait until clk = '1';
|
ip_tx.data.data_out <= x"5c"; wait for clk_period;
|
ip_tx.data.data_out <= x"5c"; wait until clk = '1';
|
|
|
ip_tx.data.data_out <= x"5d";
|
ip_tx.data.data_out <= x"5d";
|
ip_tx.data.data_out_last <= '1';
|
ip_tx.data.data_out_last <= '1';
|
wait for clk_period;
|
wait until clk = '1';
|
assert mac_data_out_last = '1' report "T1: mac_datda_out_last not set on last byte";
|
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_valid <= '0';
|
ip_tx.data.data_out_last <= '0';
|
ip_tx.data.data_out_last <= '0';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1';
|
|
|
assert ip_tx_result = IPTX_RESULT_SENT report "T1: result should be IPTX_RESULT_SENT";
|
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";
|
assert mac_tx_req = '0' report "T1: mac_tx_req held on too long after TX";
|
|
|
mac_tx_granted <= '0';
|
mac_tx_granted <= '0';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1';
|
|
|
------------
|
------------
|
-- TEST 2 -- basic functional tx test with no delays for arp and chn access
|
-- 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";
|
report "T2: basic functional tx test with no delays for arp and chn access";
|
|
|
ip_tx.hdr.protocol <= x"11";
|
ip_tx.hdr.protocol <= x"11";
|
ip_tx.hdr.data_length <= x"0006";
|
ip_tx.hdr.data_length <= x"0006";
|
ip_tx.hdr.dst_ip_addr <= x"c0123478";
|
ip_tx.hdr.dst_ip_addr <= x"c0123478";
|
ip_tx_start <= '1';
|
ip_tx_start <= '1';
|
wait for clk_period;
|
wait until clk = '1';
|
ip_tx_start <= '0'; wait for clk_period;
|
ip_tx_start <= '0'; wait until clk = '1';
|
arp_req_rslt.got_mac <= '0';
|
arp_req_rslt.got_mac <= '0';
|
|
|
assert arp_req_req.lookup_req = '1' report "T2: lookup_req not set on tx start";
|
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";
|
assert ip_tx_result = IPTX_RESULT_SENDING report "T2: result should be IPTX_RESULT_SENDING";
|
|
|
wait for clk_period; -- simulate arp lookup time
|
wait until clk = '1'; -- simulate arp lookup time
|
arp_req_rslt.mac <= x"050423271016";
|
arp_req_rslt.mac <= x"050423271016";
|
arp_req_rslt.got_mac <= '1';
|
arp_req_rslt.got_mac <= '1';
|
|
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1';
|
|
|
assert arp_req_req.lookup_req = '0' report "T2: lookup_req not clear after setting";
|
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";
|
assert mac_tx_req = '1' report "T2: mac_tx_req not set after getting mac";
|
|
|
wait for clk_period; -- simulate mac chn access time
|
wait until clk = '1'; -- simulate mac chn access time
|
mac_tx_granted <= '1';
|
mac_tx_granted <= '1';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1'; mac_data_out_ready <= '1';
|
mac_data_out_ready <= '1';
|
|
|
|
assert ip_tx_data_out_ready = '0' report "T2: IP data out ready asserted too early";
|
assert ip_tx_data_out_ready = '0' report "T2: IP data out ready asserted too early";
|
|
|
wait until ip_tx_data_out_ready = '1';
|
wait until ip_tx_data_out_ready = '1';
|
|
|
-- start to tx IP data
|
-- start to tx IP data
|
ip_tx.data.data_out_valid <= '1';
|
ip_tx.data.data_out_valid <= '1';
|
ip_tx.data.data_out <= x"c1"; wait for clk_period;
|
ip_tx.data.data_out <= x"c1"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c2"; wait for clk_period;
|
ip_tx.data.data_out <= x"c2"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c3"; wait for clk_period;
|
ip_tx.data.data_out <= x"c3"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c4"; wait for clk_period;
|
ip_tx.data.data_out <= x"c4"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c5"; wait for clk_period;
|
ip_tx.data.data_out <= x"c5"; wait until clk = '1';
|
|
|
ip_tx.data.data_out <= x"c6";
|
ip_tx.data.data_out <= x"c6";
|
ip_tx.data.data_out_last <= '1';
|
ip_tx.data.data_out_last <= '1';
|
wait for clk_period;
|
wait until clk = '1';
|
|
|
assert mac_data_out_last = '1' report "T2: mac_datda_out_last not set on last byte";
|
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_valid <= '0';
|
ip_tx.data.data_out_last <= '0';
|
ip_tx.data.data_out_last <= '0';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1';
|
|
|
assert ip_tx_result = IPTX_RESULT_SENT report "T2: result should be IPTX_RESULT_SENT";
|
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";
|
assert mac_tx_req = '0' report "T2: mac_tx_req held on too long after TX";
|
|
|
mac_tx_granted <= '0';
|
mac_tx_granted <= '0';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1';
|
|
|
------------
|
------------
|
-- TEST 3 -- tx test for IP broadcast, should be no arp req
|
-- TEST 3 -- tx test for IP broadcast, should be no arp req
|
------------
|
------------
|
|
|
report "T3: 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.protocol <= x"11";
|
ip_tx.hdr.data_length <= x"0006";
|
ip_tx.hdr.data_length <= x"0006";
|
ip_tx.hdr.dst_ip_addr <= x"ffffffff";
|
ip_tx.hdr.dst_ip_addr <= x"ffffffff";
|
ip_tx_start <= '1';
|
ip_tx_start <= '1';
|
wait for clk_period;
|
wait until clk = '1';
|
ip_tx_start <= '0'; wait for clk_period;
|
ip_tx_start <= '0'; wait until clk = '1';
|
arp_req_rslt.got_mac <= '0';
|
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 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";
|
assert ip_tx_result = IPTX_RESULT_SENDING report "T3: result should be IPTX_RESULT_SENDING";
|
|
|
wait for clk_period; -- simulate mac chn access time
|
wait until clk = '1'; -- simulate mac chn access time
|
mac_tx_granted <= '1';
|
mac_tx_granted <= '1';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1'; mac_data_out_ready <= '1';
|
mac_data_out_ready <= '1';
|
|
|
|
assert ip_tx_data_out_ready = '0' report "T3: IP data out ready asserted too early";
|
assert ip_tx_data_out_ready = '0' report "T3: IP data out ready asserted too early";
|
|
|
wait until ip_tx_data_out_ready = '1';
|
wait until ip_tx_data_out_ready = '1';
|
|
|
-- start to tx IP data
|
-- start to tx IP data
|
ip_tx.data.data_out_valid <= '1';
|
ip_tx.data.data_out_valid <= '1';
|
ip_tx.data.data_out <= x"c1"; wait for clk_period;
|
ip_tx.data.data_out <= x"c1"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c2"; wait for clk_period;
|
ip_tx.data.data_out <= x"c2"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c3"; wait for clk_period;
|
ip_tx.data.data_out <= x"c3"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c4"; wait for clk_period;
|
ip_tx.data.data_out <= x"c4"; wait until clk = '1';
|
ip_tx.data.data_out <= x"c5"; wait for clk_period;
|
ip_tx.data.data_out <= x"c5"; wait until clk = '1';
|
|
|
ip_tx.data.data_out <= x"c6";
|
ip_tx.data.data_out <= x"c6";
|
ip_tx.data.data_out_last <= '1';
|
ip_tx.data.data_out_last <= '1';
|
wait for clk_period;
|
wait until clk = '1';
|
|
|
assert mac_data_out_last = '1' report "T3: mac_datda_out_last not set on last byte";
|
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_valid <= '0';
|
ip_tx.data.data_out_last <= '0';
|
ip_tx.data.data_out_last <= '0';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1';
|
|
|
assert ip_tx_result = IPTX_RESULT_SENT report "T3: result should be IPTX_RESULT_SENT";
|
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";
|
assert mac_tx_req = '0' report "T3: mac_tx_req held on too long after TX";
|
|
|
mac_tx_granted <= '0';
|
mac_tx_granted <= '0';
|
wait for clk_period*2;
|
wait until clk = '1'; wait until clk = '1';
|
|
|
|
|
report "--- end of tests ---";
|
report "--- end of tests ---";
|
|
|
wait;
|
wait;
|
end process;
|
end process;
|
|
|
END;
|
end;
|
|
|
No newline at end of file
|
No newline at end of file
|