Support `iff` in sensitivity list (#1482) (#4626)

Adds a new field to `AstSenItem` that stores the `iff` condition which is then handled by `SenExprBuilder`.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
Krzysztof Bieganski 2023-11-29 19:10:32 +01:00 committed by GitHub
parent ebfc2a4942
commit b820e1b587
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 141 additions and 34 deletions

View File

@ -1489,6 +1489,7 @@ public:
class AstSenItem final : public AstNode {
// Parents: SENTREE
// @astgen op1 := sensp : Optional[AstNodeExpr] // Sensitivity expression
// @astgen op2 := condp : Optional[AstNodeExpr] // Sensitivity condition
VEdgeType m_edgeType; // Edge type
public:
class Combo {}; // for constructor type-overload selection
@ -1497,10 +1498,11 @@ public:
class Initial {}; // for constructor type-overload selection
class Final {}; // for constructor type-overload selection
class Never {}; // for constructor type-overload selection
AstSenItem(FileLine* fl, VEdgeType edgeType, AstNodeExpr* senp)
AstSenItem(FileLine* fl, VEdgeType edgeType, AstNodeExpr* senp, AstNodeExpr* condp = nullptr)
: ASTGEN_SUPER_SenItem(fl)
, m_edgeType{edgeType} {
this->sensp(senp);
this->condp(condp);
}
AstSenItem(FileLine* fl, Combo)
: ASTGEN_SUPER_SenItem(fl)

View File

@ -225,7 +225,9 @@ public:
for (AstSenItem* senItemp = senTreep->sensesp(); senItemp;
senItemp = VN_AS(senItemp->nextp(), SenItem)) {
const auto& pair = createTerm(senItemp);
if (AstNodeExpr* const termp = pair.first) {
if (AstNodeExpr* termp = pair.first) {
AstNodeExpr* const condp = senItemp->condp();
if (condp) termp = new AstAnd{flp, condp->cloneTreePure(false), termp};
resultp = resultp ? new AstOr{flp, resultp, termp} : termp;
firedAtInitialization |= pair.second;
}

View File

@ -3348,8 +3348,7 @@ senitem<senItemp>: // IEEE: part of event_expression, non-'OR' ','
| expr
{ $$ = new AstSenItem{$<fl>1, VEdgeType::ET_CHANGED, $1}; }
| expr yIFF expr
{ $$ = new AstSenItem{$<fl>1, VEdgeType::ET_CHANGED, $1};
if ($2) BBUNSUP($2, "Unsupported: event expression 'iff'"); }
{ $$ = new AstSenItem{$<fl>1, VEdgeType::ET_CHANGED, $1, $3}; }
;
senitemVar<senItemp>:
@ -3364,14 +3363,11 @@ senitemEdge<senItemp>: // IEEE: part of event_expression
| yEDGE expr
{ $$ = new AstSenItem{$1, VEdgeType::ET_BOTHEDGE, $2}; }
| yPOSEDGE expr yIFF expr
{ $$ = new AstSenItem{$1, VEdgeType::ET_POSEDGE, $2};
BBUNSUP($3, "Unsupported: event expression 'iff'"); }
{ $$ = new AstSenItem{$1, VEdgeType::ET_POSEDGE, $2, $4}; }
| yNEGEDGE expr yIFF expr
{ $$ = new AstSenItem{$1, VEdgeType::ET_NEGEDGE, $2};
BBUNSUP($3, "Unsupported: event expression 'iff'"); }
{ $$ = new AstSenItem{$1, VEdgeType::ET_NEGEDGE, $2, $4}; }
| yEDGE expr yIFF expr
{ $$ = new AstSenItem{$1, VEdgeType::ET_BOTHEDGE, $2};
BBUNSUP($3, "Unsupported: event expression 'iff'"); }
{ $$ = new AstSenItem{$1, VEdgeType::ET_BOTHEDGE, $2, $4}; }
;
//************************************************

22
test_regress/t/t_assert_iff.pl Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--assert --cc --coverage-user'],
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,57 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2023 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
logic[3:0] enable;
int cyc = 0;
Test test(.*);
always @ (posedge clk) begin
cyc <= cyc + 1;
`ifdef FAIL1 enable[0] <= 1; `endif
enable[1] <= 1;
`ifdef FAIL2 enable[2] <= 1; `endif
enable[3] <= 1;
if (cyc != 0) begin
if (cyc == 10) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
end
endmodule
module Test(
input clk,
input[3:0] enable
);
assert property (
@(posedge clk iff enable[0])
0
) else $stop;
assert property (
@(posedge clk iff enable[1])
1
);
cover property (
@(posedge clk iff enable[2])
1
) $stop;
cover property (
@(posedge clk iff enable[3])
0
) $stop;
endmodule

View File

@ -0,0 +1,24 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
top_filename('t_assert_iff.v');
compile(
verilator_flags2 => ['--assert --cc --coverage-user -DFAIL1'],
);
execute(
fails => 1,
);
ok(1);
1;

View File

@ -0,0 +1,24 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
top_filename('t_assert_iff.v');
compile(
verilator_flags2 => ['--assert --cc --coverage-user -DFAIL2'],
);
execute(
fails => 1,
);
ok(1);
1;

View File

@ -1,17 +0,0 @@
%Error-UNSUPPORTED: t/t_iff.v:66:15: Unsupported: event expression 'iff'
66 | always @(d iff enable) begin
| ^~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_iff.v:71:23: Unsupported: event expression 'iff'
71 | always @(posedge d iff enable) begin
| ^~~
%Error-UNSUPPORTED: t/t_iff.v:76:23: Unsupported: event expression 'iff'
76 | always @(negedge d iff enable) begin
| ^~~
%Error-UNSUPPORTED: t/t_iff.v:81:20: Unsupported: event expression 'iff'
81 | always @(edge d iff enable) begin
| ^~~
%Error-UNSUPPORTED: t/t_iff.v:86:35: Unsupported: event expression 'iff'
86 | assert property (@(posedge clk iff enable)
| ^~~
%Error: Exiting due to

View File

@ -11,14 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--timing'],
fails => $Self->{vlt_all}, # Verilator unsupported, bug1482, iff not supported
expect_filename => $Self->{golden_filename},
);
execute(
check_finished => 1,
) if !$Self->{vlt_all};
);
ok(1);
1;

View File

@ -16,7 +16,7 @@ module t (/*AUTOARG*/
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [31:0] result; // From test of Test.v
wire [63:0] result; // From test of Test.v
// End of automatics
Test test (.*);
@ -42,7 +42,7 @@ module t (/*AUTOARG*/
$write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
// What checksum will we end up with (above print should match)
`define EXPECTED_SUM 64'h390aa8652d33a691
`define EXPECTED_SUM 64'hd55eb7da9ba3354a
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
@ -56,7 +56,7 @@ module Test
input clk,
input [63:0] crc,
input [31:0] cyc,
output wire [31:0] result);
output wire [63:0] result);
wire enable = crc[32];
wire [7:0] d = crc[7:0];