Support ++/-- on dotted member variables.
This commit is contained in:
parent
827cbf22c9
commit
d67d75282c
1
Changes
1
Changes
|
|
@ -22,6 +22,7 @@ Verilator 5.009 devel
|
||||||
* Support method calls without parenthesis (#4034). [Ryszard Rozak, Antmicro Ltd]
|
* Support method calls without parenthesis (#4034). [Ryszard Rozak, Antmicro Ltd]
|
||||||
* Support complicated IEEE 'for' assignments.
|
* Support complicated IEEE 'for' assignments.
|
||||||
* Support $fopen as an expression.
|
* Support $fopen as an expression.
|
||||||
|
* Support ++/-- on dotted member variables.
|
||||||
* Change range order warning from LITENDIAN to ASCRANGE (#4010). [Iztok Jeras]
|
* Change range order warning from LITENDIAN to ASCRANGE (#4010). [Iztok Jeras]
|
||||||
* Change ZERODLY to a warning.
|
* Change ZERODLY to a warning.
|
||||||
* Fix random internal crashes (#666). [Dag Lem]
|
* Fix random internal crashes (#666). [Dag Lem]
|
||||||
|
|
|
||||||
|
|
@ -240,11 +240,12 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AstNodeVarRef* varrefp = nullptr;
|
if (m_unsupportedHere) {
|
||||||
if (m_unsupportedHere || !(varrefp = VN_CAST(nodep->rhsp(), VarRef))) {
|
|
||||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Incrementation in this context.");
|
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Incrementation in this context.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
AstNodeExpr* const readp = nodep->rhsp();
|
||||||
|
AstNodeExpr* const writep = nodep->thsp();
|
||||||
|
|
||||||
AstConst* const constp = VN_AS(nodep->lhsp(), Const);
|
AstConst* const constp = VN_AS(nodep->lhsp(), Const);
|
||||||
UASSERT_OBJ(nodep, constp, "Expecting CONST");
|
UASSERT_OBJ(nodep, constp, "Expecting CONST");
|
||||||
|
|
@ -254,8 +255,9 @@ private:
|
||||||
// Prepare a temporary variable
|
// Prepare a temporary variable
|
||||||
FileLine* const fl = backp->fileline();
|
FileLine* const fl = backp->fileline();
|
||||||
const string name = string{"__Vincrement"} + cvtToStr(++m_modIncrementsNum);
|
const string name = string{"__Vincrement"} + cvtToStr(++m_modIncrementsNum);
|
||||||
AstVar* const varp = new AstVar{fl, VVarType::BLOCKTEMP, name, VFlagChildDType{},
|
AstVar* const varp = new AstVar{
|
||||||
varrefp->varp()->subDTypep()->cloneTree(true)};
|
fl, VVarType::BLOCKTEMP, name, VFlagChildDType{},
|
||||||
|
new AstRefDType{fl, AstRefDType::FlagTypeOfExpr{}, readp->cloneTree(true)}};
|
||||||
if (m_ftaskp) varp->funcLocal(true);
|
if (m_ftaskp) varp->funcLocal(true);
|
||||||
|
|
||||||
// Declare the variable
|
// Declare the variable
|
||||||
|
|
@ -264,30 +266,29 @@ private:
|
||||||
// Define what operation will we be doing
|
// Define what operation will we be doing
|
||||||
AstNodeExpr* operp;
|
AstNodeExpr* operp;
|
||||||
if (VN_IS(nodep, PostSub) || VN_IS(nodep, PreSub)) {
|
if (VN_IS(nodep, PostSub) || VN_IS(nodep, PreSub)) {
|
||||||
operp = new AstSub{fl, new AstVarRef{fl, varrefp->varp(), VAccess::READ}, newconstp};
|
operp = new AstSub{fl, readp->cloneTree(true), newconstp};
|
||||||
} else {
|
} else {
|
||||||
operp = new AstAdd{fl, new AstVarRef{fl, varrefp->varp(), VAccess::READ}, newconstp};
|
operp = new AstAdd{fl, readp->cloneTree(true), newconstp};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VN_IS(nodep, PreAdd) || VN_IS(nodep, PreSub)) {
|
if (VN_IS(nodep, PreAdd) || VN_IS(nodep, PreSub)) {
|
||||||
// PreAdd/PreSub operations
|
// PreAdd/PreSub operations
|
||||||
// Immediately after declaration - increment it by one
|
// Immediately after declaration - increment it by one
|
||||||
varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varrefp->varp(), VAccess::WRITE},
|
varp->addNextHere(new AstAssign{fl, writep->cloneTree(true),
|
||||||
new AstVarRef{fl, varp, VAccess::READ}});
|
new AstVarRef{fl, varp, VAccess::READ}});
|
||||||
// Immediately after incrementing - assign it to the original variable
|
// Immediately after incrementing - assign it to the original variable
|
||||||
varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, operp});
|
varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, operp});
|
||||||
} else {
|
} else {
|
||||||
// PostAdd/PostSub operations
|
// PostAdd/PostSub operations
|
||||||
// assign the original variable to the temporary one
|
// assign the original variable to the temporary one
|
||||||
varp->addNextHere(
|
varp->addNextHere(new AstAssign{fl, writep->cloneTree(true), operp});
|
||||||
new AstAssign{fl, new AstVarRef{fl, varrefp->varp(), VAccess::WRITE}, operp});
|
|
||||||
// Increment the original variable by one
|
// Increment the original variable by one
|
||||||
varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||||
new AstVarRef{fl, varrefp->varp(), VAccess::READ}});
|
readp->cloneTree(true)});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the node with the temporary
|
// Replace the node with the temporary
|
||||||
nodep->replaceWith(new AstVarRef{varrefp->fileline(), varp, VAccess::READ});
|
nodep->replaceWith(new AstVarRef{readp->fileline(), varp, VAccess::READ});
|
||||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
}
|
}
|
||||||
void visit(AstPreAdd* nodep) override { prepost_visit(nodep); }
|
void visit(AstPreAdd* nodep) override { prepost_visit(nodep); }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2023 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(
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2023 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
class Base #(type T = integer);
|
||||||
|
T m_count;
|
||||||
|
|
||||||
|
function void test1();
|
||||||
|
if (this.m_count != 0) $stop;
|
||||||
|
if (this.m_count++ != 0) $stop;
|
||||||
|
if (this.m_count != 1) $stop;
|
||||||
|
if (m_count++ != 1) $stop;
|
||||||
|
if (this.m_count != 2) $stop;
|
||||||
|
endfunction
|
||||||
|
endclass
|
||||||
|
|
||||||
|
class Cls #(type T = integer) extends Base #(T);
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module t;
|
||||||
|
Cls #(int) c;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
c = new;
|
||||||
|
c.test1();
|
||||||
|
|
||||||
|
c.m_count = 0;
|
||||||
|
if (c.m_count != 0) $stop;
|
||||||
|
if (c.m_count++ != 0) $stop;
|
||||||
|
if (c.m_count != 1) $stop;
|
||||||
|
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -17,9 +17,6 @@
|
||||||
%Error-UNSUPPORTED: t/t_increment_bad.v:27:29: Unsupported: Incrementation in this context.
|
%Error-UNSUPPORTED: t/t_increment_bad.v:27:29: Unsupported: Incrementation in this context.
|
||||||
27 | pos = (a > 0) ? a++ : --b;
|
27 | pos = (a > 0) ? a++ : --b;
|
||||||
| ^~
|
| ^~
|
||||||
%Error-UNSUPPORTED: t/t_increment_bad.v:29:24: Unsupported: Incrementation in this context.
|
|
||||||
29 | pos = array[0][0]++;
|
|
||||||
| ^~
|
|
||||||
%Error-UNSUPPORTED: t/t_increment_bad.v:32:37: Unsupported: Incrementation in this context.
|
%Error-UNSUPPORTED: t/t_increment_bad.v:32:37: Unsupported: Incrementation in this context.
|
||||||
32 | assert property (@(posedge clk) a++ >= 0);
|
32 | assert property (@(posedge clk) a++ >= 0);
|
||||||
| ^~
|
| ^~
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,16 @@ module t (/*AUTOARG*/
|
||||||
r = real'(96'shf0000000_00000000_00000000);
|
r = real'(96'shf0000000_00000000_00000000);
|
||||||
if (r != -4951760157141521099596496896.0) $stop;
|
if (r != -4951760157141521099596496896.0) $stop;
|
||||||
|
|
||||||
|
r = 1.5;
|
||||||
|
if (r++ != 1.5) $stop;
|
||||||
|
if (r != 2.5) $stop;
|
||||||
|
if (r-- != 2.5) $stop;
|
||||||
|
if (r != 1.5) $stop;
|
||||||
|
if (++r != 2.5) $stop;
|
||||||
|
if (r != 2.5) $stop;
|
||||||
|
if (--r != 1.5) $stop;
|
||||||
|
if (r != 1.5) $stop;
|
||||||
|
|
||||||
r = 1.23456;
|
r = 1.23456;
|
||||||
s = $sformatf("%g", r);
|
s = $sformatf("%g", r);
|
||||||
`checks(s, "1.23456");
|
`checks(s, "1.23456");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/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 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(
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// Copyright 2023 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
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
reg [6:0] w7;
|
||||||
|
reg [14:0] w15;
|
||||||
|
reg [30:0] w31;
|
||||||
|
reg [62:0] w63;
|
||||||
|
reg [94:0] w95;
|
||||||
|
|
||||||
|
integer cyc = 0;
|
||||||
|
|
||||||
|
// Test loop
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
`ifdef TEST_VERBOSE
|
||||||
|
$write("[%0t] cyc==%0d\n", $time, cyc);
|
||||||
|
`endif
|
||||||
|
cyc <= cyc + 1;
|
||||||
|
if (cyc==0) begin
|
||||||
|
// Setup
|
||||||
|
w7 = {7{1'b1}};
|
||||||
|
w15 = {15{1'b1}};
|
||||||
|
w31 = {31{1'b1}};
|
||||||
|
w63 = {63{1'b1}};
|
||||||
|
w95 = {95{1'b1}};
|
||||||
|
end
|
||||||
|
else if (cyc == 1) begin
|
||||||
|
if (w7++ != {7{1'b1}}) $stop;
|
||||||
|
if (w7 != {7{1'b0}}) $stop;
|
||||||
|
if (w7-- != {7{1'b0}}) $stop;
|
||||||
|
if (w7 != {7{1'b1}}) $stop;
|
||||||
|
if (++w7 != {7{1'b0}}) $stop;
|
||||||
|
if (w7 != {7{1'b0}}) $stop;
|
||||||
|
if (--w7 != {7{1'b1}}) $stop;
|
||||||
|
if (w7 != {7{1'b1}}) $stop;
|
||||||
|
|
||||||
|
if (w15++ != {15{1'b1}}) $stop;
|
||||||
|
if (w15 != {15{1'b0}}) $stop;
|
||||||
|
if (w15-- != {15{1'b0}}) $stop;
|
||||||
|
if (w15 != {15{1'b1}}) $stop;
|
||||||
|
if (++w15 != {15{1'b0}}) $stop;
|
||||||
|
if (w15 != {15{1'b0}}) $stop;
|
||||||
|
if (--w15 != {15{1'b1}}) $stop;
|
||||||
|
if (w15 != {15{1'b1}}) $stop;
|
||||||
|
|
||||||
|
if (w31++ != {31{1'b1}}) $stop;
|
||||||
|
if (w31 != {31{1'b0}}) $stop;
|
||||||
|
if (w31-- != {31{1'b0}}) $stop;
|
||||||
|
if (w31 != {31{1'b1}}) $stop;
|
||||||
|
if (++w31 != {31{1'b0}}) $stop;
|
||||||
|
if (w31 != {31{1'b0}}) $stop;
|
||||||
|
if (--w31 != {31{1'b1}}) $stop;
|
||||||
|
if (w31 != {31{1'b1}}) $stop;
|
||||||
|
|
||||||
|
if (w63++ != {63{1'b1}}) $stop;
|
||||||
|
if (w63 != {63{1'b0}}) $stop;
|
||||||
|
if (w63-- != {63{1'b0}}) $stop;
|
||||||
|
if (w63 != {63{1'b1}}) $stop;
|
||||||
|
if (++w63 != {63{1'b0}}) $stop;
|
||||||
|
if (w63 != {63{1'b0}}) $stop;
|
||||||
|
if (--w63 != {63{1'b1}}) $stop;
|
||||||
|
if (w63 != {63{1'b1}}) $stop;
|
||||||
|
|
||||||
|
if (w95++ != {95{1'b1}}) $stop;
|
||||||
|
if (w95 != {95{1'b0}}) $stop;
|
||||||
|
if (w95-- != {95{1'b0}}) $stop;
|
||||||
|
if (w95 != {95{1'b1}}) $stop;
|
||||||
|
if (++w95 != {95{1'b0}}) $stop;
|
||||||
|
if (w95 != {95{1'b0}}) $stop;
|
||||||
|
if (--w95 != {95{1'b1}}) $stop;
|
||||||
|
if (w95 != {95{1'b1}}) $stop;
|
||||||
|
end
|
||||||
|
else if (cyc==99) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue