@@ -76,8 +76,7 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
76
76
}
77
77
else if (expr.id ()==ID_function_call)
78
78
{
79
- expand_function_call (to_function_call_expr (expr));
80
- return expr;
79
+ return expand_function_call (to_function_call_expr (expr));
81
80
}
82
81
else if (expr.id ()==ID_hierarchical_identifier)
83
82
{
@@ -112,6 +111,32 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
112
111
113
112
/* ******************************************************************\
114
113
114
+ Function: verilog_synthesist::function_locality
115
+
116
+ Inputs:
117
+
118
+ Outputs:
119
+
120
+ Purpose:
121
+
122
+ \*******************************************************************/
123
+
124
+ void verilog_synthesist::function_locality (const symbolt &function_symbol)
125
+ {
126
+ // Find all local symbols of the function, mark their
127
+ // assignments as local.
128
+ auto prefix = id2string (function_symbol.name ) + ' .' ;
129
+ for (auto &symbol : symbol_table.symbols )
130
+ {
131
+ if (irep_idt (symbol.first ).starts_with (prefix))
132
+ {
133
+ assignments[symbol.first ].is_cycle_local = true ;
134
+ }
135
+ }
136
+ }
137
+
138
+ /* ******************************************************************\
139
+
115
140
Function: verilog_synthesist::expand_function_call
116
141
117
142
Inputs:
@@ -122,7 +147,7 @@ Function: verilog_synthesist::expand_function_call
122
147
123
148
\*******************************************************************/
124
149
125
- void verilog_synthesist::expand_function_call (function_call_exprt &call)
150
+ exprt verilog_synthesist::expand_function_call (const function_call_exprt &call)
126
151
{
127
152
// Is it a 'system function call'?
128
153
if (call.is_system_function_call ())
@@ -138,8 +163,7 @@ void verilog_synthesist::expand_function_call(function_call_exprt &call)
138
163
throw 0 ;
139
164
}
140
165
141
- call.swap (result);
142
- return ;
166
+ return result;
143
167
}
144
168
145
169
// check some restrictions
@@ -184,7 +208,10 @@ void verilog_synthesist::expand_function_call(function_call_exprt &call)
184
208
error () << " wrong number of arguments" << eom;
185
209
throw 0 ;
186
210
}
187
-
211
+
212
+ // preserve locality of function-local variables
213
+ function_locality (symbol);
214
+
188
215
// do assignments to function parameters
189
216
for (unsigned i=0 ; i<parameters.size (); i++)
190
217
{
@@ -197,15 +224,16 @@ void verilog_synthesist::expand_function_call(function_call_exprt &call)
197
224
}
198
225
199
226
synth_statement (to_verilog_statement (symbol.value ));
200
-
227
+
201
228
// replace function call by return value symbol
202
229
const symbolt &return_symbol=
203
230
ns.lookup (id2string (symbol.name )+" ." +
204
231
id2string (symbol.base_name ));
205
232
206
- exprt return_value=return_symbol.symbol_expr ();
233
+ // get the current value
234
+ auto result = synth_expr (return_symbol.symbol_expr (), symbol_statet::CURRENT);
207
235
208
- call. swap (return_value) ;
236
+ return result ;
209
237
}
210
238
211
239
/* ******************************************************************\
@@ -362,22 +390,27 @@ void verilog_synthesist::assignment_rec(
362
390
363
391
assignmentt &assignment=assignments[symbol.name ];
364
392
365
- if (assignment.type ==event_guardt::NONE)
366
- assignment.type =new_type;
367
- else if (assignment.type !=new_type)
393
+ if (assignment.is_cycle_local )
368
394
{
369
- error ().source_location =lhs.source_location ();
370
- error () << " conflicting assignment types for `"
371
- << symbol.base_name
372
- << " ' (new: "
373
- << as_string (new_type) << " , old: "
374
- << as_string (assignment.type ) << " )" << eom;
375
- throw 0 ;
376
395
}
377
-
378
- membert member;
379
- assignment_member_rec (lhs, member,
380
- (construct==constructt::INITIAL)?assignment.init :assignment.next );
396
+ else
397
+ {
398
+ if (assignment.type == event_guardt::NONE)
399
+ assignment.type = new_type;
400
+ else if (assignment.type != new_type)
401
+ {
402
+ throw errort ().with_location (lhs.source_location ())
403
+ << " conflicting assignment types for `" << symbol.base_name
404
+ << " ' (new: " << as_string (new_type)
405
+ << " , old: " << as_string (assignment.type ) << " )" ;
406
+ }
407
+
408
+ membert member;
409
+ assignment_member_rec (
410
+ lhs,
411
+ member,
412
+ (construct == constructt::INITIAL) ? assignment.init : assignment.next );
413
+ }
381
414
}
382
415
383
416
{
@@ -2764,6 +2797,9 @@ void verilog_synthesist::synth_assignments(transt &trans)
2764
2797
{
2765
2798
assignmentt &assignment=assignments[symbol.name ];
2766
2799
2800
+ if (assignment.is_cycle_local )
2801
+ continue ; // ignore
2802
+
2767
2803
if (assignment.type ==event_guardt::COMBINATIONAL)
2768
2804
{
2769
2805
warning ().source_location = symbol.location ;
0 commit comments