From 75ac016c9afdb792527ad288ea40e5a78e5aecc6 Mon Sep 17 00:00:00 2001 From: MaxP Date: Wed, 16 Apr 2025 17:26:14 +0000 Subject: [PATCH] Refines testbench logic and parameter configurations Updates random seed values and adjusts pipeline configuration constants for improved testing flexibility. Refactors write and read processes for clarity, adding additional checks and error handling. Introduces `stop` function to terminate simulation on critical errors. Enhances test coverage and simulation reliability. --- tests/Pipeline_tb.vhd | 124 ++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 53 deletions(-) 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;