Skip to content

Commit

Permalink
Merge pull request #510 from diffblue/stable-rose-fell-changed
Browse files Browse the repository at this point in the history
SystemVerilog: $stable, $rose, $fell, $changed
  • Loading branch information
tautschnig authored May 19, 2024
2 parents e6f1060 + f39f9c4 commit 1976274
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CORE
stable-rose-fell-changed1.sv
--bound 1
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
18 changes: 18 additions & 0 deletions regression/verilog/system-functions/stable-rose-fell-changed1.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module main(input clk);

reg [31:0] counter = 0;

always @(posedge clk)
counter++;

initial p0: assert property ($stable(counter));
initial p1: assert property (!$rose(counter));
initial p2: assert property (!$fell(counter));
initial p3: assert property (!$changed(counter));

initial p4: assert property (##1 !$stable(counter));
initial p5: assert property (##1 $rose(counter));
initial p6: assert property (##1 !$fell(counter));
initial p7: assert property (##1 $changed(counter));

endmodule
25 changes: 25 additions & 0 deletions src/verilog/verilog_synthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,31 @@ exprt verilog_synthesist::expand_function_call(const function_call_exprt &call)
: call.arguments()[1];
return verilog_past_exprt{what, ticks}.with_source_location(call);
}
else if(
identifier == "$stable" || identifier == "$rose" ||
identifier == "$fell" || identifier == "$changed")
{
DATA_INVARIANT(call.arguments().size() >= 1, "must have argument");
auto what = call.arguments()[0];
auto past = verilog_past_exprt{what, from_integer(1, integer_typet())}
.with_source_location(call);

auto lsb = [](exprt expr) {
return extractbit_exprt{
std::move(expr), from_integer(0, integer_typet{})};
};

if(identifier == "$stable")
return equal_exprt{what, past};
else if(identifier == "$changed")
return notequal_exprt{what, past};
else if(identifier == "$rose")
return and_exprt{not_exprt{lsb(past)}, lsb(what)};
else if(identifier == "$fell")
return and_exprt{lsb(past), not_exprt{lsb(what)}};
else
DATA_INVARIANT(false, "all cases covered");
}
else
{
// Attempt to constant fold.
Expand Down
14 changes: 14 additions & 0 deletions src/verilog/verilog_typecheck_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,20 @@ exprt verilog_typecheck_exprt::convert_system_function(

return std::move(expr);
}
else if(
identifier == "$stable" || identifier == "$rose" || identifier == "$fell" ||
identifier == "$changed")
{
if(arguments.size() != 1 && arguments.size() != 2)
{
throw errort().with_location(expr.source_location())
<< identifier << " takes one or two arguments";
}

expr.type() = bool_typet();

return std::move(expr);
}
else
{
throw errort().with_location(expr.function().source_location())
Expand Down

0 comments on commit 1976274

Please sign in to comment.