summaryrefslogtreecommitdiff
path: root/netfpga10g/tests/engine_test.vhd
diff options
context:
space:
mode:
authorAlexander D'hoore <dhoore.alexander@gmail.com>2017-12-15 15:37:58 +0100
committerDimitri Staessens <dimitri.staessens@ugent.be>2017-12-15 15:37:58 +0100
commitd1a1059d748955ed93a8e87c437c7eae1258293c (patch)
tree9137bc921db74bb3797b8b0f05e7a69022412522 /netfpga10g/tests/engine_test.vhd
parent8f258e469b1acea8e3ccf1485779e1db0bf5f772 (diff)
downloadraptor-d1a1059d748955ed93a8e87c437c7eae1258293c.tar.gz
raptor-d1a1059d748955ed93a8e87c437c7eae1258293c.zip
Add the linux device driver and netfpga files
This adds the device driver and netfpga files from the master thesis (in Dutch) "Implementatie van de Recursive Internet Architecture op een FPGA platform" by Alexander D'hoore.
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;