Browse Source

Add a stack protected type t_stack in new package StackP

A new stack implementation is added. It's a protected type t_stack,
included in the StackP package. It has the same methods like the
t_queue types but implements a stack logic instead of a queue one.
The t_stack type is tested in the StackT testbench.
pull/1/head
T. Meissner 9 years ago
parent
commit
575d85b4f5
3 changed files with 190 additions and 1 deletions
  1. +116
    -0
      sim/StackP.vhd
  2. +5
    -1
      test/Makefile
  3. +69
    -0
      test/StackT.vhd

+ 116
- 0
sim/StackP.vhd View File

@ -0,0 +1,116 @@
library ieee;
use ieee.std_logic_1164.all;
--+ including vhdl 2008 libraries
--+ These lines can be commented out when using
--+ a simulator with built-in VHDL 2008 support
--library ieee_proposed;
-- use ieee_proposed.standard_additions.all;
-- use ieee_proposed.std_logic_1164_additions.all;
package StackP is
-- linked list stack interface
type t_stack is protected
procedure push (data : in std_logic_vector);
procedure pop (data : inout std_logic_vector);
procedure init (logging : in boolean := false);
impure function is_empty return boolean;
impure function fillstate return natural;
end protected t_stack;
end package StackP;
package body StackP is
-- linked list stack implementation
type t_stack is protected body
type t_entry;
type t_entry_ptr is access t_entry;
type t_data_ptr is access std_logic_vector;
type t_entry is record
data : t_data_ptr;
last_entry : t_entry_ptr;
next_entry : t_entry_ptr;
end record t_entry;
variable v_head : t_entry_ptr := null;
variable v_tail : t_entry_ptr := null;
variable v_count : natural := 0;
variable v_logging : boolean := false;
-- write one entry into queue by
-- creating new entry at head of list
procedure push (data : in std_logic_vector) is
variable v_entry : t_entry_ptr;
begin
if (v_count /= 0) then
v_entry := new t_entry;
v_entry.data := new std_logic_vector'(data);
v_entry.last_entry := v_head;
v_entry.next_entry := null;
v_head := v_entry;
v_head.last_entry.next_entry := v_head;
else
v_head := new t_entry;
v_head.data := new std_logic_vector'(data);
v_head.last_entry := null;
v_head.next_entry := null;
v_tail := v_head;
end if;
v_count := v_count + 1;
if v_logging then
report t_stack'instance_name & " pushed 0x" & to_hstring(data) & " on stack";
end if;
end procedure push;
-- read one entry from queue at tail of list and
-- delete that entry from list after read
procedure pop (data : inout std_logic_vector) is
variable v_entry : t_entry_ptr := v_head;
begin
assert not(is_empty)
report "pop from empty queue -> discarded"
severity failure;
data := v_head.data.all;
v_head := v_head.last_entry;
deallocate(v_entry.data);
deallocate(v_entry);
v_count := v_count - 1;
if v_logging then
report t_stack'instance_name & " popped 0x" & to_hstring(data) & " from stack";
end if;
end procedure pop;
procedure init (logging : in boolean := false) is
begin
v_logging := logging;
end procedure init;
-- returns true if queue is empty, false otherwise
impure function is_empty return boolean is
begin
return v_head = null;
end function is_empty;
-- returns number of filled slots in queue
impure function fillstate return natural is
begin
return v_count;
end function fillstate;
end protected body t_stack;
end package body StackP;

+ 5
- 1
test/Makefile View File

@ -6,7 +6,7 @@ VHD_STD := 08
.PHONY: all
all: queue dict sim wishbone
all: queue dict stack sim wishbone
.PHONY: vhdl2008
@ -41,6 +41,9 @@ dictt: RandomPkg.o DictP.o DictT.vhd
ghdl -a --std=$(VHD_STD) DictT.vhd
ghdl -e --std=$(VHD_STD) $@
stackt: RandomPkg.o AssertP.o StackP.o StackT.vhd
ghdl -a --std=$(VHD_STD) StackT.vhd
ghdl -e --std=$(VHD_STD) $@
simt: RandomPkg.o UtilsP.o AssertP.o QueueP.o SimP.o SimT.vhd
ghdl -a --std=$(VHD_STD) SimT.vhd
@ -79,6 +82,7 @@ clean:
rm -f *.ghw
rm -f queuet
rm -f dictt
rm -f stackt
rm -f stringt
rm -f simt
rm -f spit


+ 69
- 0
test/StackT.vhd View File

@ -0,0 +1,69 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--+ including vhdl 2008 libraries
--+ These lines can be commented out when using
--+ a simulator with built-in VHDL 2008 support
--library ieee_proposed;
-- use ieee_proposed.standard_additions.all;
-- use ieee_proposed.std_logic_1164_additions.all;
-- use ieee_proposed.numeric_std_additions.all;
library osvvm;
use osvvm.RandomPkg.all;
library libvhdl;
use libvhdl.AssertP.all;
use libvhdl.StackP.all;
entity StackT is
end entity StackT;
architecture sim of StackT is
constant C_STACK_DEPTH : natural := 64;
type t_scoreboard is array (natural range <>) of std_logic_vector(7 downto 0);
shared variable sv_stack : t_stack;
begin
StackInitP : process is
begin
sv_stack.init(false);
wait;
end process StackInitP;
StackTestP : process is
variable v_data : std_logic_vector(7 downto 0);
begin
-- check initial emptiness
assert_true(sv_stack.is_empty, "Stack should be empty!");
for i in 0 to C_STACK_DEPTH-1 loop
sv_stack.push(std_logic_vector(to_unsigned(i, 8)));
end loop;
-- check that it's full
assert_equal(sv_stack.fillstate, C_STACK_DEPTH, "Stack should have" & integer'image(C_STACK_DEPTH) & "entries");
-- empty the queue
for i in C_STACK_DEPTH-1 downto 0 loop
sv_stack.pop(v_data);
assert_equal(v_data, std_logic_vector(to_unsigned(i, 8)));
end loop;
-- check emptiness
assert_true(sv_stack.is_empty, "Stack should be empty!");
report "INFO: t_stack test finished successfully";
wait;
end process StackTestP;
end architecture sim;

Loading…
Cancel
Save