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.

179 lines
4.9 KiB

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