Skip to content

Commit 9628033

Browse files
committed
do not add constraints for assignments to function-local variables
Assignments to function-local variables are now treated as cycle-local, and hence neither require invariants nor next-state constraints.
1 parent 3c7393e commit 9628033

File tree

6 files changed

+93
-20
lines changed

6 files changed

+93
-20
lines changed

regression/verilog/functioncall/functioncall5.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
functioncall5.v
33
--module main --bound 0
44
^EXIT=0$

regression/verilog/functioncall/functioncall5.v

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ module main(input clk);
1717

1818
reg my_reg;
1919

20-
always @(posedge clk)
20+
always @(posedge clk) begin
2121
my_reg = isUpper(my_wire1);
22+
assert (my_reg == my_wire2);
23+
end
2224

2325
endmodule
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
functioncall7.v
3+
--module main --bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
--
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module main(input clk);
2+
3+
function negate;
4+
input in;
5+
begin
6+
negate = ~in;
7+
end
8+
endfunction
9+
10+
// same function used twice
11+
12+
wire my_wire0 = negate(0);
13+
wire my_wire1 = negate(1);
14+
15+
always assert p0: (my_wire0 == 1);
16+
always assert p1: (my_wire1 == 0);
17+
18+
endmodule

src/verilog/verilog_synthesis.cpp

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,32 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
111111

112112
/*******************************************************************\
113113
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+
114140
Function: verilog_synthesist::expand_function_call
115141
116142
Inputs:
@@ -182,7 +208,10 @@ exprt verilog_synthesist::expand_function_call(const function_call_exprt &call)
182208
error() << "wrong number of arguments" << eom;
183209
throw 0;
184210
}
185-
211+
212+
// preserve locality of function-local variables
213+
function_locality(symbol);
214+
186215
// do assignments to function parameters
187216
for(unsigned i=0; i<parameters.size(); i++)
188217
{
@@ -195,13 +224,16 @@ exprt verilog_synthesist::expand_function_call(const function_call_exprt &call)
195224
}
196225

197226
synth_statement(to_verilog_statement(symbol.value));
198-
227+
199228
// replace function call by return value symbol
200229
const symbolt &return_symbol=
201230
ns.lookup(id2string(symbol.name)+"."+
202231
id2string(symbol.base_name));
203232

204-
return return_symbol.symbol_expr();
233+
// get the current value
234+
auto result = synth_expr(return_symbol.symbol_expr(), symbol_statet::CURRENT);
235+
236+
return result;
205237
}
206238

207239
/*******************************************************************\
@@ -358,22 +390,27 @@ void verilog_synthesist::assignment_rec(
358390

359391
assignmentt &assignment=assignments[symbol.name];
360392

361-
if(assignment.type==event_guardt::NONE)
362-
assignment.type=new_type;
363-
else if(assignment.type!=new_type)
393+
if(assignment.is_cycle_local)
364394
{
365-
error().source_location=lhs.source_location();
366-
error() << "conflicting assignment types for `"
367-
<< symbol.base_name
368-
<< "' (new: "
369-
<< as_string(new_type) << ", old: "
370-
<< as_string(assignment.type) << ")" << eom;
371-
throw 0;
372395
}
373-
374-
membert member;
375-
assignment_member_rec(lhs, member,
376-
(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+
}
377414
}
378415

379416
{
@@ -2760,6 +2797,9 @@ void verilog_synthesist::synth_assignments(transt &trans)
27602797
{
27612798
assignmentt &assignment=assignments[symbol.name];
27622799

2800+
if(assignment.is_cycle_local)
2801+
continue; // ignore
2802+
27632803
if(assignment.type==event_guardt::COMBINATIONAL)
27642804
{
27652805
warning().source_location = symbol.location;

src/verilog/verilog_synthesis_class.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class verilog_synthesist:
111111

112112
// only relevant for 'next'
113113
event_guardt type;
114+
bool is_cycle_local = false;
114115

115116
assignmentt():type(event_guardt::NONE)
116117
{
@@ -299,7 +300,11 @@ class verilog_synthesist:
299300
transt &);
300301

301302
void replace_by_wire(exprt &expr, const symbolt &base);
302-
303+
304+
// Mark the local variables of a function or task
305+
// as cycle local.
306+
void function_locality(const symbolt &);
307+
303308
unsigned temporary_counter;
304309
};
305310

0 commit comments

Comments
 (0)