Browse Source

DictP is now a package with generics for key & type

T. Meissner 2 years ago
parent
commit
61eb06ee09
3 changed files with 169 additions and 177 deletions
  1. 77
    90
      sim/DictP.vhd
  2. 36
    31
      test/DictT.vhd
  3. 56
    56
      test/WishBoneT.vhd

+ 77
- 90
sim/DictP.vhd View File

@@ -6,29 +6,37 @@ library ieee;
6 6
 package DictP is
7 7
 
8 8
 
9
+  generic (
10
+    type     KEY_TYPE;
11
+    type     VALUE_TYPE;
12
+    function key_to_string(d : in KEY_TYPE) return string;
13
+    function value_to_string(d : in VALUE_TYPE) return string
14
+  );
15
+
16
+
17
+
18
+  type t_dict_key_ptr  is access KEY_TYPE;
19
+  type t_dict_data_ptr is access VALUE_TYPE;
20
+
9 21
   type t_dict_dir   is (UP, DOWN);
10
-  type t_dict_error is (NO_ERROR, KEY_INVALID, KEY_NOT_FOUND);
11 22
   type t_dict_iter  is (TAIL, HEAD);
12 23
 
13
-  type t_dict_key_ptr  is access string;
14
-  type t_dict_data_ptr is access std_logic_vector;
15
-
16 24
   type t_dict is protected
17 25
 
18
-    procedure set (constant key : in string; constant data : in std_logic_vector; err : out t_dict_error);
19
-    procedure get (constant key : in string; data : out std_logic_vector; err : out t_dict_error);
20
-    procedure del (constant key : in string; err : out t_dict_error);
26
+    procedure set (constant key : in KEY_TYPE; constant data : in VALUE_TYPE);
27
+    procedure get (constant key : in KEY_TYPE; data : out VALUE_TYPE);
28
+    procedure del (constant key : in KEY_TYPE);
21 29
     procedure init (constant logging : in boolean := false);
22
-    procedure clear (err : out t_dict_error);
23
-    impure function hasKey (constant key : string) return boolean;
30
+    procedure clear;
31
+    impure function hasKey (constant key : KEY_TYPE) return boolean;
24 32
     impure function size return natural;
25 33
     procedure setIter(constant start : in t_dict_iter := TAIL);
26
-    impure function iter (constant dir : t_dict_dir := UP) return string;
27
-    impure function get (constant key : string) return std_logic_vector;
34
+    impure function iter (constant dir : t_dict_dir := UP) return KEY_TYPE;
35
+    impure function get (constant key : KEY_TYPE) return VALUE_TYPE;
28 36
 
29 37
   end protected t_dict;
30 38
 
31
-  procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict; err : out t_dict_error);
39
+  procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict);
32 40
 
33 41
 
34 42
 end package DictP;
@@ -57,62 +65,60 @@ package body DictP is
57 65
     variable v_size     : natural := 0;
58 66
     variable v_logging  : boolean := false;
59 67
 
60
-    impure function find (constant key : string) return t_entry_ptr;
68
+    impure function find (constant key : KEY_TYPE) return t_entry_ptr;
61 69
 
62
-    procedure set (constant key : in string; constant data : in std_logic_vector; err : out t_dict_error) is
70
+    procedure set (constant key : in KEY_TYPE; constant data : in VALUE_TYPE) is
63 71
       variable v_entry : t_entry_ptr := find(key);
64 72
     begin
65
-      if (key = "") then
66
-        err := KEY_INVALID;
67
-      else
68
-        if (v_entry = null) then
69
-          if (v_head /= null) then
70
-            v_entry                      := new t_entry;
71
-            v_entry.key                  := new string'(key);
72
-            v_entry.data                 := new std_logic_vector'(data);
73
-            v_entry.last_entry           := v_head;
74
-            v_entry.next_entry           := null;
75
-            v_head                       := v_entry;
76
-            v_head.last_entry.next_entry := v_head;
77
-          else
78
-            v_head            := new t_entry;
79
-            v_head.key        := new string'(key);
80
-            v_head.data       := new std_logic_vector'(data);
81
-            v_head.last_entry := null;
82
-            v_head.next_entry := null;
83
-            v_tail           := v_head;
84
-          end if;
85
-          if (v_logging) then
86
-            report t_dict'instance_name & ": Add key " & key & " with data 0x" & to_hstring(data);
87
-          end if;
88
-          v_size := v_size + 1;
73
+      if (v_entry = null) then
74
+        if (v_head /= null) then
75
+          v_entry                      := new t_entry;
76
+          v_entry.key                  := new KEY_TYPE'(key);
77
+          v_entry.data                 := new VALUE_TYPE'(data);
78
+          v_entry.last_entry           := v_head;
79
+          v_entry.next_entry           := null;
80
+          v_head                       := v_entry;
81
+          v_head.last_entry.next_entry := v_head;
89 82
         else
