summaryrefslogtreecommitdiff
path: root/netfpga10g/tests/engine_test.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'netfpga10g/tests/engine_test.vhd')
-rw-r--r--netfpga10g/tests/engine_test.vhd1123
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;