Skip to content

Commit be60f84

Browse files
committed
fix: do not overload 'length', use a custom enumerate type instead
1 parent 6456b0f commit be60f84

3 files changed

Lines changed: 131 additions & 123 deletions

File tree

vunit/vhdl/data_types/src/string_ptr_pkg-body-200x.vhd

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ package body string_ptr_pkg is
5555
type string_ptr_storage_t is protected body
5656
type storage_t is record
5757
id : integer;
58-
length : integer; -- 0: default/internal; >0: external through access; <0: external through funcs
58+
mode : storage_mode_t;
59+
length : integer;
5960
end record;
60-
constant null_storage : storage_t := (integer'low, integer'low);
61+
constant null_storage : storage_t := (integer'low, internal, integer'low);
6162

6263
type storage_vector_t is array (natural range <>) of storage_t;
6364
type storage_vector_access_t is access storage_vector_t;
@@ -121,26 +122,38 @@ package body string_ptr_pkg is
121122

122123
impure function new_vector (
123124
length : natural := 0;
124-
id : integer := 0;
125+
id : integer := 0; -- 0: default/internal; >0: external through access; <0: external through funcs
125126
value : val_t := val_t'low
126127
) return natural is begin
127128
reallocate_ids(st.ids, st.id);
128129
if id = 0 then
129-
st.ids(st.id) := (id => st.ptr, length => 0);
130+
st.ids(st.id) := (
131+
id => st.ptr,
132+
mode => internal,
133+
length => 0
134+
);
130135

131136
reallocate_ptrs(st.ptrs, st.ptr);
132137
st.ptrs(st.ptr) := new vec_t'(1 to length => value);
133138
st.ptr := st.ptr + 1;
134139
else
135140
assert length>0 report "Length of external memory cannot be 0" severity error;
136141
if id > 0 then
137-
st.ids(st.id) := (id => st.eptr, length => length);
142+
st.ids(st.id) := (
143+
id => st.eptr,
144+
mode => extacc,
145+
length => length
146+
);
138147

139148
reallocate_eptrs(st.eptrs, st.eptr);
140149
st.eptrs(st.eptr) := get_ptr(id-1);
141150
st.eptr := st.eptr + 1;
142151
else
143-
st.ids(st.id) := (id => -id-1, length => -length);
152+
st.ids(st.id) := (
153+
id => -id-1,
154+
mode => extfunc,
155+
length => length
156+
);
144157
end if;
145158
end if;
146159
st.id := st.id + 1;
@@ -150,7 +163,7 @@ package body string_ptr_pkg is
150163
impure function is_external (
151164
ref : natural
152165
) return boolean is begin
153-
return st.ids(ref).length /= 0;
166+
return st.ids(ref).mode /= internal;
154167
end;
155168

156169
-- @TODO Remove check_external when all the functions/procedures are implemented
@@ -177,11 +190,10 @@ package body string_ptr_pkg is
177190
) return integer is
178191
variable s : storage_t := st.ids(ref);
179192
begin
180-
if s.length /= 0 then
181-
return abs(s.length);
182-
else
183-
return st.ptrs(s.id)'length;
184-
end if;
193+
case s.mode is
194+
when internal => return st.ptrs(s.id)'length;
195+
when others => return abs(s.length);
196+
end case;
185197
end;
186198

187199
procedure set (
@@ -191,16 +203,11 @@ package body string_ptr_pkg is
191203
) is
192204
variable s : storage_t := st.ids(ref);
193205
begin
194-
--report "set(" & to_string(s.id) & ", " & to_string(index) & ") length(" & to_string(s.length) & "): " & to_string(value) severity note;
195-
if s.length /= 0 then --is_external
196-
if s.length < 0 then
197-
write_char(s.id, index-1, value);
198-
else
199-
st.eptrs(s.id)(index) := value;
200-
end if;
201-
else
202-
st.ptrs(s.id)(index) := value;
203-
end if;
206+
case s.mode is
207+
when extfunc => write_char(s.id, index-1, value);
208+
when extacc => st.eptrs(s.id)(index) := value;
209+
when internal => st.ptrs(s.id)(index) := value;
210+
end case;
204211
end;
205212

