Skip to content

Commit 1976274

Browse files
authored
Merge pull request #510 from diffblue/stable-rose-fell-changed
SystemVerilog: $stable, $rose, $fell, $changed
2 parents e6f1060 + f39f9c4 commit 1976274

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
stable-rose-fell-changed1.sv
3+
--bound 1
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
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+
reg [31:0] counter = 0;
4+
5+
always @(posedge clk)
6+
counter++;
7+
8+
initial p0: assert property ($stable(counter));
9+
initial p1: assert property (!$rose(counter));
10+
initial p2: assert property (!$fell(counter));
11+
initial p3: assert property (!$changed(counter));
12+
13+
initial p4: assert property (##1 !$stable(counter));
14+
initial p5: assert property (##1 $rose(counter));
15+
initial p6: assert property (##1 !$fell(counter));
16+
initial p7: assert property (##1 $changed(counter));
17+
18+
endmodule

src/verilog/verilog_synthesis.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,31 @@ exprt verilog_synthesist::expand_function_call(const function_call_exprt &call)
192192
: call.arguments()[1];
193193
return verilog_past_exprt{what, ticks}.with_source_location(call);
194194
}
195+
else if(
196+
identifier == "$stable" || identifier == "$rose" ||
197+
identifier == "$fell" || identifier == "$changed")
198+
{
199+
DATA_INVARIANT(call.arguments().size() >= 1, "must have argument");
200+
auto what = call.arguments()[0];
201+
auto past = verilog_past_exprt{what, from_integer(1, integer_typet())}
202+
.with_source_location(call);
203+
204+
auto lsb = [](exprt expr) {
205+
return extractbit_exprt{
206+
std::move(expr), from_integer(0, integer_typet{})};
207+
};
208+
209+
if(identifier == "$stable")
210+
return equal_exprt{what, past};
211+
else if(identifier == "$changed")
212+
return notequal_exprt{what, past};
213+
else if(identifier == "$rose")
214+
return and_exprt{not_exprt{lsb(past)}, lsb(what)};
215+
else if(identifier == "$fell")
216+
return and_exprt{lsb(past), not_exprt{lsb(what)}};
217+
else
218+
DATA_INVARIANT(false, "all cases covered");
219+
}
195220
else
196221
{
197222
// Attempt to constant fold.

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,20 @@ exprt verilog_typecheck_exprt::convert_system_function(
676676

677677
return std::move(expr);
678678
}
679+
else if(
680+
identifier == "$stable" || identifier == "$rose" || identifier == "$fell" ||
681+
identifier == "$changed")
682+
{
683+
if(arguments.size() != 1 && arguments.size() != 2)
684+
{
685+
throw errort().with_location(expr.source_location())
686+
<< identifier << " takes one or two arguments";
687+
}
688+
689+
expr.type() = bool_typet();
690+
691+
return std::move(expr);
692+
}
679693
else
680694
{
681695
throw errort().with_location(expr.function().source_location())

0 commit comments

Comments
 (0)