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.

183 lines
5.1 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. package QueueP is
  4. -- simple queue interface
  5. type t_simple_queue is protected
  6. procedure push (data : in std_logic_vector);
  7. procedure pop (data : out std_logic_vector);
  8. impure function is_empty return boolean;
  9. impure function is_full return boolean;
  10. impure function fillstate return natural;
  11. impure function freeslots return natural;
  12. end protected t_simple_queue;
  13. -- linked list queue interface
  14. type t_list_queue is protected
  15. procedure push (data : in std_logic_vector);
  16. procedure pop (data : out std_logic_vector);
  17. impure function is_empty return boolean;
  18. impure function is_full return boolean;
  19. impure function fillstate return natural;
  20. impure function freeslots return natural;
  21. end protected t_list_queue;
  22. end package QueueP;
  23. package body QueueP is
  24. -- simple queue implementation
  25. -- inspired by noasic article http://noasic.com/blog/a-simple-fifo-using-vhdl-protected-types/
  26. type t_simple_queue is protected body
  27. constant C_QUEUE_DEPTH : natural := 64;
  28. constant C_QUEUE_WIDTH : natural := 64;
  29. type t_queue_array is array (0 to C_QUEUE_DEPTH-1) of std_logic_vector(C_QUEUE_WIDTH-1 downto 0);
  30. variable v_queue : t_queue_array := (others => (others => '0'));
  31. variable v_count : natural range 0 to t_queue_array'length := 0;
  32. variable v_head : natural range 0 to t_queue_array'high := 0;
  33. variable v_tail : natural range 0 to t_queue_array'high := 0;
  34. -- write one entry into queue
  35. procedure push (data : in std_logic_vector) is
  36. begin
  37. assert not(is_full)
  38. report "push into full queue -> discarded"
  39. severity failure;
  40. v_queue(v_head) := data;
  41. v_head := (v_head + 1) mod t_queue_array'length;
  42. v_count := v_count + 1;
  43. end procedure push;
  44. -- read one entry from queue
  45. procedure pop (data : out std_logic_vector) is
  46. begin
  47. assert not(is_empty)
  48. report "pop from empty queue -> discarded"
  49. severity failure;
  50. data := v_queue(v_tail);
  51. v_tail := (v_tail + 1) mod t_queue_array'length;
  52. v_count := v_count - 1;
  53. end procedure pop;
  54. -- returns true if queue is empty, false otherwise
  55. impure function is_empty return boolean is
  56. begin
  57. return v_count = 0;
  58. end function is_empty;
  59. -- returns true if queue is full, false otherwise
  60. impure function is_full return boolean is
  61. begin
  62. return v_count = t_queue_array'length;
  63. end function is_full;
  64. -- returns number of filled slots in queue
  65. impure function fillstate return natural is
  66. begin
  67. return v_count;
  68. end function fillstate;
  69. -- returns number of free slots in queue
  70. impure function freeslots return natural is
  71. begin
  72. return t_queue_array'length - v_count;
  73. end function freeslots;
  74. end protected body t_simple_queue;
  75. -- linked liste queue implementation
  76. type t_list_queue is protected body
  77. constant C_QUEUE_DEPTH : natural := 64;
  78. constant C_QUEUE_WIDTH : natural := 64;
  79. type t_entry;
  80. type t_entry_ptr is access t_entry;
  81. type t_entry is record
  82. data : std_logic_vector(C_QUEUE_WIDTH-1 downto 0);
  83. last_entry : t_entry_ptr;
  84. next_entry : t_entry_ptr;
  85. end record t_entry;
  86. variable v_head : t_entry_ptr;
  87. variable v_tail : t_entry_ptr;
  88. variable v_count : natural range 0 to C_QUEUE_DEPTH := 0;
  89. -- write one entry into queue by
  90. -- creating new entry at head of list
  91. procedure push (data : in std_logic_vector) is
  92. begin
  93. assert not(is_full)
  94. report "push into full queue -> discarded"
  95. severity failure;
  96. if(v_head /= null) then
  97. v_head := new t_entry'(data, v_head, null);
  98. v_head.last_entry.next_entry := v_head;
  99. else
  100. v_head := new t_entry'(data, null, null);
  101. v_tail := v_head;
  102. end if;
  103. v_count := v_count + 1;
  104. end procedure push;
  105. -- read one entry from queue at tail of list and
  106. -- delete that entry from list after read
  107. procedure pop (data : out std_logic_vector) is
  108. variable v_entry : t_entry_ptr;
  109. begin
  110. assert not(is_empty)
  111. report "pop from empty queue -> discarded"
  112. severity failure;
  113. data := v_tail.data;
  114. v_entry := v_tail;
  115. v_tail := v_tail.next_entry;
  116. deallocate(v_entry);
  117. v_count := v_count - 1;
  118. end procedure pop;
  119. -- returns true if queue is empty, false otherwise
  120. impure function is_empty return boolean is
  121. begin
  122. return v_tail = null;
  123. end function is_empty;
  124. -- returns true if queue is full, false otherwise
  125. impure function is_full return boolean is
  126. begin
  127. return v_count = C_QUEUE_DEPTH;
  128. end function is_full;
  129. -- returns number of filled slots in queue
  130. impure function fillstate return natural is
  131. begin
  132. return v_count;
  133. end function fillstate;
  134. -- returns number of free slots in queue
  135. impure function freeslots return natural is
  136. begin
  137. return C_QUEUE_DEPTH - v_count;
  138. end function freeslots;
  139. end protected body t_list_queue;
  140. end package body QueueP;