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;