90
-          v_entry.data.all := data;
91
-          if (v_logging) then
92
-            report t_dict'instance_name & ": Set key " & key & " to 0x" & to_hstring(data);
93
-          end if;
83
+          v_head            := new t_entry;
84
+          v_head.key        := new KEY_TYPE'(key);
85
+          v_head.data       := new VALUE_TYPE'(data);
86
+          v_head.last_entry := null;
87
+          v_head.next_entry := null;
88
+          v_tail           := v_head;
89
+        end if;
90
+        if (v_logging) then
91
+          report t_dict'instance_name & ": Add key " & key_to_string(key) & " with value " & value_to_string(data) & " to dictionary";
92
+        end if;
93
+        v_size := v_size + 1;
94
+      else
95
+        v_entry.data.all := data;
96
+        if (v_logging) then
97
+          report t_dict'instance_name & ": Set value of key " & key_to_string(key) & " to 0x" & value_to_string(data);
94 98
         end if;
95
-        err := NO_ERROR;
96 99
       end if;
97 100
     end procedure set;
98 101
 
99
-    procedure get (constant key : in string; data : out std_logic_vector; err : out t_dict_error) is
102
+    procedure get (constant key : in KEY_TYPE; data : out VALUE_TYPE) is
100 103
       variable v_entry : t_entry_ptr := find(key);
101 104
     begin
105
+      assert v_entry /= null
106
+        report t_dict'instance_name & ": key " & key_to_string(key) & " not found"
107
+        severity failure;
102 108
       if(v_entry /= null) then
103 109
         data := v_entry.data.all;
104 110
         if v_logging then
105
-          report t_dict'instance_name & ": Got key " & key & " with data 0x" & to_hstring(v_entry.data.all);
111
+          report t_dict'instance_name & ": Got key " & key_to_string(key) & " with value " & value_to_string(v_entry.data.all);
106 112
         end if;
107
-        err := NO_ERROR;
108
-      else
109
-        err := KEY_NOT_FOUND;
110 113
       end if;
111 114
     end procedure get;
112 115
 
113
-    procedure del (constant key : in string; err : out t_dict_error) is
116
+    procedure del (constant key : in KEY_TYPE) is
114 117
       variable v_entry : t_entry_ptr := find(key);
115 118
     begin
119
+      assert v_entry /= null
120
+        report t_dict'instance_name & ": key " & key_to_string(key) & " not found"
121
+        severity failure;
116 122
       if (v_entry /= null) then
117 123
         -- remove head entry
118 124
         if(v_entry.next_entry = null and v_entry.last_entry /= null) then
@@ -132,13 +138,10 @@ package body DictP is
132 138
         deallocate(v_entry.data);
133 139
         deallocate(v_entry);
134 140
         v_size := v_size - 1;
135
-        err := NO_ERROR;
136
-      else
137
-        err := KEY_NOT_FOUND;
138 141
       end if;
139 142
     end procedure del;
140 143
 
141
-    impure function find (constant key : string) return t_entry_ptr is
144
+    impure function find (constant key : KEY_TYPE) return t_entry_ptr is
142 145
       variable v_entry : t_entry_ptr := v_head;
143 146
     begin
144 147
       while (v_entry /= null) loop
@@ -150,25 +153,18 @@ package body DictP is
150 153
       return null;
151 154
     end function find;
152 155
 
153
-    procedure clear (err : out t_dict_error) is
156
+    procedure clear is
154 157
       variable v_entry   : t_entry_ptr := v_head;
155 158
       variable v_entry_d : t_entry_ptr;
156
-      variable v_err     : t_dict_error;
157 159
     begin
