diff --git a/tests/Pipeline_tb.vhd b/tests/Pipeline_tb.vhd index 522b713..bc7841a 100644 --- a/tests/Pipeline_tb.vhd +++ b/tests/Pipeline_tb.vhd @@ -2,6 +2,7 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; +use std.env.stop; entity Pipeline_tb is -- The testbench does not require any ports @@ -10,9 +11,9 @@ end entity Pipeline_tb; architecture behavior of Pipeline_tb is -- Random number generator --@ Select a random number for `seed1` to generate random numbers - shared variable seed1 : integer := 483; + shared variable seed1 : integer := 467; --@ Select a random number for `seed2` to generate random numbers - shared variable seed2 : integer := 847; + shared variable seed2 : integer := 623; --@ Generate a random number between `min_val` and `max_val` --@ You must provide the `shared variable seed1` and `shared variable seed2` to generate random numbers. --@ You need `use ieee.math_real.all;` to use this function. @@ -25,31 +26,31 @@ architecture behavior of Pipeline_tb is end function; -- Clock signal period - constant period : time := 20 ns; + constant period : time := 20 ns; -- Adjustable wait times - constant write_delay : natural := 10; -- Maximal wait time between write operations in clock cycles - constant read_delay : natural := 10; -- Maximal wait time between read operations in clock cycles + constant write_delay : natural := 40; -- Maximal wait time between write operations in clock cycles + constant read_delay : natural := 60; -- Maximal wait time between read operations in clock cycles -- Setting constants for the FIFO to be tested - constant K_Width : integer := 32; -- Data width of the FIFO - constant K_PipelineStages : integer := 3; -- Number of pipeline stages - constant K_RegisterBalancing : string := "yes"; -- Register balancing attribute + constant K_Width : integer := 32; -- Data width of the FIFO + constant K_PipelineStages : integer := 5; -- Number of pipeline stages + constant K_RegisterBalancing : string := "yes"; -- Register balancing attribute -- Testbench signals - signal CLK : std_logic := '0'; - signal RST : std_logic := '1'; - signal CE : std_logic := '1'; + signal CLK : std_logic := '0'; + signal RST : std_logic := '1'; + signal CE : std_logic := '1'; - signal I_Data : std_logic_vector(K_Width - 1 downto 0) := (others => 'U'); - signal I_Valid : std_logic := '0'; - signal O_Ready : std_logic; + signal I_Data : std_logic_vector(K_Width - 1 downto 0) := (others => 'U'); + signal I_Valid : std_logic := '0'; + signal O_Ready : std_logic; - signal O_Data : std_logic_vector(K_Width - 1 downto 0) := (others => 'U'); - signal O_Valid : std_logic; - signal I_Ready : std_logic := '0'; + signal O_Data : std_logic_vector(K_Width - 1 downto 0) := (others => 'U'); + signal O_Valid : std_logic; + signal I_Ready : std_logic := '0'; - signal PipelineEnable : std_logic; + signal PipelineEnable : std_logic; begin uut0 : entity work.PipelineController @@ -109,52 +110,69 @@ begin RST <= '1', '0' after 100 ns; -- Write process - Write : process (CLK) + Write : process variable delay : integer := 0; variable i : integer := 1; begin - if rising_edge(CLK) then - if RST = '1' then + I_Valid <= '0'; + I_Data <= (others => 'U'); + wait until RST = '0'; -- auf Reset-Ende warten + + while true loop + wait until rising_edge(CLK); + + if O_Ready = '1' and delay = 0 then + I_Data <= std_logic_vector(to_unsigned(i, K_Width)); + I_Valid <= '1'; + report "Sende Paket #" & integer'image(i) severity note; + i := i + 1; + delay := rand_int(1, write_delay); + elsif O_Ready = '1' and I_Valid = '1' then I_Valid <= '0'; - delay := write_delay; - i := 1; - I_Data <= (others => 'U'); - else - if O_Ready = '1' and delay = 0 then - I_Data <= std_logic_vector(to_unsigned(i, K_Width)); -- Data to be written - I_Valid <= '1'; - i := i + 1; - delay := rand_int(1, write_delay); - elsif O_Ready = '1' and I_Valid = '1' then - I_Valid <= '0'; - end if; - if delay /= 0 then - delay := delay - 1; - end if; end if; - end if; + + if delay /= 0 then + delay := delay - 1; + end if; + end loop; end process; -- Read process - Read : process (CLK) - variable delay : integer := 0; + Read : process + variable delay : integer := 0; + variable expected : integer := 1; + variable received : integer; begin - if rising_edge(CLK) then - if RST = '1' then + I_Ready <= '0'; + wait until RST = '0'; -- auf Reset-Ende warten + + while true loop + wait until rising_edge(CLK); + wait for 1 ns; + + if O_Valid = '1' and delay = 0 then + I_Ready <= '1'; + + received := to_integer(unsigned(O_Data)); + if received = expected then + report "Empfange Paket #" & integer'image(expected) severity note; + else + report "Fehler bei Paket #" & integer'image(expected) & + ": erwartet " & integer'image(expected) & + ", empfangen " & integer'image(received) severity error; + stop(0); + end if; + + expected := expected + 1; + delay := rand_int(1, read_delay); + elsif O_Valid = '1' and I_Ready = '1' then I_Ready <= '0'; - delay := read_delay; - else - if O_Valid = '1' and delay = 0 then - I_Ready <= '1'; -- Signal readiness to read - delay := rand_int(1, read_delay); - elsif O_Valid = '1' and I_Ready = '1' then - I_Ready <= '0'; - end if; - if delay /= 0 then - delay := delay - 1; - end if; end if; - end if; + + if delay /= 0 then + delay := delay - 1; + end if; + end loop; end process; end architecture behavior;