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.

172 lines
4.9 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. package DictP is
  4. type t_dict is protected
  5. procedure set (key : in string; data : in std_logic_vector);
  6. procedure get (key : in string; data : out std_logic_vector; err : out boolean);
  7. procedure del (key : in string; err : out boolean);
  8. procedure init (logging : in boolean := false);
  9. procedure clear (err : out boolean);
  10. impure function hasKey (key : string) return boolean;
  11. impure function size return natural;
  12. end protected t_dict;
  13. end package DictP;
  14. package body DictP is
  15. type t_dict is protected body
  16. type t_entry;
  17. type t_entry_ptr is access t_entry;
  18. type t_key_ptr is access string;
  19. type t_data_ptr is access std_logic_vector;
  20. type t_entry is record
  21. key : t_key_ptr;
  22. data : t_data_ptr;
  23. last_entry : t_entry_ptr;
  24. next_entry : t_entry_ptr;
  25. end record t_entry;
  26. variable v_head : t_entry_ptr := null;
  27. variable v_size : natural := 0;
  28. variable v_logging : boolean := false;
  29. impure function find (key : string) return t_entry_ptr;
  30. procedure set (key : in string; data : in std_logic_vector) is
  31. variable v_entry : t_entry_ptr := find(key);
  32. begin
  33. if (v_entry = null) then
  34. if (v_head /= null) then
  35. v_entry := new t_entry;
  36. v_entry.key := new string'(key);
  37. v_entry.data := new std_logic_vector'(data);
  38. v_entry.last_entry := v_head;
  39. v_entry.next_entry := null;
  40. v_head := v_entry;
  41. v_head.last_entry.next_entry := v_head;
  42. else
  43. v_head := new t_entry;
  44. v_head.key := new string'(key);
  45. v_head.data := new std_logic_vector'(data);
  46. v_head.last_entry := null;
  47. v_head.next_entry := null;
  48. end if;
  49. if (v_logging) then
  50. report t_dict'instance_name & ": Add key " & key & " with data 0x" & to_hstring(data);
  51. end if;
  52. v_size := v_size + 1;
  53. else
  54. v_entry.data.all := data;
  55. if (v_logging) then
  56. report t_dict'instance_name & ": Set key " & key & " to 0x" & to_hstring(data);
  57. end if;
  58. end if;
  59. end procedure set;
  60. procedure get (key : in string; data : out std_logic_vector; err : out boolean) is
  61. variable v_entry : t_entry_ptr := find(key);
  62. begin
  63. if(v_entry /= null) then
  64. data := v_entry.data.all;
  65. if v_logging then
  66. report t_dict'instance_name & ": Got key " & key & " with data 0x" & to_hstring(v_entry.data.all);
  67. end if;
  68. err := false;
  69. else
  70. err := true;
  71. end if;
  72. end procedure get;
  73. procedure del (key : in string; err : out boolean) is
  74. variable v_entry : t_entry_ptr := find(key);
  75. begin
  76. if (v_entry /= null) then
  77. -- remove head entry
  78. if(v_entry.next_entry = null and v_entry.last_entry /= null) then
  79. v_entry.last_entry.next_entry := null;
  80. v_head := v_entry.last_entry;
  81. -- remove start entry
  82. elsif(v_entry.next_entry /= null and v_entry.last_entry = null) then
  83. v_entry.next_entry.last_entry := null;
  84. v_entry.next_entry.last_entry := v_entry.last_entry;
  85. -- remove from between
  86. elsif(v_entry.next_entry /= null and v_entry.last_entry /= null) then
  87. v_entry.last_entry.next_entry := v_entry.next_entry;
  88. v_entry.next_entry.last_entry := v_entry.last_entry;
  89. end if;
  90. deallocate(v_entry.key);
  91. deallocate(v_entry.data);
  92. deallocate(v_entry);
  93. v_size := v_size - 1;
  94. err := false;
  95. else
  96. err := true;
  97. end if;
  98. end procedure del;
  99. impure function find (key : string) return t_entry_ptr is
  100. variable v_entry : t_entry_ptr := v_head;
  101. begin
  102. while (v_entry /= null) loop
  103. if(v_entry.key.all = key) then
  104. return v_entry;
  105. end if;
  106. v_entry := v_entry.last_entry;
  107. end loop;
  108. return null;
  109. end function find;
  110. procedure clear (err : out boolean) is
  111. variable v_entry : t_entry_ptr := v_head;
  112. variable v_entry_d : t_entry_ptr;
  113. variable v_err : boolean;
  114. begin
  115. err := false;
  116. while (v_entry /= null) loop
  117. v_entry_d := v_entry;
  118. del(v_entry_d.key.all, v_err);
  119. if v_err then
  120. err := true;
  121. return;
  122. else
  123. v_entry := v_entry.last_entry;
  124. end if;
  125. end loop;
  126. end procedure clear;
  127. impure function hasKey (key : string) return boolean is
  128. begin
  129. return find(key) /= null;
  130. end function hasKey;
  131. impure function size return natural is
  132. begin
  133. return v_size;
  134. end function size;
  135. procedure init (logging : in boolean := false) is
  136. begin
  137. v_logging := logging;
  138. end procedure init;
  139. end protected body t_dict;
  140. end package body DictP;