Skip to content

Support s_eventually (#7291)#7508

Open
b-chmiel wants to merge 1 commit intoverilator:masterfrom
antmicro:support_s_eventually
Open

Support s_eventually (#7291)#7508
b-chmiel wants to merge 1 commit intoverilator:masterfrom
antmicro:support_s_eventually

Conversation

@b-chmiel
Copy link
Copy Markdown
Member

Implements strong eventually (s_eventually, IEEE 1800-2023 16.12.13) in the context of property expression.

The algorithm lowers this code:

module t;
  bit clk = 0;
  initial forever #1 clk = ~clk;
  bit a = 0;
  bit b = 1;
  int cyc = 0;
  always @(posedge clk) begin
    ++cyc;
    b = ~b;
    $display("%0t", $time);
    if (cyc >= 3) $finish;
  end
  assert property (@(posedge clk) s_eventually a == b) begin
    $display("success");
  end
  else begin
    $display("failure");
  end
endmodule

into:

module t;
  bit clk = 0;
  initial forever #1 clk = ~clk;
  bit a = 0;
  bit b = 1;
  int cyc = 0;
  always @(posedge clk) begin
    ++cyc;
    b = ~b;
    $display("%0t", $time);
    if (cyc >= 3) $finish;
  end
  always @(posedge clk) begin
    fork
      begin
        // Note: s_eventually requires importing std
        __VassertsActive___0[std::process::self()] = 1;
        // Note: s_eventually requires --timing
        while ((!($sampled(a) == $sampled(b)))) #1;

        $display("success");
        __VassertsActive___0.delete(std::process::self());
      end
    join_none
  end
  bit __VassertsActive___0[std::process];
  final begin
    int __VassertCount;
    __VassertCount = __VassertsActive___0.size();
    while ((__VassertCount != 32'h0)) begin
      if (($sampled(a) == $sampled(b))) $display("success");
      else $display("failure");
      __VassertCount = (__VassertCount - 32'h1);
    end
  end
endmodule

Resolves #7291

Signed-off-by: Bartłomiej Chmiel <bchmiel@antmicro.com>
@wsnyder wsnyder changed the title Support s_eventually Support s_eventually (#7291) Apr 28, 2026
@wsnyder
Copy link
Copy Markdown
Member

wsnyder commented Apr 28, 2026

  always @(posedge clk) begin
    fork
      begin
        // Note: s_eventually requires importing std
        __VassertsActive___0[std::process::self()] = 1;
        // Note: s_eventually requires --timing
        while ((!($sampled(a) == $sampled(b)))) #1;

Why is any fork required and more so why fork every cycle? I'd think this can become a SERE that determines match (or not)?

Why the #1 - that certainly doesn't make sense it's at least clock edge related.

@b-chmiel
Copy link
Copy Markdown
Member Author

b-chmiel commented Apr 28, 2026

On every posedge clk new assertion is "started" and every single one of them either waits on clock events (#1 which in fact is waiting for a assertion's clocking block event) or terminates successfully when condition is fulfilled. To track those running assertions we already use forks, see:

AstFork* const forkp = new AstFork{nodep->fileline(), VJoinType::JOIN_NONE};

Copy link
Copy Markdown
Member

@wsnyder wsnyder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anything should be convertable to an appropriate state machine, but I guess I'll accept the we already fork argument and punt the performance down the road.

// SPDX-FileCopyrightText: 2026 Antmicro
// SPDX-License-Identifier: CC0-1.0

`define stop $stop
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add verilog format on/off around these please

@@ -0,0 +1,4 @@
[4] stmt, s_eventually before final, fileline: 23
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove line number from message so is less sensitive to small changes in .v file.

assert property (@(negedge clk) disable iff (cyc < MAX - 1) s_eventually (cyc == MAX)) `PROPERTY_CHECK("s_eventually during final")

assert property (@(negedge clk) disable iff (cyc < MAX - 1) s_eventually (cyc == MAX + 1)) `PROPERTY_CHECK("s_eventually after final")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest a test where have say 1000 cycles and each s_eventually terminates after say 2 cycles. This is to make sure we clean up properly (e.g. don't for some reason get 1000 forks every cycle).

Comment thread src/V3AssertPre.cpp
Comment on lines +810 to +811
= VN_AS(getMemberp(v3Global.rootp()->stdPackagep(), "process"), Class);
AstFunc* const selfMethodp = VN_AS(getMemberp(processClassp, "self"), Func);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make a rootp()->stdPackageProcessp and stdPackageClassp and use here and in V3LinkJump where this seems to have come from, to avoid duplication.

Comment thread src/V3AssertPre.cpp
iterateChildren(nodep);
FileLine* const flp = nodep->fileline();

const auto readRef
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just inline these.

Comment thread src/V3AssertPre.cpp
void visit(AstSEventually* nodep) override {
UASSERT(v3Global.rootp()->stdPackagep(), "Should be imported");
AstSenTree* const sentreep = newSenTree(nodep);
if (!sentreep->sensesp()) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test for this? I'll turn on coverage.

@wsnyder wsnyder added the pr: dev-coverage Run Code coverage workflow on PR label Apr 28, 2026
@verilator-ci
Copy link
Copy Markdown

verilator-ci Bot commented Apr 28, 2026

Patch coverage from PR workflow #2450 (code coverage of lines changed relative to 5d1b4fe):

  lines: 98.25% (112 of 114 lines)
  branches: 90.00% (18 of 20 branches)

Report: 25050153549

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: dev-coverage Run Code coverage workflow on PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for s_eventually property

2 participants