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.

214 lines
6.2 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. package DictP is
  4. type t_dict_dir is (UP, DOWN);
  5. type t_dict_error is (NO_ERROR, KEY_INVALID, KEY_NOT_FOUND);
  6. type t_dict_key_ptr is access string;
  7. type t_dict is protected
  8. procedure set (key : in string; data : in std_logic_vector; err : out t_dict_error);
  9. procedure get (key : in string; data : out std_logic_vector; err : out t_dict_error);
  10. procedure del (key : in string; err : out t_dict_error);
  11. procedure init (logging : in boolean := false);
  12. procedure clear (err : out t_dict_error);
  13. impure function hasKey (key : string) return boolean;
  14. impure function size return natural;
  15. procedure setFirst;
  16. procedure setLast;
  17. impure function iter (dir : t_dict_dir := UP) return string;
  18. end protected t_dict;
  19. end package DictP;
  20. package body DictP is
  21. type t_dict 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. key : t_dict_key_ptr;
  27. data : t_data_ptr;
  28. last_entry : t_entry_ptr;
  29. next_entry : t_entry_ptr;
  30. end record t_entry;
  31. variable v_begin : t_entry_ptr := null;
  32. variable v_head : t_entry_ptr := null;
  33. variable v_current : t_entry_ptr := null;
  34. variable v_size : natural := 0;
  35. variable v_logging : boolean := false;
  36. impure function find (key : string) return t_entry_ptr;
  37. procedure set (key : in string; data : in std_logic_vector; err : out t_dict_error) is
  38. variable v_entry : t_entry_ptr := find(key);
  39. begin
  40. if (key = "") then
  41. err := KEY_INVALID;
  42. else
  43. if (v_entry = null) then
  44. if (v_head /= null) then
  45. v_entry := new t_entry;
  46. v_entry.key := new string'(key);
  47. v_entry.data := new std_logic_vector'(data);
  48. v_entry.last_entry := v_head;
  49. v_entry.next_entry := null;
  50. v_head := v_entry;
  51. v_head.last_entry.next_entry := v_head;
  52. else
  53. v_head := new t_entry;
  54. v_head.key := new string'(key);
  55. v_head.data := new std_logic_vector'(data);
  56. v_head.last_entry := null;
  57. v_head.next_entry := null;
  58. v_begin := v_head;
  59. end if;
  60. if (v_logging) then
  61. report t_dict'instance_name & ": Add key " & key & " with data 0x" & to_hstring(data);
  62. end if;
  63. v_size := v_size + 1;
  64. else
  65. v_entry.data.all := data;
  66. if (v_logging) then
  67. report t_dict'instance_name & ": Set key " & key & " to 0x" & to_hstring(data);
  68. end if;
  69. end if;
  70. err := NO_ERROR;
  71. end if;
  72. end procedure set;
  73. procedure get (key : in string; data : out std_logic_vector; err : out t_dict_error) is
  74. variable v_entry : t_entry_ptr := find(key);
  75. begin
  76. if(v_entry /= null) then
  77. data := v_entry.data.all;
  78. if v_logging then
  79. report t_dict'instance_name & ": Got key " & key & " with data 0x" & to_hstring(v_entry.data.all);
  80. end if;
  81. err := NO_ERROR;
  82. else
  83. err := KEY_NOT_FOUND;
  84. end if;
  85. end procedure get;
  86. procedure del (key : in string; err : out t_dict_error) is
  87. variable v_entry : t_entry_ptr := find(key);
  88. begin
  89. if (v_entry /= null) then
  90. -- remove head entry
  91. if(v_entry.next_entry = null and v_entry.last_entry /= null) then
  92. v_entry.last_entry.next_entry := null;
  93. v_head := v_entry.last_entry;
  94. -- remove start entry
  95. elsif(v_entry.next_entry /= null and v_entry.last_entry = null) then
  96. v_entry.next_entry.last_entry := null;
  97. --v_entry.next_entry.last_entry := v_entry.last_entry;
  98. v_begin := v_entry.next_entry;
  99. -- remove from between
  100. elsif(v_entry.next_entry /= null and v_entry.last_entry /= null) then
  101. v_entry.last_entry.next_entry := v_entry.next_entry;
  102. v_entry.next_entry.last_entry := v_entry.last_entry;
  103. end if;
  104. deallocate(v_entry.key);
  105. deallocate(v_entry.data);
  106. deallocate(v_entry);
  107. v_size := v_size - 1;
  108. err := NO_ERROR;
  109. else
  110. err := KEY_NOT_FOUND;
  111. end if;
  112. end procedure del;
  113. impure function find (key : string) return t_entry_ptr is
  114. variable v_entry : t_entry_ptr := v_head;
  115. begin
  116. while (v_entry /= null) loop
  117. if(v_entry.key.all = key) then
  118. return v_entry;
  119. end if;
  120. v_entry := v_entry.last_entry;
  121. end loop;
  122. return null;
  123. end function find;
  124. procedure clear (err : out t_dict_error) is
  125. variable v_entry : t_entry_ptr := v_head;
  126. variable v_entry_d : t_entry_ptr;
  127. variable v_err : t_dict_error;
  128. begin
  129. while (v_entry /= null) loop
  130. v_entry_d := v_entry;
  131. del(v_entry_d.key.all, v_err);
  132. if (v_err /= NO_ERROR) then
  133. err := v_err;
  134. return;
  135. else
  136. v_entry := v_entry.last_entry;
  137. end if;
  138. end loop;
  139. err := NO_ERROR;
  140. end procedure clear;
  141. impure function hasKey (key : string) return boolean is
  142. begin
  143. return find(key) /= null;
  144. end function hasKey;
  145. impure function size return natural is
  146. begin
  147. return v_size;
  148. end function size;
  149. procedure init (logging : in boolean := false) is
  150. begin
  151. v_logging := logging;
  152. end procedure init;
  153. procedure setFirst is
  154. begin
  155. v_current := v_begin;
  156. end procedure setFirst;
  157. procedure setLast is
  158. begin
  159. v_current := v_head;
  160. end procedure setLast;
  161. impure function iter (dir : t_dict_dir := UP) return string is
  162. variable v_key : t_dict_key_ptr := null;
  163. begin
  164. if (v_current /= null) then
  165. v_key := new string'(v_current.key.all);
  166. if (dir = UP) then
  167. v_current := v_current.next_entry;
  168. else
  169. v_current := v_current.last_entry;
  170. end if;
  171. return v_key.all;
  172. else
  173. return "";
  174. end if;
  175. end function iter;
  176. end protected body t_dict;
  177. end package body DictP;