diff options
Diffstat (limited to 'netfpga10g/tests')
-rw-r--r-- | netfpga10g/tests/buff_test.vhd | 151 | ||||
-rw-r--r-- | netfpga10g/tests/engine_test.vhd | 1123 | ||||
-rw-r--r-- | netfpga10g/tests/eth_buff_loop_test.vhd | 173 | ||||
-rw-r--r-- | netfpga10g/tests/eth_rx_test.vhd | 225 | ||||
-rw-r--r-- | netfpga10g/tests/eth_tx_test.vhd | 126 | ||||
-rw-r--r-- | netfpga10g/tests/pcie_rx_test.vhd | 322 | ||||
-rw-r--r-- | netfpga10g/tests/pcie_tx_test.vhd | 561 | ||||
-rw-r--r-- | netfpga10g/tests/queue_test.vhd | 149 | ||||
-rw-r--r-- | netfpga10g/tests/send_mux_test.vhd | 199 | ||||
-rw-r--r-- | netfpga10g/tests/system_loop_test.vhd | 285 |
10 files changed, 3314 insertions, 0 deletions
diff --git a/netfpga10g/tests/buff_test.vhd b/netfpga10g/tests/buff_test.vhd new file mode 100644 index 0000000..d9f4a0a --- /dev/null +++ b/netfpga10g/tests/buff_test.vhd @@ -0,0 +1,151 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY buff_test IS +END buff_test; + +ARCHITECTURE behavior OF buff_test IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT buff + PORT( + wr_clk : IN std_logic; + wr_en : IN std_logic; + wr_data : IN std_logic_vector(63 downto 0); + wr_done : IN std_logic; + wr_accept : OUT std_logic; + rd_clk : IN std_logic; + rd_en : IN std_logic; + rd_data : OUT std_logic_vector(63 downto 0); + rd_length : OUT std_logic_vector(8 downto 0); + rd_valid : OUT std_logic + ); + END COMPONENT; + + + signal wr_clk : std_logic := '0'; + signal wr_en : std_logic := '0'; + signal wr_data : std_logic_vector(63 downto 0) := (others => '0'); + signal wr_done : std_logic := '0'; + signal wr_accept : std_logic; + + signal rd_clk : std_logic := '0'; + signal rd_en : std_logic := '0'; + signal rd_data : std_logic_vector(63 downto 0); + signal rd_length : std_logic_vector(8 downto 0); + signal rd_valid : std_logic; + + -- Clock period definitions + constant wr_clk_period : time := 10 ns; + constant rd_clk_period : time := 7 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: buff PORT MAP ( + wr_clk => wr_clk, + wr_en => wr_en, + wr_data => wr_data, + wr_done => wr_done, + wr_accept => wr_accept, + rd_clk => rd_clk, + rd_en => rd_en, + rd_data => rd_data, + rd_length => rd_length, + rd_valid => rd_valid + ); + + -- Clock process definitions + wr_clk_process :process + begin + wr_clk <= '0'; + wait for wr_clk_period/2; + wr_clk <= '1'; + wait for wr_clk_period/2; + end process; + + rd_clk_process :process + begin + rd_clk <= '0'; + wait for rd_clk_period/2; + rd_clk <= '1'; + wait for rd_clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + wait for wr_clk_period; + + wr_en <= '1'; + wr_data <= x"0123456789ABCDEF"; + + wait for wr_clk_period; + + wr_en <= '1'; + wr_data <= x"FEDCBA9876543210"; + + wait for wr_clk_period; + + wr_en <= '0'; + wr_data <= x"0000000000000000"; + wr_done <= '1'; + + wait for wr_clk_period; + + wr_done <= '0'; + + wait until wr_accept = '1'; + wait for wr_clk_period / 2; + + wr_en <= '1'; + wr_data <= x"AAAAAAAAAAAAAAAA"; + wait for wr_clk_period; + wr_data <= x"BBBBBBBBBBBBBBBB"; + wait for wr_clk_period; + wr_data <= x"CCCCCCCCCCCCCCCC"; + wait for wr_clk_period; + wr_data <= x"DDDDDDDDDDDDDDDD"; + wait for wr_clk_period; + wr_en <= '0'; + wr_data <= x"0000000000000000"; + wr_done <= '1'; + wait for wr_clk_period; + wr_done <= '0'; + + wait until wr_accept = '1'; + wait for wr_clk_period / 2; + wait for wr_clk_period; + + wr_en <= '1'; + wr_data <= x"0123456789ABCDEF"; + wait for wr_clk_period; + wr_data <= x"FEDCBA9876543210"; + wait for wr_clk_period; + wr_data <= x"0123456789ABCDEF"; + wait for wr_clk_period; + wr_data <= x"FEDCBA9876543210"; + wait for wr_clk_period; + + wr_en <= '0'; + wr_data <= x"0000000000000000"; + wr_done <= '1'; + wait for wr_clk_period; + wr_done <= '0'; + + wait; + end process; + + process + begin + rd_en <= '0'; + wait for rd_clk_period; + rd_en <= '1'; + wait for rd_clk_period * 2; + end process; + +END; diff --git a/netfpga10g/tests/engine_test.vhd b/netfpga10g/tests/engine_test.vhd new file mode 100644 index 0000000..bf1b3c3 --- /dev/null +++ b/netfpga10g/tests/engine_test.vhd @@ -0,0 +1,1123 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY engine_test IS +END engine_test; + +ARCHITECTURE behavior OF engine_test IS + + COMPONENT engine + PORT( + clk : IN std_logic; + rd_buff : OUT std_logic_vector(3 downto 0); + rd_en : OUT std_logic; + rd_data : IN std_logic_vector(63 downto 0); + rd_length : IN std_logic_vector(8 downto 0); + rd_valid : IN std_logic_vector(15 downto 0); + wr_buff : OUT std_logic_vector(3 downto 0); + wr_en : OUT std_logic; + wr_data : OUT std_logic_vector(63 downto 0); + wr_done : OUT std_logic; + wr_accept : IN std_logic_vector(15 downto 0); + rx_read : IN std_logic; + rx_write : IN std_logic; + rx_complete : IN std_logic; + rx_data : IN std_logic_vector(63 downto 0); + rx_address : IN std_logic_vector(63 downto 3); + rx_tag : IN std_logic_vector(4 downto 0); + tx_read : OUT std_logic; + tx_write : OUT std_logic; + tx_complete : OUT std_logic; + tx_data : OUT std_logic_vector(63 downto 0); + tx_address : OUT std_logic_vector(63 downto 3); + tx_length : OUT std_logic_vector(8 downto 0); + tx_tag : OUT std_logic_vector(4 downto 0); + tx_accept : IN std_logic; + tx_done : IN std_logic; + interrupt : OUT std_logic; + interrupt_rdy : IN std_logic; + max_read : IN std_logic_vector(2 downto 0); + max_write : IN std_logic_vector(2 downto 0) + ); + END COMPONENT; + + signal clk : std_logic := '0'; + + signal rd_buff : std_logic_vector(3 downto 0); + signal rd_en : std_logic; + signal rd_data : std_logic_vector(63 downto 0) := (others => '0'); + signal rd_length : std_logic_vector(8 downto 0) := (others => '0'); + signal rd_valid : std_logic_vector(15 downto 0) := (others => '0'); + + signal wr_buff : std_logic_vector(3 downto 0); + signal wr_en : std_logic; + signal wr_data : std_logic_vector(63 downto 0); + signal wr_done : std_logic; + signal wr_accept : std_logic_vector(15 downto 0) := (others => '0'); + + signal rx_read : std_logic := '0'; + signal rx_write : std_logic := '0'; + signal rx_complete : std_logic := '0'; + signal rx_data : std_logic_vector(63 downto 0) := (others => '0'); + signal rx_address : std_logic_vector(63 downto 3) := (others => '0'); + signal rx_tag : std_logic_vector(4 downto 0) := (others => '0'); + + signal tx_read : std_logic; + signal tx_write : std_logic; + signal tx_complete : std_logic; + signal tx_data : std_logic_vector(63 downto 0); + signal tx_address : std_logic_vector(63 downto 3); + signal tx_length : std_logic_vector(8 downto 0); + signal tx_tag : std_logic_vector(4 downto 0); + signal tx_accept : std_logic := '0'; + signal tx_done : std_logic := '0'; + + signal interrupt : std_logic; + signal interrupt_rdy : std_logic := '0'; + + signal max_read : std_logic_vector(2 downto 0) := (others => '0'); + signal max_write : std_logic_vector(2 downto 0) := (others => '0'); + + constant clk_period : time := 10 ns; + + signal test_fail : std_logic := '0'; + + constant CMD_STATUS : std_logic_vector(1 downto 0) := "00"; + constant CMD_SEND : std_logic_vector(1 downto 0) := "01"; + constant CMD_RECV : std_logic_vector(1 downto 0) := "10"; + constant CMD_MDIO : std_logic_vector(1 downto 0) := "11"; + + constant ADDR_31 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(31, 61)); + constant ADDR_32 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(32, 61)); + constant ADDR_4 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(4, 61)); + + constant LEN_3 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(3, 9)); + constant LEN_2 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(2, 9)); + constant LEN_1 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(1, 9)); + + constant BUFF_0 : std_logic_vector(3 downto 0) := std_logic_vector(to_unsigned(0, 4)); + constant BUFF_2 : std_logic_vector(3 downto 0) := std_logic_vector(to_unsigned(2, 4)); + constant BUFF_5 : std_logic_vector(3 downto 0) := std_logic_vector(to_unsigned(5, 4)); + + constant TAG_2 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(2, 5)); + constant TAG_5 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(5, 5)); + + constant EMPTY : std_logic_vector(1 downto 0) := "00"; + constant ADDR : std_logic_vector(1 downto 0) := "01"; + constant DATA : std_logic_vector(1 downto 0) := "10"; + constant FULL : std_logic_vector(1 downto 0) := "11"; + + constant DATA_A : std_logic_vector(63 downto 0) := x"123AAAAAAAAAAAAA"; + constant DATA_B : std_logic_vector(63 downto 0) := x"123BBBBBBBBBBBBB"; + constant DATA_C : std_logic_vector(63 downto 0) := x"123CCCCCCCCCCCCC"; + constant DATA_D : std_logic_vector(63 downto 0) := x"123DDDDDDDDDDDDD"; + constant DATA_E : std_logic_vector(63 downto 0) := x"123EEEEEEEEEEEEE"; +BEGIN + + uut: engine PORT MAP ( + clk => clk, + rd_buff => rd_buff, + rd_en => rd_en, + rd_data => rd_data, + rd_length => rd_length, + rd_valid => rd_valid, + wr_buff => wr_buff, + wr_en => wr_en, + wr_data => wr_data, + wr_done => wr_done, + wr_accept => wr_accept, + rx_read => rx_read, + rx_write => rx_write, + rx_complete => rx_complete, + rx_data => rx_data, + rx_address => rx_address, + rx_tag => rx_tag, + tx_read => tx_read, + tx_write => tx_write, + tx_complete => tx_complete, + tx_data => tx_data, + tx_address => tx_address, + tx_length => tx_length, + tx_tag => tx_tag, + tx_accept => tx_accept, + tx_done => tx_done, + interrupt => interrupt, + interrupt_rdy => interrupt_rdy, + max_read => max_read, + max_write => max_write + ); + + -- 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 + wr_accept <= (others => '1'); + + wait for clk_period; + + -- read status + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- send page: addr = 31, len = 3, data = ABC, buff = 2 + -- expecting two reads: + -- first: addr = 31, len = 1, tag = 2 + -- second: addr = 32, len = 2, tag = 2 + + rx_write <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_SEND; + rx_address(8 downto 5) <= BUFF_2; + rx_address(18 downto 10) <= LEN_3; + rx_data <= ADDR_31 & "000"; + + wait for clk_period * 3; + + if tx_read /= '1' or + tx_address /= ADDR_31 or + tx_length /= LEN_1 or + tx_tag /= TAG_2 then + test_fail <= '1'; + end if; + + rx_write <= '0'; + rx_address <= (others => '0'); + rx_data <= (others => '0'); + tx_done <= '1'; + + wait for clk_period; + + if tx_read /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- read status again + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' or + tx_data(2*4 + 1 downto 2*4 + 0) /= DATA or + tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- answer the previous read with completions + -- data = A, tag = 2, len = 1 + rx_complete <= '1'; + rx_data <= DATA_A; + rx_tag <= TAG_2; + + wait for clk_period; + + -- expect wr_en (buff = 2, data = A) + if wr_buff /= BUFF_2 or + wr_en /= '1' or + wr_data /= DATA_A or + wr_done /= '0' or + tx_read /= '0' then + test_fail <= '1'; + end if; + + rx_complete <= '0'; + rx_data <= (others => '0'); + rx_tag <= (others => '0'); + + wait for clk_period * 2; + + -- expect new tx_read (tag 2, len 2, addr 32) + if wr_en /= '0' or + tx_read /= '1' or + tx_tag /= TAG_2 or + tx_length /= LEN_2 or + tx_address /= ADDR_32 then + test_fail <= '1'; + end if; + + tx_done <= '1'; + + wait for clk_period; + + if tx_read /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + -- answer read with completions + -- data = B and C, tag = 2, len = 2 + rx_complete <= '1'; + rx_data <= DATA_B; + rx_tag <= TAG_2; + + wait for clk_period; + + -- expect wr_en (buff = 2, data = B) and no tx action + if wr_buff /= BUFF_2 or + wr_en /= '1' or + wr_data /= DATA_B or + wr_done /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_complete <= '1'; + rx_data <= DATA_C; + rx_tag <= TAG_2; + + wait for clk_period; + + -- expect wr_en (buff = 2, data = C) and no tx action + if wr_buff /= BUFF_2 or + wr_en /= '1' or + wr_data /= DATA_C or + wr_done /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_complete <= '0'; + rx_data <= (others => '0'); + rx_tag <= (others => '0'); + + wait for clk_period; + + -- expect wr_done and no tx action + if wr_done /= '1' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- buff will respond to wr_done with wr_accept = 0 + wr_accept(2) <= '0'; + + wait for clk_period; + + -- read status again + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' or + tx_data(2*4 + 1 downto 2*4 + 0) /= FULL or + tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + wr_accept(2) <= '1'; + + wait for clk_period; + + -- read status again, but this time buff must be EMPTY + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' or + tx_data(2*4 + 1 downto 2*4 + 0) /= EMPTY or + tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + -- EMPTY buff doesn't result in interrupt, because status is just read + if tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- RECEIVE PACKET + -- the buff will say there is data to read (rd_valid) + -- interrupt will be send + -- status is read + -- addr will be gotten via rx_write + -- data will be send via tx_write + -- interrupt will be send + + -- no reading and no tx actions + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- buff 5 becomes valid + rd_valid(5) <= '1'; + + wait for clk_period * 2; + + -- expect interrupt + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '1' then + test_fail <= '1'; + end if; + + -- read status again + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + interrupt_rdy <= '1'; + + wait for clk_period; + + -- expect complete, no interrupt + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '1' or + interrupt /= '0' or + tx_data(5*4 + 1 downto 5*4 + 0) /= EMPTY or + tx_data(5*4 + 3 downto 5*4 + 2) /= FULL then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + interrupt_rdy <= '0'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- no reading and no tx actions + if rd_en /= '0' or + rd_buff /= BUFF_0 or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- recv page: addr = 4, buff = 5 + rx_write <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_RECV; + rx_address(8 downto 5) <= BUFF_5; + rx_data <= ADDR_4 & "000"; + + wait for clk_period; + + -- no reading and no tx actions + if rd_en /= '0' or + rd_buff /= BUFF_0 or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_write <= '0'; + rx_address <= (others => '0'); + rx_data <= (others => '0'); + + wait for clk_period; + + -- expect to read buff 5, but no tx actions yet + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- data = D and E, length = 2 + rd_data <= DATA_D; + rd_length <= LEN_2; + + wait for clk_period; + + -- tx_write: data = D, addr = 4, length = 2 + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_D or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- same + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_D or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + tx_accept <= '1'; + + wait for clk_period; + + -- data D + if rd_en /= '1' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_D or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + rd_data <= DATA_E; + + wait for clk_period; + + -- data E + if rd_en /= '1' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_E or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + rd_valid(5) <= '0'; + rd_data <= (others => '0'); + rd_length <= (others => '0'); + tx_accept <= '0'; + tx_done <= '1'; + + wait for clk_period; + + -- nothing + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- interrupt because writing is done + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '1' then + test_fail <= '1'; + end if; + + interrupt_rdy <= '1'; + + wait for clk_period; + + -- nothing + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + interrupt_rdy <= '0'; + + wait for clk_period * 5; + + + + -- ====================== + -- LETS GO AGAIN !!!!!!! + -- ====================== + + + + -- read status + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- send page: addr = 31, len = 3, data = ABC, buff = 2 + -- expecting two reads: + -- first: addr = 31, len = 1, tag = 2 + -- second: addr = 32, len = 2, tag = 2 + + rx_write <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_SEND; + rx_address(8 downto 5) <= BUFF_2; + rx_address(18 downto 10) <= LEN_3; + rx_data <= ADDR_31 & "000"; + + wait for clk_period * 3; + + if tx_read /= '1' or + tx_address /= ADDR_31 or + tx_length /= LEN_1 or + tx_tag /= TAG_2 then + test_fail <= '1'; + end if; + + rx_write <= '0'; + rx_address <= (others => '0'); + rx_data <= (others => '0'); + tx_done <= '1'; + + wait for clk_period; + + if tx_read /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- read status again + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' or + tx_data(2*4 + 1 downto 2*4 + 0) /= DATA or + tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- answer the previous read with completions + -- data = A, tag = 2, len = 1 + rx_complete <= '1'; + rx_data <= DATA_A; + rx_tag <= TAG_2; + + wait for clk_period; + + -- expect wr_en (buff = 2, data = A) + if wr_buff /= BUFF_2 or + wr_en /= '1' or + wr_data /= DATA_A or + wr_done /= '0' or + tx_read /= '0' then + test_fail <= '1'; + end if; + + rx_complete <= '0'; + rx_data <= (others => '0'); + rx_tag <= (others => '0'); + + wait for clk_period * 2; + + -- expect new tx_read (tag 2, len 2, addr 32) + if wr_en /= '0' or + tx_read /= '1' or + tx_tag /= TAG_2 or + tx_length /= LEN_2 or + tx_address /= ADDR_32 then + test_fail <= '1'; + end if; + + tx_done <= '1'; + + wait for clk_period; + + if tx_read /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + -- answer read with completions + -- data = B and C, tag = 2, len = 2 + rx_complete <= '1'; + rx_data <= DATA_B; + rx_tag <= TAG_2; + + wait for clk_period; + + -- expect wr_en (buff = 2, data = B) and no tx action + if wr_buff /= BUFF_2 or + wr_en /= '1' or + wr_data /= DATA_B or + wr_done /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_complete <= '1'; + rx_data <= DATA_C; + rx_tag <= TAG_2; + + wait for clk_period; + + -- expect wr_en (buff = 2, data = C) and no tx action + if wr_buff /= BUFF_2 or + wr_en /= '1' or + wr_data /= DATA_C or + wr_done /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_complete <= '0'; + rx_data <= (others => '0'); + rx_tag <= (others => '0'); + + wait for clk_period; + + -- expect wr_done and no tx action + if wr_done /= '1' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- buff will respond to wr_done with wr_accept = 0 + wr_accept(2) <= '0'; + + wait for clk_period; + + -- read status again + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' or + tx_data(2*4 + 1 downto 2*4 + 0) /= FULL or + tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + wr_accept(2) <= '1'; + + wait for clk_period; + + -- read status again, but this time buff must be EMPTY + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + + wait for clk_period; + + if tx_complete /= '1' or + tx_data(2*4 + 1 downto 2*4 + 0) /= EMPTY or + tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + + wait for clk_period; + + -- EMPTY buff doesn't result in interrupt, because status is just read + if tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- RECEIVE PACKET + -- the buff will say there is data to read (rd_valid) + -- interrupt will be send + -- status is read + -- addr will be gotten via rx_write + -- data will be send via tx_write + -- interrupt will be send + + -- no reading and no tx actions + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- buff 5 becomes valid + rd_valid(5) <= '1'; + + wait for clk_period * 2; + + -- expect interrupt + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '1' then + test_fail <= '1'; + end if; + + -- read status again + rx_read <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_STATUS; + interrupt_rdy <= '1'; + + wait for clk_period; + + -- expect complete, no interrupt + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '1' or + interrupt /= '0' or + tx_data(5*4 + 1 downto 5*4 + 0) /= EMPTY or + tx_data(5*4 + 3 downto 5*4 + 2) /= FULL then + test_fail <= '1'; + end if; + + rx_read <= '0'; + tx_done <= '1'; + interrupt_rdy <= '0'; + + wait for clk_period; + + if tx_complete /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- no reading and no tx actions + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- recv page: addr = 4, buff = 5 + rx_write <= '1'; + rx_address <= (others => '0'); + rx_address(4 downto 3) <= CMD_RECV; + rx_address(8 downto 5) <= BUFF_5; + rx_data <= ADDR_4 & "000"; + + wait for clk_period; + + -- no reading and no tx actions + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_write <= '0'; + rx_address <= (others => '0'); + rx_data <= (others => '0'); + + wait for clk_period; + + -- expect to read buff 5, but no tx actions yet + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- data = D and E, length = 2 + rd_data <= DATA_D; + rd_length <= LEN_2; + + wait for clk_period; + + -- tx_write: data = D, addr = 4, length = 2 + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_D or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- same + if rd_en /= '0' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_D or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + tx_accept <= '1'; + + wait for clk_period; + + -- data D + if rd_en /= '1' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_D or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + rd_data <= DATA_E; + + wait for clk_period; + + -- data E + if rd_en /= '1' or + rd_buff /= BUFF_5 or + tx_read /= '0' or + tx_write /= '1' or + tx_complete /= '0' or + interrupt /= '0' or + tx_data /= DATA_E or + tx_address /= ADDR_4 or + tx_length /= LEN_2 then + test_fail <= '1'; + end if; + + rd_valid(5) <= '0'; + rd_data <= (others => '0'); + rd_length <= (others => '0'); + tx_accept <= '0'; + tx_done <= '1'; + + wait for clk_period; + + -- nothing + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + tx_done <= '0'; + + wait for clk_period; + + -- interrupt because writing is done + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '1' then + test_fail <= '1'; + end if; + + interrupt_rdy <= '1'; + + wait for clk_period; + + -- nothing + if rd_en /= '0' or + tx_read /= '0' or + tx_write /= '0' or + tx_complete /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + interrupt_rdy <= '0'; + + wait for clk_period * 5; + + + + + + + + + wait; + end process; + +END; diff --git a/netfpga10g/tests/eth_buff_loop_test.vhd b/netfpga10g/tests/eth_buff_loop_test.vhd new file mode 100644 index 0000000..b8c5902 --- /dev/null +++ b/netfpga10g/tests/eth_buff_loop_test.vhd @@ -0,0 +1,173 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY eth_buff_loop_test IS +END eth_buff_loop_test; + +ARCHITECTURE behavior OF eth_buff_loop_test IS + + signal eth_clk : std_logic := '0'; + signal pcie_clk: std_logic := '0'; + + signal eth_rd_en : std_logic := '0'; + signal eth_rd_data : std_logic_vector(63 downto 0); + signal eth_rd_length : std_logic_vector(8 downto 0); + signal eth_rd_valid : std_logic; + + signal eth_wr_en : std_logic := '0'; + signal eth_wr_data : std_logic_vector(63 downto 0) := (others => '0'); + signal eth_wr_done : std_logic := '0'; + signal eth_wr_accept : std_logic; + + signal pcie_rd_en : std_logic := '0'; + signal pcie_rd_data : std_logic_vector(63 downto 0); + signal pcie_rd_length : std_logic_vector(8 downto 0); + signal pcie_rd_valid : std_logic; + + signal pcie_wr_en : std_logic := '0'; + signal pcie_wr_data : std_logic_vector(63 downto 0) := (others => '0'); + signal pcie_wr_done : std_logic := '0'; + signal pcie_wr_accept : std_logic; + + constant eth_clk_period : time := 7 ns; + constant pcie_clk_period : time := 10 ns; + + signal xgmii_data : std_logic_vector(63 downto 0); + signal xgmii_control : std_logic_vector(7 downto 0); + + signal test_fail : std_logic := '0'; + +BEGIN + + buff_tx : entity work.buff port map ( + wr_clk => pcie_clk, + wr_en => pcie_wr_en, + wr_data => pcie_wr_data, + wr_done => pcie_wr_done, + wr_accept => pcie_wr_accept, + rd_clk => eth_clk, + rd_en => eth_rd_en, + rd_data => eth_rd_data, + rd_length => eth_rd_length, + rd_valid => eth_rd_valid + ); + + buff_rx : entity work.buff port map ( + wr_clk => eth_clk, + wr_en => eth_wr_en, + wr_data => eth_wr_data, + wr_done => eth_wr_done, + wr_accept => eth_wr_accept, + rd_clk => pcie_clk, + rd_en => pcie_rd_en, + rd_data => pcie_rd_data, + rd_length => pcie_rd_length, + rd_valid => pcie_rd_valid + ); + + eth_rx: entity work.eth_rx port map( + clk => eth_clk, + wr_en => eth_wr_en, + wr_data => eth_wr_data, + wr_done => eth_wr_done, + wr_accept => eth_wr_accept, + xgmii_rxd => xgmii_data, + xgmii_rxc => xgmii_control + ); + + eth_tx: entity work.eth_tx port map ( + clk => eth_clk, + rd_en => eth_rd_en, + rd_data => eth_rd_data, + rd_valid => eth_rd_valid, + xgmii_txd => xgmii_data, + xgmii_txc => xgmii_control + ); + + -- Clock process definitions + eth_clk_process : process + begin + eth_clk <= '0'; + wait for eth_clk_period/2; + eth_clk <= '1'; + wait for eth_clk_period/2; + end process; + + pcie_clk_process :process + begin + pcie_clk <= '0'; + wait for pcie_clk_period/2; + pcie_clk <= '1'; + wait for pcie_clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + wait for pcie_clk_period; + + if pcie_wr_accept /= '1' then + test_fail <= '1'; + end if; + + pcie_wr_en <= '1'; + pcie_wr_data <= x"0123456789ABCDEF"; + + wait for pcie_clk_period; + + pcie_wr_en <= '1'; + pcie_wr_data <= x"AAAAAAAAAAAAAAAA"; + + wait for pcie_clk_period; + + pcie_wr_en <= '0'; + pcie_wr_data <= (others => '0'); + pcie_wr_done <= '1'; + + wait for pcie_clk_period; + + pcie_wr_done <= '0'; + + wait until pcie_rd_valid = '1'; + wait for pcie_clk_period / 2; + + if pcie_rd_data /= x"0123456789ABCDEF" or + pcie_rd_length /= "000000010" then + test_fail <= '1'; + end if; + + pcie_rd_en <= '1'; + + wait for pcie_clk_period; + + if pcie_rd_data /= x"AAAAAAAAAAAAAAAA" then + test_fail <= '1'; + end if; + + pcie_rd_en <= '1'; + + wait for pcie_clk_period; + + if pcie_rd_valid /= '0' or + pcie_rd_data /= x"0000000000000000" or + pcie_rd_length /= "000000000" then + test_fail <= '1'; + end if; + + pcie_rd_en <= '0'; + + wait for pcie_clk_period; + + if pcie_rd_valid /= '0' or + pcie_rd_data /= x"0000000000000000" or + pcie_rd_length /= "000000000" then + test_fail <= '1'; + end if; + + wait; + end process; + +END; diff --git a/netfpga10g/tests/eth_rx_test.vhd b/netfpga10g/tests/eth_rx_test.vhd new file mode 100644 index 0000000..7497a97 --- /dev/null +++ b/netfpga10g/tests/eth_rx_test.vhd @@ -0,0 +1,225 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY eth_rx_test IS +END eth_rx_test; + +ARCHITECTURE behavior OF eth_rx_test IS + + COMPONENT eth_rx + PORT( + clk : IN std_logic; + wr_en : OUT std_logic; + wr_data : OUT std_logic_vector(63 downto 0); + wr_done : OUT std_logic; + wr_accept : IN std_logic; + xgmii_rxd : IN std_logic_vector(63 downto 0); + xgmii_rxc : IN std_logic_vector(7 downto 0) + ); + END COMPONENT; + + signal clk : std_logic := '0'; + + signal wr_en : std_logic; + signal wr_data : std_logic_vector(63 downto 0); + signal wr_done : std_logic; + signal wr_accept : std_logic := '0'; + + signal xgmii_rxd : std_logic_vector(63 downto 0) := (others => '0'); + signal xgmii_rxc : std_logic_vector(7 downto 0) := (others => '0'); + + constant clk_period : time := 10 ns; + + constant IDLE : std_logic_vector(7 downto 0) := x"07"; + constant START : std_logic_vector(7 downto 0) := x"FB"; + constant TERM : std_logic_vector(7 downto 0) := x"FD"; + constant ERR : std_logic_vector(7 downto 0) := x"FE"; + + constant PRE : std_logic_vector(7 downto 0) := "01010101"; + constant SFD : std_logic_vector(7 downto 0) := "11010101"; + + signal test_fail : std_logic := '0'; +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: eth_rx PORT MAP ( + clk => clk, + wr_en => wr_en, + wr_data => wr_data, + wr_done => wr_done, + wr_accept => wr_accept, + xgmii_rxd => xgmii_rxd, + xgmii_rxc => xgmii_rxc + ); + + -- 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 + xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE; + xgmii_rxc <= "00000000"; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START; + xgmii_rxc <= "00000001"; + wr_accept <= '1'; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= x"EFCDAB8967452301"; + xgmii_rxc <= "00000000"; + + wait for clk_period; + + if wr_en /= '1' or + wr_data /= x"0123456789ABCDEF" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & TERM; + xgmii_rxc <= "11111111"; + + wait for clk_period; + + if wr_done /= '1' then + test_fail <= '1'; + end if; + + xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE; + xgmii_rxc <= "11111111"; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START; + xgmii_rxc <= "00000001"; + wr_accept <= '0'; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= x"EFCDAB8967452301"; + xgmii_rxc <= "00000000"; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START; + xgmii_rxc <= "00000001"; + wr_accept <= '1'; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= x"ABCDABCDABCDABCD"; + xgmii_rxc <= "00000000"; + + wait for clk_period; + + if wr_en /= '1' or + wr_data /= x"CDABCDABCDABCDAB" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= IDLE & IDLE & IDLE & ERR & IDLE & IDLE & IDLE & IDLE; + xgmii_rxc <= "00010000"; + + wait for clk_period; + + if wr_done /= '1' then + test_fail <= '1'; + end if; + + xgmii_rxd <= PRE & PRE & PRE & START & IDLE & IDLE & IDLE & IDLE; + xgmii_rxc <= "00011111"; + wr_accept <= '1'; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= x"67452311" & SFD & PRE & PRE & PRE; + xgmii_rxc <= "00000000"; + + wait for clk_period; + + if wr_en /= '0' or + wr_data /= x"0000000000000000" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= IDLE & IDLE & IDLE & TERM & x"EFCDAB89"; + xgmii_rxc <= "11110000"; + + wait for clk_period; + + if wr_en /= '1' or + wr_data /= x"1123456789ABCDEF" or + wr_done /= '0' then + test_fail <= '1'; + end if; + + xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE; + xgmii_rxc <= "11111111"; + + wait for clk_period; + + if wr_done /= '1' then + test_fail <= '1'; + end if; + + wait; + end process; + +END; diff --git a/netfpga10g/tests/eth_tx_test.vhd b/netfpga10g/tests/eth_tx_test.vhd new file mode 100644 index 0000000..0697b84 --- /dev/null +++ b/netfpga10g/tests/eth_tx_test.vhd @@ -0,0 +1,126 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY eth_tx_test IS +END eth_tx_test; + +ARCHITECTURE behavior OF eth_tx_test IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT eth_tx + PORT( + clk : IN std_logic; + rd_en : OUT std_logic; + rd_data : IN std_logic_vector(63 downto 0); + rd_valid : IN std_logic; + xgmii_txd : OUT std_logic_vector(63 downto 0); + xgmii_txc : OUT std_logic_vector(7 downto 0) + ); + END COMPONENT; + + signal clk : std_logic := '0'; + signal rd_en : std_logic; + signal rd_data : std_logic_vector(63 downto 0) := (others => '0'); + signal rd_valid : std_logic := '0'; + + signal xgmii_txd : std_logic_vector(63 downto 0); + signal xgmii_txc : std_logic_vector(7 downto 0); + + -- Clock period definitions + constant clk_period : time := 10 ns; + + signal test_fail : std_logic := '0'; + + constant IDLE : std_logic_vector(7 downto 0) := x"07"; + constant START : std_logic_vector(7 downto 0) := x"FB"; + constant TERM : std_logic_vector(7 downto 0) := x"FD"; + + constant PRE : std_logic_vector(7 downto 0) := "01010101"; + constant SFD : std_logic_vector(7 downto 0) := "11010101"; +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: eth_tx PORT MAP ( + clk => clk, + rd_en => rd_en, + rd_data => rd_data, + rd_valid => rd_valid, + xgmii_txd => xgmii_txd, + xgmii_txc => xgmii_txc + ); + + -- 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 + for i in 1 to 5 loop + + if i = 1 or i = 2 then + wait for clk_period; + + if rd_en /= '0' or + xgmii_txd /= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE or + xgmii_txc /= "11111111" then + test_fail <= '1'; + end if; + end if; + + rd_valid <= '1'; + rd_data <= x"0123456789ABCDEF"; + + wait for clk_period; + + if rd_en /= '1' or + xgmii_txd /= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START or + xgmii_txc /= "00000001" then + test_fail <= '1'; + end if; + + wait for clk_period; + + if rd_en /= '1' or + xgmii_txd /= x"EFCDAB8967452301" or + xgmii_txc /= "00000000" then + test_fail <= '1'; + end if; + + rd_valid <= '1'; + rd_data <= x"BBBBBBBBBBBBBBBB"; + + wait for clk_period; + + if rd_en /= '1' or + xgmii_txd /= x"BBBBBBBBBBBBBBBB" or + xgmii_txc /= "00000000" then + test_fail <= '1'; + end if; + + rd_valid <= '0'; + rd_data <= x"0000000000000000"; + + wait for clk_period; + + if rd_en /= '0' or + xgmii_txd /= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & TERM or + xgmii_txc /= "11111111" then + test_fail <= '1'; + end if; + + end loop; + + wait; + end process; + +END; diff --git a/netfpga10g/tests/pcie_rx_test.vhd b/netfpga10g/tests/pcie_rx_test.vhd new file mode 100644 index 0000000..4180b81 --- /dev/null +++ b/netfpga10g/tests/pcie_rx_test.vhd @@ -0,0 +1,322 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY pcie_rx_test IS +END pcie_rx_test; + +ARCHITECTURE behavior OF pcie_rx_test IS + + COMPONENT pcie_rx + PORT( + clk : IN std_logic; + frame : IN std_logic_vector(63 downto 0); + sof : IN std_logic; + eof : IN std_logic; + valid : IN std_logic; + read : OUT std_logic; + write : OUT std_logic; + complete : OUT std_logic; + data : OUT std_logic_vector(63 downto 0); + address : OUT std_logic_vector(63 downto 3); + tag : OUT std_logic_vector(4 downto 0); + remote : OUT std_logic_vector(15 downto 0); + bar0 : IN std_logic + ); + END COMPONENT; + + + signal clk : std_logic := '0'; + + signal frame : std_logic_vector(63 downto 0) := (others => '0'); + signal sof : std_logic := '0'; + signal eof : std_logic := '0'; + signal valid : std_logic := '0'; + + signal read : std_logic; + signal write : std_logic; + signal complete : std_logic; + signal data : std_logic_vector(63 downto 0); + signal address : std_logic_vector(63 downto 3); + signal tag : std_logic_vector(4 downto 0); + signal remote : std_logic_vector(15 downto 0); + signal bar0 : std_logic := '0'; + + constant clk_period : time := 10 ns; + + constant ADDR_0 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(0, 61)); + constant ADDR_1 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(1, 61)); + constant ADDR_2 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(2, 61)); + + constant TAG_0 : std_logic_vector(4 downto 0) := "0" & x"0"; + constant TAG_A : std_logic_vector(4 downto 0) := "0" & x"A"; + constant TAG_B : std_logic_vector(4 downto 0) := "0" & x"B"; + + constant ID_0 : std_logic_vector(15 downto 0) := x"0000"; + constant ID_A : std_logic_vector(15 downto 0) := x"AAAA"; + constant ID_B : std_logic_vector(15 downto 0) := x"BBBB"; + + constant DATA_0 : std_logic_vector(63 downto 0) := x"0000000000000000"; + constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA"; + constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB"; + + signal test_fail : std_logic := '0'; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: pcie_rx PORT MAP ( + clk => clk, + frame => frame, + sof => sof, + eof => eof, + valid => valid, + read => read, + write => write, + complete => complete, + data => data, + address => address, + tag => tag, + remote => remote, + bar0 => bar0 + ); + + -- 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 + bar0 <= '1'; + + wait for clk_period; + + -- expect nothing + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_0 then + test_fail <= '1'; + end if; + + -- read: addr = 1, tag = A, remote = A + frame <= "0" & "00" & "00000" & + x"00" & + "000000" & "0000000010" & + ID_A & "000" & TAG_A & x"FF"; + sof <= '1'; + eof <= '0'; + valid <= '1'; + + wait for clk_period; + + -- remote = A + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= ADDR_1(31 downto 3) & "000" & x"00000000"; + sof <= '0'; + eof <= '1'; + valid <= '1'; + + wait for clk_period; + + -- read: addr = 1, tag = A, remote = A + if read /= '1' or + write /= '0' or + complete /= '0' or + data /= DATA_0 or + address /= ADDR_1 or + tag /= TAG_A or + remote /= ID_A then + test_fail <= '1'; + end if; + + -- write: data = A, addr = 2 + frame <= "0" & "10" & "00000" & + x"00" & + "000000" & "0000000010" & + ID_B & x"00" & x"FF"; + sof <= '1'; + eof <= '0'; + valid <= '1'; + + wait for clk_period; + + -- remote stays A + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= ADDR_2(31 downto 3) & "000" & DATA_A(63 downto 32); + sof <= '0'; + eof <= '0'; + valid <= '1'; + + wait for clk_period; + + -- expect nothing + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= DATA_A(31 downto 0) & x"00000000"; + sof <= '0'; + eof <= '1'; + valid <= '1'; + + wait for clk_period; + + -- write: data = A, addr = 2 + if read /= '0' or + write /= '1' or + complete /= '0' or + data /= DATA_A or + address /= ADDR_2 or + tag /= TAG_0 or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= (others => '0'); + sof <= '0'; + eof <= '0'; + valid <= '0'; + + wait for clk_period; + + -- expect nothing + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + -- complete: length = 2x32b, data = A + B, tag = B + frame <= "0" & "10" & "01010" & + x"00" & + "000000" & "0000000100" & + ID_B & x"0004"; + sof <= '1'; + eof <= '0'; + valid <= '1'; + + wait for clk_period; + + -- expect nothing + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= ID_B & "000" & TAG_B & x"00" & + DATA_A(63 downto 32); + sof <= '0'; + eof <= '0'; + valid <= '1'; + + wait for clk_period; + + -- nothing + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= DATA_A(31 downto 0) & DATA_B(63 downto 32); + sof <= '0'; + eof <= '0'; + valid <= '1'; + + wait for clk_period; + + -- completion: data = A, tag = B + if read /= '0' or + write /= '0' or + complete /= '1' or + data /= DATA_A or + address /= ADDR_0 or + tag /= TAG_B or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= (others => '0'); + sof <= '0'; + eof <= '0'; + valid <= '0'; + + wait for clk_period; + + -- nothing + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= DATA_B(31 downto 0) & x"01234567"; + sof <= '0'; + eof <= '1'; + valid <= '1'; + + wait for clk_period; + + -- completion: data = B, tag = B + if read /= '0' or + write /= '0' or + complete /= '1' or + data /= DATA_B or + address /= ADDR_0 or + tag /= TAG_B or + remote /= ID_A then + test_fail <= '1'; + end if; + + frame <= (others => '0'); + sof <= '0'; + eof <= '0'; + valid <= '0'; + + wait for clk_period; + + -- nothing + if read /= '0' or + write /= '0' or + complete /= '0' or + remote /= ID_A then + test_fail <= '1'; + end if; + + + + + + wait; + end process; + +END; diff --git a/netfpga10g/tests/pcie_tx_test.vhd b/netfpga10g/tests/pcie_tx_test.vhd new file mode 100644 index 0000000..4f9e091 --- /dev/null +++ b/netfpga10g/tests/pcie_tx_test.vhd @@ -0,0 +1,561 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY pcie_tx_test IS +END pcie_tx_test; + +ARCHITECTURE behavior OF pcie_tx_test IS + + COMPONENT pcie_tx + PORT( + clk : IN std_logic; + frame : OUT std_logic_vector(63 downto 0); + sof : OUT std_logic; + eof : OUT std_logic; + half : OUT std_logic; + valid : OUT std_logic; + ready : IN std_logic; + read : IN std_logic; + write : IN std_logic; + complete : IN std_logic; + data : IN std_logic_vector(63 downto 0); + address : IN std_logic_vector(63 downto 3); + length : IN std_logic_vector(8 downto 0); + tag : IN std_logic_vector(4 downto 0); + local : IN std_logic_vector(15 downto 0); + remote : IN std_logic_vector(15 downto 0); + accept : OUT std_logic; + done : OUT std_logic + ); + END COMPONENT; + + + signal clk : std_logic := '0'; + + signal read : std_logic := '0'; + signal write : std_logic := '0'; + signal complete : std_logic := '0'; + signal data : std_logic_vector(63 downto 0) := (others => '0'); + signal address : std_logic_vector(63 downto 3) := (others => '0'); + signal length : std_logic_vector(8 downto 0) := (others => '0'); + signal tag : std_logic_vector(4 downto 0) := (others => '0'); + signal local : std_logic_vector(15 downto 0) := (others => '0'); + signal remote : std_logic_vector(15 downto 0) := (others => '0'); + signal accept : std_logic; + signal done : std_logic; + + signal frame : std_logic_vector(63 downto 0); + signal sof : std_logic; + signal eof : std_logic; + signal half : std_logic; + signal valid : std_logic; + signal ready : std_logic := '0'; + + constant clk_period : time := 10 ns; + + signal test_fail : std_logic := '0'; + + constant FRAME_0 : std_logic_vector(63 downto 0) := (others => '0'); + + constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA"; + constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB"; + constant DATA_C : std_logic_vector(63 downto 0) := x"CCCCCCCCCCCCCCCC"; + + constant ADDR_1 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(1, 61)); + constant ADDR_2 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(2, 61)); + constant ADDR_3 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(3, 61)); + constant ADDR_HIGH : std_logic_vector(63 downto 3) := x"100000000000000" & "0"; + + constant LEN_1 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(1, 9)); + constant LEN_2 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(2, 9)); + constant LEN_3 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(3, 9)); + + constant TAG_A : std_logic_vector(4 downto 0) := "0" & x"A"; + constant TAG_B : std_logic_vector(4 downto 0) := "0" & x"B"; + constant TAG_C : std_logic_vector(4 downto 0) := "0" & x"C"; + + constant ID_A : std_logic_vector(15 downto 0) := x"AAAA"; + constant ID_B : std_logic_vector(15 downto 0) := x"BBBB"; + constant ID_C : std_logic_vector(15 downto 0) := x"CCCC"; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: pcie_tx PORT MAP ( + clk => clk, + frame => frame, + sof => sof, + eof => eof, + half => half, + valid => valid, + ready => ready, + read => read, + write => write, + complete => complete, + data => data, + address => address, + length => length, + tag => tag, + local => local, + remote => remote, + accept => accept, + done => done + ); + + -- 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 + variable expect : std_logic_vector(63 downto 0) := (others => '0'); + begin + wait for clk_period; + + -- expect nothing + if frame /= FRAME_0 or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '0' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + -- read: addr = 1, len = 1, tag = A, local = A + read <= '1'; + address <= ADDR_1; + length <= LEN_1; + tag <= TAG_A; + local <= ID_A; + + wait for clk_period; + + -- expect 32 bit read: sof valid + expect := "0" & "00" & "00000" & x"00" & + "000000" & "0000000010" & + ID_A & "000" & TAG_A & x"0F"; + + if frame /= expect or + sof /= '1' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period * 3 / 4; + ready <= '1'; + wait for clk_period / 4; + + -- same thing, because ready was 0 during clk + if frame /= expect or + sof /= '1' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period * 3 / 4; + ready <= '0'; + wait for clk_period / 4; + + -- read address: eof half valid + expect := ADDR_1(31 downto 3) & "000" & x"00000000"; + + if frame /= expect or + sof /= '0' or + eof /= '1' or + half /= '1' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period * 3 / 4; + ready <= '1'; + wait for clk_period / 4; + + -- same thing, because ready was 0 + -- but ready now, so done next time + if frame /= expect or + sof /= '0' or + eof /= '1' or + half /= '1' or + valid /= '1' or + accept /= '0' or + done /= '1' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- done, so... + read <= '0'; + write <= '0'; + complete <= '0'; + data <= (others => '0'); + address <= (others => '0'); + length <= (others => '0'); + tag <= (others => '0'); + local <= (others => '0'); + remote <= (others => '0'); + + -- expect nothing + if frame /= FRAME_0 or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '0' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect nothing + if frame /= FRAME_0 or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '0' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + -- write: data = B+C, addr = 2, length = 2, local = B + write <= '1'; + data <= DATA_B; + address <= ADDR_2; + length <= LEN_2; + local <= ID_B; + + wait for clk_period; + + -- write: sof valid + expect := "0" & "10" & "00000" & x"00" & + x"0004" & + ID_B & x"00" & x"FF"; + + if frame /= expect or + sof /= '1' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '1' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- write 32bit address + data: valid + expect := ADDR_2(31 downto 3) & "000" & DATA_B(63 downto 32); + + if frame /= expect or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '1' or + done /= '0' then + test_fail <= '1'; + end if; + + data <= DATA_C; + + wait for clk_period; + + -- write data: valid + expect := DATA_B(31 downto 0) & DATA_C(63 downto 32); + + if frame /= expect or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + data <= (others => '0'); + + wait for clk_period; + + -- write half data: eof half valid done + expect := DATA_C(31 downto 0) & x"00000000"; + + if frame /= expect or + sof /= '0' or + eof /= '1' or + half /= '1' or + valid /= '1' or + accept /= '0' or + done /= '1' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect nothing + if frame /= FRAME_0 or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '0' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + -- done, so... + read <= '0'; + write <= '0'; + complete <= '0'; + data <= (others => '0'); + address <= (others => '0'); + length <= (others => '0'); + tag <= (others => '0'); + local <= (others => '0'); + remote <= (others => '0'); + + -- complete: data = C, addr = 3, tag = C, local = A, remote = B + complete <= '1'; + data <= DATA_C; + address <= ADDR_3; + tag <= TAG_C; + local <= ID_A; + remote <= ID_B; + + wait for clk_period; + + -- expect completion 64bit + expect := "0" & "10" & "01010" & x"00" & + x"0002" & ID_A & x"0008"; + + if frame /= expect or + sof /= '1' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- compl header + data(higher 32b) + expect := ID_B & "000" & TAG_C & "0" & x"3" & "000" & + DATA_C(63 downto 32); + + if frame /= expect or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- read of compl data: eof half valid done + expect := DATA_C(31 downto 0) & x"00000000"; + + if frame /= expect or + sof /= '0' or + eof /= '1' or + half /= '1' or + valid /= '1' or + accept /= '0' or + done /= '1' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect nothing + if frame /= FRAME_0 or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '0' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + -- done, so... + read <= '0'; + write <= '0'; + complete <= '0'; + data <= (others => '0'); + address <= (others => '0'); + length <= (others => '0'); + tag <= (others => '0'); + local <= (others => '0'); + remote <= (others => '0'); + + -- 64bit read: addr = HIGH, length = 3, tag = C, local = C + read <= '1'; + address <= ADDR_HIGH; + length <= LEN_3; + tag <= TAG_C; + local <= ID_C; + + wait for clk_period; + + -- expect 64bit read + expect := "0" & "01" & "00000" & x"00" & x"0006" & + ID_C & "000" & TAG_C & x"FF"; + + if frame /= expect or + sof /= '1' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect 64bit address: eof valid done + expect := ADDR_HIGH & "000"; + + if frame /= expect or + sof /= '0' or + eof /= '1' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '1' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect nothing + if frame /= FRAME_0 or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '0' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + -- done, so... + read <= '0'; + write <= '0'; + complete <= '0'; + data <= (others => '0'); + address <= (others => '0'); + length <= (others => '0'); + tag <= (others => '0'); + local <= (others => '0'); + remote <= (others => '0'); + + -- 64bit write: addr = HIGH, length = 1, data = A, local = A + write <= '1'; + address <= ADDR_HIGH; + length <= LEN_1; + data <= DATA_A; + local <= ID_A; + + wait for clk_period; + + -- expect 64bit write header; sof valid + expect := "0" & "11" & "00000" & x"00" & x"0002" & + ID_A & x"00" & x"0F"; + + if frame /= expect or + sof /= '1' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect addr HIGH: valid accept + expect := ADDR_HIGH & "000"; + + if frame /= expect or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '1' or + accept /= '1' or + done /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect data A: eof valid done + expect := DATA_A; + + if frame /= expect or + sof /= '0' or + eof /= '1' or + half /= '0' or + valid /= '1' or + accept /= '0' or + done /= '1' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- expect nothing + if frame /= FRAME_0 or + sof /= '0' or + eof /= '0' or + half /= '0' or + valid /= '0' or + accept /= '0' or + done /= '0' then + test_fail <= '1'; + end if; + + -- done, so... + read <= '0'; + write <= '0'; + complete <= '0'; + data <= (others => '0'); + address <= (others => '0'); + length <= (others => '0'); + tag <= (others => '0'); + local <= (others => '0'); + remote <= (others => '0'); + + wait; + end process; + +END; diff --git a/netfpga10g/tests/queue_test.vhd b/netfpga10g/tests/queue_test.vhd new file mode 100644 index 0000000..dc53ea0 --- /dev/null +++ b/netfpga10g/tests/queue_test.vhd @@ -0,0 +1,149 @@ +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:42:12 02/23/2017 +-- Design Name: +-- Module Name: /home/alexander/Code/raptor2/hw/tests/queue_test.vhd +-- Project Name: raptor2 +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: queue +-- +-- 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; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--USE ieee.numeric_std.ALL; + +ENTITY queue_test IS +END queue_test; + +ARCHITECTURE behavior OF queue_test IS + + -- Component Declaration for the Unit Under Test (UUT) + + COMPONENT queue + PORT( + clk : IN std_logic; + reset : IN std_logic; + in_data : IN std_logic_vector(63 downto 0); + in_valid : in std_logic; + in_end : IN std_logic; + in_cancel : IN std_logic; + out_data : OUT std_logic_vector(63 downto 0); + out_valid : OUT std_logic; + out_next : IN std_logic + ); + END COMPONENT; + + + --Inputs + signal clk : std_logic := '0'; + signal reset : std_logic := '0'; + signal in_data : std_logic_vector(63 downto 0) := (others => '0'); + signal in_valid : std_logic := '0'; + signal in_end : std_logic := '0'; + signal in_cancel : std_logic := '0'; + signal out_next : std_logic := '0'; + + --Outputs + signal out_data : std_logic_vector(63 downto 0); + signal out_valid : std_logic; + + -- Clock period definitions + constant clk_period : time := 10 ns; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: queue PORT MAP ( + clk => clk, + reset => reset, + in_data => in_data, + in_valid => in_valid, + in_end => in_end, + in_cancel => in_cancel, + out_data => out_data, + out_valid => out_valid, + out_next => out_next + ); + + -- Clock process definitions + clk_process :process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + -- TESTS + process begin + reset <= '1'; + wait for 5 ns; + reset <= '0'; + wait; + end process; + + process begin + wait for clk_period * 2; + in_data <= x"AAAAAAAAAAAAAAAA"; + in_valid <= '1'; + wait for clk_period; + in_data <= x"BBBBBBBBBBBBBBBB"; + in_valid <= '0'; + wait for clk_period; + in_data <= x"CCCCCCCCCCCCCCCC"; + in_valid <= '1'; + wait for clk_period; + in_data <= x"DDDDDDDDDDDDDDDD"; + in_valid <= '1'; + in_end <= '1'; + wait for clk_period; + in_valid <= '0'; + in_end <= '0'; + + wait for clk_period * 2; + in_data <= x"AAAAAAAAAAAAAAAA"; + in_valid <= '1'; + wait for clk_period; + in_data <= x"BBBBBBBBBBBBBBBB"; + in_valid <= '1'; + wait for clk_period; + in_data <= x"CCCCCCCCCCCCCCCC"; + in_valid <= '1'; + wait for clk_period; + in_data <= x"DDDDDDDDDDDDDDDD"; + in_valid <= '1'; + in_cancel <= '1'; + wait for clk_period; + in_valid <= '0'; + in_cancel <= '0'; + end process; + + process begin + wait for clk_period * 15; + out_next <= '1'; + wait for clk_period * 2; + out_next <= '0'; + wait for clk_period * 2; + out_next <= '1'; + end process; +END; diff --git a/netfpga10g/tests/send_mux_test.vhd b/netfpga10g/tests/send_mux_test.vhd new file mode 100644 index 0000000..f737ca9 --- /dev/null +++ b/netfpga10g/tests/send_mux_test.vhd @@ -0,0 +1,199 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY send_mux_test IS +END send_mux_test; + +ARCHITECTURE behavior OF send_mux_test IS + + COMPONENT send_mux + PORT( + wr_clk : IN std_logic; + wr_buff : IN std_logic_vector(3 downto 0); + wr_en : IN std_logic; + wr_data : IN std_logic_vector(63 downto 0); + wr_done : IN std_logic; + wr_accept : OUT std_logic_vector(15 downto 0); + rd_clk : IN std_logic; + rd_en : IN std_logic; + rd_data : OUT std_logic_vector(63 downto 0); + rd_valid : OUT std_logic + ); + END COMPONENT; + + signal wr_clk : std_logic := '0'; + signal wr_buff : std_logic_vector(3 downto 0) := (others => '0'); + signal wr_en : std_logic := '0'; + signal wr_data : std_logic_vector(63 downto 0) := (others => '0'); + signal wr_done : std_logic := '0'; + signal wr_accept : std_logic_vector(15 downto 0); + + signal rd_clk : std_logic := '0'; + signal rd_en : std_logic := '0'; + signal rd_data : std_logic_vector(63 downto 0); + signal rd_valid : std_logic; + + constant wr_clk_period : time := 10 ns; + constant rd_clk_period : time := 7 ns; + + constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA"; + constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB"; + constant DATA_C : std_logic_vector(63 downto 0) := x"CCCCCCCCCCCCCCCC"; + + constant BUFF_1 : std_logic_vector (3 downto 0) := x"1"; + constant BUFF_2 : std_logic_vector (3 downto 0) := x"2"; + constant BUFF_3 : std_logic_vector (3 downto 0) := x"3"; + + signal test_fail : std_logic := '0'; + signal test_done : std_logic := '0'; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: send_mux PORT MAP ( + wr_clk => wr_clk, + wr_buff => wr_buff, + wr_en => wr_en, + wr_data => wr_data, + wr_done => wr_done, + wr_accept => wr_accept, + rd_clk => rd_clk, + rd_en => rd_en, + rd_data => rd_data, + rd_valid => rd_valid + ); + + -- Clock process definitions + wr_clk_process :process + begin + wr_clk <= '0'; + wait for wr_clk_period/2; + wr_clk <= '1'; + wait for wr_clk_period/2; + end process; + + rd_clk_process :process + begin + rd_clk <= '0'; + wait for rd_clk_period/2; + rd_clk <= '1'; + wait for rd_clk_period/2; + end process; + + + -- Stimulus process + stim_proc: process + begin + wait for wr_clk_period; + + if rd_valid /= '0' or + wr_accept /= x"FFFF" then + test_fail <= '1'; + end if; + + wr_buff <= BUFF_1; + wr_en <= '1'; + wr_data <= DATA_A; + wr_done <= '0'; + + wait for wr_clk_period; + + if rd_valid /= '0' or + wr_accept /= x"FFFF" then + test_fail <= '1'; + end if; + + wr_buff <= BUFF_2; + wr_en <= '1'; + wr_data <= DATA_A; + wr_done <= '0'; + + wait for wr_clk_period; + + if rd_valid /= '0' or + wr_accept /= x"FFFF" then + test_fail <= '1'; + end if; + + wr_buff <= BUFF_3; + wr_en <= '1'; + wr_data <= DATA_A; + wr_done <= '0'; + + wait for wr_clk_period; + + if rd_valid /= '0' or + wr_accept /= x"FFFF" then + test_fail <= '1'; + end if; + + wr_buff <= BUFF_1; + wr_en <= '1'; + wr_data <= DATA_B; + wr_done <= '0'; + + wait for wr_clk_period; + + if rd_valid /= '0' or + wr_accept /= x"FFFF" then + test_fail <= '1'; + end if; + + wr_buff <= BUFF_1; + wr_en <= '0'; + wr_data <= (others => '0'); + wr_done <= '1'; + + wait for wr_clk_period; + + if rd_valid /= '0' or + wr_accept /= x"FFFD" then + test_fail <= '1'; + end if; + + wr_buff <= BUFF_1; + wr_en <= '0'; + wr_data <= (others => '0'); + wr_done <= '0'; + + wait until rd_valid = '1'; + wait for rd_clk_period / 2; + + if rd_valid /= '1' or + rd_data /= DATA_A or + wr_accept /= x"FFFD" then + test_fail <= '1'; + end if; + + rd_en <= '1'; + + wait for rd_clk_period; + + if rd_valid /= '1' or + rd_data /= DATA_B or + wr_accept /= x"FFFD" then + test_fail <= '1'; + end if; + + rd_en <= '1'; + + wait for rd_clk_period; + + if rd_valid /= '0' or + wr_accept /= x"FFFD" then + test_fail <= '1'; + end if; + + rd_en <= '0'; + + wait until wr_accept(1) = '1'; + + report "done"; + test_done <= '1'; + + wait; + end process; + +END; diff --git a/netfpga10g/tests/system_loop_test.vhd b/netfpga10g/tests/system_loop_test.vhd new file mode 100644 index 0000000..81a4f6e --- /dev/null +++ b/netfpga10g/tests/system_loop_test.vhd @@ -0,0 +1,285 @@ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY system_loop_test IS +END system_loop_test; + +ARCHITECTURE behavior OF system_loop_test IS + + COMPONENT system_loop + PORT( + clk : IN std_logic; + + rx_frame : IN std_logic_vector(63 downto 0); + rx_sof : IN std_logic; + rx_eof : IN std_logic; + rx_valid : IN std_logic; + rx_bar0 : IN std_logic; + + tx_frame : OUT std_logic_vector(63 downto 0); + tx_sof : OUT std_logic; + tx_eof : OUT std_logic; + tx_half : OUT std_logic; + tx_valid : OUT std_logic; + tx_ready : IN std_logic; + + interrupt : OUT std_logic; + interrupt_rdy : IN std_logic; + max_read : IN std_logic_vector(2 downto 0); + max_write : IN std_logic_vector(2 downto 0); + local : IN std_logic_vector(15 downto 0) + ); + END COMPONENT; + + signal clk : std_logic := '0'; + + signal rx_frame : std_logic_vector(63 downto 0) := (others => '0'); + signal rx_sof : std_logic := '0'; + signal rx_eof : std_logic := '0'; + signal rx_valid : std_logic := '0'; + signal rx_bar0 : std_logic := '0'; + + signal tx_frame : std_logic_vector(63 downto 0); + signal tx_sof : std_logic; + signal tx_eof : std_logic; + signal tx_half : std_logic; + signal tx_valid : std_logic; + signal tx_ready : std_logic := '0'; + + signal interrupt : std_logic; + signal interrupt_rdy : std_logic := '0'; + + signal max_read : std_logic_vector(2 downto 0) := (others => '0'); + signal max_write : std_logic_vector(2 downto 0) := (others => '0'); + signal local : std_logic_vector(15 downto 0) := (others => '0'); + + constant clk_period : time := 10 ns; + + signal test_fail : std_logic := '0'; + + constant LEN_1 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(1, 9)); + constant LEN_2 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(2, 9)); + constant LEN_3 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(3, 9)); + + constant TAG_1 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(1, 5)); + constant TAG_2 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(2, 5)); + constant TAG_3 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(3, 5)); + + constant ADDR_1 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(1, 61)); + constant ADDR_2 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(2, 61)); + constant ADDR_3 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(3, 61)); + + constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA"; + constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB"; + constant DATA_C : std_logic_vector(63 downto 0) := x"CCCCCCCCCCCCCCCC"; + + constant ID_A : std_logic_vector(15 downto 0) := x"AAAA"; + constant ID_B : std_logic_vector(15 downto 0) := x"BBBB"; + constant ID_C : std_logic_vector(15 downto 0) := x"CCCC"; + + constant BUFF_1 : std_logic_vector(3 downto 0) := x"1"; + constant BUFF_2 : std_logic_vector(3 downto 0) := x"2"; + constant BUFF_3 : std_logic_vector(3 downto 0) := x"3"; + + constant CMD_STATUS : std_logic_vector(1 downto 0) := "00"; + constant CMD_SEND : std_logic_vector(1 downto 0) := "01"; + constant CMD_RECV : std_logic_vector(1 downto 0) := "10"; + constant CMD_MDIO : std_logic_vector(1 downto 0) := "11"; + + constant FRAME_0 : std_logic_vector(63 downto 0) := (others => '0'); + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: system_loop PORT MAP ( + clk => clk, + rx_frame => rx_frame, + rx_sof => rx_sof, + rx_eof => rx_eof, + rx_valid => rx_valid, + rx_bar0 => rx_bar0, + tx_frame => tx_frame, + tx_sof => tx_sof, + tx_eof => tx_eof, + tx_half => tx_half, + tx_valid => tx_valid, + tx_ready => tx_ready, + interrupt => interrupt, + interrupt_rdy => interrupt_rdy, + max_read => max_read, + max_write => max_write, + local => local + ); + + -- 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 + variable bar_addr : std_logic_vector(31 downto 0); + variable bar_data : std_logic_vector(63 downto 0); + variable expect : std_logic_vector(63 downto 0); + variable remote : std_logic_vector(15 downto 0); + begin + -- local = A + -- remote = B + local <= ID_A; + remote := ID_B; + + -- always bar0 + rx_bar0 <= '1'; + + wait for clk_period; + + -- nothing + if tx_frame /= FRAME_0 or + tx_sof /= '0' or + tx_eof /= '0' or + tx_half /= '0' or + tx_valid /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- rx_write of 64 bits to bar + rx_frame <= "0" & "10" & "00000" & x"00" & x"0002" & + remote & x"00" & x"0F"; + rx_sof <= '1'; + rx_eof <= '0'; + rx_valid <= '1'; + + wait for clk_period; + + -- nothing + if tx_frame /= FRAME_0 or + tx_sof /= '0' or + tx_eof /= '0' or + tx_half /= '0' or + tx_valid /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + -- rx_write: + -- bar_addr: cmd = SEND, buff = 2, len = 2 + -- bar_data: addr = 2 + bar_addr := (others => '0'); + bar_addr(4 downto 3) := CMD_SEND; + bar_addr(8 downto 5) := BUFF_2; + bar_addr(18 downto 10) := LEN_2; + bar_data := ADDR_2 & "000"; + + rx_frame <= bar_addr & bar_data(63 downto 32); + rx_sof <= '0'; + rx_eof <= '0'; + rx_valid <= '1'; + + wait for clk_period; + + -- nothing + if tx_frame /= FRAME_0 or + tx_sof /= '0' or + tx_eof /= '0' or + tx_half /= '0' or + tx_valid /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_frame <= bar_data(31 downto 0) & x"00000000"; + rx_sof <= '0'; + rx_eof <= '1'; + rx_valid <= '1'; + + wait for clk_period; + + -- nothing + if tx_frame /= FRAME_0 or + tx_sof /= '0' or + tx_eof /= '0' or + tx_half /= '0' or + tx_valid /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + rx_frame <= (others => '0'); + rx_sof <= '0'; + rx_eof <= '0'; + rx_valid <= '0'; + + wait for clk_period; + + -- nothing + if tx_frame /= FRAME_0 or + tx_sof /= '0' or + tx_eof /= '0' or + tx_half /= '0' or + tx_valid /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + wait for clk_period; + + -- tx_read: addr = 2, len = 2, tag = 2 + expect := "0" & "00" & "00000" & x"00" & "000000" & LEN_2 & "0" & + local & "000" & TAG_2 & x"FF"; + + if tx_frame /= expect or + tx_sof /= '1' or + tx_eof /= '0' or + tx_half /= '0' or + tx_valid /= '1' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + tx_ready <= '1'; + + wait for clk_period; + + expect := ADDR_2(31 downto 3) & "000" & x"00000000"; + + if tx_frame /= expect or + tx_sof /= '0' or + tx_eof /= '1' or + tx_half /= '1' or + tx_valid /= '1' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + tx_ready <= '1'; + + wait for clk_period; + + -- nothing + if tx_frame /= FRAME_0 or + tx_sof /= '0' or + tx_eof /= '0' or + tx_half /= '0' or + tx_valid /= '0' or + interrupt /= '0' then + test_fail <= '1'; + end if; + + tx_ready <= '0'; + + + + + + wait; + end process; + +END; |