diff options
Diffstat (limited to 'netfpga10g/tests/engine_test.vhd')
-rw-r--r-- | netfpga10g/tests/engine_test.vhd | 1123 |
1 files changed, 1123 insertions, 0 deletions
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; |