158 160
       while (v_entry /= null) loop
159 161
         v_entry_d := v_entry;
160
-        del(v_entry_d.key.all, v_err);
161
-        if (v_err /= NO_ERROR) then
162
-          err := v_err;
163
-          return;
164
-        else
165
-          v_entry := v_entry.last_entry;
166
-        end if;
162
+        del(v_entry_d.key.all);
163
+        v_entry := v_entry.last_entry;
167 164
       end loop;
168
-      err := NO_ERROR;
169 165
     end procedure clear;
170 166
 
171
-    impure function hasKey (constant key : string) return boolean is
167
+    impure function hasKey (constant key : KEY_TYPE) return boolean is
172 168
     begin
173 169
       return find(key) /= null;
174 170
     end function hasKey;
@@ -192,27 +188,27 @@ package body DictP is
192 188
       end if;
193 189
     end procedure setIter;
194 190
 
195
-    impure function iter (constant dir : t_dict_dir := UP) return string is
191
+    impure function iter (constant dir : t_dict_dir := UP) return KEY_TYPE is
196 192
       variable v_key : t_dict_key_ptr := null;
197 193
     begin
198
-      if (v_iterator /= null) then
199
-        v_key := new string'(v_iterator.key.all);
200
-        if (dir = UP) then
194
+      v_key := new KEY_TYPE'(v_iterator.key.all);
195
+      if (dir = UP) then
196
+        if (v_iterator.next_entry /= null) then
201 197
           v_iterator := v_iterator.next_entry;
202
-        else
203
-          v_iterator := v_iterator.last_entry;
204 198
         end if;
205
-        return v_key.all;
206 199
       else
207
-        return "";
200
+        if (v_iterator.last_entry /= null) then
201
+          v_iterator := v_iterator.last_entry;
202
+        end if;
208 203
       end if;
204
+      return v_key.all;
209 205
     end function iter;
210 206
 
211
-    impure function get(constant key : string) return std_logic_vector is
207
+    impure function get(constant key : KEY_TYPE) return VALUE_TYPE is
212 208
       variable v_entry : t_entry_ptr := find(key);
213 209
     begin
214 210
       assert v_entry /= null
215
-        report t_dict'instance_name & ": ERROR: key " & key & " not found"
211
+        report t_dict'instance_name & ": key " & key_to_string(key) & " not found"
216 212
         severity failure;
217 213
       return v_entry.data.all;
218 214
     end function get;
@@ -221,33 +217,24 @@ package body DictP is
221 217
   end protected body t_dict;
222 218
 
223 219
 
224
-  procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict; err : out t_dict_error) is
220
+  procedure merge(d0 : inout t_dict; d1 : inout t_dict; d : inout t_dict) is
225 221
     variable v_key   : t_dict_key_ptr;
226 222
     variable v_data  : t_dict_data_ptr;
227
-    variable v_error : t_dict_error;
228 223
   begin
229 224
     if (d0.size > 0) then
230 225
       d0.setIter(TAIL);
231 226
       for i in 0 to d0.size-1 loop
232
-        v_key  := new string'(d0.iter(UP));
233
-        v_data := new std_logic_vector'(d0.get(v_key.all));
234
-        d.set(v_key.all, v_data.all, v_error);
235
-        if (v_error /= NO_ERROR) then
236
-          err := v_error;
237
-          return;
238
-        end if;
227
+        v_key  := new KEY_TYPE'(d0.iter(UP));
228
+        v_data := new VALUE_TYPE'(d0.get(v_key.all));
229
+        d.set(v_key.all, v_data.all);
239 230
       end loop;
240 231
     end if;
241 232
     if (d1.size > 0) then
242 233
       d1.setIter(TAIL);
243 234
       for i in 0 to d1.size-1 loop
244
-        v_key  := new string'(d1.iter(UP));
245
-        v_data := new std_logic_vector'(d1.get(v_key.all));
246
-        d.set(v_key.all, v_data.all, v_error);
247
-        if (v_error /= NO_ERROR) then
248
-          err := v_error;
249
-          return;
250
-        end if;
235
+        v_key  := new KEY_TYPE'(d1.iter(UP));
236
+        v_data := new VALUE_TYPE'(d1.get(v_key.all));
237
+        d.set(v_key.all, v_data.all);
251 238
       end loop;
