Library of reusable VHDL components
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.1 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. --+ including vhdl 2008 libraries
  4. --+ These lines can be commented out when using
  5. --+ a simulator with built-in VHDL 2008 support
  6. --library ieee_proposed;
  7. -- use ieee_proposed.standard_additions.all;
  8. -- use ieee_proposed.std_logic_1164_additions.all;
  9. package StackP is
  10. -- linked list stack interface
  11. type t_stack is protected
  12. procedure push (data : in std_logic_vector);
  13. procedure pop (data : inout std_logic_vector);
  14. procedure init (logging : in boolean := false);
  15. impure function is_empty return boolean;
  16. impure function fillstate return natural;
  17. end protected t_stack;
  18. end package StackP;
  19. package body StackP is
  20. -- linked list stack implementation
  21. type t_stack is protected body
  22. type t_entry;
  23. type t_entry_ptr is access t_entry;
  24. type t_data_ptr is access std_logic_vector;
  25. type t_entry is record
  26. data : t_data_ptr;
  27. last_entry : t_entry_ptr;
  28. next_entry : t_entry_ptr;
  29. end record t_entry;
  30. variable v_head : t_entry_ptr := null;
  31. variable v_tail : t_entry_ptr := null;
  32. variable v_count : natural := 0;
  33. variable v_logging : boolean := false;
  34. -- write one entry into queue by
  35. -- creating new entry at head of list
  36. procedure push (data : in std_logic_vector) is
  37. variable v_entry : t_entry_ptr;
  38. begin
  39. if (v_count /= 0) then
  40. v_entry := new t_entry;
  41. v_entry.data := new std_logic_vector'(data);
  42. v_entry.last_entry := v_head;
  43. v_entry.next_entry := null;
  44. v_head := v_entry;
  45. v_head.last_entry.next_entry := v_head;
  46. else
  47. v_head := new t_entry;
  48. v_head.data := new std_logic_vector'(data);
  49. v_head.last_entry := null;
  50. v_head.next_entry := null;
  51. v_tail := v_head;
  52. end if;
  53. v_count := v_count + 1;
  54. if v_logging then
  55. report t_stack'instance_name & " pushed 0x" & to_hstring(data) & " on stack";
  56. end if;
  57. end procedure push;
  58. -- read one entry from queue at tail of list and
  59. -- delete that entry from list after read
  60. procedure pop (data : inout std_logic_vector) is
  61. variable v_entry : t_entry_ptr := v_head;
  62. begin
  63. assert not(is_empty)
  64. report "pop from empty queue -> discarded"
  65. severity failure;
  66. data := v_head.data.all;
  67. v_head := v_head.last_entry;
  68. deallocate(v_entry.data);
  69. deallocate(v_entry);
  70. v_count := v_count - 1;
  71. if v_logging then
  72. report t_stack'instance_name & " popped 0x" & to_hstring(data) & " from stack";
  73. end if;
  74. end procedure pop;
  75. procedure init (logging : in boolean := false) is
  76. begin
  77. v_logging := logging;
  78. end procedure init;
  79. -- returns true if queue is empty, false otherwise
  80. impure function is_empty return boolean is
  81. begin
  82. return v_head = null;
  83. end function is_empty;
  84. -- returns number of filled slots in queue
  85. impure function fillstate return natural is
  86. begin
  87. return v_count;
  88. end function fillstate;
  89. end protected body t_stack;
  90. end package body StackP;