206213
impure function get (
@@ -209,16 +216,11 @@ package body string_ptr_pkg is
209216
) return val_t is
210217
variable s : storage_t := st.ids(ref);
211218
begin
212-
--report "get(" & to_string(s.id) & ", " & to_string(index) & ") length(" & to_string(s.length) & ")" severity note;
213-
if s.length /= 0 then --is_external
214-
if s.length < 0 then
215-
return read_char(s.id, index-1);
216-
else
217-
return st.eptrs(s.id)(index);
218-
end if;
219-
else
220-
return st.ptrs(s.id)(index);
221-
end if;
219+
case s.mode is
220+
when extfunc => return read_char(s.id, index-1);
221+
when extacc => return st.eptrs(s.id)(index);
222+
when internal => return st.ptrs(s.id)(index);
223+
end case;
222224
end;
223225

224226
procedure reallocate (
@@ -228,18 +230,17 @@ package body string_ptr_pkg is
228230
variable s : storage_t := st.ids(ref);
229231
variable n_value : string(1 to value'length) := value;
230232
begin
231-
if s.length /= 0 then --is_external
232-
if s.length < 0 then
233+
case s.mode is
234+
when extfunc =>
233235
-- @FIXME The reallocation request is just ignored. What should we do here?
234236
--check_external(ptr, "reallocate");
235-
else
237+
when extacc =>
236238
-- @TODO Implement reallocate for external models (through access)
237239
check_external(ref, "reallocate");
238-
end if;
239-
else
240-
deallocate(st.ptrs(s.id));
241-
st.ptrs(s.id) := new vec_t'(n_value);
242-
end if;
240+
when internal =>
241+
deallocate(st.ptrs(s.id));
242+
st.ptrs(s.id) := new vec_t'(n_value);
243+
end case;
243244
end;
244245

245246
procedure resize (
@@ -252,34 +253,36 @@ package body string_ptr_pkg is
252253
variable min_len : natural := length;
253254
variable s : storage_t := st.ids(ref);
254255
begin
255-
if s.length /= 0 then
256-
-- @TODO Implement resize for external models
257-
check_external(ref, "resize");
258-
else
259-
newp := new vec_t'(1 to length => value);
260-
oldp := st.ptrs(s.id);
261-
if min_len > oldp'length - drop then
262-
min_len := oldp'length - drop;
263-
end if;
264-
for i in 1 to min_len loop
265-
newp(i) := oldp(drop + i);
266-
end loop;
267-
st.ptrs(s.id) := newp;
268-
deallocate(oldp);
269-
end if;
256+
case s.mode is
257+
when internal =>
258+
newp := new vec_t'(1 to length => value);
259+
oldp := st.ptrs(s.id);
260+
if min_len > oldp'length - drop then
261+
min_len := oldp'length - drop;
262+
end if;
263+
for i in 1 to min_len loop
264+
newp(i) := oldp(drop + i);
265+
end loop;
266+
st.ptrs(s.id) := newp;
267+
deallocate(oldp);
268+
when others =>
269+
-- @TODO Implement resize for external models
270+
check_external(ref, "resize");
271+
end case;
270272
end;
271273

272274
impure function to_string (
273275
ref : natural
274276
) return string is
275277
variable s : storage_t := st.ids(ref);
276278
begin
277-
if s.length /= 0 then
278-
-- @TODO Implement to_string for external models
279-
check_external(ref, "to_string");
280-
else
281-
return st.ptrs(s.id).all;
282-
end if;
279+
case s.mode is
280+
when internal =>
281+
return st.ptrs(s.id).all;
282+
when others =>
283+
-- @TODO Implement to_string for external models
284+
check_external(ref, "to_string");
285+
end case;
283286
end;
284287

285288
end protected body;

0 commit comments

Comments
 (0)