252 239
     end if;
253 240
   end procedure merge;

+ 36
- 31
test/DictT.vhd View File

@@ -2,19 +2,12 @@ library ieee;
2 2
   use ieee.std_logic_1164.all;
3 3
   use ieee.numeric_std.all;
4 4
 
5
---+ including vhdl 2008 libraries
6
---+ These lines can be commented out when using
7
---+ a simulator with built-in VHDL 2008 support
8
---library ieee_proposed;
5
+
9 6
 
10 7
 library osvvm;
11 8
   use osvvm.RandomPkg.all;
12 9
 
13 10
 library libvhdl;
14
-  use libvhdl.DictP.all;
15 11
 
16 12
 
17 13
 
@@ -28,6 +21,20 @@ architecture sim of DictT is
28 21
 
29 22
   type t_scoreboard is array (natural range <>) of std_logic_vector(7 downto 0);
30 23
 
24
+  function to_string(d : string) return string is
25
+  begin
26
+    return d;
27
+  end function to_string;
28
+
29
+
30
+  package StringSlvDict is new libvhdl.DictP
31
+    generic map (KEY_TYPE         => string,
32
+                 VALUE_TYPE       => std_logic_vector,
33
+                 key_to_string    => to_string,
34
+                 value_to_string  => to_hstring);
35
+
36
+  use StringSlvDict.all;
37
+
31 38
   shared variable sv_dict : t_dict;
32 39
   shared variable sv_dact : t_dict;
33 40
   shared variable sv_duct : t_dict;
@@ -36,6 +43,7 @@ architecture sim of DictT is
36 43
 begin
37 44
 
38 45
 
46
+
39 47
   DictInitP : process is
40 48
   begin
41 49
     sv_dict.init(false);
@@ -47,11 +55,11 @@ begin
47 55
 
48 56
   DictTestP : process is
49 57
     variable v_key        : t_dict_key_ptr;
58
+    variable v_last_key   : t_dict_key_ptr;
50 59
     variable v_random     : RandomPType;
51 60
     variable v_input      : std_logic_vector(7 downto 0);
52 61
     variable v_output     : std_logic_vector(7 downto 0);
53 62
     variable v_scoreboard : t_scoreboard(0 to 511);
54
-    variable v_error      : t_dict_error;
55 63
   begin
