@@ -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