library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity tb_stack is end entity tb_stack; architecture behavioural of tb_stack is constant T_clk : time := 10 ns; constant W : positive := 13; signal clk : std_logic := '0'; signal reset : std_logic := '0'; signal push : std_logic := '0'; signal pop : std_logic := '0'; signal din : std_logic_vector(W - 1 downto 0) := (others => '0'); signal dout : std_logic_vector(W - 1 downto 0); signal done : boolean := false; procedure tick(signal clk_in : in std_logic) is begin wait until rising_edge(clk_in); wait for 1 ns; end procedure; begin clk <= not clk after T_clk / 2 when not done else unaffected; dut : entity work.stack(rtl) generic map (DEPTH => 8, WIDTH => W) port map ( clk => clk, reset => reset, push => push, pop => pop, din => din, dout => dout ); stimulus : process is begin -- test 1: reset clears stack report "test 1: reset"; reset <= '1'; wait for T_clk; reset <= '0'; wait for 1 ns; assert dout = std_logic_vector(to_unsigned(0, W)) report "reset: dout should be 0" severity error; -- test 2: push one value and read it back report "test 2: push/pop single value"; din <= std_logic_vector(to_unsigned(16#42#, W)); push <= '1'; tick(clk); push <= '0'; assert dout = std_logic_vector(to_unsigned(16#42#, W)) report "push: dout should be 0x42" severity error; pop <= '1'; tick(clk); pop <= '0'; assert dout = std_logic_vector(to_unsigned(0, W)) report "pop: dout should be 0 (empty)" severity error; -- test 3: push multiple values, pop in LIFO order report "test 3: LIFO order"; din <= std_logic_vector(to_unsigned(16#100#, W)); push <= '1'; tick(clk); din <= std_logic_vector(to_unsigned(16#200#, W)); tick(clk); din <= std_logic_vector(to_unsigned(16#300#, W)); tick(clk); push <= '0'; assert dout = std_logic_vector(to_unsigned(16#300#, W)) report "LIFO: top should be 0x300" severity error; pop <= '1'; tick(clk); assert dout = std_logic_vector(to_unsigned(16#200#, W)) report "LIFO: after 1 pop should be 0x200" severity error; tick(clk); assert dout = std_logic_vector(to_unsigned(16#100#, W)) report "LIFO: after 2 pops should be 0x100" severity error; tick(clk); pop <= '0'; assert dout = std_logic_vector(to_unsigned(0, W)) report "LIFO: stack empty, dout should be 0" severity error; report "test 4: overflow wraparound"; push <= '1'; for i in 1 to 8 loop din <= std_logic_vector(to_unsigned(i, W)); tick(clk); end loop; push <= '0'; -- after 8 pushes top wraps to 0, so stack looks empty assert dout = std_logic_vector(to_unsigned(0, W)) report "overflow: top wrapped to 0, dout should be 0" severity error; -- test 5: reset mid-operation clears pointer report "test 5: reset mid-operation"; din <= std_logic_vector(to_unsigned(16#1FF#, W)); push <= '1'; tick(clk); push <= '0'; reset <= '1'; wait for T_clk; reset <= '0'; wait for 1 ns; assert dout = std_logic_vector(to_unsigned(0, W)) report "reset mid-op: dout should be 0" severity error; report "All stack tests done" severity note; done <= true; wait; end process stimulus; end architecture behavioural;