summaryrefslogtreecommitdiffstats
path: root/PIC/tb_stack.vhd
diff options
context:
space:
mode:
authorVäinö Kauppila <vaino@vke.fi>2026-04-19 00:33:08 +0300
committerVäinö Kauppila <vaino@vke.fi>2026-04-19 00:33:08 +0300
commit8bd8dd6ce07fb8e247f651b3c61c94bb1f00895a (patch)
tree87bd95bd073d68efd0ad31a34f0d8926c32ff6db /PIC/tb_stack.vhd
downloadvhdl_pic-8bd8dd6ce07fb8e247f651b3c61c94bb1f00895a.tar.gz
vhdl_pic-8bd8dd6ce07fb8e247f651b3c61c94bb1f00895a.zip
starting files and example programs
Diffstat (limited to 'PIC/tb_stack.vhd')
-rw-r--r--PIC/tb_stack.vhd121
1 files changed, 121 insertions, 0 deletions
diff --git a/PIC/tb_stack.vhd b/PIC/tb_stack.vhd
new file mode 100644
index 0000000..5b386e9
--- /dev/null
+++ b/PIC/tb_stack.vhd
@@ -0,0 +1,121 @@
+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;