56 64
     v_random.InitSeed(v_random'instance_name);
57 65
 
@@ -60,19 +68,11 @@ begin
60 68
       report "ERROR: Dict should be empty"
61 69
       severity failure;
62 70
 
63
-    -- The dict shouldn_t accept an empty key string
64
-    report "INFO: Test 0: Try to set an entry with empty key string";
65
-    sv_dict.set("", x"0123456789", v_error);
66
-    assert v_error = KEY_INVALID
67
-      report "ERROR: Key '' should raise a KEY_INVALID error"
68
-      severity failure;
69
-    report "INFO: Test successful";
70
-
71 71
     -- fill dictionary and check count
72 72
     report "INFO: Test 1: Fill dictionary";
73 73
     for i in 0 to 255 loop
74 74
       v_input := v_random.RandSlv(8);
75
-      sv_dict.set(integer'image(i), v_input, v_error);
75
+      sv_dict.set(integer'image(i), v_input);
76 76
       v_scoreboard(i) := v_input;
77 77
       assert sv_dict.size = i+1
78 78
         report "ERROR: Dict should have " & to_string(i+1) & " entries"
@@ -83,7 +83,7 @@ begin
83 83
     -- read all entries and check for correct data
84 84
     report "INFO: Test 2: Read dictionary";
85 85
     for i in 0 to 255 loop
86
-      sv_dict.get(integer'image(i), v_output, v_error);
86
+      sv_dict.get(integer'image(i), v_output);
87 87
       assert v_output = v_scoreboard(i)
88 88
         report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
89 89
         severity failure;
@@ -93,9 +93,9 @@ begin
93 93
     -- overwrite a key/value pair
94 94
     report "INFO: Test 3: Overwrite a entry";
95 95
     v_input := v_random.RandSlv(8);
96
-    sv_dict.set("128", v_input, v_error);
96
+    sv_dict.set("128", v_input);
97 97
     v_scoreboard(128) := v_input;
98
-    sv_dict.get("128", v_output, v_error);
98
+    sv_dict.get("128", v_output);
99 99
     assert v_output = v_scoreboard(128)
100 100
       report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(128))
101 101
       severity failure;
@@ -121,14 +121,15 @@ begin
121 121
       assert v_key.all = integer'image(i)
122 122
         report "ERROR: Got key " & v_key.all & ", expected " & integer'image(i)
123 123
         severity failure;
124
-      sv_dict.get(v_key.all, v_output, v_error);
124
+      sv_dict.get(v_key.all, v_output);
125 125
       assert v_key.all = integer'image(i) and v_output = v_scoreboard(i)
126 126
         report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
127 127
         severity failure;
128 128
     end loop;
129
+    v_last_key := v_key;
129 130
     v_key := new string'(sv_dict.iter(UP));
130
-    assert v_key.all = ""
131
-      report "ERROR: Got key " & v_key.all & ", expected empty key"
131
+    assert v_key.all = v_last_key.all
132
+      report "ERROR: Got key " & v_key.all & ", expected key" & v_last_key.all
132 133
       severity failure;
133 134
     report "INFO: Test successful";
134 135
 
@@ -140,14 +141,15 @@ begin
140 141
       assert v_key.all = integer'image(i)
141 142
         report "ERROR: Got key " & v_key.all & ", expected " & integer'image(i)
142 143
         severity failure;
143
-      sv_dict.get(v_key.all, v_output, v_error);
144
+      sv_dict.get(v_key.all, v_output);
144 145
       assert v_key.all = integer'image(i) and v_output = v_scoreboard(i)
145 146
         report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
146 147
         severity failure;
147 148
     end loop;
149
+    v_last_key := v_key;
148 150
     v_key := new string'(sv_dict.iter(DOWN));
149
-    assert v_key.all = ""
150
-      report "ERROR: Got key " & v_key.all & ", expected empty key"
151
+    assert v_key.all = v_last_key.all
152
+      report "ERROR: Got key " & v_key.all & ", expected key" & v_last_key.all
151 153
       severity failure;
152 154
     deallocate(v_key);
153 155
     report "INFO: Test successful";
@@ -157,17 +159,17 @@ begin
157 159
     report "INFO: Test 7: Merge dictionaries";
158 160
     for i in 256 to 511 loop
159 161
       v_input := v_random.RandSlv(8);
160
-      sv_dact.set(integer'image(i), v_input, v_error);
162
+      sv_dact.set(integer'image(i), v_input);
161 163
       v_scoreboard(i) := v_input;
162 164
       assert sv_dact.size = i-255
163 165
         report "ERROR: Dict should have " & to_string(i-255) & " entries"
164 166
         severity failure;
165 167
     end loop;
166 168
     -- merge dictionaries
167
-    merge(sv_dict, sv_dact, sv_duct, v_error);
169
+    merge(sv_dict, sv_dact, sv_duct);
168 170
     -- read all entries and check for correct data
169 171
     for i in 0 to 511 loop
170
-      sv_duct.get(integer'image(i), v_output, v_error);
172
+      sv_duct.get(integer'image(i), v_output);
171 173
       assert v_output = v_scoreboard(i)
172 174
         report "ERROR: Got 0x" & to_hstring(v_output) & ", expected 0x" & to_hstring(v_scoreboard(i))
173 175
         severity failure;
@@ -176,7 +178,7 @@ begin
176 178
 
177 179
     -- Remove key/value pair from head of dictionary
178 180
     report "INFO: Test 8: Removing entry from head of dictionary";
179
-    sv_dict.del("255", v_error);
181
+    sv_dict.del("255");
180 182
     assert not(sv_dict.hasKey("255"))
181 183
       report "ERROR: Key 255 shouldn't exist in dictionary"
182 184
       severity failure;
@@ -184,7 +186,7 @@ begin
184 186
 
185 187
     -- Remove key/value pair from head of dictionary
186 188
     report "INFO: Test 9: Removing entry from middle of dictionary";
187
-    sv_dict.del("127", v_error);
189
+    sv_dict.del("127");
188 190
     assert not(sv_dict.hasKey("127"))
189 191
       report "ERROR: Key 127 shouldn't exist in dictionary"
190 192
       severity failure;
@@ -192,7 +194,7 @@ begin
192 194
 
193 195
     -- Remove key/value pair from head of dictionary
194 196
     report "INFO: Test 10: Removing entry from beginning of dictionary";
195
-    sv_dict.del("0", v_error);
197
+    sv_dict.del("0");
196 198
     assert not(sv_dict.hasKey("0"))
197 199
       report "ERROR: Key 0 shouldn't exist in dictionary"
198 200
       severity failure;
@@ -200,7 +202,7 @@ begin
200 202
 
201 203
     -- Remove key/value pair from head of dictionary
202 204
     report "INFO: Test 11: Clear all entries from dictionary";
203
-    sv_dict.clear(v_error);
205
+    sv_dict.clear;
204 206
     assert sv_dict.size = 0
205 207
       report "ERROR: Dict should be empty"
206 208
       severity failure;

+ 56
- 56
test/WishBoneT.vhd View File

@@ -2,14 +2,6 @@ library ieee;
2 2
   use ieee.std_logic_1164.all;
3 3
   use ieee.numeric_std.all;
4 4
 
5
---+ including vhdl 2008 libraries
6
---+ These lines can be commented out when using
7
---+ a simulator with built-in VHDL 2008 support
8
---library ieee_proposed;
9
-
10 5
 library osvvm;
11 6
   use osvvm.RandomPkg.all;
12 7
   use osvvm.CoveragePkg.all;
@@ -18,9 +10,11 @@ library libvhdl;
18 10
   use libvhdl.AssertP.all;
19 11
   use libvhdl.SimP.all;
20 12
   use libvhdl.QueueP.all;
21
-  use libvhdl.DictP.all;
22 13
   use libvhdl.UtilsP.all;
23 14
 
15
+library std;
16
+  use std.env.all;
17
+
24 18
 
25 19
 
26 20
 entity WishBoneT is
@@ -90,7 +84,6 @@ architecture sim of WishBoneT is
90 84
     );
91 85
   end component WishBoneSlaveE;
92 86
 
93
-
94 87
   --* testbench global clock period
95 88
   constant C_PERIOD     : time := 5 ns;
96 89
   --* Wishbone data width
@@ -98,23 +91,26 @@ architecture sim of WishBoneT is
98 91
   --* Wishbone address width
99 92
   constant C_ADDRESS_WIDTH : natural := 8;
100 93
 
94
+  type t_wishbone is record
95
+    --+ wishbone outputs
96
+    Cyc       : std_logic;
97
+    Stb       : std_logic;
98
+    We        : std_logic;
99
+    Adr       : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
100
+    WDat      : std_logic_vector(C_DATA_WIDTH-1 downto 0);
101
+    --+ wishbone inputs
102
+    RDat      : std_logic_vector(C_DATA_WIDTH-1 downto 0);
103
+    Ack       : std_logic;
104
+    Err       : std_logic;
105
+  end record t_wishbone;
106
+
107
+  signal s_wishbone : t_wishbone := ('Z', 'Z', 'Z', (others => 'Z'), (others => 'Z'), (others => 'Z'), 'Z', 'Z');
108
+
101 109
   --* testbench global clock
102 110
   signal s_wb_clk : std_logic := '1';
103 111
   --* testbench global reset
104 112
   signal s_wb_reset : std_logic := '1';
105 113
 
106
-  --+ test done array with entry for each test
107
-  signal s_test_done : boolean;
108
-
109
-
110
-  signal s_wb_cyc              : std_logic;
111
-  signal s_wb_stb              : std_logic;
112
-  signal s_wb_we               : std_logic;
113
-  signal s_wb_adr              : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
114
-  signal s_wb_master_data      : std_logic_vector(C_DATA_WIDTH-1 downto 0);
115
-  signal s_wb_slave_data       : std_logic_vector(C_DATA_WIDTH-1 downto 0);
116
-  signal s_wb_ack              : std_logic;
117
-  signal s_wb_err              : std_logic;
118 114
   signal s_master_local_wen    : std_logic;
119 115
   signal s_master_local_ren    : std_logic;
120 116
   signal s_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
@@ -131,15 +127,23 @@ architecture sim of WishBoneT is
131 127
   type t_register is array (0 to integer'(2**C_ADDRESS_WIDTH-1)) of std_logic_vector(C_DATA_WIDTH-1 downto 0);
132 128
 
133 129
   shared variable sv_wishbone_queue : t_list_queue;
134
-  shared variable sv_wishbone_dict  : t_dict;
135
-  shared variable sv_coverage       : CovPType;
130
+
131
+  package IntSlvDict is new libvhdl.DictP
132
+    generic map (KEY_TYPE         => integer,
133
+                 VALUE_TYPE       => std_logic_vector,
134
+                 key_to_string    => to_string,
135
+                 value_to_string  => to_hstring);
136
+
137
+  shared variable sv_wishbone_dict : IntSlvDict.t_dict;
138
+
139
+  shared variable sv_coverage      : CovPType;
136 140
 
137 141
 
138 142
 begin
139 143
 
140 144
 
141 145
   --* testbench global clock
142
-  s_wb_clk <= not(s_wb_clk) after C_PERIOD/2 when not(s_test_done) else '0';
146
+  s_wb_clk <= not(s_wb_clk) after C_PERIOD/2;
143 147
   --* testbench global reset
144 148
   s_wb_reset <= '0' after C_PERIOD * 5;
145 149
 
@@ -157,7 +161,6 @@ begin
157 161
     variable v_wbmaster_address : integer;
158 162
     variable v_master_local_adress : std_logic_vector(C_ADDRESS_WIDTH-1 downto 0);
159 163
     variable v_wbmaster_data    : std_logic_vector(C_DATA_WIDTH-1 downto 0);
160
-    variable v_error            : t_dict_error;
161 164
   begin
162 165
     v_random.InitSeed(v_random'instance_name);
163 166
     v_wbmaster_data       := (others => '0');
@@ -182,10 +185,7 @@ begin
182 185
       s_master_local_wen    <= '0';
183 186
       wait until rising_edge(s_wb_clk) and s_master_local_ack = '1';
184 187
       sv_wishbone_queue.push(uint_to_slv(v_wbmaster_address, C_ADDRESS_WIDTH));
185
-      sv_wishbone_dict.set(integer'image(v_wbmaster_address), v_wbmaster_data, v_error);
186
-      assert v_error = NO_ERROR
187
-        report "ERROR: key error"
188
-        severity failure;
188
+      sv_wishbone_dict.set(v_wbmaster_address, v_wbmaster_data);
189 189
       sv_coverage.ICover(v_wbmaster_address);
190 190
     end loop;
191 191
     -- read back and check the wishbone slave registers
@@ -197,10 +197,7 @@ begin
197 197
       s_master_local_adress <= (others => '0');
198 198
       s_master_local_ren    <= '0';
199 199
       wait until rising_edge(s_wb_clk) and s_master_local_ack = '1';
200
-      sv_wishbone_dict.get(integer'image(slv_to_uint(v_master_local_adress)), v_wbmaster_data, v_error);
201
-      assert v_error = NO_ERROR
202
-        report "ERROR: key error"
203
-        severity failure;
200
+      sv_wishbone_dict.get(slv_to_uint(v_master_local_adress), v_wbmaster_data);
204 201
       assert_equal(s_master_local_dout, v_wbmaster_data);
205 202
     end loop;
206 203
     -- test local write & read at the same time
@@ -215,7 +212,7 @@ begin
215 212
     report "INFO: Test successfully finished!";
216 213
     sv_coverage.SetMessage("WishboneT coverage results");
217 214
     sv_coverage.WriteBin;
218
-    s_test_done <= true;
215
+    finish;
219 216
     wait;
220 217
   end process WbMasterLocalP;
221 218
 
@@ -230,15 +227,15 @@ begin
230 227
       WbRst_i       => s_wb_reset,
231 228
       WbClk_i       => s_wb_clk,
232 229
       --+ wishbone outputs
233
-      WbCyc_o       => s_wb_cyc,
234
-      WbStb_o       => s_wb_stb,
235
-      WbWe_o        => s_wb_we,
236
-      WbAdr_o       => s_wb_adr,
237
-      WbDat_o       => s_wb_master_data,
230
+      WbCyc_o       => s_wishbone.Cyc,
231
+      WbStb_o       => s_wishbone.Stb,
232
+      WbWe_o        => s_wishbone.We,
233
+      WbAdr_o       => s_wishbone.Adr,
234
+      WbDat_o       => s_wishbone.WDat,
238 235
       --+ wishbone inputs
239
-      WbDat_i       => s_wb_slave_data,
240
-      WbAck_i       => s_wb_ack,
241
-      WbErr_i       => s_wb_err,
236
+      WbDat_i       => s_wishbone.RDat,
237
+      WbAck_i       => s_wishbone.Ack,
238
+      WbErr_i       => s_wishbone.Err,
242 239
       --+ local register if
243 240
       LocalWen_i    => s_master_local_wen,
244 241
       LocalRen_i    => s_master_local_ren,
@@ -258,18 +255,18 @@ begin
258 255
       wait until (s_master_local_wen = '1' or s_master_local_ren = '1') and rising_edge(s_wb_clk);
259 256
       v_master_local_adress := s_master_local_adress;
260 257
       v_master_local_data   := s_master_local_din;
261
-      v_valid_access        := s_master_local_wen  xor s_master_local_ren;
258
+      v_valid_access        := s_master_local_wen xor s_master_local_ren;
262 259
       wait until rising_edge(s_wb_clk);
263
-      WB_CYC : assert v_valid_access = s_wb_cyc
264
-        report "ERROR: Wishbone cycle should be 0b" & to_string(v_valid_access) & " instead of 0b" & to_string(s_wb_cyc)
260
+      WB_CYC : assert v_valid_access = s_wishbone.Cyc
261
+        report "ERROR: Wishbone cycle should be 0b" & to_string(v_valid_access) & " instead of 0b" & to_string(s_wishbone.Cyc)
265 262
         severity failure;
266 263
       if (v_valid_access = '1') then
267
-        WB_ADDR : assert s_wb_adr = v_master_local_adress
268
-          report "ERROR: Wishbone address 0x" & to_hstring(s_wb_adr) & " differ from local address 0x" & to_hstring(v_master_local_adress)
264
+        WB_ADDR : assert s_wishbone.Adr = v_master_local_adress
265
+          report "ERROR: Wishbone address 0x" & to_hstring(s_wishbone.Adr) & " differ from local address 0x" & to_hstring(v_master_local_adress)
269 266
           severity failure;
270
-        if (s_wb_we = '1') then
271
-          WB_DATA : assert s_wb_master_data = v_master_local_data
272
-            report "ERROR: Wishbone data 0x" & to_hstring(s_wb_master_data) & " differ from local data 0x" & to_hstring(v_master_local_data)
267
+        if (s_wishbone.We = '1') then
268
+          WB_DATA : assert s_wishbone.WDat = v_master_local_data
269
+            report "ERROR: Wishbone data 0x" & to_hstring(s_wishbone.WDat) & " differ from local data 0x" & to_hstring(v_master_local_data)
273 270
             severity failure;
274 271
         end if;
275 272
       end if;
@@ -286,15 +283,15 @@ begin
286 283
       WbRst_i       => s_wb_reset,
287 284
       WbClk_i       => s_wb_clk,
288 285
       --+ wishbone inputs
289
-      WbCyc_i       => s_wb_cyc,
290
-      WbStb_i       => s_wb_stb,
291
-      WbWe_i        => s_wb_we,
292
-      WbAdr_i       => s_wb_adr,
293
-      WbDat_i       => s_wb_master_data,
286
+      WbCyc_i       => s_wishbone.Cyc,
287
+      WbStb_i       => s_wishbone.Stb,
288
+      WbWe_i        => s_wishbone.We,
289
+      WbAdr_i       => s_wishbone.Adr,
290
+      WbDat_i       => s_wishbone.WDat,
294 291
       --* wishbone outputs
295
-      WbDat_o       => s_wb_slave_data,
296
-      WbAck_o       => s_wb_ack,
297
-      WbErr_o       => s_wb_err,
292
+      WbDat_o       => s_wishbone.RDat,
293
+      WbAck_o       => s_wishbone.Ack,
294
+      WbErr_o       => s_wishbone.Err,
298 295
       --+ local register if
299 296
       LocalWen_o    => s_slave_local_wen,
300 297
       LocalRen_o    => s_slave_local_ren,